diff options
Diffstat (limited to 'drivers/net/ehea/ehea_main.c')
-rw-r--r-- | drivers/net/ehea/ehea_main.c | 144 |
1 files changed, 130 insertions, 14 deletions
diff --git a/drivers/net/ehea/ehea_main.c b/drivers/net/ehea/ehea_main.c index 383144db4d18..1d1571cf322e 100644 --- a/drivers/net/ehea/ehea_main.c +++ b/drivers/net/ehea/ehea_main.c | |||
@@ -79,6 +79,11 @@ MODULE_PARM_DESC(sq_entries, " Number of entries for the Send Queue " | |||
79 | MODULE_PARM_DESC(use_mcs, " 0:NAPI, 1:Multiple receive queues, Default = 1 "); | 79 | MODULE_PARM_DESC(use_mcs, " 0:NAPI, 1:Multiple receive queues, Default = 1 "); |
80 | 80 | ||
81 | static int port_name_cnt = 0; | 81 | static int port_name_cnt = 0; |
82 | static LIST_HEAD(adapter_list); | ||
83 | u64 ehea_driver_flags = 0; | ||
84 | struct workqueue_struct *ehea_driver_wq; | ||
85 | struct work_struct ehea_rereg_mr_task; | ||
86 | |||
82 | 87 | ||
83 | static int __devinit ehea_probe_adapter(struct ibmebus_dev *dev, | 88 | static int __devinit ehea_probe_adapter(struct ibmebus_dev *dev, |
84 | const struct of_device_id *id); | 89 | const struct of_device_id *id); |
@@ -238,13 +243,17 @@ static int ehea_refill_rq_def(struct ehea_port_res *pr, | |||
238 | rwqe->wr_id = EHEA_BMASK_SET(EHEA_WR_ID_TYPE, wqe_type) | 243 | rwqe->wr_id = EHEA_BMASK_SET(EHEA_WR_ID_TYPE, wqe_type) |
239 | | EHEA_BMASK_SET(EHEA_WR_ID_INDEX, index); | 244 | | EHEA_BMASK_SET(EHEA_WR_ID_INDEX, index); |
240 | rwqe->sg_list[0].l_key = pr->recv_mr.lkey; | 245 | rwqe->sg_list[0].l_key = pr->recv_mr.lkey; |
241 | rwqe->sg_list[0].vaddr = (u64)skb->data; | 246 | rwqe->sg_list[0].vaddr = ehea_map_vaddr(skb->data); |
242 | rwqe->sg_list[0].len = packet_size; | 247 | rwqe->sg_list[0].len = packet_size; |
243 | rwqe->data_segments = 1; | 248 | rwqe->data_segments = 1; |
244 | 249 | ||
245 | index++; | 250 | index++; |
246 | index &= max_index_mask; | 251 | index &= max_index_mask; |
252 | |||
253 | if (unlikely(test_bit(__EHEA_STOP_XFER, &ehea_driver_flags))) | ||
254 | goto out; | ||
247 | } | 255 | } |
256 | |||
248 | q_skba->index = index; | 257 | q_skba->index = index; |
249 | 258 | ||
250 | /* Ring doorbell */ | 259 | /* Ring doorbell */ |
@@ -253,7 +262,7 @@ static int ehea_refill_rq_def(struct ehea_port_res *pr, | |||
253 | ehea_update_rq2a(pr->qp, i); | 262 | ehea_update_rq2a(pr->qp, i); |
254 | else | 263 | else |
255 | ehea_update_rq3a(pr->qp, i); | 264 | ehea_update_rq3a(pr->qp, i); |
256 | 265 | out: | |
257 | return ret; | 266 | return ret; |
258 | } | 267 | } |
259 | 268 | ||
@@ -1321,7 +1330,7 @@ static void write_swqe2_TSO(struct sk_buff *skb, | |||
1321 | sg1entry->len = skb_data_size - headersize; | 1330 | sg1entry->len = skb_data_size - headersize; |
1322 | 1331 | ||
1323 | tmp_addr = (u64)(skb->data + headersize); | 1332 | tmp_addr = (u64)(skb->data + headersize); |
1324 | sg1entry->vaddr = tmp_addr; | 1333 | sg1entry->vaddr = ehea_map_vaddr(tmp_addr); |
1325 | swqe->descriptors++; | 1334 | swqe->descriptors++; |
1326 | } | 1335 | } |
1327 | } else | 1336 | } else |
@@ -1352,7 +1361,7 @@ static void write_swqe2_nonTSO(struct sk_buff *skb, | |||
1352 | sg1entry->l_key = lkey; | 1361 | sg1entry->l_key = lkey; |
1353 | sg1entry->len = skb_data_size - SWQE2_MAX_IMM; | 1362 | sg1entry->len = skb_data_size - SWQE2_MAX_IMM; |
1354 | tmp_addr = (u64)(skb->data + SWQE2_MAX_IMM); | 1363 | tmp_addr = (u64)(skb->data + SWQE2_MAX_IMM); |
1355 | sg1entry->vaddr = tmp_addr; | 1364 | sg1entry->vaddr = ehea_map_vaddr(tmp_addr); |
1356 | swqe->descriptors++; | 1365 | swqe->descriptors++; |
1357 | } | 1366 | } |
1358 | } else { | 1367 | } else { |
@@ -1391,7 +1400,7 @@ static inline void write_swqe2_data(struct sk_buff *skb, struct net_device *dev, | |||
1391 | sg1entry->len = frag->size; | 1400 | sg1entry->len = frag->size; |
1392 | tmp_addr = (u64)(page_address(frag->page) | 1401 | tmp_addr = (u64)(page_address(frag->page) |
1393 | + frag->page_offset); | 1402 | + frag->page_offset); |
1394 | sg1entry->vaddr = tmp_addr; | 1403 | sg1entry->vaddr = ehea_map_vaddr(tmp_addr); |
1395 | swqe->descriptors++; | 1404 | swqe->descriptors++; |
1396 | sg1entry_contains_frag_data = 1; | 1405 | sg1entry_contains_frag_data = 1; |
1397 | } | 1406 | } |
@@ -1406,7 +1415,7 @@ static inline void write_swqe2_data(struct sk_buff *skb, struct net_device *dev, | |||
1406 | 1415 | ||
1407 | tmp_addr = (u64)(page_address(frag->page) | 1416 | tmp_addr = (u64)(page_address(frag->page) |
1408 | + frag->page_offset); | 1417 | + frag->page_offset); |
1409 | sgentry->vaddr = tmp_addr; | 1418 | sgentry->vaddr = ehea_map_vaddr(tmp_addr); |
1410 | swqe->descriptors++; | 1419 | swqe->descriptors++; |
1411 | } | 1420 | } |
1412 | } | 1421 | } |
@@ -1878,6 +1887,9 @@ static int ehea_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
1878 | ehea_dump(swqe, 512, "swqe"); | 1887 | ehea_dump(swqe, 512, "swqe"); |
1879 | } | 1888 | } |
1880 | 1889 | ||
1890 | if (unlikely(test_bit(__EHEA_STOP_XFER, &ehea_driver_flags))) | ||
1891 | goto out; | ||
1892 | |||
1881 | ehea_post_swqe(pr->qp, swqe); | 1893 | ehea_post_swqe(pr->qp, swqe); |
1882 | pr->tx_packets++; | 1894 | pr->tx_packets++; |
1883 | 1895 | ||
@@ -1892,7 +1904,7 @@ static int ehea_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
1892 | } | 1904 | } |
1893 | dev->trans_start = jiffies; | 1905 | dev->trans_start = jiffies; |
1894 | spin_unlock(&pr->xmit_lock); | 1906 | spin_unlock(&pr->xmit_lock); |
1895 | 1907 | out: | |
1896 | return NETDEV_TX_OK; | 1908 | return NETDEV_TX_OK; |
1897 | } | 1909 | } |
1898 | 1910 | ||
@@ -2220,6 +2232,9 @@ out_dereg_bc: | |||
2220 | out_clean_pr: | 2232 | out_clean_pr: |
2221 | ehea_clean_all_portres(port); | 2233 | ehea_clean_all_portres(port); |
2222 | out: | 2234 | out: |
2235 | if (ret) | ||
2236 | ehea_info("Failed starting %s. ret=%i", dev->name, ret); | ||
2237 | |||
2223 | return ret; | 2238 | return ret; |
2224 | } | 2239 | } |
2225 | 2240 | ||
@@ -2259,8 +2274,13 @@ static int ehea_down(struct net_device *dev) | |||
2259 | msleep(1); | 2274 | msleep(1); |
2260 | 2275 | ||
2261 | ehea_broadcast_reg_helper(port, H_DEREG_BCMC); | 2276 | ehea_broadcast_reg_helper(port, H_DEREG_BCMC); |
2262 | ret = ehea_clean_all_portres(port); | ||
2263 | port->state = EHEA_PORT_DOWN; | 2277 | port->state = EHEA_PORT_DOWN; |
2278 | |||
2279 | ret = ehea_clean_all_portres(port); | ||
2280 | if (ret) | ||
2281 | ehea_info("Failed freeing resources for %s. ret=%i", | ||
2282 | dev->name, ret); | ||
2283 | |||
2264 | return ret; | 2284 | return ret; |
2265 | } | 2285 | } |
2266 | 2286 | ||
@@ -2292,15 +2312,11 @@ static void ehea_reset_port(struct work_struct *work) | |||
2292 | netif_stop_queue(dev); | 2312 | netif_stop_queue(dev); |
2293 | netif_poll_disable(dev); | 2313 | netif_poll_disable(dev); |
2294 | 2314 | ||
2295 | ret = ehea_down(dev); | 2315 | ehea_down(dev); |
2296 | if (ret) | ||
2297 | ehea_error("ehea_down failed. not all resources are freed"); | ||
2298 | 2316 | ||
2299 | ret = ehea_up(dev); | 2317 | ret = ehea_up(dev); |
2300 | if (ret) { | 2318 | if (ret) |
2301 | ehea_error("Reset device %s failed: ret=%d", dev->name, ret); | ||
2302 | goto out; | 2319 | goto out; |
2303 | } | ||
2304 | 2320 | ||
2305 | if (netif_msg_timer(port)) | 2321 | if (netif_msg_timer(port)) |
2306 | ehea_info("Device %s resetted successfully", dev->name); | 2322 | ehea_info("Device %s resetted successfully", dev->name); |
@@ -2312,6 +2328,88 @@ out: | |||
2312 | return; | 2328 | return; |
2313 | } | 2329 | } |
2314 | 2330 | ||
2331 | static void ehea_rereg_mrs(struct work_struct *work) | ||
2332 | { | ||
2333 | int ret, i; | ||
2334 | struct ehea_adapter *adapter; | ||
2335 | |||
2336 | ehea_info("LPAR memory enlarged - re-initializing driver"); | ||
2337 | |||
2338 | list_for_each_entry(adapter, &adapter_list, list) | ||
2339 | if (adapter->active_ports) { | ||
2340 | /* Shutdown all ports */ | ||
2341 | for (i = 0; i < EHEA_MAX_PORTS; i++) { | ||
2342 | struct ehea_port *port = adapter->port[i]; | ||
2343 | |||
2344 | if (port) { | ||
2345 | struct net_device *dev = port->netdev; | ||
2346 | |||
2347 | if (dev->flags & IFF_UP) { | ||
2348 | ehea_info("stopping %s", | ||
2349 | dev->name); | ||
2350 | down(&port->port_lock); | ||
2351 | netif_stop_queue(dev); | ||
2352 | netif_poll_disable(dev); | ||
2353 | ehea_down(dev); | ||
2354 | up(&port->port_lock); | ||
2355 | } | ||
2356 | } | ||
2357 | } | ||
2358 | |||
2359 | /* Unregister old memory region */ | ||
2360 | ret = ehea_rem_mr(&adapter->mr); | ||
2361 | if (ret) { | ||
2362 | ehea_error("unregister MR failed - driver" | ||
2363 | " inoperable!"); | ||
2364 | goto out; | ||
2365 | } | ||
2366 | } | ||
2367 | |||
2368 | ehea_destroy_busmap(); | ||
2369 | |||
2370 | ret = ehea_create_busmap(); | ||
2371 | if (ret) | ||
2372 | goto out; | ||
2373 | |||
2374 | clear_bit(__EHEA_STOP_XFER, &ehea_driver_flags); | ||
2375 | |||
2376 | list_for_each_entry(adapter, &adapter_list, list) | ||
2377 | if (adapter->active_ports) { | ||
2378 | /* Register new memory region */ | ||
2379 | ret = ehea_reg_kernel_mr(adapter, &adapter->mr); | ||
2380 | if (ret) { | ||
2381 | ehea_error("register MR failed - driver" | ||
2382 | " inoperable!"); | ||
2383 | goto out; | ||
2384 | } | ||
2385 | |||
2386 | /* Restart all ports */ | ||
2387 | for (i = 0; i < EHEA_MAX_PORTS; i++) { | ||
2388 | struct ehea_port *port = adapter->port[i]; | ||
2389 | |||
2390 | if (port) { | ||
2391 | struct net_device *dev = port->netdev; | ||
2392 | |||
2393 | if (dev->flags & IFF_UP) { | ||
2394 | ehea_info("restarting %s", | ||
2395 | dev->name); | ||
2396 | down(&port->port_lock); | ||
2397 | |||
2398 | ret = ehea_up(dev); | ||
2399 | if (!ret) { | ||
2400 | netif_poll_enable(dev); | ||
2401 | netif_wake_queue(dev); | ||
2402 | } | ||
2403 | |||
2404 | up(&port->port_lock); | ||
2405 | } | ||
2406 | } | ||
2407 | } | ||
2408 | } | ||
2409 | out: | ||
2410 | return; | ||
2411 | } | ||
2412 | |||
2315 | static void ehea_tx_watchdog(struct net_device *dev) | 2413 | static void ehea_tx_watchdog(struct net_device *dev) |
2316 | { | 2414 | { |
2317 | struct ehea_port *port = netdev_priv(dev); | 2415 | struct ehea_port *port = netdev_priv(dev); |
@@ -2573,6 +2671,8 @@ struct ehea_port *ehea_setup_single_port(struct ehea_adapter *adapter, | |||
2573 | ehea_info("%s: Jumbo frames are %sabled", dev->name, | 2671 | ehea_info("%s: Jumbo frames are %sabled", dev->name, |
2574 | jumbo == 1 ? "en" : "dis"); | 2672 | jumbo == 1 ? "en" : "dis"); |
2575 | 2673 | ||
2674 | adapter->active_ports++; | ||
2675 | |||
2576 | return port; | 2676 | return port; |
2577 | 2677 | ||
2578 | out_unreg_port: | 2678 | out_unreg_port: |
@@ -2596,6 +2696,7 @@ static void ehea_shutdown_single_port(struct ehea_port *port) | |||
2596 | ehea_unregister_port(port); | 2696 | ehea_unregister_port(port); |
2597 | kfree(port->mc_list); | 2697 | kfree(port->mc_list); |
2598 | free_netdev(port->netdev); | 2698 | free_netdev(port->netdev); |
2699 | port->adapter->active_ports--; | ||
2599 | } | 2700 | } |
2600 | 2701 | ||
2601 | static int ehea_setup_ports(struct ehea_adapter *adapter) | 2702 | static int ehea_setup_ports(struct ehea_adapter *adapter) |
@@ -2788,6 +2889,8 @@ static int __devinit ehea_probe_adapter(struct ibmebus_dev *dev, | |||
2788 | goto out; | 2889 | goto out; |
2789 | } | 2890 | } |
2790 | 2891 | ||
2892 | list_add(&adapter->list, &adapter_list); | ||
2893 | |||
2791 | adapter->ebus_dev = dev; | 2894 | adapter->ebus_dev = dev; |
2792 | 2895 | ||
2793 | adapter_handle = of_get_property(dev->ofdev.node, "ibm,hea-handle", | 2896 | adapter_handle = of_get_property(dev->ofdev.node, "ibm,hea-handle", |
@@ -2891,7 +2994,10 @@ static int __devexit ehea_remove(struct ibmebus_dev *dev) | |||
2891 | 2994 | ||
2892 | ehea_destroy_eq(adapter->neq); | 2995 | ehea_destroy_eq(adapter->neq); |
2893 | ehea_remove_adapter_mr(adapter); | 2996 | ehea_remove_adapter_mr(adapter); |
2997 | list_del(&adapter->list); | ||
2998 | |||
2894 | kfree(adapter); | 2999 | kfree(adapter); |
3000 | |||
2895 | return 0; | 3001 | return 0; |
2896 | } | 3002 | } |
2897 | 3003 | ||
@@ -2939,9 +3045,18 @@ int __init ehea_module_init(void) | |||
2939 | printk(KERN_INFO "IBM eHEA ethernet device driver (Release %s)\n", | 3045 | printk(KERN_INFO "IBM eHEA ethernet device driver (Release %s)\n", |
2940 | DRV_VERSION); | 3046 | DRV_VERSION); |
2941 | 3047 | ||
3048 | ehea_driver_wq = create_workqueue("ehea_driver_wq"); | ||
3049 | |||
3050 | INIT_WORK(&ehea_rereg_mr_task, ehea_rereg_mrs); | ||
3051 | |||
2942 | ret = check_module_parm(); | 3052 | ret = check_module_parm(); |
2943 | if (ret) | 3053 | if (ret) |
2944 | goto out; | 3054 | goto out; |
3055 | |||
3056 | ret = ehea_create_busmap(); | ||
3057 | if (ret) | ||
3058 | goto out; | ||
3059 | |||
2945 | ret = ibmebus_register_driver(&ehea_driver); | 3060 | ret = ibmebus_register_driver(&ehea_driver); |
2946 | if (ret) { | 3061 | if (ret) { |
2947 | ehea_error("failed registering eHEA device driver on ebus"); | 3062 | ehea_error("failed registering eHEA device driver on ebus"); |
@@ -2965,6 +3080,7 @@ static void __exit ehea_module_exit(void) | |||
2965 | { | 3080 | { |
2966 | driver_remove_file(&ehea_driver.driver, &driver_attr_capabilities); | 3081 | driver_remove_file(&ehea_driver.driver, &driver_attr_capabilities); |
2967 | ibmebus_unregister_driver(&ehea_driver); | 3082 | ibmebus_unregister_driver(&ehea_driver); |
3083 | ehea_destroy_busmap(); | ||
2968 | } | 3084 | } |
2969 | 3085 | ||
2970 | module_init(ehea_module_init); | 3086 | module_init(ehea_module_init); |