Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/dev/pci Fix MAC address check on 8257[156] and 80003 cas...



details:   https://anonhg.NetBSD.org/src/rev/410cb6c72b9d
branches:  trunk
changeset: 761380:410cb6c72b9d
user:      msaitoh <msaitoh%NetBSD.org@localhost>
date:      Wed Jan 26 00:25:34 2011 +0000

description:
Fix MAC address check on 8257[156] and 80003 case. Some cards have non 0xffff
pointer but those don't use alternative MAC address in reality. So we check
whether the broadcast bit is set or not like Intel's e1000 driver.
Fixes PR kern/44072 reported by Jean-Yves Moulin.

Remove extra Warning for newer cards.

diffstat:

 sys/dev/pci/if_wm.c |  151 ++++++++++++++++++++++++++++++++-------------------
 1 files changed, 93 insertions(+), 58 deletions(-)

diffs (198 lines):

diff -r 7324499cd5b7 -r 410cb6c72b9d sys/dev/pci/if_wm.c
--- a/sys/dev/pci/if_wm.c       Wed Jan 26 00:16:52 2011 +0000
+++ b/sys/dev/pci/if_wm.c       Wed Jan 26 00:25:34 2011 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: if_wm.c,v 1.217 2010/12/14 02:51:46 dyoung Exp $       */
+/*     $NetBSD: if_wm.c,v 1.218 2011/01/26 00:25:34 msaitoh Exp $      */
 
 /*
  * Copyright (c) 2001, 2002, 2003, 2004 Wasabi Systems, Inc.
@@ -76,7 +76,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_wm.c,v 1.217 2010/12/14 02:51:46 dyoung Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_wm.c,v 1.218 2011/01/26 00:25:34 msaitoh Exp $");
 
 #include "rnd.h"
 
@@ -510,6 +510,7 @@
 static int     wm_read_eeprom(struct wm_softc *, int, int, u_int16_t *);
 static int     wm_read_eeprom_eerd(struct wm_softc *, int, int, u_int16_t *);
 static int     wm_validate_eeprom_checksum(struct wm_softc *);
+static int     wm_check_alt_mac_addr(struct wm_softc *);
 static int     wm_read_mac_addr(struct wm_softc *, uint8_t *);
 static void    wm_tick(void *);
 
@@ -1186,11 +1187,13 @@
                            PCI_MAPREG_TYPE_IO)
                                break;
                }
-               if (i == PCI_MAPREG_END)
-                       aprint_error_dev(sc->sc_dev,
-                           "WARNING: unable to find I/O BAR\n");
-               else {
+               if (i != PCI_MAPREG_END) {
                        /*
+                        * We found PCI_MAPREG_TYPE_IO. Note that 82580
+                        * (and newer?) chip has no PCI_MAPREG_TYPE_IO.
+                        * It's no problem because newer chips has no this
+                        * bug.
+                        *
                         * The i8254x doesn't apparently respond when the
                         * I/O BAR is 0, which looks somewhat like it's not
                         * been configured.
@@ -4722,69 +4725,101 @@
 }
 
 static int
+wm_check_alt_mac_addr(struct wm_softc *sc)
+{
+       uint16_t myea[ETHER_ADDR_LEN / 2];
+       uint16_t offset = EEPROM_OFF_MACADDR;
+
+       /* Try to read alternative MAC address pointer */
+       if (wm_read_eeprom(sc, EEPROM_ALT_MAC_ADDR_PTR, 1, &offset) != 0)
+               return -1;
+
+       /* Check pointer */
+       if (offset == 0xffff)
+               return -1;
+
+       /*
+        * Check whether alternative MAC address is valid or not.
+        * Some cards have non 0xffff pointer but those don't use
+        * alternative MAC address in reality.
+        *
+        * Check whether the broadcast bit is set or not.
+        */
+       if (wm_read_eeprom(sc, offset, 1, myea) == 0)
+               if (((myea[0] & 0xff) & 0x01) == 0)
+                       return 0; /* found! */
+
+       /* not found */
+       return -1;
+}
+
+static int
 wm_read_mac_addr(struct wm_softc *sc, uint8_t *enaddr)
 {
        uint16_t myea[ETHER_ADDR_LEN / 2];
        uint16_t offset = EEPROM_OFF_MACADDR;
        int do_invert = 0;
 
-       if (sc->sc_funcid != 0)
-               switch (sc->sc_type) {
-               case WM_T_82580:
-               case WM_T_82580ER:
-                       switch (sc->sc_funcid) {
-                       case 1:
-                               offset = EEPROM_OFF_LAN1;
-                               break;
-                       case 2:
-                               offset = EEPROM_OFF_LAN2;
-                               break;
-                       case 3:
-                               offset = EEPROM_OFF_LAN3;
-                               break;
-                       default:
-                               goto bad;
-                               /* NOTREACHED */
-                               break;
-                       }
+       switch (sc->sc_type) {
+       case WM_T_82580:
+       case WM_T_82580ER:
+               switch (sc->sc_funcid) {
+               case 0:
+                       /* default value (== EEPROM_OFF_MACADDR) */
                        break;
-               case WM_T_82571:
-               case WM_T_82575:
-               case WM_T_82576:
-               case WM_T_80003:
-                       if (wm_read_eeprom(sc, EEPROM_ALT_MAC_ADDR_PTR, 1,
-                               &offset) != 0) {
-                               goto bad;
-                       }
-
-                       /* no pointer */
-                       if (offset == 0xffff) {
-                               /* reset the offset to LAN0 */
-                               offset = EEPROM_OFF_MACADDR;
-                               do_invert = 1;
-                               goto do_read;
-                       }
-
-                       switch (sc->sc_funcid) {
-                       case 1:
-                               offset += EEPROM_OFF_MACADDR_LAN1;
-                               break;
-                       case 2:
-                               offset += EEPROM_OFF_MACADDR_LAN2;
-                               break;
-                       case 3:
-                               offset += EEPROM_OFF_MACADDR_LAN3;
-                               break;
-                       default:
-                               goto bad;
-                               /* NOTREACHED */
-                               break;
-                       }
+               case 1:
+                       offset = EEPROM_OFF_LAN1;
+                       break;
+               case 2:
+                       offset = EEPROM_OFF_LAN2;
+                       break;
+               case 3:
+                       offset = EEPROM_OFF_LAN3;
                        break;
                default:
-                       do_invert = 1;
+                       goto bad;
+                       /* NOTREACHED */
                        break;
                }
+               break;
+       case WM_T_82571:
+       case WM_T_82575:
+       case WM_T_82576:
+       case WM_T_80003:
+               if (wm_check_alt_mac_addr(sc) != 0) {
+                       /* reset the offset to LAN0 */
+                       offset = EEPROM_OFF_MACADDR;
+                       if ((sc->sc_funcid & 0x01) == 1)
+                               do_invert = 1;
+                       goto do_read;
+               }
+               switch (sc->sc_funcid) {
+               case 0:
+                       /*
+                        * The offset is the value in EEPROM_ALT_MAC_ADDR_PTR
+                        * itself.
+                        */
+                       break;
+               case 1:
+                       offset += EEPROM_OFF_MACADDR_LAN1;
+                       break;
+               case 2:
+                       offset += EEPROM_OFF_MACADDR_LAN2;
+                       break;
+               case 3:
+                       offset += EEPROM_OFF_MACADDR_LAN3;
+                       break;
+               default:
+                       goto bad;
+                       /* NOTREACHED */
+                       break;
+               }
+               break;
+       default:
+               if ((sc->sc_funcid & 0x01) == 1)
+                       do_invert = 1;
+               break;
+       }
 
  do_read:
        if (wm_read_eeprom(sc, offset, sizeof(myea) / sizeof(myea[0]),



Home | Main Index | Thread Index | Old Index