aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/net/e100.c82
-rw-r--r--drivers/net/e1000/LICENSE339
-rw-r--r--drivers/net/e1000/Makefile35
-rw-r--r--drivers/net/e1000/e1000.h59
-rw-r--r--drivers/net/e1000/e1000_ethtool.c150
-rw-r--r--drivers/net/e1000/e1000_hw.c1074
-rw-r--r--drivers/net/e1000/e1000_hw.h86
-rw-r--r--drivers/net/e1000/e1000_main.c271
-rw-r--r--drivers/net/e1000/e1000_osdep.h35
-rw-r--r--drivers/net/e1000/e1000_param.c47
-rw-r--r--drivers/net/hp100.c5
-rw-r--r--drivers/net/ixgb/Makefile38
-rw-r--r--drivers/net/ixgb/ixgb.h38
-rw-r--r--drivers/net/ixgb/ixgb_ee.c36
-rw-r--r--drivers/net/ixgb/ixgb_ee.h36
-rw-r--r--drivers/net/ixgb/ixgb_ethtool.c36
-rw-r--r--drivers/net/ixgb/ixgb_hw.c36
-rw-r--r--drivers/net/ixgb/ixgb_hw.h36
-rw-r--r--drivers/net/ixgb/ixgb_ids.h36
-rw-r--r--drivers/net/ixgb/ixgb_main.c46
-rw-r--r--drivers/net/ixgb/ixgb_osdep.h36
-rw-r--r--drivers/net/ixgb/ixgb_param.c36
-rw-r--r--drivers/net/phy/fixed.c6
-rw-r--r--drivers/net/phy/phy_device.c8
-rw-r--r--drivers/net/sky2.c548
-rw-r--r--drivers/net/sky2.h62
-rw-r--r--drivers/net/spider_net.c6
-rw-r--r--drivers/net/wireless/airo.c23
-rw-r--r--drivers/net/wireless/ipw2100.c11
29 files changed, 1502 insertions, 1755 deletions
diff --git a/drivers/net/e100.c b/drivers/net/e100.c
index dc5e38aefca..26073c34521 100644
--- a/drivers/net/e100.c
+++ b/drivers/net/e100.c
@@ -1,27 +1,27 @@
/*******************************************************************************
-
- Copyright(c) 1999 - 2006 Intel Corporation. All rights reserved.
+ Intel PRO/100 Linux driver
+ Copyright(c) 1999 - 2006 Intel Corporation.
This program is free software; you can redistribute it and/or modify it
- under the terms of the GNU General Public License as published by the Free
- Software Foundation; either version 2 of the License, or (at your option)
- any later version.
+ under the terms and conditions of the GNU General Public License,
+ version 2, as published by the Free Software Foundation.
- This program is distributed in the hope that it will be useful, but WITHOUT
+ This program is distributed in the hope it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
more details.
You should have received a copy of the GNU General Public License along with
- this program; if not, write to the Free Software Foundation, Inc., 59
- Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- The full GNU General Public License is included in this distribution in the
- file called LICENSE.
+ The full GNU General Public License is included in this distribution in
+ the file called "COPYING".
Contact Information:
Linux NICS <linux.nics@intel.com>
+ e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
*******************************************************************************/
@@ -159,7 +159,7 @@
#define DRV_NAME "e100"
#define DRV_EXT "-NAPI"
-#define DRV_VERSION "3.5.16-k2"DRV_EXT
+#define DRV_VERSION "3.5.17-k2"DRV_EXT
#define DRV_DESCRIPTION "Intel(R) PRO/100 Network Driver"
#define DRV_COPYRIGHT "Copyright(c) 1999-2006 Intel Corporation"
#define PFX DRV_NAME ": "
@@ -1657,13 +1657,14 @@ static int e100_tx_clean(struct nic *nic)
spin_lock(&nic->cb_lock);
- DPRINTK(TX_DONE, DEBUG, "cb->status = 0x%04X\n",
- nic->cb_to_clean->status);
-
/* Clean CBs marked complete */
for(cb = nic->cb_to_clean;
cb->status & cpu_to_le16(cb_complete);
cb = nic->cb_to_clean = cb->next) {
+ DPRINTK(TX_DONE, DEBUG, "cb[%d]->status = 0x%04X\n",
+ (int)(((void*)cb - (void*)nic->cbs)/sizeof(struct cb)),
+ cb->status);
+
if(likely(cb->skb != NULL)) {
nic->net_stats.tx_packets++;
nic->net_stats.tx_bytes += cb->skb->len;
@@ -2572,7 +2573,7 @@ static int __devinit e100_probe(struct pci_dev *pdev,
#ifdef CONFIG_NET_POLL_CONTROLLER
netdev->poll_controller = e100_netpoll;
#endif
- strcpy(netdev->name, pci_name(pdev));
+ strncpy(netdev->name, pci_name(pdev), sizeof(netdev->name) - 1);
nic = netdev_priv(netdev);
nic->netdev = netdev;
@@ -2714,68 +2715,56 @@ static void __devexit e100_remove(struct pci_dev *pdev)
}
}
-#ifdef CONFIG_PM
static int e100_suspend(struct pci_dev *pdev, pm_message_t state)
{
struct net_device *netdev = pci_get_drvdata(pdev);
struct nic *nic = netdev_priv(netdev);
- int retval;
- if(netif_running(netdev))
+ if (netif_running(netdev))
e100_down(nic);
e100_hw_reset(nic);
netif_device_detach(netdev);
+#ifdef CONFIG_PM
pci_save_state(pdev);
- retval = pci_enable_wake(pdev, pci_choose_state(pdev, state),
- nic->flags & (wol_magic | e100_asf(nic)));
- if (retval)
- DPRINTK(PROBE,ERR, "Error enabling wake\n");
+ if (nic->flags & (wol_magic | e100_asf(nic)))
+#else
+ if (nic->flags & (wol_magic))
+#endif
+ pci_enable_wake(pdev, pci_choose_state(pdev, state), 1);
+ else
+ /* disable PME */
+ pci_enable_wake(pdev, 0, 0);
+
pci_disable_device(pdev);
- retval = pci_set_power_state(pdev, pci_choose_state(pdev, state));
- if (retval)
- DPRINTK(PROBE,ERR, "Error %d setting power state\n", retval);
+ pci_set_power_state(pdev, pci_choose_state(pdev, state));
return 0;
}
+#ifdef CONFIG_PM
static int e100_resume(struct pci_dev *pdev)
{
struct net_device *netdev = pci_get_drvdata(pdev);
struct nic *nic = netdev_priv(netdev);
- int retval;
- retval = pci_set_power_state(pdev, PCI_D0);
- if (retval)
- DPRINTK(PROBE,ERR, "Error waking adapter\n");
+ pci_set_power_state(pdev, PCI_D0);
pci_restore_state(pdev);
/* ack any pending wake events, disable PME */
- retval = pci_enable_wake(pdev, 0, 0);
- if (retval)
- DPRINTK(PROBE,ERR, "Error clearing wake events\n");
+ pci_enable_wake(pdev, 0, 0);
netif_device_attach(netdev);
- if(netif_running(netdev))
+ if (netif_running(netdev))
e100_up(nic);
return 0;
}
-#endif
+#endif /* CONFIG_PM */
static void e100_shutdown(struct pci_dev *pdev)
{
- struct net_device *netdev = pci_get_drvdata(pdev);
- struct nic *nic = netdev_priv(netdev);
- int retval;
-
-#ifdef CONFIG_PM
- retval = pci_enable_wake(pdev, 0, nic->flags & (wol_magic | e100_asf(nic)));
-#else
- retval = pci_enable_wake(pdev, 0, nic->flags & (wol_magic));
-#endif
- if (retval)
- DPRINTK(PROBE,ERR, "Error enabling wake\n");
+ e100_suspend(pdev, PMSG_SUSPEND);
}
/* ------------------ PCI Error Recovery infrastructure -------------- */
@@ -2859,8 +2848,9 @@ static struct pci_driver e100_driver = {
.id_table = e100_id_table,
.probe = e100_probe,
.remove = __devexit_p(e100_remove),
-#ifdef CONFIG_PM
+ /* Power Management hooks */
.suspend = e100_suspend,
+#ifdef CONFIG_PM
.resume = e100_resume,
#endif
.shutdown = e100_shutdown,
diff --git a/drivers/net/e1000/LICENSE b/drivers/net/e1000/LICENSE
deleted file mode 100644
index 5f297e5bb46..00000000000
--- a/drivers/net/e1000/LICENSE
+++ /dev/null
@@ -1,339 +0,0 @@
-
-"This software program is licensed subject to the GNU General Public License
-(GPL). Version 2, June 1991, available at
-<http://www.fsf.org/copyleft/gpl.html>"
-
-GNU General Public License
-
-Version 2, June 1991
-
-Copyright (C) 1989, 1991 Free Software Foundation, Inc.
-59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
-
-Everyone is permitted to copy and distribute verbatim copies of this license
-document, but changing it is not allowed.
-
-Preamble
-
-The licenses for most software are designed to take away your freedom to
-share and change it. By contrast, the GNU General Public License is intended
-to guarantee your freedom to share and change free software--to make sure
-the software is free for all its users. This General Public License applies
-to most of the Free Software Foundation's software and to any other program
-whose authors commit to using it. (Some other Free Software Foundation
-software is covered by the GNU Library General Public License instead.) You
-can apply it to your programs, too.
-
-When we speak of free software, we are referring to freedom, not price. Our
-General Public Licenses are designed to make sure that you have the freedom
-to distribute copies of free software (and charge for this service if you
-wish), that you receive source code or can get it if you want it, that you
-can change the software or use pieces of it in new free programs; and that
-you know you can do these things.
-
-To protect your rights, we need to make restrictions that forbid anyone to
-deny you these rights or to ask you to surrender the rights. These
-restrictions translate to certain responsibilities for you if you distribute
-copies of the software, or if you modify it.
-
-For example, if you distribute copies of such a program, whether gratis or
-for a fee, you must give the recipients all the rights that you have. You
-must make sure that they, too, receive or can get the source code. And you
-must show them these terms so they know their rights.
-
-We protect your rights with two steps: (1) copyright the software, and (2)
-offer you this license which gives you legal permission to copy, distribute
-and/or modify the software.
-
-Also, for each author's protection and ours, we want to make certain that
-everyone understands that there is no warranty for this free software. If
-the software is modified by someone else and passed on, we want its
-recipients to know that what they have is not the original, so that any
-problems introduced by others will not reflect on the original authors'
-reputations.
-
-Finally, any free program is threatened constantly by software patents. We
-wish to avoid the danger that redistributors of a free program will
-individually obtain patent licenses, in effect making the program
-proprietary. To prevent this, we have made it clear that any patent must be
-licensed for everyone's free use or not licensed at all.
-
-The precise terms and conditions for copying, distribution and modification
-follow.
-
-TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-
-0. This License applies to any program or other work which contains a notice
- placed by the copyright holder saying it may be distributed under the
- terms of this General Public License. The "Program", below, refers to any
- such program or work, and a "work based on the Program" means either the
- Program or any derivative work under copyright law: that is to say, a
- work containing the Program or a portion of it, either verbatim or with
- modifications and/or translated into another language. (Hereinafter,
- translation is included without limitation in the term "modification".)
- Each licensee is addressed as "you".
-
- Activities other than copying, distribution and modification are not
- covered by this License; they are outside its scope. The act of running
- the Program is not restricted, and the output from the Program is covered
- only if its contents constitute a work based on the Program (independent
- of having been made by running the Program). Whether that is true depends
- on what the Program does.
-
-1. You may copy and distribute verbatim copies of the Program's source code
- as you receive it, in any medium, provided that you conspicuously and
- appropriately publish on each copy an appropriate copyright notice and
- disclaimer of warranty; keep intact all the notices that refer to this
- License and to the absence of any warranty; and give any other recipients
- of the Program a copy of this License along with the Program.
-
- You may charge a fee for the physical act of transferring a copy, and you
- may at your option offer warranty protection in exchange for a fee.
-
-2. You may modify your copy or copies of the Program or any portion of it,
- thus forming a work based on the Program, and copy and distribute such
- modifications or work under the terms of Section 1 above, provided that
- you also meet all of these conditions:
-
- * a) You must cause the modified files to carry prominent notices stating
- that you changed the files and the date of any change.
-
- * b) You must cause any work that you distribute or publish, that in
- whole or in part contains or is derived from the Program or any part
- thereof, to be licensed as a whole at no charge to all third parties
- under the terms of this License.
-
- * c) If the modified program normally reads commands interactively when
- run, you must cause it, when started running for such interactive
- use in the most ordinary way, to print or display an announcement
- including an appropriate copyright notice and a notice that there is
- no warranty (or else, saying that you provide a warranty) and that
- users may redistribute the program under these conditions, and
- telling the user how to view a copy of this License. (Exception: if
- the Program itself is interactive but does not normally print such
- an announcement, your work based on the Program is not required to
- print an announcement.)
-
- These requirements apply to the modified work as a whole. If identifiable
- sections of that work are not derived from the Program, and can be
- reasonably considered independent and separate works in themselves, then
- this License, and its terms, do not apply to those sections when you
- distribute them as separate works. But when you distribute the same
- sections as part of a whole which is a work based on the Program, the
- distribution of the whole must be on the terms of this License, whose
- permissions for other licensees extend to the entire whole, and thus to
- each and every part regardless of who wrote it.
-
- Thus, it is not the intent of this section to claim rights or contest
- your rights to work written entirely by you; rather, the intent is to
- exercise the right to control the distribution of derivative or
- collective works based on the Program.
-
- In addition, mere aggregation of another work not based on the Program
- with the Program (or with a work based on the Program) on a volume of a
- storage or distribution medium does not bring the other work under the
- scope of this License.
-
-3. You may copy and distribute the Program (or a work based on it, under
- Section 2) in object code or executable form under the terms of Sections
- 1 and 2 above provided that you also do one of the following:
-
- * a) Accompany it with the complete corresponding machine-readable source
- code, which must be distributed under the terms of Sections 1 and 2
- above on a medium customarily used for software interchange; or,
-
- * b) Accompany it with a written offer, valid for at least three years,
- to give any third party, for a charge no more than your cost of
- physically performing source distribution, a complete machine-
- readable copy of the corresponding source code, to be distributed
- under the terms of Sections 1 and 2 above on a medium customarily
- used for software interchange; or,
-
- * c) Accompany it with the information you received as to the offer to
- distribute corresponding source code. (This alternative is allowed
- only for noncommercial distribution and only if you received the
- program in object code or executable form with such an offer, in
- accord with Subsection b above.)
-
- The source code for a work means the preferred form of the work for
- making modifications to it. For an executable work, complete source code
- means all the source code for all modules it contains, plus any
- associated interface definition files, plus the scripts used to control
- compilation and installation of the executable. However, as a special
- exception, the source code distributed need not include anything that is
- normally distributed (in either source or binary form) with the major
- components (compiler, kernel, and so on) of the operating system on which
- the executable runs, unless that component itself accompanies the
- executable.
-
- If distribution of executable or object code is made by offering access
- to copy from a designated place, then offering equivalent access to copy
- the source code from the same place counts as distribution of the source
- code, even though third parties are not compelled to copy the source
- along with the object code.
-
-4. You may not copy, modify, sublicense, or distribute the Program except as
- expressly provided under this License. Any attempt otherwise to copy,
- modify, sublicense or distribute the Program is void, and will
- automatically terminate your rights under this License. However, parties
- who have received copies, or rights, from you under this License will not
- have their licenses terminated so long as such parties remain in full
- compliance.
-
-5. You are not required to accept this License, since you have not signed
- it. However, nothing else grants you permission to modify or distribute
- the Program or its derivative works. These actions are prohibited by law
- if you do not accept this License. Therefore, by modifying or
- distributing the Program (or any work based on the Program), you
- indicate your acceptance of this License to do so, and all its terms and
- conditions for copying, distributing or modifying the Program or works
- based on it.
-
-6. Each time you redistribute the Program (or any work based on the
- Program), the recipient automatically receives a license from the
- original licensor to copy, distribute or modify the Program subject to
- these terms and conditions. You may not impose any further restrictions
- on the recipients' exercise of the rights granted herein. You are not
- responsible for enforcing compliance by third parties to this License.
-
-7. If, as a consequence of a court judgment or allegation of patent
- infringement or for any other reason (not limited to patent issues),
- conditions are imposed on you (whether by court order, agreement or
- otherwise) that contradict the conditions of this License, they do not
- excuse you from the conditions of this License. If you cannot distribute
- so as to satisfy simultaneously your obligations under this License and
- any other pertinent obligations, then as a consequence you may not
- distribute the Program at all. For example, if a patent license would
- not permit royalty-free redistribution of the Program by all those who
- receive copies directly or indirectly through you, then the only way you
- could satisfy both it and this License would be to refrain entirely from
- distribution of the Program.
-
- If any portion of this section is held invalid or unenforceable under any
- particular circumstance, the balance of the section is intended to apply
- and the section as a whole is intended to apply in other circumstances.
-
- It is not the purpose of this section to induce you to infringe any
- patents or other property right claims or to contest validity of any
- such claims; this section has the sole purpose of protecting the
- integrity of the free software distribution system, which is implemented
- by public license practices. Many people have made generous contributions
- to the wide range of software distributed through that system in
- reliance on consistent application of that system; it is up to the
- author/donor to decide if he or she is willing to distribute software
- through any other system and a licensee cannot impose that choice.
-
- This section is intended to make thoroughly clear what is believed to be
- a consequence of the rest of this License.
-
-8. If the distribution and/or use of the Program is restricted in certain
- countries either by patents or by copyrighted interfaces, the original
- copyright holder who places the Program under this License may add an
- explicit geographical distribution limitation excluding those countries,
- so that distribution is permitted only in or among countries not thus
- excluded. In such case, this License incorporates the limitation as if
- written in the body of this License.
-
-9. The Free Software Foundation may publish revised and/or new versions of
- the General Public License from time to time. Such new versions will be
- similar in spirit to the present version, but may differ in detail to
- address new problems or concerns.
-
- Each version is given a distinguishing version number. If the Program
- specifies a version number of this License which applies to it and "any
- later version", you have the option of following the terms and
- conditions either of that version or of any later version published by
- the Free Software Foundation. If the Program does not specify a version
- number of this License, you may choose any version ever published by the
- Free Software Foundation.
-
-10. If you wish to incorporate parts of the Program into other free programs
- whose distribution conditions are different, write to the author to ask
- for permission. For software which is copyrighted by the Free Software
- Foundation, write to the Free Software Foundation; we sometimes make
- exceptions for this. Our decision will be guided by the two goals of
- preserving the free status of all derivatives of our free software and
- of promoting the sharing and reuse of software generally.
-
- NO WARRANTY
-
-11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
- FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
- OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
- PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER
- EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE
- ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH
- YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL
- NECESSARY SERVICING, REPAIR OR CORRECTION.
-
-12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
- WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
- REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR
- DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL
- DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM
- (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED
- INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF
- THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR
- OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
-
-END OF TERMS AND CONDITIONS
-
-How to Apply These Terms to Your New Programs
-
-If you develop a new program, and you want it to be of the greatest
-possible use to the public, the best way to achieve this is to make it free
-software which everyone can redistribute and change under these terms.
-
-To do so, attach the following notices to the program. It is safest to
-attach them to the start of each source file to most effectively convey the
-exclusion of warranty; and each file should have at least the "copyright"
-line and a pointer to where the full notice is found.
-
-one line to give the program's name and an idea of what it does.
-Copyright (C) yyyy name of author
-
-This program is free software; you can redistribute it and/or modify it
-under the terms of the GNU General Public License as published by the Free
-Software Foundation; either version 2 of the License, or (at your option)
-any later version.
-
-This program is distributed in the hope that it will be useful, but WITHOUT
-ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
-more details.
-
-You should have received a copy of the GNU General Public License along with
-this program; if not, write to the Free Software Foundation, Inc., 59
-Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-Also add information on how to contact you by electronic and paper mail.
-
-If the program is interactive, make it output a short notice like this when
-it starts in an interactive mode:
-
-Gnomovision version 69, Copyright (C) year name of author Gnomovision comes
-with ABSOLUTELY NO WARRANTY; for details type 'show w'. This is free
-software, and you are welcome to redistribute it under certain conditions;
-type 'show c' for details.
-
-The hypothetical commands 'show w' and 'show c' should show the appropriate
-parts of the General Public License. Of course, the commands you use may be
-called something other than 'show w' and 'show c'; they could even be
-mouse-clicks or menu items--whatever suits your program.
-
-You should also get your employer (if you work as a programmer) or your
-school, if any, to sign a "copyright disclaimer" for the program, if
-necessary. Here is a sample; alter the names:
-
-Yoyodyne, Inc., hereby disclaims all copyright interest in the program
-'Gnomovision' (which makes passes at compilers) written by James Hacker.
-
-signature of Ty Coon, 1 April 1989
-Ty Coon, President of Vice
-
-This General Public License does not permit incorporating your program into
-proprietary programs. If your program is a subroutine library, you may
-consider it more useful to permit linking proprietary applications with the
-library. If this is what you want to do, use the GNU Library General Public
-License instead of this License.
diff --git a/drivers/net/e1000/Makefile b/drivers/net/e1000/Makefile
index 5dea2b7dea4..4a6ab152245 100644
--- a/drivers/net/e1000/Makefile
+++ b/drivers/net/e1000/Makefile
@@ -1,25 +1,24 @@
################################################################################
#
-#
-# Copyright(c) 1999 - 2006 Intel Corporation. All rights reserved.
-#
-# This program is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License as published by the Free
-# Software Foundation; either version 2 of the License, or (at your option)
-# any later version.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+# Intel PRO/1000 Linux driver
+# Copyright(c) 1999 - 2006 Intel Corporation.
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms and conditions of the GNU General Public License,
+# version 2, as published by the Free Software Foundation.
+#
+# This program is distributed in the hope it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
# more details.
-#
+#
# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 59
-# Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-#
-# The full GNU General Public License is included in this distribution in the
-# file called LICENSE.
-#
+# this program; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# The full GNU General Public License is included in this distribution in
+# the file called "COPYING".
+#
# Contact Information:
# Linux NICS <linux.nics@intel.com>
# e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
diff --git a/drivers/net/e1000/e1000.h b/drivers/net/e1000/e1000.h
index 98afa9c2057..7ecce438d25 100644
--- a/drivers/net/e1000/e1000.h
+++ b/drivers/net/e1000/e1000.h
@@ -1,25 +1,24 @@
/*******************************************************************************
-
- Copyright(c) 1999 - 2006 Intel Corporation. All rights reserved.
-
- This program is free software; you can redistribute it and/or modify it
- under the terms of the GNU General Public License as published by the Free
- Software Foundation; either version 2 of the License, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful, but WITHOUT
- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ Intel PRO/1000 Linux driver
+ Copyright(c) 1999 - 2006 Intel Corporation.
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms and conditions of the GNU General Public License,
+ version 2, as published by the Free Software Foundation.
+
+ This program is distributed in the hope it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
more details.
-
+
You should have received a copy of the GNU General Public License along with
- this program; if not, write to the Free Software Foundation, Inc., 59
- Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
- The full GNU General Public License is included in this distribution in the
- file called LICENSE.
-
+ this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+
+ The full GNU General Public License is included in this distribution in
+ the file called "COPYING".
+
Contact Information:
Linux NICS <linux.nics@intel.com>
e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
@@ -346,29 +345,9 @@ struct e1000_adapter {
};
enum e1000_state_t {
- __E1000_DRIVER_TESTING,
+ __E1000_TESTING,
__E1000_RESETTING,
+ __E1000_DOWN
};
-/* e1000_main.c */
-extern char e1000_driver_name[];
-extern char e1000_driver_version[];
-int e1000_up(struct e1000_adapter *adapter);
-void e1000_down(struct e1000_adapter *adapter);
-void e1000_reset(struct e1000_adapter *adapter);
-void e1000_reinit_locked(struct e1000_adapter *adapter);
-int e1000_setup_all_tx_resources(struct e1000_adapter *adapter);
-void e1000_free_all_tx_resources(struct e1000_adapter *adapter);
-int e1000_setup_all_rx_resources(struct e1000_adapter *adapter);
-void e1000_free_all_rx_resources(struct e1000_adapter *adapter);
-void e1000_update_stats(struct e1000_adapter *adapter);
-int e1000_set_spd_dplx(struct e1000_adapter *adapter, uint16_t spddplx);
-
-/* e1000_ethtool.c */
-void e1000_set_ethtool_ops(struct net_device *netdev);
-
-/* e1000_param.c */
-void e1000_check_options(struct e1000_adapter *adapter);
-
-
#endif /* _E1000_H_ */
diff --git a/drivers/net/e1000/e1000_ethtool.c b/drivers/net/e1000/e1000_ethtool.c
index e39aa1fc4d1..778ede3c021 100644
--- a/drivers/net/e1000/e1000_ethtool.c
+++ b/drivers/net/e1000/e1000_ethtool.c
@@ -1,25 +1,24 @@
/*******************************************************************************
-
- Copyright(c) 1999 - 2006 Intel Corporation. All rights reserved.
-
- This program is free software; you can redistribute it and/or modify it
- under the terms of the GNU General Public License as published by the Free
- Software Foundation; either version 2 of the License, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful, but WITHOUT
- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ Intel PRO/1000 Linux driver
+ Copyright(c) 1999 - 2006 Intel Corporation.
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms and conditions of the GNU General Public License,
+ version 2, as published by the Free Software Foundation.
+
+ This program is distributed in the hope it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
more details.
-
+
You should have received a copy of the GNU General Public License along with
- this program; if not, write to the Free Software Foundation, Inc., 59
- Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
- The full GNU General Public License is included in this distribution in the
- file called LICENSE.
-
+ this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+
+ The full GNU General Public License is included in this distribution in
+ the file called "COPYING".
+
Contact Information:
Linux NICS <linux.nics@intel.com>
e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
@@ -33,6 +32,21 @@
#include <asm/uaccess.h>
+extern char e1000_driver_name[];
+extern char e1000_driver_version[];
+
+extern int e1000_up(struct e1000_adapter *adapter);
+extern void e1000_down(struct e1000_adapter *adapter);
+extern void e1000_reinit_locked(struct e1000_adapter *adapter);
+extern void e1000_reset(struct e1000_adapter *adapter);
+extern int e1000_set_spd_dplx(struct e1000_adapter *adapter, uint16_t spddplx);
+extern int e1000_setup_all_rx_resources(struct e1000_adapter *adapter);
+extern int e1000_setup_all_tx_resources(struct e1000_adapter *adapter);
+extern void e1000_free_all_rx_resources(struct e1000_adapter *adapter);
+extern void e1000_free_all_tx_resources(struct e1000_adapter *adapter);
+extern void e1000_update_stats(struct e1000_adapter *adapter);
+
+
struct e1000_stats {
char stat_string[ETH_GSTRING_LEN];
int sizeof_stat;
@@ -42,26 +56,30 @@ struct e1000_stats {
#define E1000_STAT(m) sizeof(((struct e1000_adapter *)0)->m), \
offsetof(struct e1000_adapter, m)
static const struct e1000_stats e1000_gstrings_stats[] = {
- { "rx_packets", E1000_STAT(net_stats.rx_packets) },
- { "tx_packets", E1000_STAT(net_stats.tx_packets) },
- { "rx_bytes", E1000_STAT(net_stats.rx_bytes) },
- { "tx_bytes", E1000_STAT(net_stats.tx_bytes) },
- { "rx_errors", E1000_STAT(net_stats.rx_errors) },
- { "tx_errors", E1000_STAT(net_stats.tx_errors) },
+ { "rx_packets", E1000_STAT(stats.gprc) },
+ { "tx_packets", E1000_STAT(stats.gptc) },
+ { "rx_bytes", E1000_STAT(stats.gorcl) },
+ { "tx_bytes", E1000_STAT(stats.gotcl) },
+ { "rx_broadcast", E1000_STAT(stats.bprc) },
+ { "tx_broadcast", E1000_STAT(stats.bptc) },
+ { "rx_multicast", E1000_STAT(stats.mprc) },
+ { "tx_multicast", E1000_STAT(stats.mptc) },
+ { "rx_errors", E1000_STAT(stats.rxerrc) },
+ { "tx_errors", E1000_STAT(stats.txerrc) },
{ "tx_dropped", E1000_STAT(net_stats.tx_dropped) },
- { "multicast", E1000_STAT(net_stats.multicast) },
- { "collisions", E1000_STAT(net_stats.collisions) },
- { "rx_length_errors", E1000_STAT(net_stats.rx_length_errors) },
+ { "multicast", E1000_STAT(stats.mprc) },
+ { "collisions", E1000_STAT(stats.colc) },
+ { "rx_length_errors", E1000_STAT(stats.rlerrc) },
{ "rx_over_errors", E1000_STAT(net_stats.rx_over_errors) },
- { "rx_crc_errors", E1000_STAT(net_stats.rx_crc_errors) },
+ { "rx_crc_errors", E1000_STAT(stats.crcerrs) },
{ "rx_frame_errors", E1000_STAT(net_stats.rx_frame_errors) },
{ "rx_no_buffer_count", E1000_STAT(stats.rnbc) },
- { "rx_missed_errors", E1000_STAT(net_stats.rx_missed_errors) },
- { "tx_aborted_errors", E1000_STAT(net_stats.tx_aborted_errors) },
- { "tx_carrier_errors", E1000_STAT(net_stats.tx_carrier_errors) },
+ { "rx_missed_errors", E1000_STAT(stats.mpc) },
+ { "tx_aborted_errors", E1000_STAT(stats.ecol) },
+ { "tx_carrier_errors", E1000_STAT(stats.tncrs) },
{ "tx_fifo_errors", E1000_STAT(net_stats.tx_fifo_errors) },
{ "tx_heartbeat_errors", E1000_STAT(net_stats.tx_heartbeat_errors) },
- { "tx_window_errors", E1000_STAT(net_stats.tx_window_errors) },
+ { "tx_window_errors", E1000_STAT(stats.latecol) },
{ "tx_abort_late_coll", E1000_STAT(stats.latecol) },
{ "tx_deferred_ok", E1000_STAT(stats.dc) },
{ "tx_single_coll_ok", E1000_STAT(stats.scc) },
@@ -193,13 +211,9 @@ e1000_set_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
ADVERTISED_FIBRE |
ADVERTISED_Autoneg;
else
- hw->autoneg_advertised = ADVERTISED_10baseT_Half |
- ADVERTISED_10baseT_Full |
- ADVERTISED_100baseT_Half |
- ADVERTISED_100baseT_Full |
- ADVERTISED_1000baseT_Full|
- ADVERTISED_Autoneg |
- ADVERTISED_TP;
+ hw->autoneg_advertised = ecmd->advertising |
+ ADVERTISED_TP |
+ ADVERTISED_Autoneg;
ecmd->advertising = hw->autoneg_advertised;
} else
if (e1000_set_spd_dplx(adapter, ecmd->speed + ecmd->duplex)) {
@@ -229,11 +243,11 @@ e1000_get_pauseparam(struct net_device *netdev,
pause->autoneg =
(adapter->fc_autoneg ? AUTONEG_ENABLE : AUTONEG_DISABLE);
- if (hw->fc == e1000_fc_rx_pause)
+ if (hw->fc == E1000_FC_RX_PAUSE)
pause->rx_pause = 1;
- else if (hw->fc == e1000_fc_tx_pause)
+ else if (hw->fc == E1000_FC_TX_PAUSE)
pause->tx_pause = 1;
- else if (hw->fc == e1000_fc_full) {
+ else if (hw->fc == E1000_FC_FULL) {
pause->rx_pause = 1;
pause->tx_pause = 1;
}
@@ -253,13 +267,13 @@ e1000_set_pauseparam(struct net_device *netdev,
msleep(1);
if (pause->rx_pause && pause->tx_pause)
- hw->fc = e1000_fc_full;
+ hw->fc = E1000_FC_FULL;
else if (pause->rx_pause && !pause->tx_pause)
- hw->fc = e1000_fc_rx_pause;
+ hw->fc = E1000_FC_RX_PAUSE;
else if (!pause->rx_pause && pause->tx_pause)
- hw->fc = e1000_fc_tx_pause;
+ hw->fc = E1000_FC_TX_PAUSE;
else if (!pause->rx_pause && !pause->tx_pause)
- hw->fc = e1000_fc_none;
+ hw->fc = E1000_FC_NONE;
hw->original_fc = hw->fc;
@@ -632,8 +646,8 @@ e1000_set_ringparam(struct net_device *netdev,
{
struct e1000_adapter *adapter = netdev_priv(netdev);
e1000_mac_type mac_type = adapter->hw.mac_type;
- struct e1000_tx_ring *txdr, *tx_old, *tx_new;
- struct e1000_rx_ring *rxdr, *rx_old, *rx_new;
+ struct e1000_tx_ring *txdr, *tx_old;
+ struct e1000_rx_ring *rxdr, *rx_old;
int i, err, tx_ring_size, rx_ring_size;
if ((ring->rx_mini_pending) || (ring->rx_jumbo_pending))
@@ -651,23 +665,17 @@ e1000_set_ringparam(struct net_device *netdev,
tx_old = adapter->tx_ring;
rx_old = adapter->rx_ring;
- adapter->tx_ring = kmalloc(tx_ring_size, GFP_KERNEL);
- if (!adapter->tx_ring) {
- err = -ENOMEM;
- goto err_setup_rx;
- }
- memset(adapter->tx_ring, 0, tx_ring_size);
+ err = -ENOMEM;
+ txdr = kzalloc(tx_ring_size, GFP_KERNEL);
+ if (!txdr)
+ goto err_alloc_tx;
- adapter->rx_ring = kmalloc(rx_ring_size, GFP_KERNEL);
- if (!adapter->rx_ring) {
- kfree(adapter->tx_ring);
- err = -ENOMEM;
- goto err_setup_rx;
- }
- memset(adapter->rx_ring, 0, rx_ring_size);
+ rxdr = kzalloc(rx_ring_size, GFP_KERNEL);
+ if (!rxdr)
+ goto err_alloc_rx;
- txdr = adapter->tx_ring;
- rxdr = adapter->rx_ring;
+ adapter->tx_ring = txdr;
+ adapter->rx_ring = rxdr;
rxdr->count = max(ring->rx_pending,(uint32_t)E1000_MIN_RXD);
rxdr->count = min(rxdr->count,(uint32_t)(mac_type < e1000_82544 ?
@@ -694,16 +702,14 @@ e1000_set_ringparam(struct net_device *netdev,
/* save the new, restore the old in order to free it,
* then restore the new back again */
- rx_new = adapter->rx_ring;
- tx_new = adapter->tx_ring;
adapter->rx_ring = rx_old;
adapter->tx_ring = tx_old;
e1000_free_all_rx_resources(adapter);
e1000_free_all_tx_resources(adapter);
kfree(tx_old);
kfree(rx_old);
- adapter->rx_ring = rx_new;
- adapter->tx_ring = tx_new;
+ adapter->rx_ring = rxdr;
+ adapter->tx_ring = txdr;
if ((err = e1000_up(adapter)))
goto err_setup;
}
@@ -715,6 +721,10 @@ err_setup_tx:
err_setup_rx:
adapter->rx_ring = rx_old;
adapter->tx_ring = tx_old;
+ kfree(rxdr);
+err_alloc_rx:
+ kfree(txdr);
+err_alloc_tx:
e1000_up(adapter);
err_setup:
clear_bit(__E1000_RESETTING, &adapter->flags);
@@ -1610,7 +1620,7 @@ e1000_diag_test(struct net_device *netdev,
struct e1000_adapter *adapter = netdev_priv(netdev);
boolean_t if_running = netif_running(netdev);
- set_bit(__E1000_DRIVER_TESTING, &adapter->flags);
+ set_bit(__E1000_TESTING, &adapter->flags);
if (eth_test->flags == ETH_TEST_FL_OFFLINE) {
/* Offline tests */
@@ -1655,7 +1665,7 @@ e1000_diag_test(struct net_device *netdev,
adapter->hw.autoneg = autoneg;
e1000_reset(adapter);
- clear_bit(__E1000_DRIVER_TESTING, &adapter->flags);
+ clear_bit(__E1000_TESTING, &adapter->flags);
if (if_running)
dev_open(netdev);
} else {
@@ -1670,7 +1680,7 @@ e1000_diag_test(struct net_device *netdev,
data[2] = 0;
data[3] = 0;
- clear_bit(__E1000_DRIVER_TESTING, &adapter->flags);
+ clear_bit(__E1000_TESTING, &adapter->flags);
}
msleep_interruptible(4 * 1000);
}
diff --git a/drivers/net/e1000/e1000_hw.c b/drivers/net/e1000/e1000_hw.c
index 10b8c8c2532..65077f39da6 100644
--- a/drivers/net/e1000/e1000_hw.c
+++ b/drivers/net/e1000/e1000_hw.c
@@ -1,25 +1,24 @@
/*******************************************************************************
-
- Copyright(c) 1999 - 2006 Intel Corporation. All rights reserved.
-
- This program is free software; you can redistribute it and/or modify it
- under the terms of the GNU General Public License as published by the Free
- Software Foundation; either version 2 of the License, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful, but WITHOUT
- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ Intel PRO/1000 Linux driver
+ Copyright(c) 1999 - 2006 Intel Corporation.
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms and conditions of the GNU General Public License,
+ version 2, as published by the Free Software Foundation.
+
+ This program is distributed in the hope it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
more details.
-
+
You should have received a copy of the GNU General Public License along with
- this program; if not, write to the Free Software Foundation, Inc., 59
- Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
- The full GNU General Public License is included in this distribution in the
- file called LICENSE.
-
+ this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+
+ The full GNU General Public License is included in this distribution in
+ the file called "COPYING".
+
Contact Information:
Linux NICS <linux.nics@intel.com>
e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
@@ -34,6 +33,63 @@
#include "e1000_hw.h"
+static int32_t e1000_swfw_sync_acquire(struct e1000_hw *hw, uint16_t mask);
+static void e1000_swfw_sync_release(struct e1000_hw *hw, uint16_t mask);
+static int32_t e1000_read_kmrn_reg(struct e1000_hw *hw, uint32_t reg_addr, uint16_t *data);
+static int32_t e1000_write_kmrn_reg(struct e1000_hw *hw, uint32_t reg_addr, uint16_t data);
+static int32_t e1000_get_software_semaphore(struct e1000_hw *hw);
+static void e1000_release_software_semaphore(struct e1000_hw *hw);
+
+static uint8_t e1000_arc_subsystem_valid(struct e1000_hw *hw);
+static int32_t e1000_check_downshift(struct e1000_hw *hw);
+static int32_t e1000_check_polarity(struct e1000_hw *hw, e1000_rev_polarity *polarity);
+static void e1000_clear_hw_cntrs(struct e1000_hw *hw);
+static void e1000_clear_vfta(struct e1000_hw *hw);
+static int32_t e1000_commit_shadow_ram(struct e1000_hw *hw);
+static int32_t e1000_config_dsp_after_link_change(struct e1000_hw *hw, boolean_t link_up);
+static int32_t e1000_config_fc_after_link_up(struct e1000_hw *hw);
+static int32_t e1000_detect_gig_phy(struct e1000_hw *hw);
+static int32_t e1000_erase_ich8_4k_segment(struct e1000_hw *hw, uint32_t bank);
+static int32_t e1000_get_auto_rd_done(struct e1000_hw *hw);
+static int32_t e1000_get_cable_length(struct e1000_hw *hw, uint16_t *min_length, uint16_t *max_length);
+static int32_t e1000_get_hw_eeprom_semaphore(struct e1000_hw *hw);
+static int32_t e1000_get_phy_cfg_done(struct e1000_hw *hw);
+static int32_t e1000_get_software_flag(struct e1000_hw *hw);
+static int32_t e1000_ich8_cycle_init(struct e1000_hw *hw);
+static int32_t e1000_ich8_flash_cycle(struct e1000_hw *hw, uint32_t timeout);
+static int32_t e1000_id_led_init(struct e1000_hw *hw);
+static int32_t e1000_init_lcd_from_nvm_config_region(struct e1000_hw *hw, uint32_t cnf_base_addr, uint32_t cnf_size);
+static int32_t e1000_init_lcd_from_nvm(struct e1000_hw *hw);
+static void e1000_init_rx_addrs(struct e1000_hw *hw);
+static void e1000_initialize_hardware_bits(struct e1000_hw *hw);
+static boolean_t e1000_is_onboard_nvm_eeprom(struct e1000_hw *hw);
+static int32_t e1000_kumeran_lock_loss_workaround(struct e1000_hw *hw);
+static int32_t e1000_mng_enable_host_if(struct e1000_hw *hw);
+static int32_t e1000_mng_host_if_write(struct e1000_hw *hw, uint8_t *buffer, uint16_t length, uint16_t offset, uint8_t *sum);
+static int32_t e1000_mng_write_cmd_header(struct e1000_hw* hw, struct e1000_host_mng_command_header* hdr);
+static int32_t e1000_mng_write_commit(struct e1000_hw *hw);
+static int32_t e1000_phy_ife_get_info(struct e1000_hw *hw, struct e1000_phy_info *phy_info);
+static int32_t e1000_phy_igp_get_info(struct e1000_hw *hw, struct e1000_phy_info *phy_info);
+static int32_t e1000_read_eeprom_eerd(struct e1000_hw *hw, uint16_t offset, uint16_t words, uint16_t *data);
+static int32_t e1000_write_eeprom_eewr(struct e1000_hw *hw, uint16_t offset, uint16_t words, uint16_t *data);
+static int32_t e1000_poll_eerd_eewr_done(struct e1000_hw *hw, int eerd);
+static int32_t e1000_phy_m88_get_info(struct e1000_hw *hw, struct e1000_phy_info *phy_info);
+static void e1000_put_hw_eeprom_semaphore(struct e1000_hw *hw);
+static int32_t e1000_read_ich8_byte(struct e1000_hw *hw, uint32_t index, uint8_t *data);
+static int32_t e1000_verify_write_ich8_byte(struct e1000_hw *hw, uint32_t index, uint8_t byte);
+static int32_t e1000_write_ich8_byte(struct e1000_hw *hw, uint32_t index, uint8_t byte);
+static int32_t e1000_read_ich8_word(struct e1000_hw *hw, uint32_t index, uint16_t *data);
+static int32_t e1000_read_ich8_data(struct e1000_hw *hw, uint32_t index, uint32_t size, uint16_t *data);
+static int32_t e1000_write_ich8_data(struct e1000_hw *hw, uint32_t index, uint32_t size, uint16_t data);
+static int32_t e1000_read_eeprom_ich8(struct e1000_hw *hw, uint16_t offset, uint16_t words, uint16_t *data);
+static int32_t e1000_write_eeprom_ich8(struct e1000_hw *hw, uint16_t offset, uint16_t words, uint16_t *data);
+static void e1000_release_software_flag(struct e1000_hw *hw);
+static int32_t e1000_set_d3_lplu_state(struct e1000_hw *hw, boolean_t active);
+static int32_t e1000_set_d0_lplu_state(struct e1000_hw *hw, boolean_t active);
+static int32_t e1000_set_pci_ex_no_snoop(struct e1000_hw *hw, uint32_t no_snoop);
+static void e1000_set_pci_express_master_disable(struct e1000_hw *hw);
+static int32_t e1000_wait_autoneg(struct e1000_hw *hw);
+static void e1000_write_reg_io(struct e1000_hw *hw, uint32_t offset, uint32_t value);
static int32_t e1000_set_phy_type(struct e1000_hw *hw);
static void e1000_phy_init_script(struct e1000_hw *hw);
static int32_t e1000_setup_copper_link(struct e1000_hw *hw);
@@ -70,69 +126,10 @@ static int32_t e1000_polarity_reversal_workaround(struct e1000_hw *hw);
static int32_t e1000_set_phy_mode(struct e1000_hw *hw);
static int32_t e1000_host_if_read_cookie(struct e1000_hw *hw, uint8_t *buffer);
static uint8_t e1000_calculate_mng_checksum(char *buffer, uint32_t length);
-static uint8_t e1000_arc_subsystem_valid(struct e1000_hw *hw);
-static int32_t e1000_check_downshift(struct e1000_hw *hw);
-static int32_t e1000_check_polarity(struct e1000_hw *hw, uint16_t *polarity);
-static void e1000_clear_hw_cntrs(struct e1000_hw *hw);
-static void e1000_clear_vfta(struct e1000_hw *hw);
-static int32_t e1000_commit_shadow_ram(struct e1000_hw *hw);
-static int32_t e1000_config_dsp_after_link_change(struct e1000_hw *hw,
- boolean_t link_up);
-static int32_t e1000_config_fc_after_link_up(struct e1000_hw *hw);
-static int32_t e1000_detect_gig_phy(struct e1000_hw *hw);
-static int32_t e1000_get_auto_rd_done(struct e1000_hw *hw);
-static int32_t e1000_get_cable_length(struct e1000_hw *hw,
- uint16_t *min_length,
- uint16_t *max_length);
-static int32_t e1000_get_hw_eeprom_semaphore(struct e1000_hw *hw);
-static int32_t e1000_get_phy_cfg_done(struct e1000_hw *hw);
-static int32_t e1000_id_led_init(struct e1000_hw * hw);
-static void e1000_init_rx_addrs(struct e1000_hw *hw);
-static boolean_t e1000_is_onboard_nvm_eeprom(struct e1000_hw *hw);
-static int32_t e1000_poll_eerd_eewr_done(struct e1000_hw *hw, int eerd);
-static void e1000_put_hw_eeprom_semaphore(struct e1000_hw *hw);
-static int32_t e1000_read_eeprom_eerd(struct e1000_hw *hw, uint16_t offset,
- uint16_t words, uint16_t *data);
-static int32_t e1000_set_d0_lplu_state(struct e1000_hw *hw, boolean_t active);
-static int32_t e1000_set_d3_lplu_state(struct e1000_hw *hw, boolean_t active);
-static int32_t e1000_wait_autoneg(struct e1000_hw *hw);
-
-static void e1000_write_reg_io(struct e1000_hw *hw, uint32_t offset,
- uint32_t value);
-
-#define E1000_WRITE_REG_IO(a, reg, val) \
- e1000_write_reg_io((a), E1000_##reg, val)
static int32_t e1000_configure_kmrn_for_10_100(struct e1000_hw *hw,
uint16_t duplex);
static int32_t e1000_configure_kmrn_for_1000(struct e1000_hw *hw);
-static int32_t e1000_erase_ich8_4k_segment(struct e1000_hw *hw,
- uint32_t segment);
-static int32_t e1000_get_software_flag(struct e1000_hw *hw);
-static int32_t e1000_get_software_semaphore(struct e1000_hw *hw);
-static int32_t e1000_init_lcd_from_nvm(struct e1000_hw *hw);
-static int32_t e1000_kumeran_lock_loss_workaround(struct e1000_hw *hw);
-static int32_t e1000_read_eeprom_ich8(struct e1000_hw *hw, uint16_t offset,
- uint16_t words, uint16_t *data);
-static int32_t e1000_read_ich8_byte(struct e1000_hw *hw, uint32_t index,
- uint8_t* data);
-static int32_t e1000_read_ich8_word(struct e1000_hw *hw, uint32_t index,
- uint16_t *data);
-static int32_t e1000_read_kmrn_reg(struct e1000_hw *hw, uint32_t reg_addr,
- uint16_t *data);
-static void e1000_release_software_flag(struct e1000_hw *hw);
-static void e1000_release_software_semaphore(struct e1000_hw *hw);
-static int32_t e1000_set_pci_ex_no_snoop(struct e1000_hw *hw,
- uint32_t no_snoop);
-static int32_t e1000_verify_write_ich8_byte(struct e1000_hw *hw,
- uint32_t index, uint8_t byte);
-static int32_t e1000_write_eeprom_ich8(struct e1000_hw *hw, uint16_t offset,
- uint16_t words, uint16_t *data);
-static int32_t e1000_write_ich8_byte(struct e1000_hw *hw, uint32_t index,
- uint8_t data);
-static int32_t e1000_write_kmrn_reg(struct e1000_hw *hw, uint32_t reg_addr,
- uint16_t data);
-
/* IGP cable length table */
static const
uint16_t e1000_igp_cable_length_table[IGP01E1000_AGC_LENGTH_TABLE_SIZE] =
@@ -156,13 +153,12 @@ uint16_t e1000_igp_2_cable_length_table[IGP02E1000_AGC_LENGTH_TABLE_SIZE] =
83, 89, 95, 100, 105, 109, 113, 116, 119, 122, 124,
104, 109, 114, 118, 121, 124};
-
/******************************************************************************
* Set the phy type member in the hw struct.
*
* hw - Struct containing variables accessed by shared code
*****************************************************************************/
-int32_t
+static int32_t
e1000_set_phy_type(struct e1000_hw *hw)
{
DEBUGFUNC("e1000_set_phy_type");
@@ -208,7 +204,6 @@ e1000_set_phy_type(struct e1000_hw *hw)
return E1000_SUCCESS;
}
-
/******************************************************************************
* IGP phy init script - initializes the GbE PHY
*
@@ -667,19 +662,12 @@ e1000_reset_hw(struct e1000_hw *hw)
E1000_WRITE_FLUSH(hw);
}
/* fall through */
- case e1000_82571:
- case e1000_82572:
- case e1000_ich8lan:
- case e1000_80003es2lan:
+ default:
+ /* Auto read done will delay 5ms or poll based on mac type */
ret_val = e1000_get_auto_rd_done(hw);
if (ret_val)
- /* We don't want to continue accessing MAC registers. */
return ret_val;
break;
- default:
- /* Wait for EEPROM reload (it happens automatically) */
- msleep(5);
- break;
}
/* Disable HW ARPs on ASF enabled adapters */
@@ -722,6 +710,123 @@ e1000_reset_hw(struct e1000_hw *hw)
}
/******************************************************************************
+ *
+ * Initialize a number of hardware-dependent bits
+ *
+ * hw: Struct containing variables accessed by shared code
+ *
+ * This function contains hardware limitation workarounds for PCI-E adapters
+ *
+ *****************************************************************************/
+static void
+e1000_initialize_hardware_bits(struct e1000_hw *hw)
+{
+ if ((hw->mac_type >= e1000_82571) && (!hw->initialize_hw_bits_disable)) {
+ /* Settings common to all PCI-express silicon */
+ uint32_t reg_ctrl, reg_ctrl_ext;
+ uint32_t reg_tarc0, reg_tarc1;
+ uint32_t reg_tctl;
+ uint32_t reg_txdctl, reg_txdctl1;
+
+ /* link autonegotiation/sync workarounds */
+ reg_tarc0 = E1000_READ_REG(hw, TARC0);
+ reg_tarc0 &= ~((1 << 30)|(1 << 29)|(1 << 28)|(1 << 27));
+
+ /* Enable not-done TX descriptor counting */
+ reg_txdctl = E1000_READ_REG(hw, TXDCTL);
+ reg_txdctl |= E1000_TXDCTL_COUNT_DESC;
+ E1000_WRITE_REG(hw, TXDCTL, reg_txdctl);
+ reg_txdctl1 = E1000_READ_REG(hw, TXDCTL1);
+ reg_txdctl1 |= E1000_TXDCTL_COUNT_DESC;
+ E1000_WRITE_REG(hw, TXDCTL1, reg_txdctl1);
+
+ switch (hw->mac_type) {
+ case e1000_82571:
+ case e1000_82572:
+ /* Clear PHY TX compatible mode bits */
+ reg_tarc1 = E1000_READ_REG(hw, TARC1);
+ reg_tarc1 &= ~((1 << 30)|(1 << 29));
+
+ /* link autonegotiation/sync workarounds */
+ reg_tarc0 |= ((1 << 26)|(1 << 25)|(1 << 24)|(1 << 23));
+
+ /* TX ring control fixes */
+ reg_tarc1 |= ((1 << 26)|(1 << 25)|(1 << 24));
+
+ /* Multiple read bit is reversed polarity */
+ reg_tctl = E1000_READ_REG(hw, TCTL);
+ if (reg_tctl & E1000_TCTL_MULR)
+ reg_tarc1 &= ~(1 << 28);
+ else
+ reg_tarc1 |= (1 << 28);
+
+ E1000_WRITE_REG(hw, TARC1, reg_tarc1);
+ break;
+ case e1000_82573:
+ reg_ctrl_ext = E1000_READ_REG(hw, CTRL_EXT);
+ reg_ctrl_ext &= ~(1 << 23);
+ reg_ctrl_ext |= (1 << 22);
+
+ /* TX byte count fix */
+ reg_ctrl = E1000_READ_REG(hw, CTRL);
+ reg_ctrl &= ~(1 << 29);
+
+ E1000_WRITE_REG(hw, CTRL_EXT, reg_ctrl_ext);
+ E1000_WRITE_REG(hw, CTRL, reg_ctrl);
+ break;
+ case e1000_80003es2lan:
+ /* improve small packet performace for fiber/serdes */
+ if ((hw->media_type == e1000_media_type_fiber) ||
+ (hw->media_type == e1000_media_type_internal_serdes)) {
+ reg_tarc0 &= ~(1 << 20);
+ }
+
+ /* Multiple read bit is reversed polarity */
+ reg_tctl = E1000_READ_REG(hw, TCTL);
+ reg_tarc1 = E1000_READ_REG(hw, TARC1);
+ if (reg_tctl & E1000_TCTL_MULR)
+ reg_tarc1 &= ~(1 << 28);
+ else
+ reg_tarc1 |= (1 << 28);
+
+ E1000_WRITE_REG(hw, TARC1, reg_tarc1);
+ break;
+ case e1000_ich8lan:
+ /* Reduce concurrent DMA requests to 3 from 4 */
+ if ((hw->revision_id < 3) ||
+ ((hw->device_id != E1000_DEV_ID_ICH8_IGP_M_AMT) &&
+ (hw->device_id != E1000_DEV_ID_ICH8_IGP_M)))
+ reg_tarc0 |= ((1 << 29)|(1 << 28));
+
+ reg_ctrl_ext = E1000_READ_REG(hw, CTRL_EXT);
+ reg_ctrl_ext |= (1 << 22);
+ E1000_WRITE_REG(hw, CTRL_EXT, reg_ctrl_ext);
+
+ /* workaround TX hang with TSO=on */
+ reg_tarc0 |= ((1 << 27)|(1 << 26)|(1 << 24)|(1 << 23));
+
+ /* Multiple read bit is reversed polarity */
+ reg_tctl = E1000_READ_REG(hw, TCTL);
+ reg_tarc1 = E1000_READ_REG(hw, TARC1);
+ if (reg_tctl & E1000_TCTL_MULR)
+ reg_tarc1 &= ~(1 << 28);
+ else
+ reg_tarc1 |= (1 << 28);
+
+ /* workaround TX hang with TSO=on */
+ reg_tarc1 |= ((1 << 30)|(1 << 26)|(1 << 24));
+
+ E1000_WRITE_REG(hw, TARC1, reg_tarc1);
+ break;
+ default:
+ break;
+ }
+
+ E1000_WRITE_REG(hw, TARC0, reg_tarc0);
+ }
+}
+
+/******************************************************************************
* Performs basic configuration of the adapter.
*
* hw - Struct containing variables accessed by shared code
@@ -749,14 +854,13 @@ e1000_init_hw(struct e1000_hw *hw)
DEBUGFUNC("e1000_init_hw");
/* force full DMA clock frequency for 10/100 on ICH8 A0-B0 */
- if (hw->mac_type == e1000_ich8lan) {
- reg_data = E1000_READ_REG(hw, TARC0);
- reg_data |= 0x30000000;
- E1000_WRITE_REG(hw, TARC0, reg_data);
-
- reg_data = E1000_READ_REG(hw, STATUS);
- reg_data &= ~0x80000000;
- E1000_WRITE_REG(hw, STATUS, reg_data);
+ if ((hw->mac_type == e1000_ich8lan) &&
+ ((hw->revision_id < 3) ||
+ ((hw->device_id != E1000_DEV_ID_ICH8_IGP_M_AMT) &&
+ (hw->device_id != E1000_DEV_ID_ICH8_IGP_M)))) {
+ reg_data = E1000_READ_REG(hw, STATUS);
+ reg_data &= ~0x80000000;
+ E1000_WRITE_REG(hw, STATUS, reg_data);
}
/* Initialize Identification LED */
@@ -769,6 +873,9 @@ e1000_init_hw(struct e1000_hw *hw)
/* Set the media type and TBI compatibility */
e1000_set_media_type(hw);
+ /* Must be called after e1000_set_media_type because media_type is used */
+ e1000_initialize_hardware_bits(hw);
+
/* Disabling VLAN filtering. */
DEBUGOUT("Initializing the IEEE VLAN\n");
/* VET hardcoded to standard value and VFTA removed in ICH8 LAN */
@@ -860,17 +967,6 @@ e1000_init_hw(struct e1000_hw *hw)
if (hw->mac_type > e1000_82544) {
ctrl = E1000_READ_REG(hw, TXDCTL);
ctrl = (ctrl & ~E1000_TXDCTL_WTHRESH) | E1000_TXDCTL_FULL_TX_DESC_WB;
- switch (hw->mac_type) {
- default:
- break;
- case e1000_82571:
- case e1000_82572:
- case e1000_82573:
- case e1000_ich8lan:
- case e1000_80003es2lan:
- ctrl |= E1000_TXDCTL_COUNT_DESC;
- break;
- }
E1000_WRITE_REG(hw, TXDCTL, ctrl);
}
@@ -908,8 +1004,6 @@ e1000_init_hw(struct e1000_hw *hw)
case e1000_ich8lan:
ctrl = E1000_READ_REG(hw, TXDCTL1);
ctrl = (ctrl & ~E1000_TXDCTL_WTHRESH) | E1000_TXDCTL_FULL_TX_DESC_WB;
- if (hw->mac_type >= e1000_82571)
- ctrl |= E1000_TXDCTL_COUNT_DESC;
E1000_WRITE_REG(hw, TXDCTL1, ctrl);
break;
}
@@ -1018,11 +1112,11 @@ e1000_setup_link(struct e1000_hw *hw)
* control setting, then the variable hw->fc will
* be initialized based on a value in the EEPROM.
*/
- if (hw->fc == e1000_fc_default) {
+ if (hw->fc == E1000_FC_DEFAULT) {
switch (hw->mac_type) {
case e1000_ich8lan:
case e1000_82573:
- hw->fc = e1000_fc_full;
+ hw->fc = E1000_FC_FULL;
break;
default:
ret_val = e1000_read_eeprom(hw, EEPROM_INIT_CONTROL2_REG,
@@ -1032,12 +1126,12 @@ e1000_setup_link(struct e1000_hw *hw)
return -E1000_ERR_EEPROM;
}
if ((eeprom_data & EEPROM_WORD0F_PAUSE_MASK) == 0)
- hw->fc = e1000_fc_none;
+ hw->fc = E1000_FC_NONE;
else if ((eeprom_data & EEPROM_WORD0F_PAUSE_MASK) ==
EEPROM_WORD0F_ASM_DIR)
- hw->fc = e1000_fc_tx_pause;
+ hw->fc = E1000_FC_TX_PAUSE;
else
- hw->fc = e1000_fc_full;
+ hw->fc = E1000_FC_FULL;
break;
}
}
@@ -1047,10 +1141,10 @@ e1000_setup_link(struct e1000_hw *hw)
* hub or switch with different Flow Control capabilities.
*/
if (hw->mac_type == e1000_82542_rev2_0)
- hw->fc &= (~e1000_fc_tx_pause);
+ hw->fc &= (~E1000_FC_TX_PAUSE);
if ((hw->mac_type < e1000_82543) && (hw->report_tx_early == 1))
- hw->fc &= (~e1000_fc_rx_pause);
+ hw->fc &= (~E1000_FC_RX_PAUSE);
hw->original_fc = hw->fc;
@@ -1102,7 +1196,7 @@ e1000_setup_link(struct e1000_hw *hw)
* ability to transmit pause frames in not enabled, then these
* registers will be set to 0.
*/
- if (!(hw->fc & e1000_fc_tx_pause)) {
+ if (!(hw->fc & E1000_FC_TX_PAUSE)) {
E1000_WRITE_REG(hw, FCRTL, 0);
E1000_WRITE_REG(hw, FCRTH, 0);
} else {
@@ -1149,11 +1243,11 @@ e1000_setup_fiber_serdes_link(struct e1000_hw *hw)
if (hw->mac_type == e1000_82571 || hw->mac_type == e1000_82572)
E1000_WRITE_REG(hw, SCTL, E1000_DISABLE_SERDES_LOOPBACK);
- /* On adapters with a MAC newer than 82544, SW Defineable pin 1 will be
+ /* On adapters with a MAC newer than 82544, SWDP 1 will be
* set when the optics detect a signal. On older adapters, it will be
* cleared when there is a signal. This applies to fiber media only.
- * If we're on serdes media, adjust the output amplitude to value set in
- * the EEPROM.
+ * If we're on serdes media, adjust the output amplitude to value
+ * set in the EEPROM.
*/
ctrl = E1000_READ_REG(hw, CTRL);
if (hw->media_type == e1000_media_type_fiber)
@@ -1189,11 +1283,11 @@ e1000_setup_fiber_serdes_link(struct e1000_hw *hw)
* 3: Both Rx and TX flow control (symmetric) are enabled.
*/
switch (hw->fc) {
- case e1000_fc_none:
+ case E1000_FC_NONE:
/* Flow control is completely disabled by a software over-ride. */
txcw = (E1000_TXCW_ANE | E1000_TXCW_FD);
break;
- case e1000_fc_rx_pause:
+ case E1000_FC_RX_PAUSE:
/* RX Flow control is enabled and TX Flow control is disabled by a
* software over-ride. Since there really isn't a way to advertise
* that we are capable of RX Pause ONLY, we will advertise that we
@@ -1202,13 +1296,13 @@ e1000_setup_fiber_serdes_link(struct e1000_hw *hw)
*/
txcw = (E1000_TXCW_ANE | E1000_TXCW_FD | E1000_TXCW_PAUSE_MASK);
break;
- case e1000_fc_tx_pause:
+ case E1000_FC_TX_PAUSE:
/* TX Flow control is enabled, and RX Flow control is disabled, by a
* software over-ride.
*/
txcw = (E1000_TXCW_ANE | E1000_TXCW_FD | E1000_TXCW_ASM_DIR);
break;
- case e1000_fc_full:
+ case E1000_FC_FULL:
/* Flow control (both RX and TX) is enabled by a software over-ride. */
txcw = (E1000_TXCW_ANE | E1000_TXCW_FD | E1000_TXCW_PAUSE_MASK);
break;
@@ -2124,13 +2218,13 @@ e1000_phy_setup_autoneg(struct e1000_hw *hw)
* in the EEPROM is used.
*/
switch (hw->fc) {
- case e1000_fc_none: /* 0 */
+ case E1000_FC_NONE: /* 0 */
/* Flow control (RX & TX) is completely disabled by a
* software over-ride.
*/
mii_autoneg_adv_reg &= ~(NWAY_AR_ASM_DIR | NWAY_AR_PAUSE);
break;
- case e1000_fc_rx_pause: /* 1 */
+ case E1000_FC_RX_PAUSE: /* 1 */
/* RX Flow control is enabled, and TX Flow control is
* disabled, by a software over-ride.
*/
@@ -2142,14 +2236,14 @@ e1000_phy_setup_autoneg(struct e1000_hw *hw)
*/
mii_autoneg_adv_reg |= (NWAY_AR_ASM_DIR | NWAY_AR_PAUSE);
break;
- case e1000_fc_tx_pause: /* 2 */
+ case E1000_FC_TX_PAUSE: /* 2 */
/* TX Flow control is enabled, and RX Flow control is
* disabled, by a software over-ride.
*/
mii_autoneg_adv_reg |= NWAY_AR_ASM_DIR;
mii_autoneg_adv_reg &= ~NWAY_AR_PAUSE;
break;
- case e1000_fc_full: /* 3 */
+ case E1000_FC_FULL: /* 3 */
/* Flow control (both RX and TX) is enabled by a software
* over-ride.
*/
@@ -2193,7 +2287,7 @@ e1000_phy_force_speed_duplex(struct e1000_hw *hw)
DEBUGFUNC("e1000_phy_force_speed_duplex");
/* Turn off Flow control if we are forcing speed and duplex. */
- hw->fc = e1000_fc_none;
+ hw->fc = E1000_FC_NONE;
DEBUGOUT1("hw->fc = %d\n", hw->fc);
@@ -2547,18 +2641,18 @@ e1000_force_mac_fc(struct e1000_hw *hw)
*/
switch (hw->fc) {
- case e1000_fc_none:
+ case E1000_FC_NONE:
ctrl &= (~(E1000_CTRL_TFCE | E1000_CTRL_RFCE));
break;
- case e1000_fc_rx_pause:
+ case E1000_FC_RX_PAUSE:
ctrl &= (~E1000_CTRL_TFCE);
ctrl |= E1000_CTRL_RFCE;
break;
- case e1000_fc_tx_pause:
+ case E1000_FC_TX_PAUSE:
ctrl &= (~E1000_CTRL_RFCE);
ctrl |= E1000_CTRL_TFCE;
break;
- case e1000_fc_full:
+ case E1000_FC_FULL:
ctrl |= (E1000_CTRL_TFCE | E1000_CTRL_RFCE);
break;
default:
@@ -2657,14 +2751,14 @@ e1000_config_fc_after_link_up(struct e1000_hw *hw)
* LOCAL DEVICE | LINK PARTNER
* PAUSE | ASM_DIR | PAUSE | ASM_DIR | NIC Resolution
*-------|---------|-------|---------|--------------------
- * 0 | 0 | DC | DC | e1000_fc_none
- * 0 | 1 | 0 | DC | e1000_fc_none
- * 0 | 1 | 1 | 0 | e1000_fc_none
- * 0 | 1 | 1 | 1 | e1000_fc_tx_pause
- * 1 | 0 | 0 | DC | e1000_fc_none
- * 1 | DC | 1 | DC | e1000_fc_full
- * 1 | 1 | 0 | 0 | e1000_fc_none
- * 1 | 1 | 0 | 1 | e1000_fc_rx_pause
+ * 0 | 0 | DC | DC | E1000_FC_NONE
+ * 0 | 1 | 0 | DC | E1000_FC_NONE
+ * 0 | 1 | 1 | 0 | E1000_FC_NONE
+ * 0 | 1 | 1 | 1 | E1000_FC_TX_PAUSE
+ * 1 | 0 | 0 | DC | E1000_FC_NONE
+ * 1 | DC | 1 | DC | E1000_FC_FULL
+ * 1 | 1 | 0 | 0 | E1000_FC_NONE
+ * 1 | 1 | 0 | 1 | E1000_FC_RX_PAUSE
*
*/
/* Are both PAUSE bits set to 1? If so, this implies
@@ -2676,7 +2770,7 @@ e1000_config_fc_after_link_up(struct e1000_hw *hw)
* LOCAL DEVICE | LINK PARTNER
* PAUSE | ASM_DIR | PAUSE | ASM_DIR | Result
*-------|---------|-------|---------|--------------------
- * 1 | DC | 1 | DC | e1000_fc_full
+ * 1 | DC | 1 | DC | E1000_FC_FULL
*
*/
if ((mii_nway_adv_reg & NWAY_AR_PAUSE) &&
@@ -2687,11 +2781,11 @@ e1000_config_fc_after_link_up(struct e1000_hw *hw)
* ONLY. Hence, we must now check to see if we need to
* turn OFF the TRANSMISSION of PAUSE frames.
*/
- if (hw->original_fc == e1000_fc_full) {
- hw->fc = e1000_fc_full;
+ if (hw->original_fc == E1000_FC_FULL) {
+ hw->fc = E1000_FC_FULL;
DEBUGOUT("Flow Control = FULL.\n");
} else {
- hw->fc = e1000_fc_rx_pause;
+ hw->fc = E1000_FC_RX_PAUSE;
DEBUGOUT("Flow Control = RX PAUSE frames only.\n");
}
}
@@ -2700,14 +2794,14 @@ e1000_config_fc_after_link_up(struct e1000_hw *hw)
* LOCAL DEVICE | LINK PARTNER
* PAUSE | ASM_DIR | PAUSE | ASM_DIR | Result
*-------|---------|-------|---------|--------------------
- * 0 | 1 | 1 | 1 | e1000_fc_tx_pause
+ * 0 | 1 | 1 | 1 | E1000_FC_TX_PAUSE
*
*/
else if (!(mii_nway_adv_reg & NWAY_AR_PAUSE) &&
(mii_nway_adv_reg & NWAY_AR_ASM_DIR) &&
(mii_nway_lp_ability_reg & NWAY_LPAR_PAUSE) &&
(mii_nway_lp_ability_reg & NWAY_LPAR_ASM_DIR)) {
- hw->fc = e1000_fc_tx_pause;
+ hw->fc = E1000_FC_TX_PAUSE;
DEBUGOUT("Flow Control = TX PAUSE frames only.\n");
}
/* For transmitting PAUSE frames ONLY.
@@ -2715,14 +2809,14 @@ e1000_config_fc_after_link_up(struct e1000_hw *hw)
* LOCAL DEVICE | LINK PARTNER
* PAUSE | ASM_DIR | PAUSE | ASM_DIR | Result
*-------|---------|-------|---------|--------------------
- * 1 | 1 | 0 | 1 | e1000_fc_rx_pause
+ * 1 | 1 | 0 | 1 | E1000_FC_RX_PAUSE
*
*/
else if ((mii_nway_adv_reg & NWAY_AR_PAUSE) &&
(mii_nway_adv_reg & NWAY_AR_ASM_DIR) &&
!(mii_nway_lp_ability_reg & NWAY_LPAR_PAUSE) &&
(mii_nway_lp_ability_reg & NWAY_LPAR_ASM_DIR)) {
- hw->fc = e1000_fc_rx_pause;
+ hw->fc = E1000_FC_RX_PAUSE;
DEBUGOUT("Flow Control = RX PAUSE frames only.\n");
}
/* Per the IEEE spec, at this point flow control should be
@@ -2745,13 +2839,13 @@ e1000_config_fc_after_link_up(struct e1000_hw *hw)
* be asked to delay transmission of packets than asking
* our link partner to pause transmission of frames.
*/
- else if ((hw->original_fc == e1000_fc_none ||
- hw->original_fc == e1000_fc_tx_pause) ||
+ else if ((hw->original_fc == E1000_FC_NONE ||
+ hw->original_fc == E1000_FC_TX_PAUSE) ||
hw->fc_strict_ieee) {
- hw->fc = e1000_fc_none;
+ hw->fc = E1000_FC_NONE;
DEBUGOUT("Flow Control = NONE.\n");
} else {
- hw->fc = e1000_fc_rx_pause;
+ hw->fc = E1000_FC_RX_PAUSE;
DEBUGOUT("Flow Control = RX PAUSE frames only.\n");
}
@@ -2766,7 +2860,7 @@ e1000_config_fc_after_link_up(struct e1000_hw *hw)
}
if (duplex == HALF_DUPLEX)
- hw->fc = e1000_fc_none;
+ hw->fc = E1000_FC_NONE;
/* Now we call a subroutine to actually force the MAC
* controller to use the correct flow control settings.
@@ -3417,9 +3511,8 @@ e1000_read_phy_reg(struct e1000_hw *hw,
return ret_val;
}
-int32_t
-e1000_read_phy_reg_ex(struct e1000_hw *hw,
- uint32_t reg_addr,
+static int32_t
+e1000_read_phy_reg_ex(struct e1000_hw *hw, uint32_t reg_addr,
uint16_t *phy_data)
{
uint32_t i;
@@ -3499,8 +3592,7 @@ e1000_read_phy_reg_ex(struct e1000_hw *hw,
* data - data to write to the PHY
******************************************************************************/
int32_t
-e1000_write_phy_reg(struct e1000_hw *hw,
- uint32_t reg_addr,
+e1000_write_phy_reg(struct e1000_hw *hw, uint32_t reg_addr,
uint16_t phy_data)
{
uint32_t ret_val;
@@ -3557,10 +3649,9 @@ e1000_write_phy_reg(struct e1000_hw *hw,
return ret_val;
}
-int32_t
-e1000_write_phy_reg_ex(struct e1000_hw *hw,
- uint32_t reg_addr,
- uint16_t phy_data)
+static int32_t
+e1000_write_phy_reg_ex(struct e1000_hw *hw, uint32_t reg_addr,
+ uint16_t phy_data)
{
uint32_t i;
uint32_t mdic = 0;
@@ -3711,7 +3802,7 @@ e1000_phy_hw_reset(struct e1000_hw *hw)
swfw = E1000_SWFW_PHY0_SM;
}
if (e1000_swfw_sync_acquire(hw, swfw)) {
- e1000_release_software_semaphore(hw);
+ DEBUGOUT("Unable to acquire swfw sync\n");
return -E1000_ERR_SWFW_SYNC;
}
/* Read the device control register and assert the E1000_CTRL_PHY_RST
@@ -3734,6 +3825,7 @@ e1000_phy_hw_reset(struct e1000_hw *hw)
if (hw->mac_type >= e1000_82571)
mdelay(10);
+
e1000_swfw_sync_release(hw, swfw);
} else {
/* Read the Extended Device Control Register, assert the PHY_RESET_DIR
@@ -3792,15 +3884,14 @@ e1000_phy_reset(struct e1000_hw *hw)
if (ret_val)
return E1000_SUCCESS;
- switch (hw->mac_type) {
- case e1000_82541_rev_2:
- case e1000_82571:
- case e1000_82572:
- case e1000_ich8lan:
+ switch (hw->phy_type) {
+ case e1000_phy_igp:
+ case e1000_phy_igp_2:
+ case e1000_phy_igp_3:
+ case e1000_phy_ife:
ret_val = e1000_phy_hw_reset(hw);
if (ret_val)
return ret_val;
-
break;
default:
ret_val = e1000_read_phy_reg(hw, PHY_CTRL, &phy_data);
@@ -3936,7 +4027,7 @@ e1000_kumeran_lock_loss_workaround(struct e1000_hw *hw)
*
* hw - Struct containing variables accessed by shared code
******************************************************************************/
-int32_t
+static int32_t
e1000_detect_gig_phy(struct e1000_hw *hw)
{
int32_t phy_init_status, ret_val;
@@ -3945,6 +4036,9 @@ e1000_detect_gig_phy(struct e1000_hw *hw)
DEBUGFUNC("e1000_detect_gig_phy");
+ if (hw->phy_id != 0)
+ return E1000_SUCCESS;
+
/* The 82571 firmware may still be configuring the PHY. In this
* case, we cannot access the PHY until the configuration is done. So
* we explicitly set the PHY values. */
@@ -4061,7 +4155,8 @@ e1000_phy_igp_get_info(struct e1000_hw *hw,
struct e1000_phy_info *phy_info)
{
int32_t ret_val;
- uint16_t phy_data, polarity, min_length, max_length, average;
+ uint16_t phy_data, min_length, max_length, average;
+ e1000_rev_polarity polarity;
DEBUGFUNC("e1000_phy_igp_get_info");
@@ -4086,8 +4181,8 @@ e1000_phy_igp_get_info(struct e1000_hw *hw,
if (ret_val)
return ret_val;
- phy_info->mdix_mode = (phy_data & IGP01E1000_PSSR_MDIX) >>
- IGP01E1000_PSSR_MDIX_SHIFT;
+ phy_info->mdix_mode = (e1000_auto_x_mode)((phy_data & IGP01E1000_PSSR_MDIX) >>
+ IGP01E1000_PSSR_MDIX_SHIFT);
if ((phy_data & IGP01E1000_PSSR_SPEED_MASK) ==
IGP01E1000_PSSR_SPEED_1000MBPS) {
@@ -4096,10 +4191,12 @@ e1000_phy_igp_get_info(struct e1000_hw *hw,
if (ret_val)
return ret_val;
- phy_info->local_rx = (phy_data & SR_1000T_LOCAL_RX_STATUS) >>
- SR_1000T_LOCAL_RX_STATUS_SHIFT;
- phy_info->remote_rx = (phy_data & SR_1000T_REMOTE_RX_STATUS) >>
- SR_1000T_REMOTE_RX_STATUS_SHIFT;
+ phy_info->local_rx = ((phy_data & SR_1000T_LOCAL_RX_STATUS) >>
+ SR_1000T_LOCAL_RX_STATUS_SHIFT) ?
+ e1000_1000t_rx_status_ok : e1000_1000t_rx_status_not_ok;
+ phy_info->remote_rx = ((phy_data & SR_1000T_REMOTE_RX_STATUS) >>
+ SR_1000T_REMOTE_RX_STATUS_SHIFT) ?
+ e1000_1000t_rx_status_ok : e1000_1000t_rx_status_not_ok;
/* Get cable length */
ret_val = e1000_get_cable_length(hw, &min_length, &max_length);
@@ -4135,7 +4232,8 @@ e1000_phy_ife_get_info(struct e1000_hw *hw,
struct e1000_phy_info *phy_info)
{
int32_t ret_val;
- uint16_t phy_data, polarity;
+ uint16_t phy_data;
+ e1000_rev_polarity polarity;
DEBUGFUNC("e1000_phy_ife_get_info");
@@ -4146,8 +4244,9 @@ e1000_phy_ife_get_info(struct e1000_hw *hw,
if (ret_val)
return ret_val;
phy_info->polarity_correction =
- (phy_data & IFE_PSC_AUTO_POLARITY_DISABLE) >>
- IFE_PSC_AUTO_POLARITY_DISABLE_SHIFT;
+ ((phy_data & IFE_PSC_AUTO_POLARITY_DISABLE) >>
+ IFE_PSC_AUTO_POLARITY_DISABLE_SHIFT) ?
+ e1000_polarity_reversal_disabled : e1000_polarity_reversal_enabled;
if (phy_info->polarity_correction == e1000_polarity_reversal_enabled) {
ret_val = e1000_check_polarity(hw, &polarity);
@@ -4155,8 +4254,9 @@ e1000_phy_ife_get_info(struct e1000_hw *hw,
return ret_val;
} else {
/* Polarity is forced. */
- polarity = (phy_data & IFE_PSC_FORCE_POLARITY) >>
- IFE_PSC_FORCE_POLARITY_SHIFT;
+ polarity = ((phy_data & IFE_PSC_FORCE_POLARITY) >>
+ IFE_PSC_FORCE_POLARITY_SHIFT) ?
+ e1000_rev_polarity_reversed : e1000_rev_polarity_normal;
}
phy_info->cable_polarity = polarity;
@@ -4164,9 +4264,9 @@ e1000_phy_ife_get_info(struct e1000_hw *hw,
if (ret_val)
return ret_val;
- phy_info->mdix_mode =
- (phy_data & (IFE_PMC_AUTO_MDIX | IFE_PMC_FORCE_MDIX)) >>
- IFE_PMC_MDIX_MODE_SHIFT;
+ phy_info->mdix_mode = (e1000_auto_x_mode)
+ ((phy_data & (IFE_PMC_AUTO_MDIX | IFE_PMC_FORCE_MDIX)) >>
+ IFE_PMC_MDIX_MODE_SHIFT);
return E1000_SUCCESS;
}
@@ -4182,7 +4282,8 @@ e1000_phy_m88_get_info(struct e1000_hw *hw,
struct e1000_phy_info *phy_info)
{
int32_t ret_val;
- uint16_t phy_data, polarity;
+ uint16_t phy_data;
+ e1000_rev_polarity polarity;
DEBUGFUNC("e1000_phy_m88_get_info");
@@ -4195,11 +4296,14 @@ e1000_phy_m88_get_info(struct e1000_hw *hw,
return ret_val;
phy_info->extended_10bt_distance =
- (phy_data & M88E1000_PSCR_10BT_EXT_DIST_ENABLE) >>
- M88E1000_PSCR_10BT_EXT_DIST_ENABLE_SHIFT;
+ ((phy_data & M88E1000_PSCR_10BT_EXT_DIST_ENABLE) >>
+ M88E1000_PSCR_10BT_EXT_DIST_ENABLE_SHIFT) ?
+ e1000_10bt_ext_dist_enable_lower : e1000_10bt_ext_dist_enable_normal;
+
phy_info->polarity_correction =
- (phy_data & M88E1000_PSCR_POLARITY_REVERSAL) >>
- M88E1000_PSCR_POLARITY_REVERSAL_SHIFT;
+ ((phy_data & M88E1000_PSCR_POLARITY_REVERSAL) >>
+ M88E1000_PSCR_POLARITY_REVERSAL_SHIFT) ?
+ e1000_polarity_reversal_disabled : e1000_polarity_reversal_enabled;
/* Check polarity status */
ret_val = e1000_check_polarity(hw, &polarity);
@@ -4211,15 +4315,15 @@ e1000_phy_m88_get_info(struct e1000_hw *hw,
if (ret_val)
return ret_val;
- phy_info->mdix_mode = (phy_data & M88E1000_PSSR_MDIX) >>
- M88E1000_PSSR_MDIX_SHIFT;
+ phy_info->mdix_mode = (e1000_auto_x_mode)((phy_data & M88E1000_PSSR_MDIX) >>
+ M88E1000_PSSR_MDIX_SHIFT);
if ((phy_data & M88E1000_PSSR_SPEED) == M88E1000_PSSR_1000MBS) {
/* Cable Length Estimation and Local/Remote Receiver Information
* are only valid at 1000 Mbps.
*/
if (hw->phy_type != e1000_phy_gg82563) {
- phy_info->cable_length = ((phy_data & M88E1000_PSSR_CABLE_LENGTH) >>
+ phy_info->cable_length = (e1000_cable_length)((phy_data & M88E1000_PSSR_CABLE_LENGTH) >>
M88E1000_PSSR_CABLE_LENGTH_SHIFT);
} else {
ret_val = e1000_read_phy_reg(hw, GG82563_PHY_DSP_DISTANCE,
@@ -4227,18 +4331,20 @@ e1000_phy_m88_get_info(struct e1000_hw *hw,
if (ret_val)
return ret_val;
- phy_info->cable_length = phy_data & GG82563_DSPD_CABLE_LENGTH;
+ phy_info->cable_length = (e1000_cable_length)(phy_data & GG82563_DSPD_CABLE_LENGTH);
}
ret_val = e1000_read_phy_reg(hw, PHY_1000T_STATUS, &phy_data);
if (ret_val)
return ret_val;
- phy_info->local_rx = (phy_data & SR_1000T_LOCAL_RX_STATUS) >>
- SR_1000T_LOCAL_RX_STATUS_SHIFT;
+ phy_info->local_rx = ((phy_data & SR_1000T_LOCAL_RX_STATUS) >>
+ SR_1000T_LOCAL_RX_STATUS_SHIFT) ?
+ e1000_1000t_rx_status_ok : e1000_1000t_rx_status_not_ok;
+ phy_info->remote_rx = ((phy_data & SR_1000T_REMOTE_RX_STATUS) >>
+ SR_1000T_REMOTE_RX_STATUS_SHIFT) ?
+ e1000_1000t_rx_status_ok : e1000_1000t_rx_status_not_ok;
- phy_info->remote_rx = (phy_data & SR_1000T_REMOTE_RX_STATUS) >>
- SR_1000T_REMOTE_RX_STATUS_SHIFT;
}
return E1000_SUCCESS;
@@ -4441,7 +4547,7 @@ e1000_init_eeprom_params(struct e1000_hw *hw)
eeprom->use_eewr = FALSE;
break;
case e1000_ich8lan:
- {
+ {
int32_t i = 0;
uint32_t flash_size = E1000_READ_ICH8_REG(hw, ICH8_FLASH_GFPREG);
@@ -4468,7 +4574,7 @@ e1000_init_eeprom_params(struct e1000_hw *hw)
hw->flash_bank_size /= 2 * sizeof(uint16_t);
break;
- }
+ }
default:
break;
}
@@ -4800,7 +4906,7 @@ e1000_release_eeprom(struct e1000_hw *hw)
*
* hw - Struct containing variables accessed by shared code
*****************************************************************************/
-int32_t
+static int32_t
e1000_spi_eeprom_ready(struct e1000_hw *hw)
{
uint16_t retry_count = 0;
@@ -4854,44 +4960,43 @@ e1000_read_eeprom(struct e1000_hw *hw,
{
struct e1000_eeprom_info *eeprom = &hw->eeprom;
uint32_t i = 0;
- int32_t ret_val;
DEBUGFUNC("e1000_read_eeprom");
+ /* If eeprom is not yet detected, do so now */
+ if (eeprom->word_size == 0)
+ e1000_init_eeprom_params(hw);
+
/* A check for invalid values: offset too large, too many words, and not
* enough words.
*/
if ((offset >= eeprom->word_size) || (words > eeprom->word_size - offset) ||
(words == 0)) {
- DEBUGOUT("\"words\" parameter out of bounds\n");
+ DEBUGOUT2("\"words\" parameter out of bounds. Words = %d, size = %d\n", offset, eeprom->word_size);
return -E1000_ERR_EEPROM;
}
- /* FLASH reads without acquiring the semaphore are safe */
+ /* EEPROM's that don't use EERD to read require us to bit-bang the SPI
+ * directly. In this case, we need to acquire the EEPROM so that
+ * FW or other port software does not interrupt.
+ */
if (e1000_is_onboard_nvm_eeprom(hw) == TRUE &&
hw->eeprom.use_eerd == FALSE) {
- switch (hw->mac_type) {
- case e1000_80003es2lan:
- break;
- default:
- /* Prepare the EEPROM for reading */
- if (e1000_acquire_eeprom(hw) != E1000_SUCCESS)
- return -E1000_ERR_EEPROM;
- break;
- }
+ /* Prepare the EEPROM for bit-bang reading */
+ if (e1000_acquire_eeprom(hw) != E1000_SUCCESS)
+ return -E1000_ERR_EEPROM;
}
- if (eeprom->use_eerd == TRUE) {
- ret_val = e1000_read_eeprom_eerd(hw, offset, words, data);
- if ((e1000_is_onboard_nvm_eeprom(hw) == TRUE) ||
- (hw->mac_type != e1000_82573))
- e1000_release_eeprom(hw);
- return ret_val;
- }
+ /* Eerd register EEPROM access requires no eeprom aquire/release */
+ if (eeprom->use_eerd == TRUE)
+ return e1000_read_eeprom_eerd(hw, offset, words, data);
+ /* ICH EEPROM access is done via the ICH flash controller */
if (eeprom->type == e1000_eeprom_ich8)
return e1000_read_eeprom_ich8(hw, offset, words, data);
+ /* Set up the SPI or Microwire EEPROM for bit-bang reading. We have
+ * acquired the EEPROM at this point, so any returns should relase it */
if (eeprom->type == e1000_eeprom_spi) {
uint16_t word_in;
uint8_t read_opcode = EEPROM_READ_OPCODE_SPI;
@@ -5206,6 +5311,10 @@ e1000_write_eeprom(struct e1000_hw *hw,
DEBUGFUNC("e1000_write_eeprom");
+ /* If eeprom is not yet detected, do so now */
+ if (eeprom->word_size == 0)
+ e1000_init_eeprom_params(hw);
+
/* A check for invalid values: offset too large, too many words, and not
* enough words.
*/
@@ -5248,7 +5357,7 @@ e1000_write_eeprom(struct e1000_hw *hw,
* data - pointer to array of 8 bit words to be written to the EEPROM
*
*****************************************************************************/
-int32_t
+static int32_t
e1000_write_eeprom_spi(struct e1000_hw *hw,
uint16_t offset,
uint16_t words,
@@ -5314,7 +5423,7 @@ e1000_write_eeprom_spi(struct e1000_hw *hw,
* data - pointer to array of 16 bit words to be written to the EEPROM
*
*****************************************************************************/
-int32_t
+static int32_t
e1000_write_eeprom_microwire(struct e1000_hw *hw,
uint16_t offset,
uint16_t words,
@@ -5411,10 +5520,8 @@ e1000_commit_shadow_ram(struct e1000_hw *hw)
int32_t error = E1000_SUCCESS;
uint32_t old_bank_offset = 0;
uint32_t new_bank_offset = 0;
- uint32_t sector_retries = 0;
uint8_t low_byte = 0;
uint8_t high_byte = 0;
- uint8_t temp_byte = 0;
boolean_t sector_write_failed = FALSE;
if (hw->mac_type == e1000_82573) {
@@ -5467,41 +5574,46 @@ e1000_commit_shadow_ram(struct e1000_hw *hw)
e1000_erase_ich8_4k_segment(hw, 0);
}
- do {
- sector_write_failed = FALSE;
- /* Loop for every byte in the shadow RAM,
- * which is in units of words. */
- for (i = 0; i < E1000_SHADOW_RAM_WORDS; i++) {
- /* Determine whether to write the value stored
- * in the other NVM bank or a modified value stored
- * in the shadow RAM */
- if (hw->eeprom_shadow_ram[i].modified == TRUE) {
- low_byte = (uint8_t)hw->eeprom_shadow_ram[i].eeprom_word;
- e1000_read_ich8_byte(hw, (i << 1) + old_bank_offset,
- &temp_byte);
- udelay(100);
- error = e1000_verify_write_ich8_byte(hw,
- (i << 1) + new_bank_offset,
- low_byte);
- if (error != E1000_SUCCESS)
- sector_write_failed = TRUE;
+ sector_write_failed = FALSE;
+ /* Loop for every byte in the shadow RAM,
+ * which is in units of words. */
+ for (i = 0; i < E1000_SHADOW_RAM_WORDS; i++) {
+ /* Determine whether to write the value stored
+ * in the other NVM bank or a modified value stored
+ * in the shadow RAM */
+ if (hw->eeprom_shadow_ram[i].modified == TRUE) {
+ low_byte = (uint8_t)hw->eeprom_shadow_ram[i].eeprom_word;
+ udelay(100);
+ error = e1000_verify_write_ich8_byte(hw,
+ (i << 1) + new_bank_offset, low_byte);
+
+ if (error != E1000_SUCCESS)
+ sector_write_failed = TRUE;
+ else {
high_byte =
(uint8_t)(hw->eeprom_shadow_ram[i].eeprom_word >> 8);
- e1000_read_ich8_byte(hw, (i << 1) + old_bank_offset + 1,
- &temp_byte);
- udelay(100);
- } else {
- e1000_read_ich8_byte(hw, (i << 1) + old_bank_offset,
- &low_byte);
udelay(100);
- error = e1000_verify_write_ich8_byte(hw,
- (i << 1) + new_bank_offset, low_byte);
- if (error != E1000_SUCCESS)
- sector_write_failed = TRUE;
+ }
+ } else {
+ e1000_read_ich8_byte(hw, (i << 1) + old_bank_offset,
+ &low_byte);
+ udelay(100);
+ error = e1000_verify_write_ich8_byte(hw,
+ (i << 1) + new_bank_offset, low_byte);
+
+ if (error != E1000_SUCCESS)
+ sector_write_failed = TRUE;
+ else {
e1000_read_ich8_byte(hw, (i << 1) + old_bank_offset + 1,
&high_byte);
+ udelay(100);
}
+ }
+ /* If the write of the low byte was successful, go ahread and
+ * write the high byte while checking to make sure that if it
+ * is the signature byte, then it is handled properly */
+ if (sector_write_failed == FALSE) {
/* If the word is 0x13, then make sure the signature bits
* (15:14) are 11b until the commit has completed.
* This will allow us to write 10b which indicates the
@@ -5512,45 +5624,45 @@ e1000_commit_shadow_ram(struct e1000_hw *hw)
high_byte = E1000_ICH8_NVM_SIG_MASK | high_byte;
error = e1000_verify_write_ich8_byte(hw,
- (i << 1) + new_bank_offset + 1, high_byte);
+ (i << 1) + new_bank_offset + 1, high_byte);
if (error != E1000_SUCCESS)
sector_write_failed = TRUE;
- if (sector_write_failed == FALSE) {
- /* Clear the now not used entry in the cache */
- hw->eeprom_shadow_ram[i].modified = FALSE;
- hw->eeprom_shadow_ram[i].eeprom_word = 0xFFFF;
- }
+ } else {
+ /* If the write failed then break from the loop and
+ * return an error */
+ break;
}
+ }
- /* Don't bother writing the segment valid bits if sector
- * programming failed. */
- if (sector_write_failed == FALSE) {
- /* Finally validate the new segment by setting bit 15:14
- * to 10b in word 0x13 , this can be done without an
- * erase as well since these bits are 11 to start with
- * and we need to change bit 14 to 0b */
- e1000_read_ich8_byte(hw,
- E1000_ICH8_NVM_SIG_WORD * 2 + 1 + new_bank_offset,
- &high_byte);
- high_byte &= 0xBF;
+ /* Don't bother writing the segment valid bits if sector
+ * programming failed. */
+ if (sector_write_failed == FALSE) {
+ /* Finally validate the new segment by setting bit 15:14
+ * to 10b in word 0x13 , this can be done without an
+ * erase as well since these bits are 11 to start with
+ * and we need to change bit 14 to 0b */
+ e1000_read_ich8_byte(hw,
+ E1000_ICH8_NVM_SIG_WORD * 2 + 1 + new_bank_offset,
+ &high_byte);
+ high_byte &= 0xBF;
+ error = e1000_verify_write_ich8_byte(hw,
+ E1000_ICH8_NVM_SIG_WORD * 2 + 1 + new_bank_offset, high_byte);
+ /* And invalidate the previously valid segment by setting
+ * its signature word (0x13) high_byte to 0b. This can be
+ * done without an erase because flash erase sets all bits
+ * to 1's. We can write 1's to 0's without an erase */
+ if (error == E1000_SUCCESS) {
error = e1000_verify_write_ich8_byte(hw,
- E1000_ICH8_NVM_SIG_WORD * 2 + 1 + new_bank_offset,
- high_byte);
- if (error != E1000_SUCCESS)
- sector_write_failed = TRUE;
+ E1000_ICH8_NVM_SIG_WORD * 2 + 1 + old_bank_offset, 0);
+ }
- /* And invalidate the previously valid segment by setting
- * its signature word (0x13) high_byte to 0b. This can be
- * done without an erase because flash erase sets all bits
- * to 1's. We can write 1's to 0's without an erase */
- error = e1000_verify_write_ich8_byte(hw,
- E1000_ICH8_NVM_SIG_WORD * 2 + 1 + old_bank_offset,
- 0);
- if (error != E1000_SUCCESS)
- sector_write_failed = TRUE;
+ /* Clear the now not used entry in the cache */
+ for (i = 0; i < E1000_SHADOW_RAM_WORDS; i++) {
+ hw->eeprom_shadow_ram[i].modified = FALSE;
+ hw->eeprom_shadow_ram[i].eeprom_word = 0xFFFF;
}
- } while (++sector_retries < 10 && sector_write_failed == TRUE);
+ }
}
return error;
@@ -5640,99 +5752,6 @@ e1000_init_rx_addrs(struct e1000_hw *hw)
}
/******************************************************************************
- * Updates the MAC's list of multicast addresses.
- *
- * hw - Struct containing variables accessed by shared code
- * mc_addr_list - the list of new multicast addresses
- * mc_addr_count - number of addresses
- * pad - number of bytes between addresses in the list
- * rar_used_count - offset where to start adding mc addresses into the RAR's
- *
- * The given list replaces any existing list. Clears the last 15 receive
- * address registers and the multicast table. Uses receive address registers
- * for the first 15 multicast addresses, and hashes the rest into the
- * multicast table.
- *****************************************************************************/
-#if 0
-void
-e1000_mc_addr_list_update(struct e1000_hw *hw,
- uint8_t *mc_addr_list,
- uint32_t mc_addr_count,
- uint32_t pad,
- uint32_t rar_used_count)
-{
- uint32_t hash_value;
- uint32_t i;
- uint32_t num_rar_entry;
- uint32_t num_mta_entry;
-
- DEBUGFUNC("e1000_mc_addr_list_update");
-
- /* Set the new number of MC addresses that we are being requested to use. */
- hw->num_mc_addrs = mc_addr_count;
-
- /* Clear RAR[1-15] */
- DEBUGOUT(" Clearing RAR[1-15]\n");
- num_rar_entry = E1000_RAR_ENTRIES;
- if (hw->mac_type == e1000_ich8lan)
- num_rar_entry = E1000_RAR_ENTRIES_ICH8LAN;
- /* Reserve a spot for the Locally Administered Address to work around
- * an 82571 issue in which a reset on one port will reload the MAC on
- * the other port. */
- if ((hw->mac_type == e1000_82571) && (hw->laa_is_present == TRUE))
- num_rar_entry -= 1;
-
- for (i = rar_used_count; i < num_rar_entry; i++) {
- E1000_WRITE_REG_ARRAY(hw, RA, (i << 1), 0);
- E1000_WRITE_FLUSH(hw);
- E1000_WRITE_REG_ARRAY(hw, RA, ((i << 1) + 1), 0);
- E1000_WRITE_FLUSH(hw);
- }
-
- /* Clear the MTA */
- DEBUGOUT(" Clearing MTA\n");
- num_mta_entry = E1000_NUM_MTA_REGISTERS;
- if (hw->mac_type == e1000_ich8lan)
- num_mta_entry = E1000_NUM_MTA_REGISTERS_ICH8LAN;
- for (i = 0; i < num_mta_entry; i++) {
- E1000_WRITE_REG_ARRAY(hw, MTA, i, 0);
- E1000_WRITE_FLUSH(hw);
- }
-
- /* Add the new addresses */
- for (i = 0; i < mc_addr_count; i++) {
- DEBUGOUT(" Adding the multicast addresses:\n");
- DEBUGOUT7(" MC Addr #%d =%.2X %.2X %.2X %.2X %.2X %.2X\n", i,
- mc_addr_list[i * (ETH_LENGTH_OF_ADDRESS + pad)],
- mc_addr_list[i * (ETH_LENGTH_OF_ADDRESS + pad) + 1],
- mc_addr_list[i * (ETH_LENGTH_OF_ADDRESS + pad) + 2],
- mc_addr_list[i * (ETH_LENGTH_OF_ADDRESS + pad) + 3],
- mc_addr_list[i * (ETH_LENGTH_OF_ADDRESS + pad) + 4],
- mc_addr_list[i * (ETH_LENGTH_OF_ADDRESS + pad) + 5]);
-
- hash_value = e1000_hash_mc_addr(hw,
- mc_addr_list +
- (i * (ETH_LENGTH_OF_ADDRESS + pad)));
-
- DEBUGOUT1(" Hash value = 0x%03X\n", hash_value);
-
- /* Place this multicast address in the RAR if there is room, *
- * else put it in the MTA
- */
- if (rar_used_count < num_rar_entry) {
- e1000_rar_set(hw,
- mc_addr_list + (i * (ETH_LENGTH_OF_ADDRESS + pad)),
- rar_used_count);
- rar_used_count++;
- } else {
- e1000_mta_set(hw, hash_value);
- }
- }
- DEBUGOUT("MC Update Complete\n");
-}
-#endif /* 0 */
-
-/******************************************************************************
* Hashes an address to determine its location in the multicast table
*
* hw - Struct containing variables accessed by shared code
@@ -6290,7 +6309,7 @@ e1000_led_off(struct e1000_hw *hw)
*
* hw - Struct containing variables accessed by shared code
*****************************************************************************/
-void
+static void
e1000_clear_hw_cntrs(struct e1000_hw *hw)
{
volatile uint32_t temp;
@@ -6539,6 +6558,8 @@ e1000_tbi_adjust_stats(struct e1000_hw *hw,
void
e1000_get_bus_info(struct e1000_hw *hw)
{
+ int32_t ret_val;
+ uint16_t pci_ex_link_status;
uint32_t status;
switch (hw->mac_type) {
@@ -6548,18 +6569,25 @@ e1000_get_bus_info(struct e1000_hw *hw)
hw->bus_speed = e1000_bus_speed_unknown;
hw->bus_width = e1000_bus_width_unknown;
break;
+ case e1000_82571:
case e1000_82572:
case e1000_82573:
+ case e1000_80003es2lan:
hw->bus_type = e1000_bus_type_pci_express;
hw->bus_speed = e1000_bus_speed_2500;
- hw->bus_width = e1000_bus_width_pciex_1;
+ ret_val = e1000_read_pcie_cap_reg(hw,
+ PCI_EX_LINK_STATUS,
+ &pci_ex_link_status);
+ if (ret_val)
+ hw->bus_width = e1000_bus_width_unknown;
+ else
+ hw->bus_width = (pci_ex_link_status & PCI_EX_LINK_WIDTH_MASK) >>
+ PCI_EX_LINK_WIDTH_SHIFT;
break;
- case e1000_82571:
case e1000_ich8lan:
- case e1000_80003es2lan:
hw->bus_type = e1000_bus_type_pci_express;
hw->bus_speed = e1000_bus_speed_2500;
- hw->bus_width = e1000_bus_width_pciex_4;
+ hw->bus_width = e1000_bus_width_pciex_1;
break;
default:
status = E1000_READ_REG(hw, STATUS);
@@ -6593,25 +6621,6 @@ e1000_get_bus_info(struct e1000_hw *hw)
break;
}
}
-/******************************************************************************
- * Reads a value from one of the devices registers using port I/O (as opposed
- * memory mapped I/O). Only 82544 and newer devices support port I/O.
- *
- * hw - Struct containing variables accessed by shared code
- * offset - offset to read from
- *****************************************************************************/
-#if 0
-uint32_t
-e1000_read_reg_io(struct e1000_hw *hw,
- uint32_t offset)
-{
- unsigned long io_addr = hw->io_base;
- unsigned long io_data = hw->io_base + 4;
-
- e1000_io_write(hw, io_addr, offset);
- return e1000_io_read(hw, io_data);
-}
-#endif /* 0 */
/******************************************************************************
* Writes a value to one of the devices registers using port I/O (as opposed to
@@ -6633,7 +6642,6 @@ e1000_write_reg_io(struct e1000_hw *hw,
e1000_io_write(hw, io_data, value);
}
-
/******************************************************************************
* Estimates the cable length.
*
@@ -6842,7 +6850,7 @@ e1000_get_cable_length(struct e1000_hw *hw,
*****************************************************************************/
static int32_t
e1000_check_polarity(struct e1000_hw *hw,
- uint16_t *polarity)
+ e1000_rev_polarity *polarity)
{
int32_t ret_val;
uint16_t phy_data;
@@ -6856,8 +6864,10 @@ e1000_check_polarity(struct e1000_hw *hw,
&phy_data);
if (ret_val)
return ret_val;
- *polarity = (phy_data & M88E1000_PSSR_REV_POLARITY) >>
- M88E1000_PSSR_REV_POLARITY_SHIFT;
+ *polarity = ((phy_data & M88E1000_PSSR_REV_POLARITY) >>
+ M88E1000_PSSR_REV_POLARITY_SHIFT) ?
+ e1000_rev_polarity_reversed : e1000_rev_polarity_normal;
+
} else if (hw->phy_type == e1000_phy_igp ||
hw->phy_type == e1000_phy_igp_3 ||
hw->phy_type == e1000_phy_igp_2) {
@@ -6879,19 +6889,22 @@ e1000_check_polarity(struct e1000_hw *hw,
return ret_val;
/* Check the polarity bits */
- *polarity = (phy_data & IGP01E1000_PHY_POLARITY_MASK) ? 1 : 0;
+ *polarity = (phy_data & IGP01E1000_PHY_POLARITY_MASK) ?
+ e1000_rev_polarity_reversed : e1000_rev_polarity_normal;
} else {
/* For 10 Mbps, read the polarity bit in the status register. (for
* 100 Mbps this bit is always 0) */
- *polarity = phy_data & IGP01E1000_PSSR_POLARITY_REVERSED;
+ *polarity = (phy_data & IGP01E1000_PSSR_POLARITY_REVERSED) ?
+ e1000_rev_polarity_reversed : e1000_rev_polarity_normal;
}
} else if (hw->phy_type == e1000_phy_ife) {
ret_val = e1000_read_phy_reg(hw, IFE_PHY_EXTENDED_STATUS_CONTROL,
&phy_data);
if (ret_val)
return ret_val;
- *polarity = (phy_data & IFE_PESC_POLARITY_REVERSED) >>
- IFE_PESC_POLARITY_REVERSED_SHIFT;
+ *polarity = ((phy_data & IFE_PESC_POLARITY_REVERSED) >>
+ IFE_PESC_POLARITY_REVERSED_SHIFT) ?
+ e1000_rev_polarity_reversed : e1000_rev_polarity_normal;
}
return E1000_SUCCESS;
}
@@ -7259,7 +7272,7 @@ e1000_set_d3_lplu_state(struct e1000_hw *hw,
} else if (hw->smart_speed == e1000_smart_speed_off) {
ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG,
&phy_data);
- if (ret_val)
+ if (ret_val)
return ret_val;
phy_data &= ~IGP01E1000_PSCFR_SMART_SPEED;
@@ -7369,7 +7382,7 @@ e1000_set_d0_lplu_state(struct e1000_hw *hw,
} else if (hw->smart_speed == e1000_smart_speed_off) {
ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG,
&phy_data);
- if (ret_val)
+ if (ret_val)
return ret_val;
phy_data &= ~IGP01E1000_PSCFR_SMART_SPEED;
@@ -7475,7 +7488,7 @@ e1000_set_vco_speed(struct e1000_hw *hw)
*
* returns: - E1000_SUCCESS .
****************************************************************************/
-int32_t
+static int32_t
e1000_host_if_read_cookie(struct e1000_hw * hw, uint8_t *buffer)
{
uint8_t i;
@@ -7686,7 +7699,7 @@ e1000_check_mng_mode(struct e1000_hw *hw)
****************************************************************************/
int32_t
e1000_mng_write_dhcp_info(struct e1000_hw * hw, uint8_t *buffer,
- uint16_t length)
+ uint16_t length)
{
int32_t ret_val;
struct e1000_host_mng_command_header hdr;
@@ -7716,7 +7729,7 @@ e1000_mng_write_dhcp_info(struct e1000_hw * hw, uint8_t *buffer,
*
* returns - checksum of buffer contents.
****************************************************************************/
-uint8_t
+static uint8_t
e1000_calculate_mng_checksum(char *buffer, uint32_t length)
{
uint8_t sum = 0;
@@ -7914,32 +7927,6 @@ e1000_set_pci_express_master_disable(struct e1000_hw *hw)
E1000_WRITE_REG(hw, CTRL, ctrl);
}
-/***************************************************************************
- *
- * Enables PCI-Express master access.
- *
- * hw: Struct containing variables accessed by shared code
- *
- * returns: - none.
- *
- ***************************************************************************/
-#if 0
-void
-e1000_enable_pciex_master(struct e1000_hw *hw)
-{
- uint32_t ctrl;
-
- DEBUGFUNC("e1000_enable_pciex_master");
-
- if (hw->bus_type != e1000_bus_type_pci_express)
- return;
-
- ctrl = E1000_READ_REG(hw, CTRL);
- ctrl &= ~E1000_CTRL_GIO_MASTER_DISABLE;
- E1000_WRITE_REG(hw, CTRL, ctrl);
-}
-#endif /* 0 */
-
/*******************************************************************************
*
* Disables PCI-Express master access and verifies there are no pending requests
@@ -8063,7 +8050,6 @@ e1000_get_phy_cfg_done(struct e1000_hw *hw)
msleep(1);
timeout--;
}
-
if (!timeout) {
DEBUGOUT("MNG configuration cycle has not completed.\n");
return -E1000_ERR_RESET;
@@ -8172,8 +8158,9 @@ e1000_get_software_semaphore(struct e1000_hw *hw)
DEBUGFUNC("e1000_get_software_semaphore");
- if (hw->mac_type != e1000_80003es2lan)
+ if (hw->mac_type != e1000_80003es2lan) {
return E1000_SUCCESS;
+ }
while (timeout) {
swsm = E1000_READ_REG(hw, SWSM);
@@ -8206,8 +8193,9 @@ e1000_release_software_semaphore(struct e1000_hw *hw)
DEBUGFUNC("e1000_release_software_semaphore");
- if (hw->mac_type != e1000_80003es2lan)
+ if (hw->mac_type != e1000_80003es2lan) {
return;
+ }
swsm = E1000_READ_REG(hw, SWSM);
/* Release the SW semaphores.*/
@@ -8241,7 +8229,7 @@ e1000_check_phy_reset_block(struct e1000_hw *hw)
if (hw->mac_type > e1000_82547_rev_2)
manc = E1000_READ_REG(hw, MANC);
return (manc & E1000_MANC_BLK_PHY_RST_ON_IDE) ?
- E1000_BLK_PHY_RESET : E1000_SUCCESS;
+ E1000_BLK_PHY_RESET : E1000_SUCCESS;
}
static uint8_t
@@ -8377,66 +8365,6 @@ e1000_release_software_flag(struct e1000_hw *hw)
return;
}
-/***************************************************************************
- *
- * Disable dynamic power down mode in ife PHY.
- * It can be used to workaround band-gap problem.
- *
- * hw: Struct containing variables accessed by shared code
- *
- ***************************************************************************/
-#if 0
-int32_t
-e1000_ife_disable_dynamic_power_down(struct e1000_hw *hw)
-{
- uint16_t phy_data;
- int32_t ret_val = E1000_SUCCESS;
-
- DEBUGFUNC("e1000_ife_disable_dynamic_power_down");
-
- if (hw->phy_type == e1000_phy_ife) {
- ret_val = e1000_read_phy_reg(hw, IFE_PHY_SPECIAL_CONTROL, &phy_data);
- if (ret_val)
- return ret_val;
-
- phy_data |= IFE_PSC_DISABLE_DYNAMIC_POWER_DOWN;
- ret_val = e1000_write_phy_reg(hw, IFE_PHY_SPECIAL_CONTROL, phy_data);
- }
-
- return ret_val;
-}
-#endif /* 0 */
-
-/***************************************************************************
- *
- * Enable dynamic power down mode in ife PHY.
- * It can be used to workaround band-gap problem.
- *
- * hw: Struct containing variables accessed by shared code
- *
- ***************************************************************************/
-#if 0
-int32_t
-e1000_ife_enable_dynamic_power_down(struct e1000_hw *hw)
-{
- uint16_t phy_data;
- int32_t ret_val = E1000_SUCCESS;
-
- DEBUGFUNC("e1000_ife_enable_dynamic_power_down");
-
- if (hw->phy_type == e1000_phy_ife) {
- ret_val = e1000_read_phy_reg(hw, IFE_PHY_SPECIAL_CONTROL, &phy_data);
- if (ret_val)
- return ret_val;
-
- phy_data &= ~IFE_PSC_DISABLE_DYNAMIC_POWER_DOWN;
- ret_val = e1000_write_phy_reg(hw, IFE_PHY_SPECIAL_CONTROL, phy_data);
- }
-
- return ret_val;
-}
-#endif /* 0 */
-
/******************************************************************************
* Reads a 16 bit word or words from the EEPROM using the ICH8's flash access
* register.
@@ -8832,20 +8760,22 @@ static int32_t
e1000_verify_write_ich8_byte(struct e1000_hw *hw, uint32_t index, uint8_t byte)
{
int32_t error = E1000_SUCCESS;
- int32_t program_retries;
- uint8_t temp_byte;
+ int32_t program_retries = 0;
- e1000_write_ich8_byte(hw, index, byte);
- udelay(100);
+ DEBUGOUT2("Byte := %2.2X Offset := %d\n", byte, index);
- for (program_retries = 0; program_retries < 100; program_retries++) {
- e1000_read_ich8_byte(hw, index, &temp_byte);
- if (temp_byte == byte)
- break;
- udelay(10);
- e1000_write_ich8_byte(hw, index, byte);
- udelay(100);
+ error = e1000_write_ich8_byte(hw, index, byte);
+
+ if (error != E1000_SUCCESS) {
+ for (program_retries = 0; program_retries < 100; program_retries++) {
+ DEBUGOUT2("Retrying \t Byte := %2.2X Offset := %d\n", byte, index);
+ error = e1000_write_ich8_byte(hw, index, byte);
+ udelay(100);
+ if (error == E1000_SUCCESS)
+ break;
+ }
}
+
if (program_retries == 100)
error = E1000_ERR_EEPROM;
@@ -8886,39 +8816,27 @@ e1000_read_ich8_word(struct e1000_hw *hw, uint32_t index, uint16_t *data)
}
/******************************************************************************
- * Writes a word to the NVM using the ICH8 flash access registers.
+ * Erases the bank specified. Each bank may be a 4, 8 or 64k block. Banks are 0
+ * based.
*
* hw - pointer to e1000_hw structure
- * index - The starting byte index of the word to read.
- * data - The word to write to the NVM.
- *****************************************************************************/
-#if 0
-int32_t
-e1000_write_ich8_word(struct e1000_hw *hw, uint32_t index, uint16_t data)
-{
- int32_t status = E1000_SUCCESS;
- status = e1000_write_ich8_data(hw, index, 2, data);
- return status;
-}
-#endif /* 0 */
-
-/******************************************************************************
- * Erases the bank specified. Each bank is a 4k block. Segments are 0 based.
- * segment N is 4096 * N + flash_reg_addr.
+ * bank - 0 for first bank, 1 for second bank
*
- * hw - pointer to e1000_hw structure
- * segment - 0 for first segment, 1 for second segment, etc.
+ * Note that this function may actually erase as much as 8 or 64 KBytes. The
+ * amount of NVM used in each bank is a *minimum* of 4 KBytes, but in fact the
+ * bank size may be 4, 8 or 64 KBytes
*****************************************************************************/
-static int32_t
-e1000_erase_ich8_4k_segment(struct e1000_hw *hw, uint32_t segment)
+int32_t
+e1000_erase_ich8_4k_segment(struct e1000_hw *hw, uint32_t bank)
{
union ich8_hws_flash_status hsfsts;
union ich8_hws_flash_ctrl hsflctl;
uint32_t flash_linear_address;
int32_t count = 0;
int32_t error = E1000_ERR_EEPROM;
- int32_t iteration, seg_size;
- int32_t sector_size;
+ int32_t iteration;
+ int32_t sub_sector_size = 0;
+ int32_t bank_size;
int32_t j = 0;
int32_t error_flag = 0;
@@ -8927,22 +8845,27 @@ e1000_erase_ich8_4k_segment(struct e1000_hw *hw, uint32_t segment)
/* Determine HW Sector size: Read BERASE bits of Hw flash Status register */
/* 00: The Hw sector is 256 bytes, hence we need to erase 16
* consecutive sectors. The start index for the nth Hw sector can be
- * calculated as = segment * 4096 + n * 256
+ * calculated as bank * 4096 + n * 256
* 01: The Hw sector is 4K bytes, hence we need to erase 1 sector.
* The start index for the nth Hw sector can be calculated
- * as = segment * 4096
- * 10: Error condition
- * 11: The Hw sector size is much bigger than the size asked to
- * erase...error condition */
+ * as bank * 4096
+ * 10: The HW sector is 8K bytes
+ * 11: The Hw sector size is 64K bytes */
if (hsfsts.hsf_status.berasesz == 0x0) {
/* Hw sector size 256 */
- sector_size = seg_size = ICH8_FLASH_SEG_SIZE_256;
+ sub_sector_size = ICH8_FLASH_SEG_SIZE_256;
+ bank_size = ICH8_FLASH_SECTOR_SIZE;
iteration = ICH8_FLASH_SECTOR_SIZE / ICH8_FLASH_SEG_SIZE_256;
} else if (hsfsts.hsf_status.berasesz == 0x1) {
- sector_size = seg_size = ICH8_FLASH_SEG_SIZE_4K;
+ bank_size = ICH8_FLASH_SEG_SIZE_4K;
+ iteration = 1;
+ } else if (hw->mac_type != e1000_ich8lan &&
+ hsfsts.hsf_status.berasesz == 0x2) {
+ /* 8K erase size invalid for ICH8 - added in for ICH9 */
+ bank_size = ICH9_FLASH_SEG_SIZE_8K;
iteration = 1;
} else if (hsfsts.hsf_status.berasesz == 0x3) {
- sector_size = seg_size = ICH8_FLASH_SEG_SIZE_64K;
+ bank_size = ICH8_FLASH_SEG_SIZE_64K;
iteration = 1;
} else {
return error;
@@ -8966,16 +8889,15 @@ e1000_erase_ich8_4k_segment(struct e1000_hw *hw, uint32_t segment)
/* Write the last 24 bits of an index within the block into Flash
* Linear address field in Flash Address. This probably needs to
- * be calculated here based off the on-chip segment size and the
- * software segment size assumed (4K) */
- /* TBD */
- flash_linear_address = segment * sector_size + j * seg_size;
- flash_linear_address &= ICH8_FLASH_LINEAR_ADDR_MASK;
+ * be calculated here based off the on-chip erase sector size and
+ * the software bank size (4, 8 or 64 KBytes) */
+ flash_linear_address = bank * bank_size + j * sub_sector_size;
flash_linear_address += hw->flash_base_addr;
+ flash_linear_address &= ICH8_FLASH_LINEAR_ADDR_MASK;
E1000_WRITE_ICH8_REG(hw, ICH8_FLASH_FADDR, flash_linear_address);
- error = e1000_ich8_flash_cycle(hw, 1000000);
+ error = e1000_ich8_flash_cycle(hw, ICH8_FLASH_ERASE_TIMEOUT);
/* Check if FCERR is set to 1. If 1, clear it and try the whole
* sequence a few more times else Done */
if (error == E1000_SUCCESS) {
@@ -8999,44 +8921,6 @@ e1000_erase_ich8_4k_segment(struct e1000_hw *hw, uint32_t segment)
return error;
}
-/******************************************************************************
- *
- * Reverse duplex setting without breaking the link.
- *
- * hw: Struct containing variables accessed by shared code
- *
- *****************************************************************************/
-#if 0
-int32_t
-e1000_duplex_reversal(struct e1000_hw *hw)
-{
- int32_t ret_val;
- uint16_t phy_data;
-
- if (hw->phy_type != e1000_phy_igp_3)
- return E1000_SUCCESS;
-
- ret_val = e1000_read_phy_reg(hw, PHY_CTRL, &phy_data);
- if (ret_val)
- return ret_val;
-
- phy_data ^= MII_CR_FULL_DUPLEX;
-
- ret_val = e1000_write_phy_reg(hw, PHY_CTRL, phy_data);
- if (ret_val)
- return ret_val;
-
- ret_val = e1000_read_phy_reg(hw, IGP3E1000_PHY_MISC_CTRL, &phy_data);
- if (ret_val)
- return ret_val;
-
- phy_data |= IGP3_PHY_MISC_DUPLEX_MANUAL_SET;
- ret_val = e1000_write_phy_reg(hw, IGP3E1000_PHY_MISC_CTRL, phy_data);
-
- return ret_val;
-}
-#endif /* 0 */
-
static int32_t
e1000_init_lcd_from_nvm_config_region(struct e1000_hw *hw,
uint32_t cnf_base_addr, uint32_t cnf_size)
@@ -9071,6 +8955,14 @@ e1000_init_lcd_from_nvm_config_region(struct e1000_hw *hw,
}
+/******************************************************************************
+ * This function initializes the PHY from the NVM on ICH8 platforms. This
+ * is needed due to an issue where the NVM configuration is not properly
+ * autoloaded after power transitions. Therefore, after each PHY reset, we
+ * will load the configuration data out of the NVM manually.
+ *
+ * hw: Struct containing variables accessed by shared code
+ *****************************************************************************/
static int32_t
e1000_init_lcd_from_nvm(struct e1000_hw *hw)
{
diff --git a/drivers/net/e1000/e1000_hw.h b/drivers/net/e1000/e1000_hw.h
index 4020acb5500..112447fd8bf 100644
--- a/drivers/net/e1000/e1000_hw.h
+++ b/drivers/net/e1000/e1000_hw.h
@@ -1,25 +1,24 @@
/*******************************************************************************
-
- Copyright(c) 1999 - 2006 Intel Corporation. All rights reserved.
-
- This program is free software; you can redistribute it and/or modify it
- under the terms of the GNU General Public License as published by the Free
- Software Foundation; either version 2 of the License, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful, but WITHOUT
- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ Intel PRO/1000 Linux driver
+ Copyright(c) 1999 - 2006 Intel Corporation.
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms and conditions of the GNU General Public License,
+ version 2, as published by the Free Software Foundation.
+
+ This program is distributed in the hope it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
more details.
-
+
You should have received a copy of the GNU General Public License along with
- this program; if not, write to the Free Software Foundation, Inc., 59
- Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
- The full GNU General Public License is included in this distribution in the
- file called LICENSE.
-
+ this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+
+ The full GNU General Public License is included in this distribution in
+ the file called "COPYING".
+
Contact Information:
Linux NICS <linux.nics@intel.com>
e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
@@ -93,11 +92,11 @@ typedef enum {
/* Flow Control Settings */
typedef enum {
- e1000_fc_none = 0,
- e1000_fc_rx_pause = 1,
- e1000_fc_tx_pause = 2,
- e1000_fc_full = 3,
- e1000_fc_default = 0xFF
+ E1000_FC_NONE = 0,
+ E1000_FC_RX_PAUSE = 1,
+ E1000_FC_TX_PAUSE = 2,
+ E1000_FC_FULL = 3,
+ E1000_FC_DEFAULT = 0xFF
} e1000_fc_type;
struct e1000_shadow_ram {
@@ -302,6 +301,9 @@ typedef enum {
#define E1000_BLK_PHY_RESET 12
#define E1000_ERR_SWFW_SYNC 13
+#define E1000_BYTE_SWAP_WORD(_value) ((((_value) & 0x00ff) << 8) | \
+ (((_value) & 0xff00) >> 8))
+
/* Function prototypes */
/* Initialization */
int32_t e1000_reset_hw(struct e1000_hw *hw);
@@ -314,7 +316,7 @@ int32_t e1000_setup_link(struct e1000_hw *hw);
int32_t e1000_phy_setup_autoneg(struct e1000_hw *hw);
void e1000_config_collision_dist(struct e1000_hw *hw);
int32_t e1000_check_for_link(struct e1000_hw *hw);
-int32_t e1000_get_speed_and_duplex(struct e1000_hw *hw, uint16_t * speed, uint16_t * duplex);
+int32_t e1000_get_speed_and_duplex(struct e1000_hw *hw, uint16_t *speed, uint16_t *duplex);
int32_t e1000_force_mac_fc(struct e1000_hw *hw);
/* PHY */
@@ -322,9 +324,9 @@ int32_t e1000_read_phy_reg(struct e1000_hw *hw, uint32_t reg_addr, uint16_t *phy
int32_t e1000_write_phy_reg(struct e1000_hw *hw, uint32_t reg_addr, uint16_t data);
int32_t e1000_phy_hw_reset(struct e1000_hw *hw);
int32_t e1000_phy_reset(struct e1000_hw *hw);
-void e1000_phy_powerdown_workaround(struct e1000_hw *hw);
int32_t e1000_phy_get_info(struct e1000_hw *hw, struct e1000_phy_info *phy_info);
int32_t e1000_validate_mdi_setting(struct e1000_hw *hw);
+void e1000_phy_powerdown_workaround(struct e1000_hw *hw);
/* EEPROM Functions */
int32_t e1000_init_eeprom_params(struct e1000_hw *hw);
@@ -393,7 +395,6 @@ int32_t e1000_read_eeprom(struct e1000_hw *hw, uint16_t reg, uint16_t words, uin
int32_t e1000_validate_eeprom_checksum(struct e1000_hw *hw);
int32_t e1000_update_eeprom_checksum(struct e1000_hw *hw);
int32_t e1000_write_eeprom(struct e1000_hw *hw, uint16_t reg, uint16_t words, uint16_t *data);
-int32_t e1000_read_part_num(struct e1000_hw *hw, uint32_t * part_num);
int32_t e1000_read_mac_addr(struct e1000_hw * hw);
/* Filters (multicast, vlan, receive) */
@@ -420,6 +421,7 @@ void e1000_pci_set_mwi(struct e1000_hw *hw);
void e1000_pci_clear_mwi(struct e1000_hw *hw);
void e1000_read_pci_cfg(struct e1000_hw *hw, uint32_t reg, uint16_t * value);
void e1000_write_pci_cfg(struct e1000_hw *hw, uint32_t reg, uint16_t * value);
+int32_t e1000_read_pcie_cap_reg(struct e1000_hw *hw, uint32_t reg, uint16_t *value);
/* Port I/O is only supported on 82544 and newer */
void e1000_io_write(struct e1000_hw *hw, unsigned long port, uint32_t value);
int32_t e1000_disable_pciex_master(struct e1000_hw *hw);
@@ -574,10 +576,10 @@ int32_t e1000_check_phy_reset_block(struct e1000_hw *hw);
* E1000_RAR_ENTRIES - 1 multicast addresses.
*/
#define E1000_RAR_ENTRIES 15
-#define E1000_RAR_ENTRIES_ICH8LAN 7
+#define E1000_RAR_ENTRIES_ICH8LAN 6
-#define MIN_NUMBER_OF_DESCRIPTORS 8
-#define MAX_NUMBER_OF_DESCRIPTORS 0xFFF8
+#define MIN_NUMBER_OF_DESCRIPTORS 8
+#define MAX_NUMBER_OF_DESCRIPTORS 0xFFF8
/* Receive Descriptor */
struct e1000_rx_desc {
@@ -1300,6 +1302,7 @@ struct e1000_hw_stats {
uint64_t algnerrc;
uint64_t symerrs;
uint64_t rxerrc;
+ uint64_t txerrc;
uint64_t mpc;
uint64_t scc;
uint64_t ecol;
@@ -1332,8 +1335,9 @@ struct e1000_hw_stats {
uint64_t gotch;
uint64_t rnbc;
uint64_t ruc;
- uint64_t rfc;
uint64_t roc;
+ uint64_t rlerrc;
+ uint64_t rfc;
uint64_t rjc;
uint64_t mgprc;
uint64_t mgpdc;
@@ -1440,6 +1444,7 @@ struct e1000_hw {
boolean_t tbi_compatibility_on;
boolean_t laa_is_present;
boolean_t phy_reset_disable;
+ boolean_t initialize_hw_bits_disable;
boolean_t fc_send_xon;
boolean_t fc_strict_ieee;
boolean_t report_tx_early;
@@ -1613,16 +1618,17 @@ struct e1000_hw {
#define E1000_CTRL_EXT_LINK_MODE_MASK 0x00C00000
#define E1000_CTRL_EXT_LINK_MODE_GMII 0x00000000
#define E1000_CTRL_EXT_LINK_MODE_TBI 0x00C00000
-#define E1000_CTRL_EXT_LINK_MODE_KMRN 0x00000000
+#define E1000_CTRL_EXT_LINK_MODE_KMRN 0x00000000
#define E1000_CTRL_EXT_LINK_MODE_SERDES 0x00C00000
+#define E1000_CTRL_EXT_LINK_MODE_SGMII 0x00800000
#define E1000_CTRL_EXT_WR_WMARK_MASK 0x03000000
#define E1000_CTRL_EXT_WR_WMARK_256 0x00000000
#define E1000_CTRL_EXT_WR_WMARK_320 0x01000000
#define E1000_CTRL_EXT_WR_WMARK_384 0x02000000
#define E1000_CTRL_EXT_WR_WMARK_448 0x03000000
-#define E1000_CTRL_EXT_DRV_LOAD 0x10000000 /* Driver loaded bit for FW */
-#define E1000_CTRL_EXT_IAME 0x08000000 /* Interrupt acknowledge Auto-mask */
-#define E1000_CTRL_EXT_INT_TIMER_CLR 0x20000000 /* Clear Interrupt timers after IMS clear */
+#define E1000_CTRL_EXT_DRV_LOAD 0x10000000 /* Driver loaded bit for FW */
+#define E1000_CTRL_EXT_IAME 0x08000000 /* Interrupt acknowledge Auto-mask */
+#define E1000_CTRL_EXT_INT_TIMER_CLR 0x20000000 /* Clear Interrupt timers after IMS clear */
#define E1000_CRTL_EXT_PB_PAREN 0x01000000 /* packet buffer parity error detection enabled */
#define E1000_CTRL_EXT_DF_PAREN 0x02000000 /* descriptor FIFO parity error detection enable */
#define E1000_CTRL_EXT_GHOST_PAREN 0x40000000
@@ -2218,6 +2224,11 @@ struct e1000_host_command_info {
#define E1000_FACTPS_LAN_FUNC_SEL 0x40000000
#define E1000_FACTPS_PM_STATE_CHANGED 0x80000000
+/* PCI-Ex Config Space */
+#define PCI_EX_LINK_STATUS 0x12
+#define PCI_EX_LINK_WIDTH_MASK 0x3F0
+#define PCI_EX_LINK_WIDTH_SHIFT 4
+
/* EEPROM Commands - Microwire */
#define EEPROM_READ_OPCODE_MICROWIRE 0x6 /* EEPROM read opcode */
#define EEPROM_WRITE_OPCODE_MICROWIRE 0x5 /* EEPROM write opcode */
@@ -3120,6 +3131,7 @@ struct e1000_host_command_info {
/* I = Integrated
* E = External
*/
+#define M88_VENDOR 0x0141
#define M88E1000_E_PHY_ID 0x01410C50
#define M88E1000_I_PHY_ID 0x01410C30
#define M88E1011_I_PHY_ID 0x01410C20
@@ -3244,10 +3256,12 @@ struct e1000_host_command_info {
#define IFE_PSCL_PROBE_LEDS_OFF 0x0006 /* Force LEDs 0 and 2 off */
#define IFE_PSCL_PROBE_LEDS_ON 0x0007 /* Force LEDs 0 and 2 on */
-#define ICH8_FLASH_COMMAND_TIMEOUT 500 /* 500 ms , should be adjusted */
-#define ICH8_FLASH_CYCLE_REPEAT_COUNT 10 /* 10 cycles , should be adjusted */
+#define ICH8_FLASH_COMMAND_TIMEOUT 5000 /* 5000 uSecs - adjusted */
+#define ICH8_FLASH_ERASE_TIMEOUT 3000000 /* Up to 3 seconds - worst case */
+#define ICH8_FLASH_CYCLE_REPEAT_COUNT 10 /* 10 cycles */
#define ICH8_FLASH_SEG_SIZE_256 256
#define ICH8_FLASH_SEG_SIZE_4K 4096
+#define ICH9_FLASH_SEG_SIZE_8K 8192
#define ICH8_FLASH_SEG_SIZE_64K 65536
#define ICH8_CYCLE_READ 0x0
diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c
index 3f6a752700a..7dca38fba6a 100644
--- a/drivers/net/e1000/e1000_main.c
+++ b/drivers/net/e1000/e1000_main.c
@@ -1,25 +1,24 @@
/*******************************************************************************
-
- Copyright(c) 1999 - 2006 Intel Corporation. All rights reserved.
-
- This program is free software; you can redistribute it and/or modify it
- under the terms of the GNU General Public License as published by the Free
- Software Foundation; either version 2 of the License, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful, but WITHOUT
- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ Intel PRO/1000 Linux driver
+ Copyright(c) 1999 - 2006 Intel Corporation.
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms and conditions of the GNU General Public License,
+ version 2, as published by the Free Software Foundation.
+
+ This program is distributed in the hope it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
more details.
-
+
You should have received a copy of the GNU General Public License along with
- this program; if not, write to the Free Software Foundation, Inc., 59
- Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
- The full GNU General Public License is included in this distribution in the
- file called LICENSE.
-
+ this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+
+ The full GNU General Public License is included in this distribution in
+ the file called "COPYING".
+
Contact Information:
Linux NICS <linux.nics@intel.com>
e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
@@ -36,7 +35,7 @@ static char e1000_driver_string[] = "Intel(R) PRO/1000 Network Driver";
#else
#define DRIVERNAPI "-NAPI"
#endif
-#define DRV_VERSION "7.2.7-k2"DRIVERNAPI
+#define DRV_VERSION "7.2.9-k2"DRIVERNAPI
char e1000_driver_version[] = DRV_VERSION;
static char e1000_copyright[] = "Copyright (c) 1999-2006 Intel Corporation.";
@@ -110,16 +109,24 @@ static struct pci_device_id e1000_pci_tbl[] = {
MODULE_DEVICE_TABLE(pci, e1000_pci_tbl);
+int e1000_up(struct e1000_adapter *adapter);
+void e1000_down(struct e1000_adapter *adapter);
+void e1000_reinit_locked(struct e1000_adapter *adapter);
+void e1000_reset(struct e1000_adapter *adapter);
+int e1000_set_spd_dplx(struct e1000_adapter *adapter, uint16_t spddplx);
+int e1000_setup_all_tx_resources(struct e1000_adapter *adapter);
+int e1000_setup_all_rx_resources(struct e1000_adapter *adapter);
+void e1000_free_all_tx_resources(struct e1000_adapter *adapter);
+void e1000_free_all_rx_resources(struct e1000_adapter *adapter);
static int e1000_setup_tx_resources(struct e1000_adapter *adapter,
- struct e1000_tx_ring *txdr);
+ struct e1000_tx_ring *txdr);
static int e1000_setup_rx_resources(struct e1000_adapter *adapter,
- struct e1000_rx_ring *rxdr);
+ struct e1000_rx_ring *rxdr);
static void e1000_free_tx_resources(struct e1000_adapter *adapter,
- struct e1000_tx_ring *tx_ring);
+ struct e1000_tx_ring *tx_ring);
static void e1000_free_rx_resources(struct e1000_adapter *adapter,
- struct e1000_rx_ring *rx_ring);
-
-/* Local Function Prototypes */
+ struct e1000_rx_ring *rx_ring);
+void e1000_update_stats(struct e1000_adapter *adapter);
static int e1000_init_module(void);
static void e1000_exit_module(void);
@@ -172,6 +179,7 @@ static void e1000_alloc_rx_buffers_ps(struct e1000_adapter *adapter,
static int e1000_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd);
static int e1000_mii_ioctl(struct net_device *netdev, struct ifreq *ifr,
int cmd);
+void e1000_set_ethtool_ops(struct net_device *netdev);
static void e1000_enter_82542_rst(struct e1000_adapter *adapter);
static void e1000_leave_82542_rst(struct e1000_adapter *adapter);
static void e1000_tx_timeout(struct net_device *dev);
@@ -196,6 +204,8 @@ static void e1000_shutdown(struct pci_dev *pdev);
static void e1000_netpoll (struct net_device *netdev);
#endif
+extern void e1000_check_options(struct e1000_adapter *adapter);
+
static pci_ers_result_t e1000_io_error_detected(struct pci_dev *pdev,
pci_channel_state_t state);
static pci_ers_result_t e1000_io_slot_reset(struct pci_dev *pdev);
@@ -212,9 +222,9 @@ static struct pci_driver e1000_driver = {
.id_table = e1000_pci_tbl,
.probe = e1000_probe,
.remove = __devexit_p(e1000_remove),
+#ifdef CONFIG_PM
/* Power Managment Hooks */
.suspend = e1000_suspend,
-#ifdef CONFIG_PM
.resume = e1000_resume,
#endif
.shutdown = e1000_shutdown,
@@ -466,13 +476,14 @@ e1000_up(struct e1000_adapter *adapter)
adapter->tx_queue_len = netdev->tx_queue_len;
- mod_timer(&adapter->watchdog_timer, jiffies);
-
#ifdef CONFIG_E1000_NAPI
netif_poll_enable(netdev);
#endif
e1000_irq_enable(adapter);
+ clear_bit(__E1000_DOWN, &adapter->flags);
+
+ mod_timer(&adapter->watchdog_timer, jiffies + 2 * HZ);
return 0;
}
@@ -502,25 +513,48 @@ void e1000_power_up_phy(struct e1000_adapter *adapter)
static void e1000_power_down_phy(struct e1000_adapter *adapter)
{
- boolean_t mng_mode_enabled = (adapter->hw.mac_type >= e1000_82571) &&
- e1000_check_mng_mode(&adapter->hw);
- /* Power down the PHY so no link is implied when interface is down
- * The PHY cannot be powered down if any of the following is TRUE
+ /* Power down the PHY so no link is implied when interface is down *
+ * The PHY cannot be powered down if any of the following is TRUE *
* (a) WoL is enabled
* (b) AMT is active
* (c) SoL/IDER session is active */
if (!adapter->wol && adapter->hw.mac_type >= e1000_82540 &&
- adapter->hw.mac_type != e1000_ich8lan &&
- adapter->hw.media_type == e1000_media_type_copper &&
- !(E1000_READ_REG(&adapter->hw, MANC) & E1000_MANC_SMBUS_EN) &&
- !mng_mode_enabled &&
- !e1000_check_phy_reset_block(&adapter->hw)) {
+ adapter->hw.media_type == e1000_media_type_copper) {
uint16_t mii_reg = 0;
+
+ switch (adapter->hw.mac_type) {
+ case e1000_82540:
+ case e1000_82545:
+ case e1000_82545_rev_3:
+ case e1000_82546:
+ case e1000_82546_rev_3:
+ case e1000_82541:
+ case e1000_82541_rev_2:
+ case e1000_82547:
+ case e1000_82547_rev_2:
+ if (E1000_READ_REG(&adapter->hw, MANC) &
+ E1000_MANC_SMBUS_EN)
+ goto out;
+ break;
+ case e1000_82571:
+ case e1000_82572:
+ case e1000_82573:
+ case e1000_80003es2lan:
+ case e1000_ich8lan:
+ if (e1000_check_mng_mode(&adapter->hw) ||
+ e1000_check_phy_reset_block(&adapter->hw))
+ goto out;
+ break;
+ default:
+ goto out;
+ }
e1000_read_phy_reg(&adapter->hw, PHY_CTRL, &mii_reg);
mii_reg |= MII_CR_POWER_DOWN;
e1000_write_phy_reg(&adapter->hw, PHY_CTRL, mii_reg);
mdelay(1);
}
+out:
+ return;
}
void
@@ -528,6 +562,10 @@ e1000_down(struct e1000_adapter *adapter)
{
struct net_device *netdev = adapter->netdev;
+ /* signal that we're down so the interrupt handler does not
+ * reschedule our watchdog timer */
+ set_bit(__E1000_DOWN, &adapter->flags);
+
e1000_irq_disable(adapter);
del_timer_sync(&adapter->tx_fifo_stall_timer);
@@ -563,6 +601,9 @@ void
e1000_reset(struct e1000_adapter *adapter)
{
uint32_t pba, manc;
+#ifdef DISABLE_MULR
+ uint32_t tctl;
+#endif
uint16_t fc_high_water_mark = E1000_FC_HIGH_DIFF;
/* Repartition Pba for greater than 9k mtu
@@ -629,6 +670,12 @@ e1000_reset(struct e1000_adapter *adapter)
e1000_reset_hw(&adapter->hw);
if (adapter->hw.mac_type >= e1000_82544)
E1000_WRITE_REG(&adapter->hw, WUC, 0);
+#ifdef DISABLE_MULR
+ /* disable Multiple Reads in Transmit Control Register for debugging */
+ tctl = E1000_READ_REG(hw, TCTL);
+ E1000_WRITE_REG(hw, TCTL, tctl & ~E1000_TCTL_MULR);
+
+#endif
if (e1000_init_hw(&adapter->hw))
DPRINTK(PROBE, ERR, "Hardware Error\n");
e1000_update_mng_vlan(adapter);
@@ -652,9 +699,7 @@ e1000_reset(struct e1000_adapter *adapter)
phy_data);
}
- if (adapter->hw.mac_type < e1000_ich8lan)
- /* FIXME: this code is duplicate and wrong for PCI Express */
- if (adapter->en_mng_pt) {
+ if ((adapter->en_mng_pt) && (adapter->hw.mac_type < e1000_82571)) {
manc = E1000_READ_REG(&adapter->hw, MANC);
manc |= (E1000_MANC_ARP_EN | E1000_MANC_EN_MNG2HOST);
E1000_WRITE_REG(&adapter->hw, MANC, manc);
@@ -760,7 +805,7 @@ e1000_probe(struct pci_dev *pdev,
#ifdef CONFIG_NET_POLL_CONTROLLER
netdev->poll_controller = e1000_netpoll;
#endif
- strcpy(netdev->name, pci_name(pdev));
+ strncpy(netdev->name, pci_name(pdev), sizeof(netdev->name) - 1);
netdev->mem_start = mmio_start;
netdev->mem_end = mmio_start + mmio_len;
@@ -863,11 +908,6 @@ e1000_probe(struct pci_dev *pdev,
INIT_WORK(&adapter->reset_task,
(void (*)(void *))e1000_reset_task, netdev);
- /* we're going to reset, so assume we have no link for now */
-
- netif_carrier_off(netdev);
- netif_stop_queue(netdev);
-
e1000_check_options(adapter);
/* Initial Wake on LAN setting
@@ -974,6 +1014,10 @@ e1000_probe(struct pci_dev *pdev,
if ((err = register_netdev(netdev)))
goto err_register;
+ /* tell the stack to leave us alone until e1000_open() is called */
+ netif_carrier_off(netdev);
+ netif_stop_queue(netdev);
+
DPRINTK(PROBE, INFO, "Intel(R) PRO/1000 Network Connection\n");
cards_found++;
@@ -1032,8 +1076,7 @@ e1000_remove(struct pci_dev *pdev)
flush_scheduled_work();
- if (adapter->hw.mac_type >= e1000_82540 &&
- adapter->hw.mac_type != e1000_ich8lan &&
+ if (adapter->hw.mac_type < e1000_82571 &&
adapter->hw.media_type == e1000_media_type_copper) {
manc = E1000_READ_REG(&adapter->hw, MANC);
if (manc & E1000_MANC_SMBUS_EN) {
@@ -1161,6 +1204,8 @@ e1000_sw_init(struct e1000_adapter *adapter)
atomic_set(&adapter->irq_sem, 1);
spin_lock_init(&adapter->stats_lock);
+ set_bit(__E1000_DOWN, &adapter->flags);
+
return 0;
}
@@ -1226,7 +1271,7 @@ e1000_open(struct net_device *netdev)
int err;
/* disallow open during test */
- if (test_bit(__E1000_DRIVER_TESTING, &adapter->flags))
+ if (test_bit(__E1000_TESTING, &adapter->flags))
return -EBUSY;
/* allocate transmit descriptors */
@@ -1299,8 +1344,12 @@ e1000_close(struct net_device *netdev)
e1000_free_all_tx_resources(adapter);
e1000_free_all_rx_resources(adapter);
+ /* kill manageability vlan ID if supported, but not if a vlan with
+ * the same ID is registered on the host OS (let 8021q kill it) */
if ((adapter->hw.mng_cookie.status &
- E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT)) {
+ E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT) &&
+ !(adapter->vlgrp &&
+ adapter->vlgrp->vlan_devices[adapter->mng_vlan_id])) {
e1000_vlan_rx_kill_vid(netdev, adapter->mng_vlan_id);
}
@@ -1510,27 +1559,14 @@ e1000_configure_tx(struct e1000_adapter *adapter)
/* Program the Transmit Control Register */
tctl = E1000_READ_REG(hw, TCTL);
-
tctl &= ~E1000_TCTL_CT;
tctl |= E1000_TCTL_PSP | E1000_TCTL_RTLC |
(E1000_COLLISION_THRESHOLD << E1000_CT_SHIFT);
-#ifdef DISABLE_MULR
- /* disable Multiple Reads for debugging */
- tctl &= ~E1000_TCTL_MULR;
-#endif
-
if (hw->mac_type == e1000_82571 || hw->mac_type == e1000_82572) {
tarc = E1000_READ_REG(hw, TARC0);
- tarc |= ((1 << 25) | (1 << 21));
+ tarc |= (1 << 21);
E1000_WRITE_REG(hw, TARC0, tarc);
- tarc = E1000_READ_REG(hw, TARC1);
- tarc |= (1 << 25);
- if (tctl & E1000_TCTL_MULR)
- tarc &= ~(1 << 28);
- else
- tarc |= (1 << 28);
- E1000_WRITE_REG(hw, TARC1, tarc);
} else if (hw->mac_type == e1000_80003es2lan) {
tarc = E1000_READ_REG(hw, TARC0);
tarc |= 1;
@@ -2892,6 +2928,35 @@ e1000_transfer_dhcp_info(struct e1000_adapter *adapter, struct sk_buff *skb)
return 0;
}
+static int __e1000_maybe_stop_tx(struct net_device *netdev, int size)
+{
+ struct e1000_adapter *adapter = netdev_priv(netdev);
+ struct e1000_tx_ring *tx_ring = adapter->tx_ring;
+
+ netif_stop_queue(netdev);
+ /* Herbert's original patch had:
+ * smp_mb__after_netif_stop_queue();
+ * but since that doesn't exist yet, just open code it. */
+ smp_mb();
+
+ /* We need to check again in a case another CPU has just
+ * made room available. */
+ if (likely(E1000_DESC_UNUSED(tx_ring) < size))
+ return -EBUSY;
+
+ /* A reprieve! */
+ netif_start_queue(netdev);
+ return 0;
+}
+
+static int e1000_maybe_stop_tx(struct net_device *netdev,
+ struct e1000_tx_ring *tx_ring, int size)
+{
+ if (likely(E1000_DESC_UNUSED(tx_ring) >= size))
+ return 0;
+ return __e1000_maybe_stop_tx(netdev, size);
+}
+
#define TXD_USE_COUNT(S, X) (((S) >> (X)) + 1 )
static int
e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
@@ -2910,6 +2975,10 @@ e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
unsigned int f;
len -= skb->data_len;
+ /* This goes back to the question of how to logically map a tx queue
+ * to a flow. Right now, performance is impacted slightly negatively
+ * if using multiple tx queues. If the stack breaks away from a
+ * single qdisc implementation, we can look at this again. */
tx_ring = adapter->tx_ring;
if (unlikely(skb->len <= 0)) {
@@ -3005,8 +3074,7 @@ e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
/* need: count + 2 desc gap to keep tail from touching
* head, otherwise try next time */
- if (unlikely(E1000_DESC_UNUSED(tx_ring) < count + 2)) {
- netif_stop_queue(netdev);
+ if (unlikely(e1000_maybe_stop_tx(netdev, tx_ring, count + 2))) {
spin_unlock_irqrestore(&tx_ring->tx_lock, flags);
return NETDEV_TX_BUSY;
}
@@ -3014,7 +3082,7 @@ e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
if (unlikely(adapter->hw.mac_type == e1000_82547)) {
if (unlikely(e1000_82547_fifo_workaround(adapter, skb))) {
netif_stop_queue(netdev);
- mod_timer(&adapter->tx_fifo_stall_timer, jiffies);
+ mod_timer(&adapter->tx_fifo_stall_timer, jiffies + 1);
spin_unlock_irqrestore(&tx_ring->tx_lock, flags);
return NETDEV_TX_BUSY;
}
@@ -3053,8 +3121,7 @@ e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
netdev->trans_start = jiffies;
/* Make sure there is space in the ring for the next send. */
- if (unlikely(E1000_DESC_UNUSED(tx_ring) < MAX_SKB_FRAGS + 2))
- netif_stop_queue(netdev);
+ e1000_maybe_stop_tx(netdev, tx_ring, MAX_SKB_FRAGS + 2);
spin_unlock_irqrestore(&tx_ring->tx_lock, flags);
return NETDEV_TX_OK;
@@ -3131,11 +3198,13 @@ e1000_change_mtu(struct net_device *netdev, int new_mtu)
}
break;
case e1000_82573:
- /* only enable jumbo frames if ASPM is disabled completely
- * this means both bits must be zero in 0x1A bits 3:2 */
+ /* Jumbo Frames not supported if:
+ * - this is not an 82573L device
+ * - ASPM is enabled in any way (0x1A bits 3:2) */
e1000_read_eeprom(&adapter->hw, EEPROM_INIT_3GIO_3, 1,
&eeprom_data);
- if (eeprom_data & EEPROM_WORD1A_ASPM_MASK) {
+ if ((adapter->hw.device_id != E1000_DEV_ID_82573L) ||
+ (eeprom_data & EEPROM_WORD1A_ASPM_MASK)) {
if (max_frame > MAXIMUM_ETHERNET_FRAME_SIZE) {
DPRINTK(PROBE, ERR,
"Jumbo Frames not supported.\n");
@@ -3143,6 +3212,8 @@ e1000_change_mtu(struct net_device *netdev, int new_mtu)
}
break;
}
+ /* ERT will be enabled later to enable wire speed receives */
+
/* fall through to get support */
case e1000_82571:
case e1000_82572:
@@ -3328,16 +3399,15 @@ e1000_update_stats(struct e1000_adapter *adapter)
adapter->stats.crcerrs + adapter->stats.algnerrc +
adapter->stats.ruc + adapter->stats.roc +
adapter->stats.cexterr;
- adapter->net_stats.rx_length_errors = adapter->stats.ruc +
- adapter->stats.roc;
+ adapter->stats.rlerrc = adapter->stats.ruc + adapter->stats.roc;
+ adapter->net_stats.rx_length_errors = adapter->stats.rlerrc;
adapter->net_stats.rx_crc_errors = adapter->stats.crcerrs;
adapter->net_stats.rx_frame_errors = adapter->stats.algnerrc;
adapter->net_stats.rx_missed_errors = adapter->stats.mpc;
/* Tx Errors */
-
- adapter->net_stats.tx_errors = adapter->stats.ecol +
- adapter->stats.latecol;
+ adapter->stats.txerrc = adapter->stats.ecol + adapter->stats.latecol;
+ adapter->net_stats.tx_errors = adapter->stats.txerrc;
adapter->net_stats.tx_aborted_errors = adapter->stats.ecol;
adapter->net_stats.tx_window_errors = adapter->stats.latecol;
adapter->net_stats.tx_carrier_errors = adapter->stats.tncrs;
@@ -3408,7 +3478,9 @@ e1000_intr(int irq, void *data, struct pt_regs *regs)
rctl = E1000_READ_REG(hw, RCTL);
E1000_WRITE_REG(hw, RCTL, rctl & ~E1000_RCTL_EN);
}
- mod_timer(&adapter->watchdog_timer, jiffies);
+ /* guard against interrupt when we're going down */
+ if (!test_bit(__E1000_DOWN, &adapter->flags))
+ mod_timer(&adapter->watchdog_timer, jiffies + 1);
}
#ifdef CONFIG_E1000_NAPI
@@ -3546,13 +3618,14 @@ e1000_clean_tx_irq(struct e1000_adapter *adapter,
tx_ring->next_to_clean = i;
#define TX_WAKE_THRESHOLD 32
- if (unlikely(cleaned && netif_queue_stopped(netdev) &&
- netif_carrier_ok(netdev))) {
- spin_lock(&tx_ring->tx_lock);
- if (netif_queue_stopped(netdev) &&
- (E1000_DESC_UNUSED(tx_ring) >= TX_WAKE_THRESHOLD))
+ if (unlikely(cleaned && netif_carrier_ok(netdev) &&
+ E1000_DESC_UNUSED(tx_ring) >= TX_WAKE_THRESHOLD)) {
+ /* Make sure that anybody stopping the queue after this
+ * sees the new next_to_clean.
+ */
+ smp_mb();
+ if (netif_queue_stopped(netdev))
netif_wake_queue(netdev);
- spin_unlock(&tx_ring->tx_lock);
}
if (adapter->detect_tx_hung) {
@@ -4412,13 +4485,21 @@ e1000_write_pci_cfg(struct e1000_hw *hw, uint32_t reg, uint16_t *value)
pci_write_config_word(adapter->pdev, reg, *value);
}
-#if 0
-uint32_t
-e1000_io_read(struct e1000_hw *hw, unsigned long port)
+int32_t
+e1000_read_pcie_cap_reg(struct e1000_hw *hw, uint32_t reg, uint16_t *value)
{
- return inl(port);
+ struct e1000_adapter *adapter = hw->back;
+ uint16_t cap_offset;
+
+ cap_offset = pci_find_capability(adapter->pdev, PCI_CAP_ID_EXP);
+ if (!cap_offset)
+ return -E1000_ERR_CONFIG;
+
+ pci_read_config_word(adapter->pdev, cap_offset + reg, value);
+
+ return E1000_SUCCESS;
}
-#endif /* 0 */
+
void
e1000_io_write(struct e1000_hw *hw, unsigned long port, uint32_t value)
@@ -4693,9 +4774,7 @@ e1000_suspend(struct pci_dev *pdev, pm_message_t state)
pci_enable_wake(pdev, PCI_D3cold, 0);
}
- /* FIXME: this code is incorrect for PCI Express */
- if (adapter->hw.mac_type >= e1000_82540 &&
- adapter->hw.mac_type != e1000_ich8lan &&
+ if (adapter->hw.mac_type < e1000_82571 &&
adapter->hw.media_type == e1000_media_type_copper) {
manc = E1000_READ_REG(&adapter->hw, MANC);
if (manc & E1000_MANC_SMBUS_EN) {
@@ -4747,9 +4826,7 @@ e1000_resume(struct pci_dev *pdev)
netif_device_attach(netdev);
- /* FIXME: this code is incorrect for PCI Express */
- if (adapter->hw.mac_type >= e1000_82540 &&
- adapter->hw.mac_type != e1000_ich8lan &&
+ if (adapter->hw.mac_type < e1000_82571 &&
adapter->hw.media_type == e1000_media_type_copper) {
manc = E1000_READ_REG(&adapter->hw, MANC);
manc &= ~(E1000_MANC_ARP_EN);
@@ -4835,8 +4912,8 @@ static pci_ers_result_t e1000_io_slot_reset(struct pci_dev *pdev)
}
pci_set_master(pdev);
- pci_enable_wake(pdev, 3, 0);
- pci_enable_wake(pdev, 4, 0); /* 4 == D3 cold */
+ pci_enable_wake(pdev, PCI_D3hot, 0);
+ pci_enable_wake(pdev, PCI_D3cold, 0);
/* Perform card reset only on one instance of the card */
if (PCI_FUNC (pdev->devfn) != 0)
diff --git a/drivers/net/e1000/e1000_osdep.h b/drivers/net/e1000/e1000_osdep.h
index 46bc49df15e..a464cb29062 100644
--- a/drivers/net/e1000/e1000_osdep.h
+++ b/drivers/net/e1000/e1000_osdep.h
@@ -1,25 +1,24 @@
/*******************************************************************************
-
- Copyright(c) 1999 - 2006 Intel Corporation. All rights reserved.
-
- This program is free software; you can redistribute it and/or modify it
- under the terms of the GNU General Public License as published by the Free
- Software Foundation; either version 2 of the License, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful, but WITHOUT
- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ Intel PRO/1000 Linux driver
+ Copyright(c) 1999 - 2006 Intel Corporation.
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms and conditions of the GNU General Public License,
+ version 2, as published by the Free Software Foundation.
+
+ This program is distributed in the hope it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
more details.
-
+
You should have received a copy of the GNU General Public License along with
- this program; if not, write to the Free Software Foundation, Inc., 59
- Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
- The full GNU General Public License is included in this distribution in the
- file called LICENSE.
-
+ this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+
+ The full GNU General Public License is included in this distribution in
+ the file called "COPYING".
+
Contact Information:
Linux NICS <linux.nics@intel.com>
e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
diff --git a/drivers/net/e1000/e1000_param.c b/drivers/net/e1000/e1000_param.c
index 21284273897..9c3c1acefcc 100644
--- a/drivers/net/e1000/e1000_param.c
+++ b/drivers/net/e1000/e1000_param.c
@@ -1,25 +1,24 @@
/*******************************************************************************
-
- Copyright(c) 1999 - 2006 Intel Corporation. All rights reserved.
-
- This program is free software; you can redistribute it and/or modify it
- under the terms of the GNU General Public License as published by the Free
- Software Foundation; either version 2 of the License, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful, but WITHOUT
- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ Intel PRO/1000 Linux driver
+ Copyright(c) 1999 - 2006 Intel Corporation.
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms and conditions of the GNU General Public License,
+ version 2, as published by the Free Software Foundation.
+
+ This program is distributed in the hope it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
more details.
-
+
You should have received a copy of the GNU General Public License along with
- this program; if not, write to the Free Software Foundation, Inc., 59
- Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
- The full GNU General Public License is included in this distribution in the
- file called LICENSE.
-
+ this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+
+ The full GNU General Public License is included in this distribution in
+ the file called "COPYING".
+
Contact Information:
Linux NICS <linux.nics@intel.com>
e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
@@ -397,17 +396,17 @@ e1000_check_options(struct e1000_adapter *adapter)
{ /* Flow Control */
struct e1000_opt_list fc_list[] =
- {{ e1000_fc_none, "Flow Control Disabled" },
- { e1000_fc_rx_pause,"Flow Control Receive Only" },
- { e1000_fc_tx_pause,"Flow Control Transmit Only" },
- { e1000_fc_full, "Flow Control Enabled" },
- { e1000_fc_default, "Flow Control Hardware Default" }};
+ {{ E1000_FC_NONE, "Flow Control Disabled" },
+ { E1000_FC_RX_PAUSE,"Flow Control Receive Only" },
+ { E1000_FC_TX_PAUSE,"Flow Control Transmit Only" },
+ { E1000_FC_FULL, "Flow Control Enabled" },
+ { E1000_FC_DEFAULT, "Flow Control Hardware Default" }};
struct e1000_option opt = {
.type = list_option,
.name = "Flow Control",
.err = "reading default settings from EEPROM",
- .def = e1000_fc_default,
+ .def = E1000_FC_DEFAULT,
.arg = { .l = { .nr = ARRAY_SIZE(fc_list),
.p = fc_list }}
};
diff --git a/drivers/net/hp100.c b/drivers/net/hp100.c
index 03b3df33d81..561db440bc2 100644
--- a/drivers/net/hp100.c
+++ b/drivers/net/hp100.c
@@ -188,10 +188,12 @@ struct hp100_private {
/*
* variables
*/
+#ifndef MODULE
static const char *hp100_isa_tbl[] = {
"HWPF150", /* HP J2573 rev A */
"HWP1950", /* HP J2573 */
};
+#endif
#ifdef CONFIG_EISA
static struct eisa_device_id hp100_eisa_tbl[] = {
@@ -333,6 +335,7 @@ static __devinit const char *hp100_read_id(int ioaddr)
return str;
}
+#ifndef MODULE
static __init int hp100_isa_probe1(struct net_device *dev, int ioaddr)
{
const char *sig;
@@ -391,8 +394,6 @@ static int __init hp100_isa_probe(struct net_device *dev, int addr)
return err;
}
-
-#ifndef MODULE
struct net_device * __init hp100_probe(int unit)
{
struct net_device *dev = alloc_etherdev(sizeof(struct hp100_private));
diff --git a/drivers/net/ixgb/Makefile b/drivers/net/ixgb/Makefile
index a8a2d3d0356..838a5084fa0 100644
--- a/drivers/net/ixgb/Makefile
+++ b/drivers/net/ixgb/Makefile
@@ -1,33 +1,33 @@
################################################################################
#
-#
-# Copyright(c) 1999 - 2006 Intel Corporation. All rights reserved.
-#
-# This program is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License as published by the Free
-# Software Foundation; either version 2 of the License, or (at your option)
-# any later version.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+# Intel PRO/10GbE Linux driver
+# Copyright(c) 1999 - 2006 Intel Corporation.
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms and conditions of the GNU General Public License,
+# version 2, as published by the Free Software Foundation.
+#
+# This program is distributed in the hope it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
# more details.
-#
+#
# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 59
-# Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-#
-# The full GNU General Public License is included in this distribution in the
-# file called LICENSE.
-#
+# this program; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# The full GNU General Public License is included in this distribution in
+# the file called "COPYING".
+#
# Contact Information:
# Linux NICS <linux.nics@intel.com>
+# e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
# Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
#
################################################################################
#
-# Makefile for the Intel(R) PRO/10GbE driver
+# Makefile for the Intel(R) PRO/10GbE ethernet driver
#
obj-$(CONFIG_IXGB) += ixgb.o
diff --git a/drivers/net/ixgb/ixgb.h b/drivers/net/ixgb/ixgb.h
index a51604b3651..50ffe90488f 100644
--- a/drivers/net/ixgb/ixgb.h
+++ b/drivers/net/ixgb/ixgb.h
@@ -1,27 +1,27 @@
/*******************************************************************************
-
- Copyright(c) 1999 - 2006 Intel Corporation. All rights reserved.
-
- This program is free software; you can redistribute it and/or modify it
- under the terms of the GNU General Public License as published by the Free
- Software Foundation; either version 2 of the License, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful, but WITHOUT
- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ Intel PRO/10GbE Linux driver
+ Copyright(c) 1999 - 2006 Intel Corporation.
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms and conditions of the GNU General Public License,
+ version 2, as published by the Free Software Foundation.
+
+ This program is distributed in the hope it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
more details.
-
+
You should have received a copy of the GNU General Public License along with
- this program; if not, write to the Free Software Foundation, Inc., 59
- Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
- The full GNU General Public License is included in this distribution in the
- file called LICENSE.
-
+ this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+
+ The full GNU General Public License is included in this distribution in
+ the file called "COPYING".
+
Contact Information:
Linux NICS <linux.nics@intel.com>
+ e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
*******************************************************************************/
@@ -111,7 +111,7 @@ struct ixgb_adapter;
#define IXGB_RXBUFFER_16384 16384
/* How many Rx Buffers do we bundle into one write to the hardware ? */
-#define IXGB_RX_BUFFER_WRITE 4 /* Must be power of 2 */
+#define IXGB_RX_BUFFER_WRITE 8 /* Must be power of 2 */
/* only works for sizes that are powers of 2 */
#define IXGB_ROUNDUP(i, size) ((i) = (((i) + (size) - 1) & ~((size) - 1)))
diff --git a/drivers/net/ixgb/ixgb_ee.c b/drivers/net/ixgb/ixgb_ee.c
index 8357c5590bf..f15aebde7b9 100644
--- a/drivers/net/ixgb/ixgb_ee.c
+++ b/drivers/net/ixgb/ixgb_ee.c
@@ -1,27 +1,27 @@
/*******************************************************************************
-
- Copyright(c) 1999 - 2006 Intel Corporation. All rights reserved.
-
- This program is free software; you can redistribute it and/or modify it
- under the terms of the GNU General Public License as published by the Free
- Software Foundation; either version 2 of the License, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful, but WITHOUT
- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ Intel PRO/10GbE Linux driver
+ Copyright(c) 1999 - 2006 Intel Corporation.
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms and conditions of the GNU General Public License,
+ version 2, as published by the Free Software Foundation.
+
+ This program is distributed in the hope it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
more details.
-
+
You should have received a copy of the GNU General Public License along with
- this program; if not, write to the Free Software Foundation, Inc., 59
- Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
- The full GNU General Public License is included in this distribution in the
- file called LICENSE.
-
+ this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+
+ The full GNU General Public License is included in this distribution in
+ the file called "COPYING".
+
Contact Information:
Linux NICS <linux.nics@intel.com>
+ e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
*******************************************************************************/
diff --git a/drivers/net/ixgb/ixgb_ee.h b/drivers/net/ixgb/ixgb_ee.h
index bf6fa220f38..ef236b935c1 100644
--- a/drivers/net/ixgb/ixgb_ee.h
+++ b/drivers/net/ixgb/ixgb_ee.h
@@ -1,27 +1,27 @@
/*******************************************************************************
-
- Copyright(c) 1999 - 2006 Intel Corporation. All rights reserved.
-
- This program is free software; you can redistribute it and/or modify it
- under the terms of the GNU General Public License as published by the Free
- Software Foundation; either version 2 of the License, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful, but WITHOUT
- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ Intel PRO/10GbE Linux driver
+ Copyright(c) 1999 - 2006 Intel Corporation.
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms and conditions of the GNU General Public License,
+ version 2, as published by the Free Software Foundation.
+
+ This program is distributed in the hope it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
more details.
-
+
You should have received a copy of the GNU General Public License along with
- this program; if not, write to the Free Software Foundation, Inc., 59
- Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
- The full GNU General Public License is included in this distribution in the
- file called LICENSE.
-
+ this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+
+ The full GNU General Public License is included in this distribution in
+ the file called "COPYING".
+
Contact Information:
Linux NICS <linux.nics@intel.com>
+ e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
*******************************************************************************/
diff --git a/drivers/net/ixgb/ixgb_ethtool.c b/drivers/net/ixgb/ixgb_ethtool.c
index 64a383e4e89..cd22523fb03 100644
--- a/drivers/net/ixgb/ixgb_ethtool.c
+++ b/drivers/net/ixgb/ixgb_ethtool.c
@@ -1,27 +1,27 @@
/*******************************************************************************
-
- Copyright(c) 1999 - 2006 Intel Corporation. All rights reserved.
-
- This program is free software; you can redistribute it and/or modify it
- under the terms of the GNU General Public License as published by the Free
- Software Foundation; either version 2 of the License, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful, but WITHOUT
- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ Intel PRO/10GbE Linux driver
+ Copyright(c) 1999 - 2006 Intel Corporation.
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms and conditions of the GNU General Public License,
+ version 2, as published by the Free Software Foundation.
+
+ This program is distributed in the hope it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
more details.
-
+
You should have received a copy of the GNU General Public License along with
- this program; if not, write to the Free Software Foundation, Inc., 59
- Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
- The full GNU General Public License is included in this distribution in the
- file called LICENSE.
-
+ this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+
+ The full GNU General Public License is included in this distribution in
+ the file called "COPYING".
+
Contact Information:
Linux NICS <linux.nics@intel.com>
+ e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
*******************************************************************************/
diff --git a/drivers/net/ixgb/ixgb_hw.c b/drivers/net/ixgb/ixgb_hw.c
index acc6df7a6b3..02089b64e42 100644
--- a/drivers/net/ixgb/ixgb_hw.c
+++ b/drivers/net/ixgb/ixgb_hw.c
@@ -1,27 +1,27 @@
/*******************************************************************************
-
- Copyright(c) 1999 - 2006 Intel Corporation. All rights reserved.
-
- This program is free software; you can redistribute it and/or modify it
- under the terms of the GNU General Public License as published by the Free
- Software Foundation; either version 2 of the License, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful, but WITHOUT
- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ Intel PRO/10GbE Linux driver
+ Copyright(c) 1999 - 2006 Intel Corporation.
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms and conditions of the GNU General Public License,
+ version 2, as published by the Free Software Foundation.
+
+ This program is distributed in the hope it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
more details.
-
+
You should have received a copy of the GNU General Public License along with
- this program; if not, write to the Free Software Foundation, Inc., 59
- Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
- The full GNU General Public License is included in this distribution in the
- file called LICENSE.
-
+ this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+
+ The full GNU General Public License is included in this distribution in
+ the file called "COPYING".
+
Contact Information:
Linux NICS <linux.nics@intel.com>
+ e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
*******************************************************************************/
diff --git a/drivers/net/ixgb/ixgb_hw.h b/drivers/net/ixgb/ixgb_hw.h
index cb4568915ad..40ef5ca8871 100644
--- a/drivers/net/ixgb/ixgb_hw.h
+++ b/drivers/net/ixgb/ixgb_hw.h
@@ -1,27 +1,27 @@
/*******************************************************************************
-
- Copyright(c) 1999 - 2006 Intel Corporation. All rights reserved.
-
- This program is free software; you can redistribute it and/or modify it
- under the terms of the GNU General Public License as published by the Free
- Software Foundation; either version 2 of the License, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful, but WITHOUT
- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ Intel PRO/10GbE Linux driver
+ Copyright(c) 1999 - 2006 Intel Corporation.
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms and conditions of the GNU General Public License,
+ version 2, as published by the Free Software Foundation.
+
+ This program is distributed in the hope it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
more details.
-
+
You should have received a copy of the GNU General Public License along with
- this program; if not, write to the Free Software Foundation, Inc., 59
- Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
- The full GNU General Public License is included in this distribution in the
- file called LICENSE.
-
+ this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+
+ The full GNU General Public License is included in this distribution in
+ the file called "COPYING".
+
Contact Information:
Linux NICS <linux.nics@intel.com>
+ e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
*******************************************************************************/
diff --git a/drivers/net/ixgb/ixgb_ids.h b/drivers/net/ixgb/ixgb_ids.h
index 9fd61189b4b..4376e7e8fbe 100644
--- a/drivers/net/ixgb/ixgb_ids.h
+++ b/drivers/net/ixgb/ixgb_ids.h
@@ -1,27 +1,27 @@
/*******************************************************************************
-
- Copyright(c) 1999 - 2006 Intel Corporation. All rights reserved.
-
- This program is free software; you can redistribute it and/or modify it
- under the terms of the GNU General Public License as published by the Free
- Software Foundation; either version 2 of the License, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful, but WITHOUT
- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ Intel PRO/10GbE Linux driver
+ Copyright(c) 1999 - 2006 Intel Corporation.
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms and conditions of the GNU General Public License,
+ version 2, as published by the Free Software Foundation.
+
+ This program is distributed in the hope it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
more details.
-
+
You should have received a copy of the GNU General Public License along with
- this program; if not, write to the Free Software Foundation, Inc., 59
- Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
- The full GNU General Public License is included in this distribution in the
- file called LICENSE.
-
+ this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+
+ The full GNU General Public License is included in this distribution in
+ the file called "COPYING".
+
Contact Information:
Linux NICS <linux.nics@intel.com>
+ e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
*******************************************************************************/
diff --git a/drivers/net/ixgb/ixgb_main.c b/drivers/net/ixgb/ixgb_main.c
index 2e0f4b950a9..cfde7c2569b 100644
--- a/drivers/net/ixgb/ixgb_main.c
+++ b/drivers/net/ixgb/ixgb_main.c
@@ -1,27 +1,27 @@
/*******************************************************************************
-
- Copyright(c) 1999 - 2006 Intel Corporation. All rights reserved.
-
- This program is free software; you can redistribute it and/or modify it
- under the terms of the GNU General Public License as published by the Free
- Software Foundation; either version 2 of the License, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful, but WITHOUT
- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ Intel PRO/10GbE Linux driver
+ Copyright(c) 1999 - 2006 Intel Corporation.
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms and conditions of the GNU General Public License,
+ version 2, as published by the Free Software Foundation.
+
+ This program is distributed in the hope it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
more details.
-
+
You should have received a copy of the GNU General Public License along with
- this program; if not, write to the Free Software Foundation, Inc., 59
- Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
- The full GNU General Public License is included in this distribution in the
- file called LICENSE.
-
+ this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+
+ The full GNU General Public License is included in this distribution in
+ the file called "COPYING".
+
Contact Information:
Linux NICS <linux.nics@intel.com>
+ e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
*******************************************************************************/
@@ -36,7 +36,7 @@ static char ixgb_driver_string[] = "Intel(R) PRO/10GbE Network Driver";
#else
#define DRIVERNAPI "-NAPI"
#endif
-#define DRV_VERSION "1.0.112-k2"DRIVERNAPI
+#define DRV_VERSION "1.0.117-k2"DRIVERNAPI
char ixgb_driver_version[] = DRV_VERSION;
static char ixgb_copyright[] = "Copyright (c) 1999-2006 Intel Corporation.";
@@ -437,7 +437,7 @@ ixgb_probe(struct pci_dev *pdev,
netdev->poll_controller = ixgb_netpoll;
#endif
- strcpy(netdev->name, pci_name(pdev));
+ strncpy(netdev->name, pci_name(pdev), sizeof(netdev->name) - 1);
netdev->mem_start = mmio_start;
netdev->mem_end = mmio_start + mmio_len;
netdev->base_addr = adapter->hw.io_base;
@@ -2230,7 +2230,7 @@ static pci_ers_result_t ixgb_io_error_detected (struct pci_dev *pdev,
enum pci_channel_state state)
{
struct net_device *netdev = pci_get_drvdata(pdev);
- struct ixgb_adapter *adapter = netdev->priv;
+ struct ixgb_adapter *adapter = netdev_priv(netdev);
if(netif_running(netdev))
ixgb_down(adapter, TRUE);
@@ -2253,7 +2253,7 @@ static pci_ers_result_t ixgb_io_error_detected (struct pci_dev *pdev,
static pci_ers_result_t ixgb_io_slot_reset (struct pci_dev *pdev)
{
struct net_device *netdev = pci_get_drvdata(pdev);
- struct ixgb_adapter *adapter = netdev->priv;
+ struct ixgb_adapter *adapter = netdev_priv(netdev);
if(pci_enable_device(pdev)) {
DPRINTK(PROBE, ERR, "Cannot re-enable PCI device after reset.\n");
@@ -2297,7 +2297,7 @@ static pci_ers_result_t ixgb_io_slot_reset (struct pci_dev *pdev)
static void ixgb_io_resume (struct pci_dev *pdev)
{
struct net_device *netdev = pci_get_drvdata(pdev);
- struct ixgb_adapter *adapter = netdev->priv;
+ struct ixgb_adapter *adapter = netdev_priv(netdev);
pci_set_master(pdev);
diff --git a/drivers/net/ixgb/ixgb_osdep.h b/drivers/net/ixgb/ixgb_osdep.h
index 19cb1d586de..8434d752fd8 100644
--- a/drivers/net/ixgb/ixgb_osdep.h
+++ b/drivers/net/ixgb/ixgb_osdep.h
@@ -1,27 +1,27 @@
/*******************************************************************************
-
- Copyright(c) 1999 - 2006 Intel Corporation. All rights reserved.
-
- This program is free software; you can redistribute it and/or modify it
- under the terms of the GNU General Public License as published by the Free
- Software Foundation; either version 2 of the License, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful, but WITHOUT
- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ Intel PRO/10GbE Linux driver
+ Copyright(c) 1999 - 2006 Intel Corporation.
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms and conditions of the GNU General Public License,
+ version 2, as published by the Free Software Foundation.
+
+ This program is distributed in the hope it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
more details.
-
+
You should have received a copy of the GNU General Public License along with
- this program; if not, write to the Free Software Foundation, Inc., 59
- Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
- The full GNU General Public License is included in this distribution in the
- file called LICENSE.
-
+ this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+
+ The full GNU General Public License is included in this distribution in
+ the file called "COPYING".
+
Contact Information:
Linux NICS <linux.nics@intel.com>
+ e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
*******************************************************************************/
diff --git a/drivers/net/ixgb/ixgb_param.c b/drivers/net/ixgb/ixgb_param.c
index 39fbed29a3d..b27442a121f 100644
--- a/drivers/net/ixgb/ixgb_param.c
+++ b/drivers/net/ixgb/ixgb_param.c
@@ -1,27 +1,27 @@
/*******************************************************************************
-
- Copyright(c) 1999 - 2006 Intel Corporation. All rights reserved.
-
- This program is free software; you can redistribute it and/or modify it
- under the terms of the GNU General Public License as published by the Free
- Software Foundation; either version 2 of the License, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful, but WITHOUT
- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ Intel PRO/10GbE Linux driver
+ Copyright(c) 1999 - 2006 Intel Corporation.
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms and conditions of the GNU General Public License,
+ version 2, as published by the Free Software Foundation.
+
+ This program is distributed in the hope it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
more details.
-
+
You should have received a copy of the GNU General Public License along with
- this program; if not, write to the Free Software Foundation, Inc., 59
- Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
- The full GNU General Public License is included in this distribution in the
- file called LICENSE.
-
+ this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+
+ The full GNU General Public License is included in this distribution in
+ the file called "COPYING".
+
Contact Information:
Linux NICS <linux.nics@intel.com>
+ e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
*******************************************************************************/
diff --git a/drivers/net/phy/fixed.c b/drivers/net/phy/fixed.c
index 19f7ee63276..94b47c8d0ab 100644
--- a/drivers/net/phy/fixed.c
+++ b/drivers/net/phy/fixed.c
@@ -289,9 +289,13 @@ static int fixed_mdio_register_device(int number, int speed, int duplex)
goto probe_fail;
}
- device_bind_driver(&phydev->dev);
+ err = device_bind_driver(&phydev->dev);
+
up_write(&phydev->dev.bus->subsys.rwsem);
+ if (err)
+ goto probe_fail;
+
return 0;
probe_fail:
diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
index ecd3da151e2..3bbd5e70c20 100644
--- a/drivers/net/phy/phy_device.c
+++ b/drivers/net/phy/phy_device.c
@@ -212,11 +212,13 @@ struct phy_device *phy_attach(struct net_device *dev,
err = d->driver->probe(d);
- if (err < 0)
- return ERR_PTR(err);
+ if (err >= 0)
+ err = device_bind_driver(d);
- device_bind_driver(d);
up_write(&d->bus->subsys.rwsem);
+
+ if (err)
+ return ERR_PTR(err);
}
if (phydev->attached_dev) {
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c
index 7eeefa2d6c8..396e7df3c61 100644
--- a/drivers/net/sky2.c
+++ b/drivers/net/sky2.c
@@ -50,19 +50,18 @@
#include "sky2.h"
#define DRV_NAME "sky2"
-#define DRV_VERSION "1.7"
+#define DRV_VERSION "1.9"
#define PFX DRV_NAME " "
/*
* The Yukon II chipset takes 64 bit command blocks (called list elements)
* that are organized into three (receive, transmit, status) different rings
- * similar to Tigon3. A transmit can require several elements;
- * a receive requires one (or two if using 64 bit dma).
+ * similar to Tigon3.
*/
-#define RX_LE_SIZE 512
+#define RX_LE_SIZE 1024
#define RX_LE_BYTES (RX_LE_SIZE*sizeof(struct sky2_rx_le))
-#define RX_MAX_PENDING (RX_LE_SIZE/2 - 2)
+#define RX_MAX_PENDING (RX_LE_SIZE/6 - 2)
#define RX_DEF_PENDING RX_MAX_PENDING
#define RX_SKB_ALIGN 8
#define RX_BUF_WRITE 16
@@ -74,7 +73,6 @@
#define STATUS_RING_SIZE 2048 /* 2 ports * (TX + 2*RX) */
#define STATUS_LE_BYTES (STATUS_RING_SIZE*sizeof(struct sky2_status_le))
-#define ETH_JUMBO_MTU 9000
#define TX_WATCHDOG (5 * HZ)
#define NAPI_WEIGHT 64
#define PHY_RETRIES 1000
@@ -90,7 +88,7 @@ static int debug = -1; /* defaults above */
module_param(debug, int, 0);
MODULE_PARM_DESC(debug, "Debug level (0=none,...,16=all)");
-static int copybreak __read_mostly = 256;
+static int copybreak __read_mostly = 128;
module_param(copybreak, int, 0);
MODULE_PARM_DESC(copybreak, "Receive copy threshold");
@@ -769,9 +767,16 @@ static inline struct sky2_tx_le *get_tx_le(struct sky2_port *sky2)
struct sky2_tx_le *le = sky2->tx_le + sky2->tx_prod;
sky2->tx_prod = RING_NEXT(sky2->tx_prod, TX_RING_SIZE);
+ le->ctrl = 0;
return le;
}
+static inline struct tx_ring_info *tx_le_re(struct sky2_port *sky2,
+ struct sky2_tx_le *le)
+{
+ return sky2->tx_ring + (le - sky2->tx_le);
+}
+
/* Update chip's next pointer */
static inline void sky2_put_idx(struct sky2_hw *hw, unsigned q, u16 idx)
{
@@ -786,6 +791,7 @@ static inline struct sky2_rx_le *sky2_next_rx(struct sky2_port *sky2)
{
struct sky2_rx_le *le = sky2->rx_le + sky2->rx_put;
sky2->rx_put = RING_NEXT(sky2->rx_put, RX_LE_SIZE);
+ le->ctrl = 0;
return le;
}
@@ -795,17 +801,16 @@ static inline u32 high32(dma_addr_t a)
return sizeof(a) > sizeof(u32) ? (a >> 16) >> 16 : 0;
}
-/* Build description to hardware about buffer */
-static void sky2_rx_add(struct sky2_port *sky2, dma_addr_t map)
+/* Build description to hardware for one receive segment */
+static void sky2_rx_add(struct sky2_port *sky2, u8 op,
+ dma_addr_t map, unsigned len)
{
struct sky2_rx_le *le;
u32 hi = high32(map);
- u16 len = sky2->rx_bufsize;
if (sky2->rx_addr64 != hi) {
le = sky2_next_rx(sky2);
le->addr = cpu_to_le32(hi);
- le->ctrl = 0;
le->opcode = OP_ADDR64 | HW_OWNER;
sky2->rx_addr64 = high32(map + len);
}
@@ -813,11 +818,53 @@ static void sky2_rx_add(struct sky2_port *sky2, dma_addr_t map)
le = sky2_next_rx(sky2);
le->addr = cpu_to_le32((u32) map);
le->length = cpu_to_le16(len);
- le->ctrl = 0;
- le->opcode = OP_PACKET | HW_OWNER;
+ le->opcode = op | HW_OWNER;
+}
+
+/* Build description to hardware for one possibly fragmented skb */
+static void sky2_rx_submit(struct sky2_port *sky2,
+ const struct rx_ring_info *re)
+{
+ int i;
+
+ sky2_rx_add(sky2, OP_PACKET, re->data_addr, sky2->rx_data_size);
+
+ for (i = 0; i < skb_shinfo(re->skb)->nr_frags; i++)
+ sky2_rx_add(sky2, OP_BUFFER, re->frag_addr[i], PAGE_SIZE);
}
+static void sky2_rx_map_skb(struct pci_dev *pdev, struct rx_ring_info *re,
+ unsigned size)
+{
+ struct sk_buff *skb = re->skb;
+ int i;
+
+ re->data_addr = pci_map_single(pdev, skb->data, size, PCI_DMA_FROMDEVICE);
+ pci_unmap_len_set(re, data_size, size);
+
+ for (i = 0; i < skb_shinfo(skb)->nr_frags; i++)
+ re->frag_addr[i] = pci_map_page(pdev,
+ skb_shinfo(skb)->frags[i].page,
+ skb_shinfo(skb)->frags[i].page_offset,
+ skb_shinfo(skb)->frags[i].size,
+ PCI_DMA_FROMDEVICE);
+}
+
+static void sky2_rx_unmap_skb(struct pci_dev *pdev, struct rx_ring_info *re)
+{
+ struct sk_buff *skb = re->skb;
+ int i;
+
+ pci_unmap_single(pdev, re->data_addr, pci_unmap_len(re, data_size),
+ PCI_DMA_FROMDEVICE);
+
+ for (i = 0; i < skb_shinfo(skb)->nr_frags; i++)
+ pci_unmap_page(pdev, re->frag_addr[i],
+ skb_shinfo(skb)->frags[i].size,
+ PCI_DMA_FROMDEVICE);
+}
+
/* Tell chip where to start receive checksum.
* Actually has two checksums, but set both same to avoid possible byte
* order problems.
@@ -877,12 +924,10 @@ static void sky2_rx_clean(struct sky2_port *sky2)
memset(sky2->rx_le, 0, RX_LE_BYTES);
for (i = 0; i < sky2->rx_pending; i++) {
- struct ring_info *re = sky2->rx_ring + i;
+ struct rx_ring_info *re = sky2->rx_ring + i;
if (re->skb) {
- pci_unmap_single(sky2->hw->pdev,
- re->mapaddr, sky2->rx_bufsize,
- PCI_DMA_FROMDEVICE);
+ sky2_rx_unmap_skb(sky2->hw->pdev, re);
kfree_skb(re->skb);
re->skb = NULL;
}
@@ -936,13 +981,13 @@ static void sky2_vlan_rx_register(struct net_device *dev, struct vlan_group *grp
struct sky2_hw *hw = sky2->hw;
u16 port = sky2->port;
- spin_lock_bh(&sky2->tx_lock);
+ netif_tx_lock_bh(dev);
sky2_write32(hw, SK_REG(port, RX_GMF_CTRL_T), RX_VLAN_STRIP_ON);
sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T), TX_VLAN_TAG_ON);
sky2->vlgrp = grp;
- spin_unlock_bh(&sky2->tx_lock);
+ netif_tx_unlock_bh(dev);
}
static void sky2_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid)
@@ -951,50 +996,69 @@ static void sky2_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid)
struct sky2_hw *hw = sky2->hw;
u16 port = sky2->port;
- spin_lock_bh(&sky2->tx_lock);
+ netif_tx_lock_bh(dev);
sky2_write32(hw, SK_REG(port, RX_GMF_CTRL_T), RX_VLAN_STRIP_OFF);
sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T), TX_VLAN_TAG_OFF);
if (sky2->vlgrp)
sky2->vlgrp->vlan_devices[vid] = NULL;
- spin_unlock_bh(&sky2->tx_lock);
+ netif_tx_unlock_bh(dev);
}
#endif
/*
+ * Allocate an skb for receiving. If the MTU is large enough
+ * make the skb non-linear with a fragment list of pages.
+ *
* It appears the hardware has a bug in the FIFO logic that
* cause it to hang if the FIFO gets overrun and the receive buffer
* is not 64 byte aligned. The buffer returned from netdev_alloc_skb is
* aligned except if slab debugging is enabled.
*/
-static inline struct sk_buff *sky2_alloc_skb(struct net_device *dev,
- unsigned int length,
- gfp_t gfp_mask)
+static struct sk_buff *sky2_rx_alloc(struct sky2_port *sky2)
{
struct sk_buff *skb;
+ unsigned long p;
+ int i;
- skb = __netdev_alloc_skb(dev, length + RX_SKB_ALIGN, gfp_mask);
- if (likely(skb)) {
- unsigned long p = (unsigned long) skb->data;
- skb_reserve(skb, ALIGN(p, RX_SKB_ALIGN) - p);
+ skb = netdev_alloc_skb(sky2->netdev, sky2->rx_data_size + RX_SKB_ALIGN);
+ if (!skb)
+ goto nomem;
+
+ p = (unsigned long) skb->data;
+ skb_reserve(skb, ALIGN(p, RX_SKB_ALIGN) - p);
+
+ for (i = 0; i < sky2->rx_nfrags; i++) {
+ struct page *page = alloc_page(GFP_ATOMIC);
+
+ if (!page)
+ goto free_partial;
+ skb_fill_page_desc(skb, i, page, 0, PAGE_SIZE);
}
return skb;
+free_partial:
+ kfree_skb(skb);
+nomem:
+ return NULL;
}
/*
* Allocate and setup receiver buffer pool.
- * In case of 64 bit dma, there are 2X as many list elements
- * available as ring entries
- * and need to reserve one list element so we don't wrap around.
+ * Normal case this ends up creating one list element for skb
+ * in the receive ring. Worst case if using large MTU and each
+ * allocation falls on a different 64 bit region, that results
+ * in 6 list elements per ring entry.
+ * One element is used for checksum enable/disable, and one
+ * extra to avoid wrap.
*/
static int sky2_rx_start(struct sky2_port *sky2)
{
struct sky2_hw *hw = sky2->hw;
+ struct rx_ring_info *re;
unsigned rxq = rxqaddr[sky2->port];
- int i;
- unsigned thresh;
+ unsigned i, size, space, thresh;
sky2->rx_put = sky2->rx_next = 0;
sky2_qset(hw, rxq);
@@ -1007,27 +1071,56 @@ static int sky2_rx_start(struct sky2_port *sky2)
sky2_prefetch_init(hw, rxq, sky2->rx_le_map, RX_LE_SIZE - 1);
rx_set_checksum(sky2);
+
+ /* Space needed for frame data + headers rounded up */
+ size = ALIGN(sky2->netdev->mtu + ETH_HLEN + VLAN_HLEN, 8)
+ + 8;
+
+ /* Stopping point for hardware truncation */
+ thresh = (size - 8) / sizeof(u32);
+
+ /* Account for overhead of skb - to avoid order > 0 allocation */
+ space = SKB_DATA_ALIGN(size) + NET_SKB_PAD
+ + sizeof(struct skb_shared_info);
+
+ sky2->rx_nfrags = space >> PAGE_SHIFT;
+ BUG_ON(sky2->rx_nfrags > ARRAY_SIZE(re->frag_addr));
+
+ if (sky2->rx_nfrags != 0) {
+ /* Compute residue after pages */
+ space = sky2->rx_nfrags << PAGE_SHIFT;
+
+ if (space < size)
+ size -= space;
+ else
+ size = 0;
+
+ /* Optimize to handle small packets and headers */
+ if (size < copybreak)
+ size = copybreak;
+ if (size < ETH_HLEN)
+ size = ETH_HLEN;
+ }
+ sky2->rx_data_size = size;
+
+ /* Fill Rx ring */
for (i = 0; i < sky2->rx_pending; i++) {
- struct ring_info *re = sky2->rx_ring + i;
+ re = sky2->rx_ring + i;
- re->skb = sky2_alloc_skb(sky2->netdev, sky2->rx_bufsize,
- GFP_KERNEL);
+ re->skb = sky2_rx_alloc(sky2);
if (!re->skb)
goto nomem;
- re->mapaddr = pci_map_single(hw->pdev, re->skb->data,
- sky2->rx_bufsize, PCI_DMA_FROMDEVICE);
- sky2_rx_add(sky2, re->mapaddr);
+ sky2_rx_map_skb(hw->pdev, re, sky2->rx_data_size);
+ sky2_rx_submit(sky2, re);
}
-
/*
* The receiver hangs if it receives frames larger than the
* packet buffer. As a workaround, truncate oversize frames, but
* the register is limited to 9 bits, so if you do frames > 2052
* you better get the MTU right!
*/
- thresh = (sky2->rx_bufsize - 8) / sizeof(u32);
if (thresh > 0x1ff)
sky2_write32(hw, SK_REG(sky2->port, RX_GMF_CTRL_T), RX_TRUNC_OFF);
else {
@@ -1035,7 +1128,6 @@ static int sky2_rx_start(struct sky2_port *sky2)
sky2_write32(hw, SK_REG(sky2->port, RX_GMF_CTRL_T), RX_TRUNC_ON);
}
-
/* Tell chip about available buffers */
sky2_write16(hw, Y2_QADDR(rxq, PREF_UNIT_PUT_IDX), sky2->rx_put);
return 0;
@@ -1094,7 +1186,7 @@ static int sky2_up(struct net_device *dev)
goto err_out;
memset(sky2->rx_le, 0, RX_LE_BYTES);
- sky2->rx_ring = kcalloc(sky2->rx_pending, sizeof(struct ring_info),
+ sky2->rx_ring = kcalloc(sky2->rx_pending, sizeof(struct rx_ring_info),
GFP_KERNEL);
if (!sky2->rx_ring)
goto err_out;
@@ -1124,7 +1216,8 @@ static int sky2_up(struct net_device *dev)
sky2_qset(hw, txqaddr[port]);
/* Set almost empty threshold */
- if (hw->chip_id == CHIP_ID_YUKON_EC_U && hw->chip_rev == 1)
+ if (hw->chip_id == CHIP_ID_YUKON_EC_U
+ && hw->chip_rev == CHIP_REV_YU_EC_U_A0)
sky2_write16(hw, Q_ADDR(txqaddr[port], Q_AL), 0x1a0);
sky2_prefetch_init(hw, txqaddr[port], sky2->tx_le_map,
@@ -1195,8 +1288,6 @@ static unsigned tx_le_req(const struct sk_buff *skb)
* A single packet can generate multiple list elements, and
* the number of ring elements will probably be less than the number
* of list elements used.
- *
- * No BH disabling for tx_lock here (like tg3)
*/
static int sky2_xmit_frame(struct sk_buff *skb, struct net_device *dev)
{
@@ -1210,27 +1301,8 @@ static int sky2_xmit_frame(struct sk_buff *skb, struct net_device *dev)
u16 mss;
u8 ctrl;
- /* No BH disabling for tx_lock here. We are running in BH disabled
- * context and TX reclaim runs via poll inside of a software
- * interrupt, and no related locks in IRQ processing.
- */
- if (!spin_trylock(&sky2->tx_lock))
- return NETDEV_TX_LOCKED;
-
- if (unlikely(tx_avail(sky2) < tx_le_req(skb))) {
- /* There is a known but harmless race with lockless tx
- * and netif_stop_queue.
- */
- if (!netif_queue_stopped(dev)) {
- netif_stop_queue(dev);
- if (net_ratelimit())
- printk(KERN_WARNING PFX "%s: ring full when queue awake!\n",
- dev->name);
- }
- spin_unlock(&sky2->tx_lock);
-
- return NETDEV_TX_BUSY;
- }
+ if (unlikely(tx_avail(sky2) < tx_le_req(skb)))
+ return NETDEV_TX_BUSY;
if (unlikely(netif_msg_tx_queued(sky2)))
printk(KERN_DEBUG "%s: tx queued, slot %u, len %d\n",
@@ -1240,13 +1312,10 @@ static int sky2_xmit_frame(struct sk_buff *skb, struct net_device *dev)
mapping = pci_map_single(hw->pdev, skb->data, len, PCI_DMA_TODEVICE);
addr64 = high32(mapping);
- re = sky2->tx_ring + sky2->tx_prod;
-
/* Send high bits if changed or crosses boundary */
if (addr64 != sky2->tx_addr64 || high32(mapping + len) != sky2->tx_addr64) {
le = get_tx_le(sky2);
le->addr = cpu_to_le32(addr64);
- le->ctrl = 0;
le->opcode = OP_ADDR64 | HW_OWNER;
sky2->tx_addr64 = high32(mapping + len);
}
@@ -1262,7 +1331,6 @@ static int sky2_xmit_frame(struct sk_buff *skb, struct net_device *dev)
le = get_tx_le(sky2);
le->addr = cpu_to_le32(mss);
le->opcode = OP_LRGLEN | HW_OWNER;
- le->ctrl = 0;
sky2->tx_last_mss = mss;
}
}
@@ -1275,7 +1343,6 @@ static int sky2_xmit_frame(struct sk_buff *skb, struct net_device *dev)
le = get_tx_le(sky2);
le->addr = 0;
le->opcode = OP_VLAN|HW_OWNER;
- le->ctrl = 0;
} else
le->opcode |= OP_VLAN;
le->length = cpu_to_be16(vlan_tx_tag_get(skb));
@@ -1312,13 +1379,13 @@ static int sky2_xmit_frame(struct sk_buff *skb, struct net_device *dev)
le->ctrl = ctrl;
le->opcode = mss ? (OP_LARGESEND | HW_OWNER) : (OP_PACKET | HW_OWNER);
- /* Record the transmit mapping info */
+ re = tx_le_re(sky2, le);
re->skb = skb;
pci_unmap_addr_set(re, mapaddr, mapping);
+ pci_unmap_len_set(re, maplen, len);
for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
- skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
- struct tx_ring_info *fre;
+ const skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
mapping = pci_map_page(hw->pdev, frag->page, frag->page_offset,
frag->size, PCI_DMA_TODEVICE);
@@ -1337,12 +1404,12 @@ static int sky2_xmit_frame(struct sk_buff *skb, struct net_device *dev)
le->ctrl = ctrl;
le->opcode = OP_BUFFER | HW_OWNER;
- fre = sky2->tx_ring
- + RING_NEXT((re - sky2->tx_ring) + i, TX_RING_SIZE);
- pci_unmap_addr_set(fre, mapaddr, mapping);
+ re = tx_le_re(sky2, le);
+ re->skb = skb;
+ pci_unmap_addr_set(re, mapaddr, mapping);
+ pci_unmap_len_set(re, maplen, frag->size);
}
- re->idx = sky2->tx_prod;
le->ctrl |= EOP;
if (tx_avail(sky2) <= MAX_SKB_TX_LE)
@@ -1350,8 +1417,6 @@ static int sky2_xmit_frame(struct sk_buff *skb, struct net_device *dev)
sky2_put_idx(hw, txqaddr[sky2->port], sky2->tx_prod);
- spin_unlock(&sky2->tx_lock);
-
dev->trans_start = jiffies;
return NETDEV_TX_OK;
}
@@ -1360,59 +1425,59 @@ static int sky2_xmit_frame(struct sk_buff *skb, struct net_device *dev)
* Free ring elements from starting at tx_cons until "done"
*
* NB: the hardware will tell us about partial completion of multi-part
- * buffers; these are deferred until completion.
+ * buffers so make sure not to free skb to early.
*/
static void sky2_tx_complete(struct sky2_port *sky2, u16 done)
{
struct net_device *dev = sky2->netdev;
struct pci_dev *pdev = sky2->hw->pdev;
- u16 nxt, put;
- unsigned i;
+ unsigned idx;
BUG_ON(done >= TX_RING_SIZE);
- if (unlikely(netif_msg_tx_done(sky2)))
- printk(KERN_DEBUG "%s: tx done, up to %u\n",
- dev->name, done);
-
- for (put = sky2->tx_cons; put != done; put = nxt) {
- struct tx_ring_info *re = sky2->tx_ring + put;
- struct sk_buff *skb = re->skb;
-
- nxt = re->idx;
- BUG_ON(nxt >= TX_RING_SIZE);
- prefetch(sky2->tx_ring + nxt);
-
- /* Check for partial status */
- if (tx_dist(put, done) < tx_dist(put, nxt))
+ for (idx = sky2->tx_cons; idx != done;
+ idx = RING_NEXT(idx, TX_RING_SIZE)) {
+ struct sky2_tx_le *le = sky2->tx_le + idx;
+ struct tx_ring_info *re = sky2->tx_ring + idx;
+
+ switch(le->opcode & ~HW_OWNER) {
+ case OP_LARGESEND:
+ case OP_PACKET:
+ pci_unmap_single(pdev,
+ pci_unmap_addr(re, mapaddr),
+ pci_unmap_len(re, maplen),
+ PCI_DMA_TODEVICE);
break;
-
- skb = re->skb;
- pci_unmap_single(pdev, pci_unmap_addr(re, mapaddr),
- skb_headlen(skb), PCI_DMA_TODEVICE);
-
- for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
- struct tx_ring_info *fre;
- fre = sky2->tx_ring + RING_NEXT(put + i, TX_RING_SIZE);
- pci_unmap_page(pdev, pci_unmap_addr(fre, mapaddr),
- skb_shinfo(skb)->frags[i].size,
+ case OP_BUFFER:
+ pci_unmap_page(pdev, pci_unmap_addr(re, mapaddr),
+ pci_unmap_len(re, maplen),
PCI_DMA_TODEVICE);
+ break;
}
- dev_kfree_skb(skb);
+ if (le->ctrl & EOP) {
+ if (unlikely(netif_msg_tx_done(sky2)))
+ printk(KERN_DEBUG "%s: tx done %u\n",
+ dev->name, idx);
+ dev_kfree_skb(re->skb);
+ }
+
+ le->opcode = 0; /* paranoia */
}
- sky2->tx_cons = put;
+ sky2->tx_cons = idx;
if (tx_avail(sky2) > MAX_SKB_TX_LE + 4)
netif_wake_queue(dev);
}
/* Cleanup all untransmitted buffers, assume transmitter not running */
-static void sky2_tx_clean(struct sky2_port *sky2)
+static void sky2_tx_clean(struct net_device *dev)
{
- spin_lock_bh(&sky2->tx_lock);
+ struct sky2_port *sky2 = netdev_priv(dev);
+
+ netif_tx_lock_bh(dev);
sky2_tx_complete(sky2, sky2->tx_prod);
- spin_unlock_bh(&sky2->tx_lock);
+ netif_tx_unlock_bh(dev);
}
/* Network shutdown */
@@ -1443,6 +1508,13 @@ static int sky2_down(struct net_device *dev)
sky2_write32(hw, RB_ADDR(txqaddr[port], RB_CTRL),
RB_RST_SET | RB_DIS_OP_MD);
+ /* WA for dev. #4.209 */
+ if (hw->chip_id == CHIP_ID_YUKON_EC_U
+ && hw->chip_rev == CHIP_REV_YU_EC_U_A1)
+ sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T),
+ sky2->speed != SPEED_1000 ?
+ TX_STFW_ENA : TX_STFW_DIS);
+
ctrl = gma_read16(hw, port, GM_GP_CTRL);
ctrl &= ~(GM_GPCR_TX_ENA | GM_GPCR_RX_ENA);
gma_write16(hw, port, GM_GP_CTRL, ctrl);
@@ -1489,7 +1561,7 @@ static int sky2_down(struct net_device *dev)
synchronize_irq(hw->pdev->irq);
- sky2_tx_clean(sky2);
+ sky2_tx_clean(dev);
sky2_rx_clean(sky2);
pci_free_consistent(hw->pdev, RX_LE_BYTES,
@@ -1624,22 +1696,33 @@ static int sky2_autoneg_done(struct sky2_port *sky2, u16 aux)
return -1;
}
- if (hw->chip_id != CHIP_ID_YUKON_FE &&
- gm_phy_read(hw, port, PHY_MARV_1000T_STAT) & PHY_B_1000S_MSF) {
- printk(KERN_ERR PFX "%s: master/slave fault",
- sky2->netdev->name);
- return -1;
- }
-
if (!(aux & PHY_M_PS_SPDUP_RES)) {
printk(KERN_ERR PFX "%s: speed/duplex mismatch",
sky2->netdev->name);
return -1;
}
- sky2->duplex = (aux & PHY_M_PS_FULL_DUP) ? DUPLEX_FULL : DUPLEX_HALF;
-
sky2->speed = sky2_phy_speed(hw, aux);
+ if (sky2->speed == SPEED_1000) {
+ u16 ctl2 = gm_phy_read(hw, port, PHY_MARV_1000T_CTRL);
+ u16 lpa2 = gm_phy_read(hw, port, PHY_MARV_1000T_STAT);
+ if (lpa2 & PHY_B_1000S_MSF) {
+ printk(KERN_ERR PFX "%s: master/slave fault",
+ sky2->netdev->name);
+ return -1;
+ }
+
+ if ((ctl2 & PHY_M_1000C_AFD) && (lpa2 & PHY_B_1000S_LP_FD))
+ sky2->duplex = DUPLEX_FULL;
+ else
+ sky2->duplex = DUPLEX_HALF;
+ } else {
+ u16 adv = gm_phy_read(hw, port, PHY_MARV_AUNE_ADV);
+ if ((aux & adv) & PHY_AN_FULL)
+ sky2->duplex = DUPLEX_FULL;
+ else
+ sky2->duplex = DUPLEX_HALF;
+ }
/* Pause bits are offset (9..8) */
if (hw->chip_id == CHIP_ID_YUKON_XL || hw->chip_id == CHIP_ID_YUKON_EC_U)
@@ -1730,31 +1813,22 @@ static void sky2_tx_timeout(struct net_device *dev)
} else if (report != sky2->tx_cons) {
printk(KERN_INFO PFX "status report lost?\n");
- spin_lock_bh(&sky2->tx_lock);
+ netif_tx_lock_bh(dev);
sky2_tx_complete(sky2, report);
- spin_unlock_bh(&sky2->tx_lock);
+ netif_tx_unlock_bh(dev);
} else {
printk(KERN_INFO PFX "hardware hung? flushing\n");
sky2_write32(hw, Q_ADDR(txq, Q_CSR), BMU_STOP);
sky2_write32(hw, Y2_QADDR(txq, PREF_UNIT_CTRL), PREF_UNIT_RST_SET);
- sky2_tx_clean(sky2);
+ sky2_tx_clean(dev);
sky2_qset(hw, txq);
sky2_prefetch_init(hw, txq, sky2->tx_le_map, TX_RING_SIZE - 1);
}
}
-
-/* Want receive buffer size to be multiple of 64 bits
- * and incl room for vlan and truncation
- */
-static inline unsigned sky2_buf_size(int mtu)
-{
- return ALIGN(mtu + ETH_HLEN + VLAN_HLEN, 8) + 8;
-}
-
static int sky2_change_mtu(struct net_device *dev, int new_mtu)
{
struct sky2_port *sky2 = netdev_priv(dev);
@@ -1789,7 +1863,7 @@ static int sky2_change_mtu(struct net_device *dev, int new_mtu)
sky2_rx_clean(sky2);
dev->mtu = new_mtu;
- sky2->rx_bufsize = sky2_buf_size(new_mtu);
+
mode = DATA_BLIND_VAL(DATA_BLIND_DEF) |
GM_SMOD_VLAN_ENA | IPG_DATA_VAL(IPG_DATA_DEF);
@@ -1815,16 +1889,100 @@ static int sky2_change_mtu(struct net_device *dev, int new_mtu)
return err;
}
+/* For small just reuse existing skb for next receive */
+static struct sk_buff *receive_copy(struct sky2_port *sky2,
+ const struct rx_ring_info *re,
+ unsigned length)
+{
+ struct sk_buff *skb;
+
+ skb = netdev_alloc_skb(sky2->netdev, length + 2);
+ if (likely(skb)) {
+ skb_reserve(skb, 2);
+ pci_dma_sync_single_for_cpu(sky2->hw->pdev, re->data_addr,
+ length, PCI_DMA_FROMDEVICE);
+ memcpy(skb->data, re->skb->data, length);
+ skb->ip_summed = re->skb->ip_summed;
+ skb->csum = re->skb->csum;
+ pci_dma_sync_single_for_device(sky2->hw->pdev, re->data_addr,
+ length, PCI_DMA_FROMDEVICE);
+ re->skb->ip_summed = CHECKSUM_NONE;
+ __skb_put(skb, length);
+ }
+ return skb;
+}
+
+/* Adjust length of skb with fragments to match received data */
+static void skb_put_frags(struct sk_buff *skb, unsigned int hdr_space,
+ unsigned int length)
+{
+ int i, num_frags;
+ unsigned int size;
+
+ /* put header into skb */
+ size = min(length, hdr_space);
+ skb->tail += size;
+ skb->len += size;
+ length -= size;
+
+ num_frags = skb_shinfo(skb)->nr_frags;
+ for (i = 0; i < num_frags; i++) {
+ skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
+
+ if (length == 0) {
+ /* don't need this page */
+ __free_page(frag->page);
+ --skb_shinfo(skb)->nr_frags;
+ } else {
+ size = min(length, (unsigned) PAGE_SIZE);
+
+ frag->size = size;
+ skb->data_len += size;
+ skb->truesize += size;
+ skb->len += size;
+ length -= size;
+ }
+ }
+}
+
+/* Normal packet - take skb from ring element and put in a new one */
+static struct sk_buff *receive_new(struct sky2_port *sky2,
+ struct rx_ring_info *re,
+ unsigned int length)
+{
+ struct sk_buff *skb, *nskb;
+ unsigned hdr_space = sky2->rx_data_size;
+
+ pr_debug(PFX "receive new length=%d\n", length);
+
+ /* Don't be tricky about reusing pages (yet) */
+ nskb = sky2_rx_alloc(sky2);
+ if (unlikely(!nskb))
+ return NULL;
+
+ skb = re->skb;
+ sky2_rx_unmap_skb(sky2->hw->pdev, re);
+
+ prefetch(skb->data);
+ re->skb = nskb;
+ sky2_rx_map_skb(sky2->hw->pdev, re, hdr_space);
+
+ if (skb_shinfo(skb)->nr_frags)
+ skb_put_frags(skb, hdr_space, length);
+ else
+ skb_put(skb, hdr_space);
+ return skb;
+}
+
/*
* Receive one packet.
- * For small packets or errors, just reuse existing skb.
* For larger packets, get new buffer.
*/
static struct sk_buff *sky2_receive(struct net_device *dev,
u16 length, u32 status)
{
struct sky2_port *sky2 = netdev_priv(dev);
- struct ring_info *re = sky2->rx_ring + sky2->rx_next;
+ struct rx_ring_info *re = sky2->rx_ring + sky2->rx_next;
struct sk_buff *skb = NULL;
if (unlikely(netif_msg_rx_status(sky2)))
@@ -1843,40 +2001,12 @@ static struct sk_buff *sky2_receive(struct net_device *dev,
if (length > dev->mtu + ETH_HLEN)
goto oversize;
- if (length < copybreak) {
- skb = netdev_alloc_skb(dev, length + 2);
- if (!skb)
- goto resubmit;
-
- skb_reserve(skb, 2);
- pci_dma_sync_single_for_cpu(sky2->hw->pdev, re->mapaddr,
- length, PCI_DMA_FROMDEVICE);
- memcpy(skb->data, re->skb->data, length);
- skb->ip_summed = re->skb->ip_summed;
- skb->csum = re->skb->csum;
- pci_dma_sync_single_for_device(sky2->hw->pdev, re->mapaddr,
- length, PCI_DMA_FROMDEVICE);
- } else {
- struct sk_buff *nskb;
-
- nskb = sky2_alloc_skb(dev, sky2->rx_bufsize, GFP_ATOMIC);
- if (!nskb)
- goto resubmit;
-
- skb = re->skb;
- re->skb = nskb;
- pci_unmap_single(sky2->hw->pdev, re->mapaddr,
- sky2->rx_bufsize, PCI_DMA_FROMDEVICE);
- prefetch(skb->data);
-
- re->mapaddr = pci_map_single(sky2->hw->pdev, nskb->data,
- sky2->rx_bufsize, PCI_DMA_FROMDEVICE);
- }
-
- skb_put(skb, length);
+ if (length < copybreak)
+ skb = receive_copy(sky2, re, length);
+ else
+ skb = receive_new(sky2, re, length);
resubmit:
- re->skb->ip_summed = CHECKSUM_NONE;
- sky2_rx_add(sky2, re->mapaddr);
+ sky2_rx_submit(sky2, re);
return skb;
@@ -1909,9 +2039,9 @@ static inline void sky2_tx_done(struct net_device *dev, u16 last)
struct sky2_port *sky2 = netdev_priv(dev);
if (netif_running(dev)) {
- spin_lock(&sky2->tx_lock);
+ netif_tx_lock(dev);
sky2_tx_complete(sky2, last);
- spin_unlock(&sky2->tx_lock);
+ netif_tx_unlock(dev);
}
}
@@ -2082,7 +2212,7 @@ static void sky2_hw_intr(struct sky2_hw *hw)
sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON);
sky2_pci_write16(hw, PCI_STATUS,
- pci_err | PCI_STATUS_ERROR_BITS);
+ pci_err | PCI_STATUS_ERROR_BITS);
sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF);
}
@@ -2090,7 +2220,8 @@ static void sky2_hw_intr(struct sky2_hw *hw)
/* PCI-Express uncorrectable Error occurred */
u32 pex_err;
- pex_err = sky2_pci_read32(hw, PEX_UNC_ERR_STAT);
+ pex_err = sky2_pci_read32(hw,
+ hw->err_cap + PCI_ERR_UNCOR_STATUS);
if (net_ratelimit())
printk(KERN_ERR PFX "%s: pci express error (0x%x)\n",
@@ -2098,15 +2229,20 @@ static void sky2_hw_intr(struct sky2_hw *hw)
/* clear the interrupt */
sky2_write32(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON);
- sky2_pci_write32(hw, PEX_UNC_ERR_STAT,
- 0xffffffffUL);
+ sky2_pci_write32(hw,
+ hw->err_cap + PCI_ERR_UNCOR_STATUS,
+ 0xffffffffUL);
sky2_write32(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF);
- if (pex_err & PEX_FATAL_ERRORS) {
+
+ /* In case of fatal error mask off to keep from getting stuck */
+ if (pex_err & (PCI_ERR_UNC_POISON_TLP | PCI_ERR_UNC_FCP
+ | PCI_ERR_UNC_DLP)) {
u32 hwmsk = sky2_read32(hw, B0_HWE_IMSK);
hwmsk &= ~Y2_IS_PCI_EXP;
sky2_write32(hw, B0_HWE_IMSK, hwmsk);
}
+
}
if (status & Y2_HWE_L1_MASK)
@@ -2287,6 +2423,7 @@ static int sky2_reset(struct sky2_hw *hw)
u16 status;
u8 t8;
int i;
+ u32 msk;
sky2_write8(hw, B0_CTST, CS_RST_CLR);
@@ -2327,9 +2464,13 @@ static int sky2_reset(struct sky2_hw *hw)
sky2_write8(hw, B0_CTST, CS_MRST_CLR);
/* clear any PEX errors */
- if (pci_find_capability(hw->pdev, PCI_CAP_ID_EXP))
- sky2_pci_write32(hw, PEX_UNC_ERR_STAT, 0xffffffffUL);
-
+ if (pci_find_capability(hw->pdev, PCI_CAP_ID_EXP)) {
+ hw->err_cap = pci_find_ext_capability(hw->pdev, PCI_EXT_CAP_ID_ERR);
+ if (hw->err_cap)
+ sky2_pci_write32(hw,
+ hw->err_cap + PCI_ERR_UNCOR_STATUS,
+ 0xffffffffUL);
+ }
hw->pmd_type = sky2_read8(hw, B2_PMD_TYP);
hw->ports = 1;
@@ -2386,7 +2527,10 @@ static int sky2_reset(struct sky2_hw *hw)
sky2_write8(hw, RAM_BUFFER(i, B3_RI_RTO_XS2), SK_RI_TO_53);
}
- sky2_write32(hw, B0_HWE_IMSK, Y2_HWE_ALL_MASK);
+ msk = Y2_HWE_ALL_MASK;
+ if (!hw->err_cap)
+ msk &= ~Y2_IS_PCI_EXP;
+ sky2_write32(hw, B0_HWE_IMSK, msk);
for (i = 0; i < hw->ports; i++)
sky2_gmac_reset(hw, i);
@@ -3102,7 +3246,6 @@ static __devinit struct net_device *sky2_init_netdev(struct sky2_hw *hw,
sky2->hw = hw;
sky2->msg_enable = netif_msg_init(debug, default_msg);
- spin_lock_init(&sky2->tx_lock);
/* Auto speed and flow control */
sky2->autoneg = AUTONEG_ENABLE;
sky2->tx_pause = 1;
@@ -3115,13 +3258,11 @@ static __devinit struct net_device *sky2_init_netdev(struct sky2_hw *hw,
spin_lock_init(&sky2->phy_lock);
sky2->tx_pending = TX_DEF_PENDING;
sky2->rx_pending = RX_DEF_PENDING;
- sky2->rx_bufsize = sky2_buf_size(ETH_DATA_LEN);
hw->dev[port] = dev;
sky2->port = port;
- dev->features |= NETIF_F_LLTX;
if (hw->chip_id != CHIP_ID_YUKON_EC_U)
dev->features |= NETIF_F_TSO;
if (highmem)
@@ -3316,6 +3457,14 @@ static int __devinit sky2_probe(struct pci_dev *pdev,
if (!dev)
goto err_out_free_pci;
+ if (!disable_msi && pci_enable_msi(pdev) == 0) {
+ err = sky2_test_msi(hw);
+ if (err == -EOPNOTSUPP)
+ pci_disable_msi(pdev);
+ else if (err)
+ goto err_out_free_netdev;
+ }
+
err = register_netdev(dev);
if (err) {
printk(KERN_ERR PFX "%s: cannot register net device\n",
@@ -3323,6 +3472,14 @@ static int __devinit sky2_probe(struct pci_dev *pdev,
goto err_out_free_netdev;
}
+ err = request_irq(pdev->irq, sky2_intr, IRQF_SHARED, dev->name, hw);
+ if (err) {
+ printk(KERN_ERR PFX "%s: cannot assign irq %d\n",
+ pci_name(pdev), pdev->irq);
+ goto err_out_unregister;
+ }
+ sky2_write32(hw, B0_IMSK, Y2_IS_BASE);
+
sky2_show_addr(dev);
if (hw->ports > 1 && (dev1 = sky2_init_netdev(hw, 1, using_dac))) {
@@ -3337,23 +3494,6 @@ static int __devinit sky2_probe(struct pci_dev *pdev,
}
}
- if (!disable_msi && pci_enable_msi(pdev) == 0) {
- err = sky2_test_msi(hw);
- if (err == -EOPNOTSUPP)
- pci_disable_msi(pdev);
- else if (err)
- goto err_out_unregister;
- }
-
- err = request_irq(pdev->irq, sky2_intr, IRQF_SHARED, DRV_NAME, hw);
- if (err) {
- printk(KERN_ERR PFX "%s: cannot assign irq %d\n",
- pci_name(pdev), pdev->irq);
- goto err_out_unregister;
- }
-
- sky2_write32(hw, B0_IMSK, Y2_IS_BASE);
-
setup_timer(&hw->idle_timer, sky2_idle, (unsigned long) hw);
sky2_idle_start(hw);
@@ -3363,10 +3503,6 @@ static int __devinit sky2_probe(struct pci_dev *pdev,
err_out_unregister:
pci_disable_msi(pdev);
- if (dev1) {
- unregister_netdev(dev1);
- free_netdev(dev1);
- }
unregister_netdev(dev);
err_out_free_netdev:
free_netdev(dev);
diff --git a/drivers/net/sky2.h b/drivers/net/sky2.h
index 4c13c371bc2..f66109a96d9 100644
--- a/drivers/net/sky2.h
+++ b/drivers/net/sky2.h
@@ -4,24 +4,17 @@
#ifndef _SKY2_H
#define _SKY2_H
-/* PCI config registers */
+#define ETH_JUMBO_MTU 9000 /* Maximum MTU supported */
+
+/* PCI device specific config registers */
enum {
PCI_DEV_REG1 = 0x40,
PCI_DEV_REG2 = 0x44,
- PCI_DEV_STATUS = 0x7c,
PCI_DEV_REG3 = 0x80,
PCI_DEV_REG4 = 0x84,
PCI_DEV_REG5 = 0x88,
};
-enum {
- PEX_DEV_CAP = 0xe4,
- PEX_DEV_CTRL = 0xe8,
- PEX_DEV_STA = 0xea,
- PEX_LNK_STAT = 0xf2,
- PEX_UNC_ERR_STAT= 0x104,
-};
-
/* Yukon-2 */
enum pci_dev_reg_1 {
PCI_Y2_PIG_ENA = 1<<31, /* Enable Plug-in-Go (YUKON-2) */
@@ -70,39 +63,6 @@ enum pci_dev_reg_4 {
PCI_STATUS_REC_MASTER_ABORT | \
PCI_STATUS_REC_TARGET_ABORT | \
PCI_STATUS_PARITY)
-
-enum pex_dev_ctrl {
- PEX_DC_MAX_RRS_MSK = 7<<12, /* Bit 14..12: Max. Read Request Size */
- PEX_DC_EN_NO_SNOOP = 1<<11,/* Enable No Snoop */
- PEX_DC_EN_AUX_POW = 1<<10,/* Enable AUX Power */
- PEX_DC_EN_PHANTOM = 1<<9, /* Enable Phantom Functions */
- PEX_DC_EN_EXT_TAG = 1<<8, /* Enable Extended Tag Field */
- PEX_DC_MAX_PLS_MSK = 7<<5, /* Bit 7.. 5: Max. Payload Size Mask */
- PEX_DC_EN_REL_ORD = 1<<4, /* Enable Relaxed Ordering */
- PEX_DC_EN_UNS_RQ_RP = 1<<3, /* Enable Unsupported Request Reporting */
- PEX_DC_EN_FAT_ER_RP = 1<<2, /* Enable Fatal Error Reporting */
- PEX_DC_EN_NFA_ER_RP = 1<<1, /* Enable Non-Fatal Error Reporting */
- PEX_DC_EN_COR_ER_RP = 1<<0, /* Enable Correctable Error Reporting */
-};
-#define PEX_DC_MAX_RD_RQ_SIZE(x) (((x)<<12) & PEX_DC_MAX_RRS_MSK)
-
-/* PEX_UNC_ERR_STAT PEX Uncorrectable Errors Status Register (Yukon-2) */
-enum pex_err {
- PEX_UNSUP_REQ = 1<<20, /* Unsupported Request Error */
-
- PEX_MALFOR_TLP = 1<<18, /* Malformed TLP */
-
- PEX_UNEXP_COMP = 1<<16, /* Unexpected Completion */
-
- PEX_COMP_TO = 1<<14, /* Completion Timeout */
- PEX_FLOW_CTRL_P = 1<<13, /* Flow Control Protocol Error */
- PEX_POIS_TLP = 1<<12, /* Poisoned TLP */
-
- PEX_DATA_LINK_P = 1<<4, /* Data Link Protocol Error */
- PEX_FATAL_ERRORS= (PEX_MALFOR_TLP | PEX_FLOW_CTRL_P | PEX_DATA_LINK_P),
-};
-
-
enum csr_regs {
B0_RAP = 0x0000,
B0_CTST = 0x0004,
@@ -1816,12 +1776,14 @@ struct sky2_status_le {
struct tx_ring_info {
struct sk_buff *skb;
DECLARE_PCI_UNMAP_ADDR(mapaddr);
- u16 idx;
+ DECLARE_PCI_UNMAP_ADDR(maplen);
};
-struct ring_info {
+struct rx_ring_info {
struct sk_buff *skb;
- dma_addr_t mapaddr;
+ dma_addr_t data_addr;
+ DECLARE_PCI_UNMAP_ADDR(data_size);
+ dma_addr_t frag_addr[ETH_JUMBO_MTU >> PAGE_SHIFT];
};
struct sky2_port {
@@ -1831,7 +1793,6 @@ struct sky2_port {
u32 msg_enable;
spinlock_t phy_lock;
- spinlock_t tx_lock ____cacheline_aligned_in_smp;
struct tx_ring_info *tx_ring;
struct sky2_tx_le *tx_le;
u16 tx_cons; /* next le to check */
@@ -1841,13 +1802,15 @@ struct sky2_port {
u16 tx_last_mss;
u32 tx_tcpsum;
- struct ring_info *rx_ring ____cacheline_aligned_in_smp;
+ struct rx_ring_info *rx_ring ____cacheline_aligned_in_smp;
struct sky2_rx_le *rx_le;
u32 rx_addr64;
u16 rx_next; /* next re to check */
u16 rx_put; /* next le index to use */
u16 rx_pending;
- u16 rx_bufsize;
+ u16 rx_data_size;
+ u16 rx_nfrags;
+
#ifdef SKY2_VLAN_TAG_USED
u16 rx_tag;
struct vlan_group *vlgrp;
@@ -1873,6 +1836,7 @@ struct sky2_hw {
struct net_device *dev[2];
int pm_cap;
+ int err_cap;
u8 chip_id;
u8 chip_rev;
u8 pmd_type;
diff --git a/drivers/net/spider_net.c b/drivers/net/spider_net.c
index cc240adb726..1397fc55cf6 100644
--- a/drivers/net/spider_net.c
+++ b/drivers/net/spider_net.c
@@ -317,7 +317,7 @@ spider_net_init_chain(struct spider_net_card *card,
SPIDER_NET_DESCR_SIZE,
direction);
- if (buf == DMA_ERROR_CODE)
+ if (pci_dma_mapping_error(buf))
goto iommu_error;
descr->bus_addr = buf;
@@ -420,7 +420,7 @@ spider_net_prepare_rx_descr(struct spider_net_card *card,
buf = pci_map_single(card->pdev, descr->skb->data,
SPIDER_NET_MAX_FRAME, PCI_DMA_FROMDEVICE);
descr->buf_addr = buf;
- if (buf == DMA_ERROR_CODE) {
+ if (pci_dma_mapping_error(buf)) {
dev_kfree_skb_any(descr->skb);
if (netif_msg_rx_err(card) && net_ratelimit())
pr_err("Could not iommu-map rx buffer\n");
@@ -649,7 +649,7 @@ spider_net_prepare_tx_descr(struct spider_net_card *card,
dma_addr_t buf;
buf = pci_map_single(card->pdev, skb->data, skb->len, PCI_DMA_TODEVICE);
- if (buf == DMA_ERROR_CODE) {
+ if (pci_dma_mapping_error(buf)) {
if (netif_msg_tx_err(card) && net_ratelimit())
pr_err("could not iommu-map packet (%p, %i). "
"Dropping packet\n", skb->data, skb->len);
diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c
index ba737c6cebe..39d09345027 100644
--- a/drivers/net/wireless/airo.c
+++ b/drivers/net/wireless/airo.c
@@ -5659,25 +5659,40 @@ static int airo_pci_resume(struct pci_dev *pdev)
static int __init airo_init_module( void )
{
- int i, have_isa_dev = 0;
+ int i;
+#if 0
+ int have_isa_dev = 0;
+#endif
airo_entry = create_proc_entry("aironet",
S_IFDIR | airo_perm,
proc_root_driver);
- airo_entry->uid = proc_uid;
- airo_entry->gid = proc_gid;
+
+ if (airo_entry) {
+ airo_entry->uid = proc_uid;
+ airo_entry->gid = proc_gid;
+ }
for( i = 0; i < 4 && io[i] && irq[i]; i++ ) {
airo_print_info("", "Trying to configure ISA adapter at irq=%d "
"io=0x%x", irq[i], io[i] );
if (init_airo_card( irq[i], io[i], 0, NULL ))
+#if 0
have_isa_dev = 1;
+#else
+ /* do nothing */ ;
+#endif
}
#ifdef CONFIG_PCI
airo_print_info("", "Probing for PCI adapters");
- pci_register_driver(&airo_driver);
+ i = pci_register_driver(&airo_driver);
airo_print_info("", "Finished probing for PCI adapters");
+
+ if (i) {
+ remove_proc_entry("aironet", proc_root_driver);
+ return i;
+ }
#endif
/* Always exit with success, as we are a library module
diff --git a/drivers/net/wireless/ipw2100.c b/drivers/net/wireless/ipw2100.c
index eddfa8786e8..599e2fe7618 100644
--- a/drivers/net/wireless/ipw2100.c
+++ b/drivers/net/wireless/ipw2100.c
@@ -6274,7 +6274,9 @@ static int ipw2100_pci_init_one(struct pci_dev *pci_dev,
IPW_DEBUG_INFO("%s: Bound to %s\n", dev->name, pci_name(pci_dev));
/* perform this after register_netdev so that dev->name is set */
- sysfs_create_group(&pci_dev->dev.kobj, &ipw2100_attribute_group);
+ err = sysfs_create_group(&pci_dev->dev.kobj, &ipw2100_attribute_group);
+ if (err)
+ goto fail_unlock;
/* If the RF Kill switch is disabled, go ahead and complete the
* startup sequence */
@@ -6540,14 +6542,17 @@ static int __init ipw2100_init(void)
printk(KERN_INFO DRV_NAME ": %s\n", DRV_COPYRIGHT);
ret = pci_register_driver(&ipw2100_pci_driver);
+ if (ret)
+ goto out;
set_acceptable_latency("ipw2100", INFINITE_LATENCY);
#ifdef CONFIG_IPW2100_DEBUG
ipw2100_debug_level = debug;
- driver_create_file(&ipw2100_pci_driver.driver,
- &driver_attr_debug_level);
+ ret = driver_create_file(&ipw2100_pci_driver.driver,
+ &driver_attr_debug_level);
#endif
+out:
return ret;
}