diff options
Diffstat (limited to 'drivers/net/qlge/qlge_main.c')
-rw-r--r-- | drivers/net/qlge/qlge_main.c | 50 |
1 files changed, 43 insertions, 7 deletions
diff --git a/drivers/net/qlge/qlge_main.c b/drivers/net/qlge/qlge_main.c index 74ed84a288c2..46dea2bd94d0 100644 --- a/drivers/net/qlge/qlge_main.c +++ b/drivers/net/qlge/qlge_main.c | |||
@@ -413,6 +413,41 @@ exit: | |||
413 | return status; | 413 | return status; |
414 | } | 414 | } |
415 | 415 | ||
416 | /* Set or clear MAC address in hardware. We sometimes | ||
417 | * have to clear it to prevent wrong frame routing | ||
418 | * especially in a bonding environment. | ||
419 | */ | ||
420 | static int ql_set_mac_addr(struct ql_adapter *qdev, int set) | ||
421 | { | ||
422 | int status; | ||
423 | char zero_mac_addr[ETH_ALEN]; | ||
424 | char *addr; | ||
425 | |||
426 | if (set) { | ||
427 | addr = &qdev->ndev->dev_addr[0]; | ||
428 | QPRINTK(qdev, IFUP, DEBUG, | ||
429 | "Set Mac addr %02x:%02x:%02x:%02x:%02x:%02x\n", | ||
430 | addr[0], addr[1], addr[2], addr[3], | ||
431 | addr[4], addr[5]); | ||
432 | } else { | ||
433 | memset(zero_mac_addr, 0, ETH_ALEN); | ||
434 | addr = &zero_mac_addr[0]; | ||
435 | QPRINTK(qdev, IFUP, DEBUG, | ||
436 | "Clearing MAC address on %s\n", | ||
437 | qdev->ndev->name); | ||
438 | } | ||
439 | status = ql_sem_spinlock(qdev, SEM_MAC_ADDR_MASK); | ||
440 | if (status) | ||
441 | return status; | ||
442 | status = ql_set_mac_addr_reg(qdev, (u8 *) addr, | ||
443 | MAC_ADDR_TYPE_CAM_MAC, qdev->func * MAX_CQ); | ||
444 | ql_sem_unlock(qdev, SEM_MAC_ADDR_MASK); | ||
445 | if (status) | ||
446 | QPRINTK(qdev, IFUP, ERR, "Failed to init mac " | ||
447 | "address.\n"); | ||
448 | return status; | ||
449 | } | ||
450 | |||
416 | /* Get a specific frame routing value from the CAM. | 451 | /* Get a specific frame routing value from the CAM. |
417 | * Used for debug and reg dump. | 452 | * Used for debug and reg dump. |
418 | */ | 453 | */ |
@@ -3112,14 +3147,15 @@ exit: | |||
3112 | 3147 | ||
3113 | int ql_cam_route_initialize(struct ql_adapter *qdev) | 3148 | int ql_cam_route_initialize(struct ql_adapter *qdev) |
3114 | { | 3149 | { |
3115 | int status; | 3150 | int status, set; |
3116 | 3151 | ||
3117 | status = ql_sem_spinlock(qdev, SEM_MAC_ADDR_MASK); | 3152 | /* If check if the link is up and use to |
3118 | if (status) | 3153 | * determine if we are setting or clearing |
3119 | return status; | 3154 | * the MAC address in the CAM. |
3120 | status = ql_set_mac_addr_reg(qdev, (u8 *) qdev->ndev->perm_addr, | 3155 | */ |
3121 | MAC_ADDR_TYPE_CAM_MAC, qdev->func * MAX_CQ); | 3156 | set = ql_read32(qdev, STS); |
3122 | ql_sem_unlock(qdev, SEM_MAC_ADDR_MASK); | 3157 | set &= qdev->port_link_up; |
3158 | status = ql_set_mac_addr(qdev, set); | ||
3123 | if (status) { | 3159 | if (status) { |
3124 | QPRINTK(qdev, IFUP, ERR, "Failed to init mac address.\n"); | 3160 | QPRINTK(qdev, IFUP, ERR, "Failed to init mac address.\n"); |
3125 | return status; | 3161 | return status; |