aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/cnic.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/cnic.c')
-rw-r--r--drivers/net/cnic.c143
1 files changed, 104 insertions, 39 deletions
diff --git a/drivers/net/cnic.c b/drivers/net/cnic.c
index f8a09236dc0a..d45eacb76702 100644
--- a/drivers/net/cnic.c
+++ b/drivers/net/cnic.c
@@ -138,6 +138,16 @@ static struct cnic_dev *cnic_from_netdev(struct net_device *netdev)
138 return NULL; 138 return NULL;
139} 139}
140 140
141static inline void ulp_get(struct cnic_ulp_ops *ulp_ops)
142{
143 atomic_inc(&ulp_ops->ref_count);
144}
145
146static inline void ulp_put(struct cnic_ulp_ops *ulp_ops)
147{
148 atomic_dec(&ulp_ops->ref_count);
149}
150
141static void cnic_ctx_wr(struct cnic_dev *dev, u32 cid_addr, u32 off, u32 val) 151static void cnic_ctx_wr(struct cnic_dev *dev, u32 cid_addr, u32 off, u32 val)
142{ 152{
143 struct cnic_local *cp = dev->cnic_priv; 153 struct cnic_local *cp = dev->cnic_priv;
@@ -358,6 +368,7 @@ int cnic_register_driver(int ulp_type, struct cnic_ulp_ops *ulp_ops)
358 } 368 }
359 read_unlock(&cnic_dev_lock); 369 read_unlock(&cnic_dev_lock);
360 370
371 atomic_set(&ulp_ops->ref_count, 0);
361 rcu_assign_pointer(cnic_ulp_tbl[ulp_type], ulp_ops); 372 rcu_assign_pointer(cnic_ulp_tbl[ulp_type], ulp_ops);
362 mutex_unlock(&cnic_lock); 373 mutex_unlock(&cnic_lock);
363 374
@@ -379,6 +390,8 @@ int cnic_register_driver(int ulp_type, struct cnic_ulp_ops *ulp_ops)
379int cnic_unregister_driver(int ulp_type) 390int cnic_unregister_driver(int ulp_type)
380{ 391{
381 struct cnic_dev *dev; 392 struct cnic_dev *dev;
393 struct cnic_ulp_ops *ulp_ops;
394 int i = 0;
382 395
383 if (ulp_type >= MAX_CNIC_ULP_TYPE) { 396 if (ulp_type >= MAX_CNIC_ULP_TYPE) {
384 printk(KERN_ERR PFX "cnic_unregister_driver: Bad type %d\n", 397 printk(KERN_ERR PFX "cnic_unregister_driver: Bad type %d\n",
@@ -386,7 +399,8 @@ int cnic_unregister_driver(int ulp_type)
386 return -EINVAL; 399 return -EINVAL;
387 } 400 }
388 mutex_lock(&cnic_lock); 401 mutex_lock(&cnic_lock);
389 if (!cnic_ulp_tbl[ulp_type]) { 402 ulp_ops = cnic_ulp_tbl[ulp_type];
403 if (!ulp_ops) {
390 printk(KERN_ERR PFX "cnic_unregister_driver: Type %d has not " 404 printk(KERN_ERR PFX "cnic_unregister_driver: Type %d has not "
391 "been registered\n", ulp_type); 405 "been registered\n", ulp_type);
392 goto out_unlock; 406 goto out_unlock;
@@ -411,6 +425,14 @@ int cnic_unregister_driver(int ulp_type)
411 425
412 mutex_unlock(&cnic_lock); 426 mutex_unlock(&cnic_lock);
413 synchronize_rcu(); 427 synchronize_rcu();
428 while ((atomic_read(&ulp_ops->ref_count) != 0) && (i < 20)) {
429 msleep(100);
430 i++;
431 }
432
433 if (atomic_read(&ulp_ops->ref_count) != 0)
434 printk(KERN_WARNING PFX "%s: Failed waiting for ref count to go"
435 " to zero.\n", dev->netdev->name);
414 return 0; 436 return 0;
415 437
416out_unlock: 438out_unlock:
@@ -466,6 +488,7 @@ EXPORT_SYMBOL(cnic_register_driver);
466static int cnic_unregister_device(struct cnic_dev *dev, int ulp_type) 488static int cnic_unregister_device(struct cnic_dev *dev, int ulp_type)
467{ 489{
468 struct cnic_local *cp = dev->cnic_priv; 490 struct cnic_local *cp = dev->cnic_priv;
491 int i = 0;
469 492
470 if (ulp_type >= MAX_CNIC_ULP_TYPE) { 493 if (ulp_type >= MAX_CNIC_ULP_TYPE) {
471 printk(KERN_ERR PFX "cnic_unregister_device: Bad type %d\n", 494 printk(KERN_ERR PFX "cnic_unregister_device: Bad type %d\n",
@@ -486,6 +509,15 @@ static int cnic_unregister_device(struct cnic_dev *dev, int ulp_type)
486 509
487 synchronize_rcu(); 510 synchronize_rcu();
488 511
512 while (test_bit(ULP_F_CALL_PENDING, &cp->ulp_flags[ulp_type]) &&
513 i < 20) {
514 msleep(100);
515 i++;
516 }
517 if (test_bit(ULP_F_CALL_PENDING, &cp->ulp_flags[ulp_type]))
518 printk(KERN_WARNING PFX "%s: Failed waiting for ULP up call"
519 " to complete.\n", dev->netdev->name);
520
489 return 0; 521 return 0;
490} 522}
491EXPORT_SYMBOL(cnic_unregister_driver); 523EXPORT_SYMBOL(cnic_unregister_driver);
@@ -1101,18 +1133,23 @@ static void cnic_ulp_stop(struct cnic_dev *dev)
1101 if (cp->cnic_uinfo) 1133 if (cp->cnic_uinfo)
1102 cnic_send_nlmsg(cp, ISCSI_KEVENT_IF_DOWN, NULL); 1134 cnic_send_nlmsg(cp, ISCSI_KEVENT_IF_DOWN, NULL);
1103 1135
1104 rcu_read_lock();
1105 for (if_type = 0; if_type < MAX_CNIC_ULP_TYPE; if_type++) { 1136 for (if_type = 0; if_type < MAX_CNIC_ULP_TYPE; if_type++) {
1106 struct cnic_ulp_ops *ulp_ops; 1137 struct cnic_ulp_ops *ulp_ops;
1107 1138
1108 ulp_ops = rcu_dereference(cp->ulp_ops[if_type]); 1139 mutex_lock(&cnic_lock);
1109 if (!ulp_ops) 1140 ulp_ops = cp->ulp_ops[if_type];
1141 if (!ulp_ops) {
1142 mutex_unlock(&cnic_lock);
1110 continue; 1143 continue;
1144 }
1145 set_bit(ULP_F_CALL_PENDING, &cp->ulp_flags[if_type]);
1146 mutex_unlock(&cnic_lock);
1111 1147
1112 if (test_and_clear_bit(ULP_F_START, &cp->ulp_flags[if_type])) 1148 if (test_and_clear_bit(ULP_F_START, &cp->ulp_flags[if_type]))
1113 ulp_ops->cnic_stop(cp->ulp_handle[if_type]); 1149 ulp_ops->cnic_stop(cp->ulp_handle[if_type]);
1150
1151 clear_bit(ULP_F_CALL_PENDING, &cp->ulp_flags[if_type]);
1114 } 1152 }
1115 rcu_read_unlock();
1116} 1153}
1117 1154
1118static void cnic_ulp_start(struct cnic_dev *dev) 1155static void cnic_ulp_start(struct cnic_dev *dev)
@@ -1120,18 +1157,23 @@ static void cnic_ulp_start(struct cnic_dev *dev)
1120 struct cnic_local *cp = dev->cnic_priv; 1157 struct cnic_local *cp = dev->cnic_priv;
1121 int if_type; 1158 int if_type;
1122 1159
1123 rcu_read_lock();
1124 for (if_type = 0; if_type < MAX_CNIC_ULP_TYPE; if_type++) { 1160 for (if_type = 0; if_type < MAX_CNIC_ULP_TYPE; if_type++) {
1125 struct cnic_ulp_ops *ulp_ops; 1161 struct cnic_ulp_ops *ulp_ops;
1126 1162
1127 ulp_ops = rcu_dereference(cp->ulp_ops[if_type]); 1163 mutex_lock(&cnic_lock);
1128 if (!ulp_ops || !ulp_ops->cnic_start) 1164 ulp_ops = cp->ulp_ops[if_type];
1165 if (!ulp_ops || !ulp_ops->cnic_start) {
1166 mutex_unlock(&cnic_lock);
1129 continue; 1167 continue;
1168 }
1169 set_bit(ULP_F_CALL_PENDING, &cp->ulp_flags[if_type]);
1170 mutex_unlock(&cnic_lock);
1130 1171
1131 if (!test_and_set_bit(ULP_F_START, &cp->ulp_flags[if_type])) 1172 if (!test_and_set_bit(ULP_F_START, &cp->ulp_flags[if_type]))
1132 ulp_ops->cnic_start(cp->ulp_handle[if_type]); 1173 ulp_ops->cnic_start(cp->ulp_handle[if_type]);
1174
1175 clear_bit(ULP_F_CALL_PENDING, &cp->ulp_flags[if_type]);
1133 } 1176 }
1134 rcu_read_unlock();
1135} 1177}
1136 1178
1137static int cnic_ctl(void *data, struct cnic_ctl_info *info) 1179static int cnic_ctl(void *data, struct cnic_ctl_info *info)
@@ -1141,22 +1183,18 @@ static int cnic_ctl(void *data, struct cnic_ctl_info *info)
1141 switch (info->cmd) { 1183 switch (info->cmd) {
1142 case CNIC_CTL_STOP_CMD: 1184 case CNIC_CTL_STOP_CMD:
1143 cnic_hold(dev); 1185 cnic_hold(dev);
1144 mutex_lock(&cnic_lock);
1145 1186
1146 cnic_ulp_stop(dev); 1187 cnic_ulp_stop(dev);
1147 cnic_stop_hw(dev); 1188 cnic_stop_hw(dev);
1148 1189
1149 mutex_unlock(&cnic_lock);
1150 cnic_put(dev); 1190 cnic_put(dev);
1151 break; 1191 break;
1152 case CNIC_CTL_START_CMD: 1192 case CNIC_CTL_START_CMD:
1153 cnic_hold(dev); 1193 cnic_hold(dev);
1154 mutex_lock(&cnic_lock);
1155 1194
1156 if (!cnic_start_hw(dev)) 1195 if (!cnic_start_hw(dev))
1157 cnic_ulp_start(dev); 1196 cnic_ulp_start(dev);
1158 1197
1159 mutex_unlock(&cnic_lock);
1160 cnic_put(dev); 1198 cnic_put(dev);
1161 break; 1199 break;
1162 default: 1200 default:
@@ -1170,19 +1208,23 @@ static void cnic_ulp_init(struct cnic_dev *dev)
1170 int i; 1208 int i;
1171 struct cnic_local *cp = dev->cnic_priv; 1209 struct cnic_local *cp = dev->cnic_priv;
1172 1210
1173 rcu_read_lock();
1174 for (i = 0; i < MAX_CNIC_ULP_TYPE_EXT; i++) { 1211 for (i = 0; i < MAX_CNIC_ULP_TYPE_EXT; i++) {
1175 struct cnic_ulp_ops *ulp_ops; 1212 struct cnic_ulp_ops *ulp_ops;
1176 1213
1177 ulp_ops = rcu_dereference(cnic_ulp_tbl[i]); 1214 mutex_lock(&cnic_lock);
1178 if (!ulp_ops || !ulp_ops->cnic_init) 1215 ulp_ops = cnic_ulp_tbl[i];
1216 if (!ulp_ops || !ulp_ops->cnic_init) {
1217 mutex_unlock(&cnic_lock);
1179 continue; 1218 continue;
1219 }
1220 ulp_get(ulp_ops);
1221 mutex_unlock(&cnic_lock);
1180 1222
1181 if (!test_and_set_bit(ULP_F_INIT, &cp->ulp_flags[i])) 1223 if (!test_and_set_bit(ULP_F_INIT, &cp->ulp_flags[i]))
1182 ulp_ops->cnic_init(dev); 1224 ulp_ops->cnic_init(dev);
1183 1225
1226 ulp_put(ulp_ops);
1184 } 1227 }
1185 rcu_read_unlock();
1186} 1228}
1187 1229
1188static void cnic_ulp_exit(struct cnic_dev *dev) 1230static void cnic_ulp_exit(struct cnic_dev *dev)
@@ -1190,19 +1232,23 @@ static void cnic_ulp_exit(struct cnic_dev *dev)
1190 int i; 1232 int i;
1191 struct cnic_local *cp = dev->cnic_priv; 1233 struct cnic_local *cp = dev->cnic_priv;
1192 1234
1193 rcu_read_lock();
1194 for (i = 0; i < MAX_CNIC_ULP_TYPE_EXT; i++) { 1235 for (i = 0; i < MAX_CNIC_ULP_TYPE_EXT; i++) {
1195 struct cnic_ulp_ops *ulp_ops; 1236 struct cnic_ulp_ops *ulp_ops;
1196 1237
1197 ulp_ops = rcu_dereference(cnic_ulp_tbl[i]); 1238 mutex_lock(&cnic_lock);
1198 if (!ulp_ops || !ulp_ops->cnic_exit) 1239 ulp_ops = cnic_ulp_tbl[i];
1240 if (!ulp_ops || !ulp_ops->cnic_exit) {
1241 mutex_unlock(&cnic_lock);
1199 continue; 1242 continue;
1243 }
1244 ulp_get(ulp_ops);
1245 mutex_unlock(&cnic_lock);
1200 1246
1201 if (test_and_clear_bit(ULP_F_INIT, &cp->ulp_flags[i])) 1247 if (test_and_clear_bit(ULP_F_INIT, &cp->ulp_flags[i]))
1202 ulp_ops->cnic_exit(dev); 1248 ulp_ops->cnic_exit(dev);
1203 1249
1250 ulp_put(ulp_ops);
1204 } 1251 }
1205 rcu_read_unlock();
1206} 1252}
1207 1253
1208static int cnic_cm_offload_pg(struct cnic_sock *csk) 1254static int cnic_cm_offload_pg(struct cnic_sock *csk)
@@ -2418,21 +2464,45 @@ static int cnic_start_bnx2_hw(struct cnic_dev *dev)
2418 return 0; 2464 return 0;
2419} 2465}
2420 2466
2421static int cnic_start_hw(struct cnic_dev *dev) 2467static int cnic_register_netdev(struct cnic_dev *dev)
2422{ 2468{
2423 struct cnic_local *cp = dev->cnic_priv; 2469 struct cnic_local *cp = dev->cnic_priv;
2424 struct cnic_eth_dev *ethdev = cp->ethdev; 2470 struct cnic_eth_dev *ethdev = cp->ethdev;
2425 int err; 2471 int err;
2426 2472
2427 if (test_bit(CNIC_F_CNIC_UP, &dev->flags)) 2473 if (!ethdev)
2428 return -EALREADY; 2474 return -ENODEV;
2475
2476 if (ethdev->drv_state & CNIC_DRV_STATE_REGD)
2477 return 0;
2429 2478
2430 err = ethdev->drv_register_cnic(dev->netdev, cp->cnic_ops, dev); 2479 err = ethdev->drv_register_cnic(dev->netdev, cp->cnic_ops, dev);
2431 if (err) { 2480 if (err)
2432 printk(KERN_ERR PFX "%s: register_cnic failed\n", 2481 printk(KERN_ERR PFX "%s: register_cnic failed\n",
2433 dev->netdev->name); 2482 dev->netdev->name);
2434 goto err2; 2483
2435 } 2484 return err;
2485}
2486
2487static void cnic_unregister_netdev(struct cnic_dev *dev)
2488{
2489 struct cnic_local *cp = dev->cnic_priv;
2490 struct cnic_eth_dev *ethdev = cp->ethdev;
2491
2492 if (!ethdev)
2493 return;
2494
2495 ethdev->drv_unregister_cnic(dev->netdev);
2496}
2497
2498static int cnic_start_hw(struct cnic_dev *dev)
2499{
2500 struct cnic_local *cp = dev->cnic_priv;
2501 struct cnic_eth_dev *ethdev = cp->ethdev;
2502 int err;
2503
2504 if (test_bit(CNIC_F_CNIC_UP, &dev->flags))
2505 return -EALREADY;
2436 2506
2437 dev->regview = ethdev->io_base; 2507 dev->regview = ethdev->io_base;
2438 cp->chip_id = ethdev->chip_id; 2508 cp->chip_id = ethdev->chip_id;
@@ -2463,18 +2533,13 @@ static int cnic_start_hw(struct cnic_dev *dev)
2463 return 0; 2533 return 0;
2464 2534
2465err1: 2535err1:
2466 ethdev->drv_unregister_cnic(dev->netdev);
2467 cp->free_resc(dev); 2536 cp->free_resc(dev);
2468 pci_dev_put(dev->pcidev); 2537 pci_dev_put(dev->pcidev);
2469err2:
2470 return err; 2538 return err;
2471} 2539}
2472 2540
2473static void cnic_stop_bnx2_hw(struct cnic_dev *dev) 2541static void cnic_stop_bnx2_hw(struct cnic_dev *dev)
2474{ 2542{
2475 struct cnic_local *cp = dev->cnic_priv;
2476 struct cnic_eth_dev *ethdev = cp->ethdev;
2477
2478 cnic_disable_bnx2_int_sync(dev); 2543 cnic_disable_bnx2_int_sync(dev);
2479 2544
2480 cnic_reg_wr_ind(dev, BNX2_CP_SCRATCH + 0x20, 0); 2545 cnic_reg_wr_ind(dev, BNX2_CP_SCRATCH + 0x20, 0);
@@ -2486,8 +2551,6 @@ static void cnic_stop_bnx2_hw(struct cnic_dev *dev)
2486 cnic_setup_5709_context(dev, 0); 2551 cnic_setup_5709_context(dev, 0);
2487 cnic_free_irq(dev); 2552 cnic_free_irq(dev);
2488 2553
2489 ethdev->drv_unregister_cnic(dev->netdev);
2490
2491 cnic_free_resc(dev); 2554 cnic_free_resc(dev);
2492} 2555}
2493 2556
@@ -2568,7 +2631,7 @@ static struct cnic_dev *init_bnx2_cnic(struct net_device *dev)
2568 probe = symbol_get(bnx2_cnic_probe); 2631 probe = symbol_get(bnx2_cnic_probe);
2569 if (probe) { 2632 if (probe) {
2570 ethdev = (*probe)(dev); 2633 ethdev = (*probe)(dev);
2571 symbol_put_addr(probe); 2634 symbol_put(bnx2_cnic_probe);
2572 } 2635 }
2573 if (!ethdev) 2636 if (!ethdev)
2574 return NULL; 2637 return NULL;
@@ -2671,10 +2734,12 @@ static int cnic_netdev_event(struct notifier_block *this, unsigned long event,
2671 else if (event == NETDEV_UNREGISTER) 2734 else if (event == NETDEV_UNREGISTER)
2672 cnic_ulp_exit(dev); 2735 cnic_ulp_exit(dev);
2673 else if (event == NETDEV_UP) { 2736 else if (event == NETDEV_UP) {
2674 mutex_lock(&cnic_lock); 2737 if (cnic_register_netdev(dev) != 0) {
2738 cnic_put(dev);
2739 goto done;
2740 }
2675 if (!cnic_start_hw(dev)) 2741 if (!cnic_start_hw(dev))
2676 cnic_ulp_start(dev); 2742 cnic_ulp_start(dev);
2677 mutex_unlock(&cnic_lock);
2678 } 2743 }
2679 2744
2680 rcu_read_lock(); 2745 rcu_read_lock();
@@ -2693,10 +2758,9 @@ static int cnic_netdev_event(struct notifier_block *this, unsigned long event,
2693 rcu_read_unlock(); 2758 rcu_read_unlock();
2694 2759
2695 if (event == NETDEV_GOING_DOWN) { 2760 if (event == NETDEV_GOING_DOWN) {
2696 mutex_lock(&cnic_lock);
2697 cnic_ulp_stop(dev); 2761 cnic_ulp_stop(dev);
2698 cnic_stop_hw(dev); 2762 cnic_stop_hw(dev);
2699 mutex_unlock(&cnic_lock); 2763 cnic_unregister_netdev(dev);
2700 } else if (event == NETDEV_UNREGISTER) { 2764 } else if (event == NETDEV_UNREGISTER) {
2701 write_lock(&cnic_dev_lock); 2765 write_lock(&cnic_dev_lock);
2702 list_del_init(&dev->list); 2766 list_del_init(&dev->list);
@@ -2728,6 +2792,7 @@ static void cnic_release(void)
2728 } 2792 }
2729 2793
2730 cnic_ulp_exit(dev); 2794 cnic_ulp_exit(dev);
2795 cnic_unregister_netdev(dev);
2731 list_del_init(&dev->list); 2796 list_del_init(&dev->list);
2732 cnic_free_dev(dev); 2797 cnic_free_dev(dev);
2733 } 2798 }