Skip to content

Commit 44c8215

Browse files
Thomas KleinJeff Garzik
authored andcommitted
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 <[email protected]> Signed-off-by: Jeff Garzik <[email protected]>
1 parent 5be8084 commit 44c8215

File tree

5 files changed

+275
-65
lines changed

5 files changed

+275
-65
lines changed

drivers/net/ehea/ehea.h

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -39,13 +39,13 @@
3939
#include <asm/io.h>
4040

4141
#define DRV_NAME "ehea"
42-
#define DRV_VERSION "EHEA_0067"
42+
#define DRV_VERSION "EHEA_0070"
4343

44-
/* EHEA capability flags */
44+
/* eHEA capability flags */
4545
#define DLPAR_PORT_ADD_REM 1
46-
#define DLPAR_MEM_ADD 2
47-
#define DLPAR_MEM_REM 4
48-
#define EHEA_CAPABILITIES (DLPAR_PORT_ADD_REM)
46+
#define DLPAR_MEM_ADD 2
47+
#define DLPAR_MEM_REM 4
48+
#define EHEA_CAPABILITIES (DLPAR_PORT_ADD_REM)
4949

5050
#define EHEA_MSG_DEFAULT (NETIF_MSG_LINK | NETIF_MSG_TIMER \
5151
| NETIF_MSG_RX_ERR | NETIF_MSG_TX_ERR)
@@ -113,6 +113,8 @@
113113
/* Memory Regions */
114114
#define EHEA_MR_ACC_CTRL 0x00800000
115115

116+
#define EHEA_BUSMAP_START 0x8000000000000000ULL
117+
116118
#define EHEA_WATCH_DOG_TIMEOUT 10*HZ
117119

118120
/* utility functions */
@@ -186,6 +188,12 @@ struct h_epas {
186188
set to 0 if unused */
187189
};
188190

191+
struct ehea_busmap {
192+
unsigned int entries; /* total number of entries */
193+
unsigned int valid_sections; /* number of valid sections */
194+
u64 *vaddr;
195+
};
196+
189197
struct ehea_qp;
190198
struct ehea_cq;
191199
struct ehea_eq;
@@ -382,6 +390,8 @@ struct ehea_adapter {
382390
struct ehea_mr mr;
383391
u32 pd; /* protection domain */
384392
u64 max_mc_mac; /* max number of multicast mac addresses */
393+
int active_ports;
394+
struct list_head list;
385395
};
386396

387397

@@ -431,6 +441,9 @@ struct port_res_cfg {
431441
int max_entries_rq3;
432442
};
433443

444+
enum ehea_flag_bits {
445+
__EHEA_STOP_XFER
446+
};
434447

435448
void ehea_set_ethtool_ops(struct net_device *netdev);
436449
int ehea_sense_port_attr(struct ehea_port *port);

drivers/net/ehea/ehea_main.c

Lines changed: 130 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,11 @@ MODULE_PARM_DESC(sq_entries, " Number of entries for the Send Queue "
7979
MODULE_PARM_DESC(use_mcs, " 0:NAPI, 1:Multiple receive queues, Default = 1 ");
8080

8181
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+
8287

8388
static int __devinit ehea_probe_adapter(struct ibmebus_dev *dev,
8489
const struct of_device_id *id);
@@ -238,13 +243,17 @@ static int ehea_refill_rq_def(struct ehea_port_res *pr,
238243
rwqe->wr_id = EHEA_BMASK_SET(EHEA_WR_ID_TYPE, wqe_type)
239244
| EHEA_BMASK_SET(EHEA_WR_ID_INDEX, index);
240245
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);
242247
rwqe->sg_list[0].len = packet_size;
243248
rwqe->data_segments = 1;
244249

245250
index++;
246251
index &= max_index_mask;
252+
253+
if (unlikely(test_bit(__EHEA_STOP_XFER, &ehea_driver_flags)))
254+
goto out;
247255
}
256+
248257
q_skba->index = index;
249258

250259
/* Ring doorbell */
@@ -253,7 +262,7 @@ static int ehea_refill_rq_def(struct ehea_port_res *pr,
253262
ehea_update_rq2a(pr->qp, i);
254263
else
255264
ehea_update_rq3a(pr->qp, i);
256-
265+
out:
257266
return ret;
258267
}
259268

@@ -1321,7 +1330,7 @@ static void write_swqe2_TSO(struct sk_buff *skb,
13211330
sg1entry->len = skb_data_size - headersize;
13221331

13231332
tmp_addr = (u64)(skb->data + headersize);
1324-
sg1entry->vaddr = tmp_addr;
1333+
sg1entry->vaddr = ehea_map_vaddr(tmp_addr);
13251334
swqe->descriptors++;
13261335
}
13271336
} else
@@ -1352,7 +1361,7 @@ static void write_swqe2_nonTSO(struct sk_buff *skb,
13521361
sg1entry->l_key = lkey;
13531362
sg1entry->len = skb_data_size - SWQE2_MAX_IMM;
13541363
tmp_addr = (u64)(skb->data + SWQE2_MAX_IMM);
1355-
sg1entry->vaddr = tmp_addr;
1364+
sg1entry->vaddr = ehea_map_vaddr(tmp_addr);
13561365
swqe->descriptors++;
13571366
}
13581367
} else {
@@ -1391,7 +1400,7 @@ static inline void write_swqe2_data(struct sk_buff *skb, struct net_device *dev,
13911400
sg1entry->len = frag->size;
13921401
tmp_addr = (u64)(page_address(frag->page)
13931402
+ frag->page_offset);
1394-
sg1entry->vaddr = tmp_addr;
1403+
sg1entry->vaddr = ehea_map_vaddr(tmp_addr);
13951404
swqe->descriptors++;
13961405
sg1entry_contains_frag_data = 1;
13971406
}
@@ -1406,7 +1415,7 @@ static inline void write_swqe2_data(struct sk_buff *skb, struct net_device *dev,
14061415

14071416
tmp_addr = (u64)(page_address(frag->page)
14081417
+ frag->page_offset);
1409-
sgentry->vaddr = tmp_addr;
1418+
sgentry->vaddr = ehea_map_vaddr(tmp_addr);
14101419
swqe->descriptors++;
14111420
}
14121421
}
@@ -1878,6 +1887,9 @@ static int ehea_start_xmit(struct sk_buff *skb, struct net_device *dev)
18781887
ehea_dump(swqe, 512, "swqe");
18791888
}
18801889

1890+
if (unlikely(test_bit(__EHEA_STOP_XFER, &ehea_driver_flags)))
1891+
goto out;
1892+
18811893
ehea_post_swqe(pr->qp, swqe);
18821894
pr->tx_packets++;
18831895

@@ -1892,7 +1904,7 @@ static int ehea_start_xmit(struct sk_buff *skb, struct net_device *dev)
18921904
}
18931905
dev->trans_start = jiffies;
18941906
spin_unlock(&pr->xmit_lock);
1895-
1907+
out:
18961908
return NETDEV_TX_OK;
18971909
}
18981910

@@ -2220,6 +2232,9 @@ static int ehea_up(struct net_device *dev)
22202232
out_clean_pr:
22212233
ehea_clean_all_portres(port);
22222234
out:
2235+
if (ret)
2236+
ehea_info("Failed starting %s. ret=%i", dev->name, ret);
2237+
22232238
return ret;
22242239
}
22252240

@@ -2259,8 +2274,13 @@ static int ehea_down(struct net_device *dev)
22592274
msleep(1);
22602275

22612276
ehea_broadcast_reg_helper(port, H_DEREG_BCMC);
2262-
ret = ehea_clean_all_portres(port);
22632277
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+
22642284
return ret;
22652285
}
22662286

@@ -2292,15 +2312,11 @@ static void ehea_reset_port(struct work_struct *work)
22922312
netif_stop_queue(dev);
22932313
netif_poll_disable(dev);
22942314

2295-
ret = ehea_down(dev);
2296-
if (ret)
2297-
ehea_error("ehea_down failed. not all resources are freed");
2315+
ehea_down(dev);
22982316

22992317
ret = ehea_up(dev);
2300-
if (ret) {
2301-
ehea_error("Reset device %s failed: ret=%d", dev->name, ret);
2318+
if (ret)
23022319
goto out;
2303-
}
23042320

23052321
if (netif_msg_timer(port))
23062322
ehea_info("Device %s resetted successfully", dev->name);
@@ -2312,6 +2328,88 @@ static void ehea_reset_port(struct work_struct *work)
23122328
return;
23132329
}
23142330

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+
23152413
static void ehea_tx_watchdog(struct net_device *dev)
23162414
{
23172415
struct ehea_port *port = netdev_priv(dev);
@@ -2573,6 +2671,8 @@ struct ehea_port *ehea_setup_single_port(struct ehea_adapter *adapter,
25732671
ehea_info("%s: Jumbo frames are %sabled", dev->name,
25742672
jumbo == 1 ? "en" : "dis");
25752673

2674+
adapter->active_ports++;
2675+
25762676
return port;
25772677

25782678
out_unreg_port:
@@ -2596,6 +2696,7 @@ static void ehea_shutdown_single_port(struct ehea_port *port)
25962696
ehea_unregister_port(port);
25972697
kfree(port->mc_list);
25982698
free_netdev(port->netdev);
2699+
port->adapter->active_ports--;
25992700
}
26002701

26012702
static int ehea_setup_ports(struct ehea_adapter *adapter)
@@ -2788,6 +2889,8 @@ static int __devinit ehea_probe_adapter(struct ibmebus_dev *dev,
27882889
goto out;
27892890
}
27902891

2892+
list_add(&adapter->list, &adapter_list);
2893+
27912894
adapter->ebus_dev = dev;
27922895

27932896
adapter_handle = of_get_property(dev->ofdev.node, "ibm,hea-handle",
@@ -2891,7 +2994,10 @@ static int __devexit ehea_remove(struct ibmebus_dev *dev)
28912994

28922995
ehea_destroy_eq(adapter->neq);
28932996
ehea_remove_adapter_mr(adapter);
2997+
list_del(&adapter->list);
2998+
28942999
kfree(adapter);
3000+
28953001
return 0;
28963002
}
28973003

@@ -2939,9 +3045,18 @@ int __init ehea_module_init(void)
29393045
printk(KERN_INFO "IBM eHEA ethernet device driver (Release %s)\n",
29403046
DRV_VERSION);
29413047

3048+
ehea_driver_wq = create_workqueue("ehea_driver_wq");
3049+
3050+
INIT_WORK(&ehea_rereg_mr_task, ehea_rereg_mrs);
3051+
29423052
ret = check_module_parm();
29433053
if (ret)
29443054
goto out;
3055+
3056+
ret = ehea_create_busmap();
3057+
if (ret)
3058+
goto out;
3059+
29453060
ret = ibmebus_register_driver(&ehea_driver);
29463061
if (ret) {
29473062
ehea_error("failed registering eHEA device driver on ebus");
@@ -2965,6 +3080,7 @@ static void __exit ehea_module_exit(void)
29653080
{
29663081
driver_remove_file(&ehea_driver.driver, &driver_attr_capabilities);
29673082
ibmebus_unregister_driver(&ehea_driver);
3083+
ehea_destroy_busmap();
29683084
}
29693085

29703086
module_init(ehea_module_init);

drivers/net/ehea/ehea_phyp.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,9 @@ static inline u32 get_longbusy_msecs(int long_busy_ret_code)
6060
}
6161
}
6262

63+
/* Number of pages which can be registered at once by H_REGISTER_HEA_RPAGES */
64+
#define EHEA_MAX_RPAGE 512
65+
6366
/* Notification Event Queue (NEQ) Entry bit masks */
6467
#define NEQE_EVENT_CODE EHEA_BMASK_IBM(2, 7)
6568
#define NEQE_PORTNUM EHEA_BMASK_IBM(32, 47)

0 commit comments

Comments
 (0)