diff options
author | Ron Mercer <ron.mercer@qlogic.com> | 2009-02-23 05:42:14 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-02-25 02:50:00 -0500 |
commit | cc288f54bbace136c08742da84712add54e4acfa (patch) | |
tree | 6e4742f194bc787fa3cf9c2c416e95e02204a5ab | |
parent | bb58b5b67c08b5fde08090917a040a07ac9d43de (diff) |
qlge: Increase MAC addr hw sem granularity.
Instead of taking/giving the semaphore repeatedly when iterating over
several adderesses, we have the caller hold it until all are done. This
reduces PCI bus chatter and possible waits.
Signed-off-by: Ron Mercer <ron.mercer@qlogic.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/net/qlge/qlge_dbg.c | 9 | ||||
-rw-r--r-- | drivers/net/qlge/qlge_main.c | 51 |
2 files changed, 43 insertions, 17 deletions
diff --git a/drivers/net/qlge/qlge_dbg.c b/drivers/net/qlge/qlge_dbg.c index 379b895ed6e6..40a70c36f5ae 100644 --- a/drivers/net/qlge/qlge_dbg.c +++ b/drivers/net/qlge/qlge_dbg.c | |||
@@ -83,6 +83,10 @@ static void ql_dump_cam_entries(struct ql_adapter *qdev) | |||
83 | { | 83 | { |
84 | int i; | 84 | int i; |
85 | u32 value[3]; | 85 | u32 value[3]; |
86 | |||
87 | i = ql_sem_spinlock(qdev, SEM_MAC_ADDR_MASK); | ||
88 | if (i) | ||
89 | return; | ||
86 | for (i = 0; i < 4; i++) { | 90 | for (i = 0; i < 4; i++) { |
87 | if (ql_get_mac_addr_reg(qdev, MAC_ADDR_TYPE_CAM_MAC, i, value)) { | 91 | if (ql_get_mac_addr_reg(qdev, MAC_ADDR_TYPE_CAM_MAC, i, value)) { |
88 | printk(KERN_ERR PFX | 92 | printk(KERN_ERR PFX |
@@ -111,12 +115,16 @@ static void ql_dump_cam_entries(struct ql_adapter *qdev) | |||
111 | qdev->ndev->name, i, value[1], value[0]); | 115 | qdev->ndev->name, i, value[1], value[0]); |
112 | } | 116 | } |
113 | } | 117 | } |
118 | ql_sem_unlock(qdev, SEM_MAC_ADDR_MASK); | ||
114 | } | 119 | } |
115 | 120 | ||
116 | void ql_dump_routing_entries(struct ql_adapter *qdev) | 121 | void ql_dump_routing_entries(struct ql_adapter *qdev) |
117 | { | 122 | { |
118 | int i; | 123 | int i; |
119 | u32 value; | 124 | u32 value; |
125 | i = ql_sem_spinlock(qdev, SEM_RT_IDX_MASK); | ||
126 | if (i) | ||
127 | return; | ||
120 | for (i = 0; i < 16; i++) { | 128 | for (i = 0; i < 16; i++) { |
121 | value = 0; | 129 | value = 0; |
122 | if (ql_get_routing_reg(qdev, i, &value)) { | 130 | if (ql_get_routing_reg(qdev, i, &value)) { |
@@ -131,6 +139,7 @@ void ql_dump_routing_entries(struct ql_adapter *qdev) | |||
131 | qdev->ndev->name, i, value); | 139 | qdev->ndev->name, i, value); |
132 | } | 140 | } |
133 | } | 141 | } |
142 | ql_sem_unlock(qdev, SEM_RT_IDX_MASK); | ||
134 | } | 143 | } |
135 | 144 | ||
136 | void ql_dump_regs(struct ql_adapter *qdev) | 145 | void ql_dump_regs(struct ql_adapter *qdev) |
diff --git a/drivers/net/qlge/qlge_main.c b/drivers/net/qlge/qlge_main.c index 3a041b6d9fec..d316e508d06e 100644 --- a/drivers/net/qlge/qlge_main.c +++ b/drivers/net/qlge/qlge_main.c | |||
@@ -247,9 +247,6 @@ int ql_get_mac_addr_reg(struct ql_adapter *qdev, u32 type, u16 index, | |||
247 | u32 offset = 0; | 247 | u32 offset = 0; |
248 | int status; | 248 | int status; |
249 | 249 | ||
250 | status = ql_sem_spinlock(qdev, SEM_MAC_ADDR_MASK); | ||
251 | if (status) | ||
252 | return status; | ||
253 | switch (type) { | 250 | switch (type) { |
254 | case MAC_ADDR_TYPE_MULTI_MAC: | 251 | case MAC_ADDR_TYPE_MULTI_MAC: |
255 | case MAC_ADDR_TYPE_CAM_MAC: | 252 | case MAC_ADDR_TYPE_CAM_MAC: |
@@ -308,7 +305,6 @@ int ql_get_mac_addr_reg(struct ql_adapter *qdev, u32 type, u16 index, | |||
308 | status = -EPERM; | 305 | status = -EPERM; |
309 | } | 306 | } |
310 | exit: | 307 | exit: |
311 | ql_sem_unlock(qdev, SEM_MAC_ADDR_MASK); | ||
312 | return status; | 308 | return status; |
313 | } | 309 | } |
314 | 310 | ||
@@ -321,9 +317,6 @@ static int ql_set_mac_addr_reg(struct ql_adapter *qdev, u8 *addr, u32 type, | |||
321 | u32 offset = 0; | 317 | u32 offset = 0; |
322 | int status = 0; | 318 | int status = 0; |
323 | 319 | ||
324 | status = ql_sem_spinlock(qdev, SEM_MAC_ADDR_MASK); | ||
325 | if (status) | ||
326 | return status; | ||
327 | switch (type) { | 320 | switch (type) { |
328 | case MAC_ADDR_TYPE_MULTI_MAC: | 321 | case MAC_ADDR_TYPE_MULTI_MAC: |
329 | case MAC_ADDR_TYPE_CAM_MAC: | 322 | case MAC_ADDR_TYPE_CAM_MAC: |
@@ -415,7 +408,6 @@ static int ql_set_mac_addr_reg(struct ql_adapter *qdev, u8 *addr, u32 type, | |||
415 | status = -EPERM; | 408 | status = -EPERM; |
416 | } | 409 | } |
417 | exit: | 410 | exit: |
418 | ql_sem_unlock(qdev, SEM_MAC_ADDR_MASK); | ||
419 | return status; | 411 | return status; |
420 | } | 412 | } |
421 | 413 | ||
@@ -1690,19 +1682,29 @@ static void ql_vlan_rx_add_vid(struct net_device *ndev, u16 vid) | |||
1690 | { | 1682 | { |
1691 | struct ql_adapter *qdev = netdev_priv(ndev); | 1683 | struct ql_adapter *qdev = netdev_priv(ndev); |
1692 | u32 enable_bit = MAC_ADDR_E; | 1684 | u32 enable_bit = MAC_ADDR_E; |
1685 | int status; | ||
1693 | 1686 | ||
1687 | status = ql_sem_spinlock(qdev, SEM_MAC_ADDR_MASK); | ||
1688 | if (status) | ||
1689 | return; | ||
1694 | spin_lock(&qdev->hw_lock); | 1690 | spin_lock(&qdev->hw_lock); |
1695 | if (ql_set_mac_addr_reg | 1691 | if (ql_set_mac_addr_reg |
1696 | (qdev, (u8 *) &enable_bit, MAC_ADDR_TYPE_VLAN, vid)) { | 1692 | (qdev, (u8 *) &enable_bit, MAC_ADDR_TYPE_VLAN, vid)) { |
1697 | QPRINTK(qdev, IFUP, ERR, "Failed to init vlan address.\n"); | 1693 | QPRINTK(qdev, IFUP, ERR, "Failed to init vlan address.\n"); |
1698 | } | 1694 | } |
1699 | spin_unlock(&qdev->hw_lock); | 1695 | spin_unlock(&qdev->hw_lock); |
1696 | ql_sem_unlock(qdev, SEM_MAC_ADDR_MASK); | ||
1700 | } | 1697 | } |
1701 | 1698 | ||
1702 | static void ql_vlan_rx_kill_vid(struct net_device *ndev, u16 vid) | 1699 | static void ql_vlan_rx_kill_vid(struct net_device *ndev, u16 vid) |
1703 | { | 1700 | { |
1704 | struct ql_adapter *qdev = netdev_priv(ndev); | 1701 | struct ql_adapter *qdev = netdev_priv(ndev); |
1705 | u32 enable_bit = 0; | 1702 | u32 enable_bit = 0; |
1703 | int status; | ||
1704 | |||
1705 | status = ql_sem_spinlock(qdev, SEM_MAC_ADDR_MASK); | ||
1706 | if (status) | ||
1707 | return; | ||
1706 | 1708 | ||
1707 | spin_lock(&qdev->hw_lock); | 1709 | spin_lock(&qdev->hw_lock); |
1708 | if (ql_set_mac_addr_reg | 1710 | if (ql_set_mac_addr_reg |
@@ -1710,6 +1712,7 @@ static void ql_vlan_rx_kill_vid(struct net_device *ndev, u16 vid) | |||
1710 | QPRINTK(qdev, IFUP, ERR, "Failed to clear vlan address.\n"); | 1712 | QPRINTK(qdev, IFUP, ERR, "Failed to clear vlan address.\n"); |
1711 | } | 1713 | } |
1712 | spin_unlock(&qdev->hw_lock); | 1714 | spin_unlock(&qdev->hw_lock); |
1715 | ql_sem_unlock(qdev, SEM_MAC_ADDR_MASK); | ||
1713 | 1716 | ||
1714 | } | 1717 | } |
1715 | 1718 | ||
@@ -2962,8 +2965,12 @@ static int ql_cam_route_initialize(struct ql_adapter *qdev) | |||
2962 | { | 2965 | { |
2963 | int status; | 2966 | int status; |
2964 | 2967 | ||
2968 | status = ql_sem_spinlock(qdev, SEM_MAC_ADDR_MASK); | ||
2969 | if (status) | ||
2970 | return status; | ||
2965 | status = ql_set_mac_addr_reg(qdev, (u8 *) qdev->ndev->perm_addr, | 2971 | status = ql_set_mac_addr_reg(qdev, (u8 *) qdev->ndev->perm_addr, |
2966 | MAC_ADDR_TYPE_CAM_MAC, qdev->func * MAX_CQ); | 2972 | MAC_ADDR_TYPE_CAM_MAC, qdev->func * MAX_CQ); |
2973 | ql_sem_unlock(qdev, SEM_MAC_ADDR_MASK); | ||
2967 | if (status) { | 2974 | if (status) { |
2968 | QPRINTK(qdev, IFUP, ERR, "Failed to init mac address.\n"); | 2975 | QPRINTK(qdev, IFUP, ERR, "Failed to init mac address.\n"); |
2969 | return status; | 2976 | return status; |
@@ -3428,8 +3435,11 @@ static void qlge_set_multicast_list(struct net_device *ndev) | |||
3428 | { | 3435 | { |
3429 | struct ql_adapter *qdev = (struct ql_adapter *)netdev_priv(ndev); | 3436 | struct ql_adapter *qdev = (struct ql_adapter *)netdev_priv(ndev); |
3430 | struct dev_mc_list *mc_ptr; | 3437 | struct dev_mc_list *mc_ptr; |
3431 | int i; | 3438 | int i, status; |
3432 | 3439 | ||
3440 | status = ql_sem_spinlock(qdev, SEM_RT_IDX_MASK); | ||
3441 | if (status) | ||
3442 | return; | ||
3433 | spin_lock(&qdev->hw_lock); | 3443 | spin_lock(&qdev->hw_lock); |
3434 | /* | 3444 | /* |
3435 | * Set or clear promiscuous mode if a | 3445 | * Set or clear promiscuous mode if a |
@@ -3485,14 +3495,19 @@ static void qlge_set_multicast_list(struct net_device *ndev) | |||
3485 | } | 3495 | } |
3486 | 3496 | ||
3487 | if (ndev->mc_count) { | 3497 | if (ndev->mc_count) { |
3498 | status = ql_sem_spinlock(qdev, SEM_MAC_ADDR_MASK); | ||
3499 | if (status) | ||
3500 | goto exit; | ||
3488 | for (i = 0, mc_ptr = ndev->mc_list; mc_ptr; | 3501 | for (i = 0, mc_ptr = ndev->mc_list; mc_ptr; |
3489 | i++, mc_ptr = mc_ptr->next) | 3502 | i++, mc_ptr = mc_ptr->next) |
3490 | if (ql_set_mac_addr_reg(qdev, (u8 *) mc_ptr->dmi_addr, | 3503 | if (ql_set_mac_addr_reg(qdev, (u8 *) mc_ptr->dmi_addr, |
3491 | MAC_ADDR_TYPE_MULTI_MAC, i)) { | 3504 | MAC_ADDR_TYPE_MULTI_MAC, i)) { |
3492 | QPRINTK(qdev, HW, ERR, | 3505 | QPRINTK(qdev, HW, ERR, |
3493 | "Failed to loadmulticast address.\n"); | 3506 | "Failed to loadmulticast address.\n"); |
3507 | ql_sem_unlock(qdev, SEM_MAC_ADDR_MASK); | ||
3494 | goto exit; | 3508 | goto exit; |
3495 | } | 3509 | } |
3510 | ql_sem_unlock(qdev, SEM_MAC_ADDR_MASK); | ||
3496 | if (ql_set_routing_reg | 3511 | if (ql_set_routing_reg |
3497 | (qdev, RT_IDX_MCAST_MATCH_SLOT, RT_IDX_MCAST_MATCH, 1)) { | 3512 | (qdev, RT_IDX_MCAST_MATCH_SLOT, RT_IDX_MCAST_MATCH, 1)) { |
3498 | QPRINTK(qdev, HW, ERR, | 3513 | QPRINTK(qdev, HW, ERR, |
@@ -3509,7 +3524,7 @@ static int qlge_set_mac_address(struct net_device *ndev, void *p) | |||
3509 | { | 3524 | { |
3510 | struct ql_adapter *qdev = (struct ql_adapter *)netdev_priv(ndev); | 3525 | struct ql_adapter *qdev = (struct ql_adapter *)netdev_priv(ndev); |
3511 | struct sockaddr *addr = p; | 3526 | struct sockaddr *addr = p; |
3512 | int ret = 0; | 3527 | int status; |
3513 | 3528 | ||
3514 | if (netif_running(ndev)) | 3529 | if (netif_running(ndev)) |
3515 | return -EBUSY; | 3530 | return -EBUSY; |
@@ -3518,15 +3533,17 @@ static int qlge_set_mac_address(struct net_device *ndev, void *p) | |||
3518 | return -EADDRNOTAVAIL; | 3533 | return -EADDRNOTAVAIL; |
3519 | memcpy(ndev->dev_addr, addr->sa_data, ndev->addr_len); | 3534 | memcpy(ndev->dev_addr, addr->sa_data, ndev->addr_len); |
3520 | 3535 | ||
3536 | status = ql_sem_spinlock(qdev, SEM_MAC_ADDR_MASK); | ||
3537 | if (status) | ||
3538 | return status; | ||
3521 | spin_lock(&qdev->hw_lock); | 3539 | spin_lock(&qdev->hw_lock); |
3522 | if (ql_set_mac_addr_reg(qdev, (u8 *) ndev->dev_addr, | 3540 | status = ql_set_mac_addr_reg(qdev, (u8 *) ndev->dev_addr, |
3523 | MAC_ADDR_TYPE_CAM_MAC, qdev->func)) {/* Unicast */ | 3541 | MAC_ADDR_TYPE_CAM_MAC, qdev->func * MAX_CQ); |
3524 | QPRINTK(qdev, HW, ERR, "Failed to load MAC address.\n"); | ||
3525 | ret = -1; | ||
3526 | } | ||
3527 | spin_unlock(&qdev->hw_lock); | 3542 | spin_unlock(&qdev->hw_lock); |
3528 | 3543 | if (status) | |
3529 | return ret; | 3544 | QPRINTK(qdev, HW, ERR, "Failed to load MAC address.\n"); |
3545 | ql_sem_unlock(qdev, SEM_MAC_ADDR_MASK); | ||
3546 | return status; | ||
3530 | } | 3547 | } |
3531 | 3548 | ||
3532 | static void qlge_tx_timeout(struct net_device *ndev) | 3549 | static void qlge_tx_timeout(struct net_device *ndev) |