aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/qlge
diff options
context:
space:
mode:
authorRon Mercer <ron.mercer@qlogic.com>2009-02-23 05:42:14 -0500
committerDavid S. Miller <davem@davemloft.net>2009-02-25 02:50:00 -0500
commitcc288f54bbace136c08742da84712add54e4acfa (patch)
tree6e4742f194bc787fa3cf9c2c416e95e02204a5ab /drivers/net/qlge
parentbb58b5b67c08b5fde08090917a040a07ac9d43de (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>
Diffstat (limited to 'drivers/net/qlge')
-rw-r--r--drivers/net/qlge/qlge_dbg.c9
-rw-r--r--drivers/net/qlge/qlge_main.c51
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
116void ql_dump_routing_entries(struct ql_adapter *qdev) 121void 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
136void ql_dump_regs(struct ql_adapter *qdev) 145void 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 }
310exit: 307exit:
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 }
417exit: 410exit:
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
1702static void ql_vlan_rx_kill_vid(struct net_device *ndev, u16 vid) 1699static 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
3532static void qlge_tx_timeout(struct net_device *ndev) 3549static void qlge_tx_timeout(struct net_device *ndev)