aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ehea/ehea_main.c
diff options
context:
space:
mode:
authorThomas Klein <osstklei@de.ibm.com>2007-07-11 10:32:00 -0400
committerJeff Garzik <jeff@garzik.org>2007-07-16 17:59:50 -0400
commit44c821525778c5d2e81da293195d5d589e8ad845 (patch)
tree7996d9d180023c752b61e2fcfe96a42a00a1510f /drivers/net/ehea/ehea_main.c
parent5be808467347fc99bdd216883c5dbd123d6ad9d6 (diff)
eHEA: Introducing support vor DLPAR memory add
This patch adds support for DLPAR memory add to the eHEA driver. To detect whether memory was added the driver uses its own memory mapping table and checks for kernel addresses whether they're located in already known memory sections. If not the function ehea_rereg_mrs() is triggered which performs a rebuild of the mapping table and a re-registration of the global memory region. Signed-off-by: Thomas Klein <tklein@de.ibm.com> Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers/net/ehea/ehea_main.c')
-rw-r--r--drivers/net/ehea/ehea_main.c144
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 "
79MODULE_PARM_DESC(use_mcs, " 0:NAPI, 1:Multiple receive queues, Default = 1 "); 79MODULE_PARM_DESC(use_mcs, " 0:NAPI, 1:Multiple receive queues, Default = 1 ");
80 80
81static int port_name_cnt = 0; 81static int port_name_cnt = 0;
82static LIST_HEAD(adapter_list);
83u64 ehea_driver_flags = 0;
84struct workqueue_struct *ehea_driver_wq;
85struct work_struct ehea_rereg_mr_task;
86
82 87
83static int __devinit ehea_probe_adapter(struct ibmebus_dev *dev, 88static 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 265out:
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 1907out:
1896 return NETDEV_TX_OK; 1908 return NETDEV_TX_OK;
1897} 1909}
1898 1910
@@ -2220,6 +2232,9 @@ out_dereg_bc:
2220out_clean_pr: 2232out_clean_pr:
2221 ehea_clean_all_portres(port); 2233 ehea_clean_all_portres(port);
2222out: 2234out:
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
2331static 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 }
2409out:
2410 return;
2411}
2412
2315static void ehea_tx_watchdog(struct net_device *dev) 2413static 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
2578out_unreg_port: 2678out_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
2601static int ehea_setup_ports(struct ehea_adapter *adapter) 2702static 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
2970module_init(ehea_module_init); 3086module_init(ehea_module_init);