diff options
author | Linus Torvalds <torvalds@g5.osdl.org> | 2006-10-02 08:56:58 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-10-02 08:56:58 -0700 |
commit | 95f3eff6997ae4a6754c1d874ec0a414d97c44d1 (patch) | |
tree | 0aba758649b4f56264cbe9736f6db18a98b9cc1f | |
parent | 44f549217cd26daf7063984ae4ee6e46beca9c41 (diff) | |
parent | 2c81fbc4cfc895e80c18fffdc04a3d870eb16cb8 (diff) | |
download | op-kernel-dev-95f3eff6997ae4a6754c1d874ec0a414d97c44d1.zip op-kernel-dev-95f3eff6997ae4a6754c1d874ec0a414d97c44d1.tar.gz |
Merge branch 'upstream-linus' of master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/netdev-2.6
* 'upstream-linus' of master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/netdev-2.6: (37 commits)
[netdrvr] hp100: encapsulate all non-module code
drivers/net/wireless/{airo,ipw2100}: fix error handling bugs
[netdrvr] phy: Fix bugs in error handling
[PATCH] spidernet: Use pci_dma_mapping_error()
[PATCH] sky2: version 1.9
[PATCH] sky2: fragmented receive for large MTU
[PATCH] sky2: use netif_tx_lock instead of LLTX
[PATCH] sky2: incremental transmit completion
[PATCH] sky2: name irq after eth for irqbalance
[PATCH] sky2: workarounds for some 88e806x chips
[PATCH] sky2: use standard pci register capabilties for error register
[PATCH] sky2: gigabit full duplex negotiation
e100, e1000, ixgb: increment version numbers
ixgb: convert to netdev_priv(netdev)
ixgb: combine more rx descriptors to improve performance
e1000: possible memory leak in e1000_set_ringparam
e1000: Janitor: Use #defined values for literals
e1000: don't strip vlan ID if 8021q claims it
e1000: rework polarity, NVM, eeprom code and fixes.
e1000: driver state fixes (race fix)
...
29 files changed, 1502 insertions, 1755 deletions
diff --git a/drivers/net/e100.c b/drivers/net/e100.c index dc5e38a..26073c3 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 5f297e5..0000000 --- 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 5dea2b7..4a6ab15 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 98afa9c..7ecce43 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 e39aa1f..778ede3 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 10b8c8c..65077f3 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 4020acb..112447f 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 3f6a752..7dca38f 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 46bc49d..a464cb2 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 2128427..9c3c1ac 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 03b3df3..561db44 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 a8a2d3d..838a508 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 a51604b..50ffe90 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 8357c55..f15aebd 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 bf6fa22..ef236b9 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 64a383e..cd22523 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 acc6df7..02089b6 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 cb45689..40ef5ca 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 9fd6118..4376e7e 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 2e0f4b9..cfde7c2 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 19cb1d5..8434d75 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 39fbed2..b27442a 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 19f7ee6..94b47c8d0 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 ecd3da1..3bbd5e7 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 7eeefa2..396e7df 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 4c13c37..f66109a 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 cc240ad..1397fc5 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 ba737c6..39d0934 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 eddfa87..599e2fe 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; } |