diff options
Diffstat (limited to 'drivers/net/ehea')
-rw-r--r-- | drivers/net/ehea/ehea.h | 42 | ||||
-rw-r--r-- | drivers/net/ehea/ehea_ethtool.c | 115 | ||||
-rw-r--r-- | drivers/net/ehea/ehea_main.c | 940 | ||||
-rw-r--r-- | drivers/net/ehea/ehea_phyp.c | 6 | ||||
-rw-r--r-- | drivers/net/ehea/ehea_phyp.h | 6 | ||||
-rw-r--r-- | drivers/net/ehea/ehea_qmr.c | 184 | ||||
-rw-r--r-- | drivers/net/ehea/ehea_qmr.h | 16 |
7 files changed, 816 insertions, 493 deletions
diff --git a/drivers/net/ehea/ehea.h b/drivers/net/ehea/ehea.h index 42295d61ecd8..602872dbe15f 100644 --- a/drivers/net/ehea/ehea.h +++ b/drivers/net/ehea/ehea.h | |||
@@ -39,7 +39,7 @@ | |||
39 | #include <asm/io.h> | 39 | #include <asm/io.h> |
40 | 40 | ||
41 | #define DRV_NAME "ehea" | 41 | #define DRV_NAME "ehea" |
42 | #define DRV_VERSION "EHEA_0046" | 42 | #define DRV_VERSION "EHEA_0058" |
43 | 43 | ||
44 | #define EHEA_MSG_DEFAULT (NETIF_MSG_LINK | NETIF_MSG_TIMER \ | 44 | #define EHEA_MSG_DEFAULT (NETIF_MSG_LINK | NETIF_MSG_TIMER \ |
45 | | NETIF_MSG_RX_ERR | NETIF_MSG_TX_ERR) | 45 | | NETIF_MSG_RX_ERR | NETIF_MSG_TX_ERR) |
@@ -78,10 +78,7 @@ | |||
78 | #define EHEA_RQ2_PKT_SIZE 1522 | 78 | #define EHEA_RQ2_PKT_SIZE 1522 |
79 | #define EHEA_L_PKT_SIZE 256 /* low latency */ | 79 | #define EHEA_L_PKT_SIZE 256 /* low latency */ |
80 | 80 | ||
81 | #define EHEA_POLL_MAX_RWQE 1000 | ||
82 | |||
83 | /* Send completion signaling */ | 81 | /* Send completion signaling */ |
84 | #define EHEA_SIG_IV_LONG 1 | ||
85 | 82 | ||
86 | /* Protection Domain Identifier */ | 83 | /* Protection Domain Identifier */ |
87 | #define EHEA_PD_ID 0xaabcdeff | 84 | #define EHEA_PD_ID 0xaabcdeff |
@@ -108,11 +105,7 @@ | |||
108 | #define EHEA_CACHE_LINE 128 | 105 | #define EHEA_CACHE_LINE 128 |
109 | 106 | ||
110 | /* Memory Regions */ | 107 | /* Memory Regions */ |
111 | #define EHEA_MR_MAX_TX_PAGES 20 | ||
112 | #define EHEA_MR_TX_DATA_PN 3 | ||
113 | #define EHEA_MR_ACC_CTRL 0x00800000 | 108 | #define EHEA_MR_ACC_CTRL 0x00800000 |
114 | #define EHEA_RWQES_PER_MR_RQ2 10 | ||
115 | #define EHEA_RWQES_PER_MR_RQ3 10 | ||
116 | 109 | ||
117 | #define EHEA_WATCH_DOG_TIMEOUT 10*HZ | 110 | #define EHEA_WATCH_DOG_TIMEOUT 10*HZ |
118 | 111 | ||
@@ -311,6 +304,7 @@ struct ehea_cq { | |||
311 | * Memory Region | 304 | * Memory Region |
312 | */ | 305 | */ |
313 | struct ehea_mr { | 306 | struct ehea_mr { |
307 | struct ehea_adapter *adapter; | ||
314 | u64 handle; | 308 | u64 handle; |
315 | u64 vaddr; | 309 | u64 vaddr; |
316 | u32 lkey; | 310 | u32 lkey; |
@@ -319,17 +313,12 @@ struct ehea_mr { | |||
319 | /* | 313 | /* |
320 | * Port state information | 314 | * Port state information |
321 | */ | 315 | */ |
322 | struct port_state { | 316 | struct port_stats { |
323 | int poll_max_processed; | ||
324 | int poll_receive_errors; | 317 | int poll_receive_errors; |
325 | int ehea_poll; | ||
326 | int queue_stopped; | 318 | int queue_stopped; |
327 | int min_swqe_avail; | 319 | int err_tcp_cksum; |
328 | u64 sqc_stop_sum; | 320 | int err_ip_cksum; |
329 | int pkt_send; | 321 | int err_frame_crc; |
330 | int pkt_xmit; | ||
331 | int send_tasklet; | ||
332 | int nwqe; | ||
333 | }; | 322 | }; |
334 | 323 | ||
335 | #define EHEA_IRQ_NAME_SIZE 20 | 324 | #define EHEA_IRQ_NAME_SIZE 20 |
@@ -348,6 +337,7 @@ struct ehea_q_skb_arr { | |||
348 | * Port resources | 337 | * Port resources |
349 | */ | 338 | */ |
350 | struct ehea_port_res { | 339 | struct ehea_port_res { |
340 | struct port_stats p_stats; | ||
351 | struct ehea_mr send_mr; /* send memory region */ | 341 | struct ehea_mr send_mr; /* send memory region */ |
352 | struct ehea_mr recv_mr; /* receive memory region */ | 342 | struct ehea_mr recv_mr; /* receive memory region */ |
353 | spinlock_t xmit_lock; | 343 | spinlock_t xmit_lock; |
@@ -357,9 +347,8 @@ struct ehea_port_res { | |||
357 | struct ehea_qp *qp; | 347 | struct ehea_qp *qp; |
358 | struct ehea_cq *send_cq; | 348 | struct ehea_cq *send_cq; |
359 | struct ehea_cq *recv_cq; | 349 | struct ehea_cq *recv_cq; |
360 | struct ehea_eq *send_eq; | 350 | struct ehea_eq *eq; |
361 | struct ehea_eq *recv_eq; | 351 | struct net_device *d_netdev; |
362 | spinlock_t send_lock; | ||
363 | struct ehea_q_skb_arr rq1_skba; | 352 | struct ehea_q_skb_arr rq1_skba; |
364 | struct ehea_q_skb_arr rq2_skba; | 353 | struct ehea_q_skb_arr rq2_skba; |
365 | struct ehea_q_skb_arr rq3_skba; | 354 | struct ehea_q_skb_arr rq3_skba; |
@@ -369,21 +358,18 @@ struct ehea_port_res { | |||
369 | int swqe_refill_th; | 358 | int swqe_refill_th; |
370 | atomic_t swqe_avail; | 359 | atomic_t swqe_avail; |
371 | int swqe_ll_count; | 360 | int swqe_ll_count; |
372 | int swqe_count; | ||
373 | u32 swqe_id_counter; | 361 | u32 swqe_id_counter; |
374 | u64 tx_packets; | 362 | u64 tx_packets; |
375 | struct tasklet_struct send_comp_task; | ||
376 | spinlock_t recv_lock; | ||
377 | struct port_state p_state; | ||
378 | u64 rx_packets; | 363 | u64 rx_packets; |
379 | u32 poll_counter; | 364 | u32 poll_counter; |
380 | }; | 365 | }; |
381 | 366 | ||
382 | 367 | ||
368 | #define EHEA_MAX_PORTS 16 | ||
383 | struct ehea_adapter { | 369 | struct ehea_adapter { |
384 | u64 handle; | 370 | u64 handle; |
385 | u8 num_ports; | 371 | struct ibmebus_dev *ebus_dev; |
386 | struct ehea_port *port[16]; | 372 | struct ehea_port *port[EHEA_MAX_PORTS]; |
387 | struct ehea_eq *neq; /* notification event queue */ | 373 | struct ehea_eq *neq; /* notification event queue */ |
388 | struct workqueue_struct *ehea_wq; | 374 | struct workqueue_struct *ehea_wq; |
389 | struct tasklet_struct neq_tasklet; | 375 | struct tasklet_struct neq_tasklet; |
@@ -406,7 +392,7 @@ struct ehea_port { | |||
406 | struct net_device *netdev; | 392 | struct net_device *netdev; |
407 | struct net_device_stats stats; | 393 | struct net_device_stats stats; |
408 | struct ehea_port_res port_res[EHEA_MAX_PORT_RES]; | 394 | struct ehea_port_res port_res[EHEA_MAX_PORT_RES]; |
409 | struct device_node *of_dev_node; /* Open Firmware Device Node */ | 395 | struct of_device ofdev; /* Open Firmware Device */ |
410 | struct ehea_mc_list *mc_list; /* Multicast MAC addresses */ | 396 | struct ehea_mc_list *mc_list; /* Multicast MAC addresses */ |
411 | struct vlan_group *vgrp; | 397 | struct vlan_group *vgrp; |
412 | struct ehea_eq *qp_eq; | 398 | struct ehea_eq *qp_eq; |
@@ -415,7 +401,9 @@ struct ehea_port { | |||
415 | char int_aff_name[EHEA_IRQ_NAME_SIZE]; | 401 | char int_aff_name[EHEA_IRQ_NAME_SIZE]; |
416 | int allmulti; /* Indicates IFF_ALLMULTI state */ | 402 | int allmulti; /* Indicates IFF_ALLMULTI state */ |
417 | int promisc; /* Indicates IFF_PROMISC state */ | 403 | int promisc; /* Indicates IFF_PROMISC state */ |
404 | int num_tx_qps; | ||
418 | int num_add_tx_qps; | 405 | int num_add_tx_qps; |
406 | int num_mcs; | ||
419 | int resets; | 407 | int resets; |
420 | u64 mac_addr; | 408 | u64 mac_addr; |
421 | u32 logical_port_id; | 409 | u32 logical_port_id; |
diff --git a/drivers/net/ehea/ehea_ethtool.c b/drivers/net/ehea/ehea_ethtool.c index 9f57c2e78ced..decec8cfe96b 100644 --- a/drivers/net/ehea/ehea_ethtool.c +++ b/drivers/net/ehea/ehea_ethtool.c | |||
@@ -144,8 +144,8 @@ static int ehea_nway_reset(struct net_device *dev) | |||
144 | static void ehea_get_drvinfo(struct net_device *dev, | 144 | static void ehea_get_drvinfo(struct net_device *dev, |
145 | struct ethtool_drvinfo *info) | 145 | struct ethtool_drvinfo *info) |
146 | { | 146 | { |
147 | strlcpy(info->driver, DRV_NAME, sizeof(info->driver) - 1); | 147 | strlcpy(info->driver, DRV_NAME, sizeof(info->driver)); |
148 | strlcpy(info->version, DRV_VERSION, sizeof(info->version) - 1); | 148 | strlcpy(info->version, DRV_VERSION, sizeof(info->version)); |
149 | } | 149 | } |
150 | 150 | ||
151 | static u32 ehea_get_msglevel(struct net_device *dev) | 151 | static u32 ehea_get_msglevel(struct net_device *dev) |
@@ -166,33 +166,23 @@ static u32 ehea_get_rx_csum(struct net_device *dev) | |||
166 | } | 166 | } |
167 | 167 | ||
168 | static char ehea_ethtool_stats_keys[][ETH_GSTRING_LEN] = { | 168 | static char ehea_ethtool_stats_keys[][ETH_GSTRING_LEN] = { |
169 | {"poll_max_processed"}, | ||
170 | {"queue_stopped"}, | ||
171 | {"min_swqe_avail"}, | ||
172 | {"poll_receive_err"}, | ||
173 | {"pkt_send"}, | ||
174 | {"pkt_xmit"}, | ||
175 | {"send_tasklet"}, | ||
176 | {"ehea_poll"}, | ||
177 | {"nwqe"}, | ||
178 | {"swqe_available_0"}, | ||
179 | {"sig_comp_iv"}, | 169 | {"sig_comp_iv"}, |
180 | {"swqe_refill_th"}, | 170 | {"swqe_refill_th"}, |
181 | {"port resets"}, | 171 | {"port resets"}, |
182 | {"rxo"}, | 172 | {"Receive errors"}, |
183 | {"rx64"}, | 173 | {"TCP cksum errors"}, |
184 | {"rx65"}, | 174 | {"IP cksum errors"}, |
185 | {"rx128"}, | 175 | {"Frame cksum errors"}, |
186 | {"rx256"}, | 176 | {"num SQ stopped"}, |
187 | {"rx512"}, | 177 | {"SQ stopped"}, |
188 | {"rx1024"}, | 178 | {"PR0 free_swqes"}, |
189 | {"txo"}, | 179 | {"PR1 free_swqes"}, |
190 | {"tx64"}, | 180 | {"PR2 free_swqes"}, |
191 | {"tx65"}, | 181 | {"PR3 free_swqes"}, |
192 | {"tx128"}, | 182 | {"PR4 free_swqes"}, |
193 | {"tx256"}, | 183 | {"PR5 free_swqes"}, |
194 | {"tx512"}, | 184 | {"PR6 free_swqes"}, |
195 | {"tx1024"}, | 185 | {"PR7 free_swqes"}, |
196 | }; | 186 | }; |
197 | 187 | ||
198 | static void ehea_get_strings(struct net_device *dev, u32 stringset, u8 *data) | 188 | static void ehea_get_strings(struct net_device *dev, u32 stringset, u8 *data) |
@@ -211,63 +201,44 @@ static int ehea_get_stats_count(struct net_device *dev) | |||
211 | static void ehea_get_ethtool_stats(struct net_device *dev, | 201 | static void ehea_get_ethtool_stats(struct net_device *dev, |
212 | struct ethtool_stats *stats, u64 *data) | 202 | struct ethtool_stats *stats, u64 *data) |
213 | { | 203 | { |
214 | u64 hret; | 204 | int i, k, tmp; |
215 | int i; | ||
216 | struct ehea_port *port = netdev_priv(dev); | 205 | struct ehea_port *port = netdev_priv(dev); |
217 | struct ehea_adapter *adapter = port->adapter; | ||
218 | struct ehea_port_res *pr = &port->port_res[0]; | ||
219 | struct port_state *p_state = &pr->p_state; | ||
220 | struct hcp_ehea_port_cb6 *cb6; | ||
221 | 206 | ||
222 | for (i = 0; i < ehea_get_stats_count(dev); i++) | 207 | for (i = 0; i < ehea_get_stats_count(dev); i++) |
223 | data[i] = 0; | 208 | data[i] = 0; |
224 | |||
225 | i = 0; | 209 | i = 0; |
226 | 210 | ||
227 | data[i++] = p_state->poll_max_processed; | ||
228 | data[i++] = p_state->queue_stopped; | ||
229 | data[i++] = p_state->min_swqe_avail; | ||
230 | data[i++] = p_state->poll_receive_errors; | ||
231 | data[i++] = p_state->pkt_send; | ||
232 | data[i++] = p_state->pkt_xmit; | ||
233 | data[i++] = p_state->send_tasklet; | ||
234 | data[i++] = p_state->ehea_poll; | ||
235 | data[i++] = p_state->nwqe; | ||
236 | data[i++] = atomic_read(&port->port_res[0].swqe_avail); | ||
237 | data[i++] = port->sig_comp_iv; | 211 | data[i++] = port->sig_comp_iv; |
238 | data[i++] = port->port_res[0].swqe_refill_th; | 212 | data[i++] = port->port_res[0].swqe_refill_th; |
239 | data[i++] = port->resets; | 213 | data[i++] = port->resets; |
240 | 214 | ||
241 | cb6 = kzalloc(PAGE_SIZE, GFP_KERNEL); | 215 | for (k = 0, tmp = 0; k < EHEA_MAX_PORT_RES; k++) |
242 | if (!cb6) { | 216 | tmp += port->port_res[k].p_stats.poll_receive_errors; |
243 | ehea_error("no mem for cb6"); | 217 | data[i++] = tmp; |
244 | return; | 218 | |
245 | } | 219 | for (k = 0, tmp = 0; k < EHEA_MAX_PORT_RES; k++) |
220 | tmp += port->port_res[k].p_stats.err_tcp_cksum; | ||
221 | data[i++] = tmp; | ||
222 | |||
223 | for (k = 0, tmp = 0; k < EHEA_MAX_PORT_RES; k++) | ||
224 | tmp += port->port_res[k].p_stats.err_ip_cksum; | ||
225 | data[i++] = tmp; | ||
226 | |||
227 | for (k = 0, tmp = 0; k < EHEA_MAX_PORT_RES; k++) | ||
228 | tmp += port->port_res[k].p_stats.err_frame_crc; | ||
229 | data[i++] = tmp; | ||
230 | |||
231 | for (k = 0, tmp = 0; k < EHEA_MAX_PORT_RES; k++) | ||
232 | tmp += port->port_res[k].p_stats.queue_stopped; | ||
233 | data[i++] = tmp; | ||
234 | |||
235 | for (k = 0, tmp = 0; k < EHEA_MAX_PORT_RES; k++) | ||
236 | tmp |= port->port_res[k].queue_stopped; | ||
237 | data[i++] = tmp; | ||
238 | |||
239 | for (k = 0; k < 8; k++) | ||
240 | data[i++] = atomic_read(&port->port_res[k].swqe_avail); | ||
246 | 241 | ||
247 | hret = ehea_h_query_ehea_port(adapter->handle, port->logical_port_id, | ||
248 | H_PORT_CB6, H_PORT_CB6_ALL, cb6); | ||
249 | if (netif_msg_hw(port)) | ||
250 | ehea_dump(cb6, sizeof(*cb6), "ehea_get_ethtool_stats"); | ||
251 | |||
252 | if (hret == H_SUCCESS) { | ||
253 | data[i++] = cb6->rxo; | ||
254 | data[i++] = cb6->rx64; | ||
255 | data[i++] = cb6->rx65; | ||
256 | data[i++] = cb6->rx128; | ||
257 | data[i++] = cb6->rx256; | ||
258 | data[i++] = cb6->rx512; | ||
259 | data[i++] = cb6->rx1024; | ||
260 | data[i++] = cb6->txo; | ||
261 | data[i++] = cb6->tx64; | ||
262 | data[i++] = cb6->tx65; | ||
263 | data[i++] = cb6->tx128; | ||
264 | data[i++] = cb6->tx256; | ||
265 | data[i++] = cb6->tx512; | ||
266 | data[i++] = cb6->tx1024; | ||
267 | } else | ||
268 | ehea_error("query_ehea_port failed"); | ||
269 | |||
270 | kfree(cb6); | ||
271 | } | 242 | } |
272 | 243 | ||
273 | const struct ethtool_ops ehea_ethtool_ops = { | 244 | const struct ethtool_ops ehea_ethtool_ops = { |
diff --git a/drivers/net/ehea/ehea_main.c b/drivers/net/ehea/ehea_main.c index 58364a0ff378..c7a5614e66c0 100644 --- a/drivers/net/ehea/ehea_main.c +++ b/drivers/net/ehea/ehea_main.c | |||
@@ -51,13 +51,18 @@ static int rq1_entries = EHEA_DEF_ENTRIES_RQ1; | |||
51 | static int rq2_entries = EHEA_DEF_ENTRIES_RQ2; | 51 | static int rq2_entries = EHEA_DEF_ENTRIES_RQ2; |
52 | static int rq3_entries = EHEA_DEF_ENTRIES_RQ3; | 52 | static int rq3_entries = EHEA_DEF_ENTRIES_RQ3; |
53 | static int sq_entries = EHEA_DEF_ENTRIES_SQ; | 53 | static int sq_entries = EHEA_DEF_ENTRIES_SQ; |
54 | static int use_mcs = 0; | ||
55 | static int num_tx_qps = EHEA_NUM_TX_QP; | ||
54 | 56 | ||
55 | module_param(msg_level, int, 0); | 57 | module_param(msg_level, int, 0); |
56 | module_param(rq1_entries, int, 0); | 58 | module_param(rq1_entries, int, 0); |
57 | module_param(rq2_entries, int, 0); | 59 | module_param(rq2_entries, int, 0); |
58 | module_param(rq3_entries, int, 0); | 60 | module_param(rq3_entries, int, 0); |
59 | module_param(sq_entries, int, 0); | 61 | module_param(sq_entries, int, 0); |
62 | module_param(use_mcs, int, 0); | ||
63 | module_param(num_tx_qps, int, 0); | ||
60 | 64 | ||
65 | MODULE_PARM_DESC(num_tx_qps, "Number of TX-QPS"); | ||
61 | MODULE_PARM_DESC(msg_level, "msg_level"); | 66 | MODULE_PARM_DESC(msg_level, "msg_level"); |
62 | MODULE_PARM_DESC(rq3_entries, "Number of entries for Receive Queue 3 " | 67 | MODULE_PARM_DESC(rq3_entries, "Number of entries for Receive Queue 3 " |
63 | "[2^x - 1], x = [6..14]. Default = " | 68 | "[2^x - 1], x = [6..14]. Default = " |
@@ -71,6 +76,29 @@ MODULE_PARM_DESC(rq1_entries, "Number of entries for Receive Queue 1 " | |||
71 | MODULE_PARM_DESC(sq_entries, " Number of entries for the Send Queue " | 76 | MODULE_PARM_DESC(sq_entries, " Number of entries for the Send Queue " |
72 | "[2^x - 1], x = [6..14]. Default = " | 77 | "[2^x - 1], x = [6..14]. Default = " |
73 | __MODULE_STRING(EHEA_DEF_ENTRIES_SQ) ")"); | 78 | __MODULE_STRING(EHEA_DEF_ENTRIES_SQ) ")"); |
79 | MODULE_PARM_DESC(use_mcs, " 0:NAPI, 1:Multiple receive queues, Default = 1 "); | ||
80 | |||
81 | static int port_name_cnt = 0; | ||
82 | |||
83 | static int __devinit ehea_probe_adapter(struct ibmebus_dev *dev, | ||
84 | const struct of_device_id *id); | ||
85 | |||
86 | static int __devexit ehea_remove(struct ibmebus_dev *dev); | ||
87 | |||
88 | static struct of_device_id ehea_device_table[] = { | ||
89 | { | ||
90 | .name = "lhea", | ||
91 | .compatible = "IBM,lhea", | ||
92 | }, | ||
93 | {}, | ||
94 | }; | ||
95 | |||
96 | static struct ibmebus_driver ehea_driver = { | ||
97 | .name = "ehea", | ||
98 | .id_table = ehea_device_table, | ||
99 | .probe = ehea_probe_adapter, | ||
100 | .remove = ehea_remove, | ||
101 | }; | ||
74 | 102 | ||
75 | void ehea_dump(void *adr, int len, char *msg) { | 103 | void ehea_dump(void *adr, int len, char *msg) { |
76 | int x; | 104 | int x; |
@@ -197,7 +225,7 @@ static int ehea_refill_rq_def(struct ehea_port_res *pr, | |||
197 | struct sk_buff *skb = netdev_alloc_skb(dev, packet_size); | 225 | struct sk_buff *skb = netdev_alloc_skb(dev, packet_size); |
198 | if (!skb) { | 226 | if (!skb) { |
199 | ehea_error("%s: no mem for skb/%d wqes filled", | 227 | ehea_error("%s: no mem for skb/%d wqes filled", |
200 | dev->name, i); | 228 | pr->port->netdev->name, i); |
201 | q_skba->os_skbs = fill_wqes - i; | 229 | q_skba->os_skbs = fill_wqes - i; |
202 | ret = -ENOMEM; | 230 | ret = -ENOMEM; |
203 | break; | 231 | break; |
@@ -321,6 +349,13 @@ static int ehea_treat_poll_error(struct ehea_port_res *pr, int rq, | |||
321 | { | 349 | { |
322 | struct sk_buff *skb; | 350 | struct sk_buff *skb; |
323 | 351 | ||
352 | if (cqe->status & EHEA_CQE_STAT_ERR_TCP) | ||
353 | pr->p_stats.err_tcp_cksum++; | ||
354 | if (cqe->status & EHEA_CQE_STAT_ERR_IP) | ||
355 | pr->p_stats.err_ip_cksum++; | ||
356 | if (cqe->status & EHEA_CQE_STAT_ERR_CRC) | ||
357 | pr->p_stats.err_frame_crc++; | ||
358 | |||
324 | if (netif_msg_rx_err(pr->port)) { | 359 | if (netif_msg_rx_err(pr->port)) { |
325 | ehea_error("CQE Error for QP %d", pr->qp->init_attr.qp_nr); | 360 | ehea_error("CQE Error for QP %d", pr->qp->init_attr.qp_nr); |
326 | ehea_dump(cqe, sizeof(*cqe), "CQE"); | 361 | ehea_dump(cqe, sizeof(*cqe), "CQE"); |
@@ -345,10 +380,11 @@ static int ehea_treat_poll_error(struct ehea_port_res *pr, int rq, | |||
345 | return 0; | 380 | return 0; |
346 | } | 381 | } |
347 | 382 | ||
348 | static int ehea_poll(struct net_device *dev, int *budget) | 383 | static struct ehea_cqe *ehea_proc_rwqes(struct net_device *dev, |
384 | struct ehea_port_res *pr, | ||
385 | int *budget) | ||
349 | { | 386 | { |
350 | struct ehea_port *port = netdev_priv(dev); | 387 | struct ehea_port *port = pr->port; |
351 | struct ehea_port_res *pr = &port->port_res[0]; | ||
352 | struct ehea_qp *qp = pr->qp; | 388 | struct ehea_qp *qp = pr->qp; |
353 | struct ehea_cqe *cqe; | 389 | struct ehea_cqe *cqe; |
354 | struct sk_buff *skb; | 390 | struct sk_buff *skb; |
@@ -359,14 +395,12 @@ static int ehea_poll(struct net_device *dev, int *budget) | |||
359 | int skb_arr_rq2_len = pr->rq2_skba.len; | 395 | int skb_arr_rq2_len = pr->rq2_skba.len; |
360 | int skb_arr_rq3_len = pr->rq3_skba.len; | 396 | int skb_arr_rq3_len = pr->rq3_skba.len; |
361 | int processed, processed_rq1, processed_rq2, processed_rq3; | 397 | int processed, processed_rq1, processed_rq2, processed_rq3; |
362 | int wqe_index, last_wqe_index, rq, intreq, my_quota, port_reset; | 398 | int wqe_index, last_wqe_index, rq, my_quota, port_reset; |
363 | 399 | ||
364 | processed = processed_rq1 = processed_rq2 = processed_rq3 = 0; | 400 | processed = processed_rq1 = processed_rq2 = processed_rq3 = 0; |
365 | last_wqe_index = 0; | 401 | last_wqe_index = 0; |
366 | my_quota = min(*budget, dev->quota); | 402 | my_quota = min(*budget, dev->quota); |
367 | my_quota = min(my_quota, EHEA_POLL_MAX_RWQE); | ||
368 | 403 | ||
369 | /* rq0 is low latency RQ */ | ||
370 | cqe = ehea_poll_rq1(qp, &wqe_index); | 404 | cqe = ehea_poll_rq1(qp, &wqe_index); |
371 | while ((my_quota > 0) && cqe) { | 405 | while ((my_quota > 0) && cqe) { |
372 | ehea_inc_rq1(qp); | 406 | ehea_inc_rq1(qp); |
@@ -386,7 +420,8 @@ static int ehea_poll(struct net_device *dev, int *budget) | |||
386 | if (unlikely(!skb)) { | 420 | if (unlikely(!skb)) { |
387 | if (netif_msg_rx_err(port)) | 421 | if (netif_msg_rx_err(port)) |
388 | ehea_error("LL rq1: skb=NULL"); | 422 | ehea_error("LL rq1: skb=NULL"); |
389 | skb = netdev_alloc_skb(dev, | 423 | |
424 | skb = netdev_alloc_skb(port->netdev, | ||
390 | EHEA_L_PKT_SIZE); | 425 | EHEA_L_PKT_SIZE); |
391 | if (!skb) | 426 | if (!skb) |
392 | break; | 427 | break; |
@@ -402,7 +437,7 @@ static int ehea_poll(struct net_device *dev, int *budget) | |||
402 | ehea_error("rq2: skb=NULL"); | 437 | ehea_error("rq2: skb=NULL"); |
403 | break; | 438 | break; |
404 | } | 439 | } |
405 | ehea_fill_skb(dev, skb, cqe); | 440 | ehea_fill_skb(port->netdev, skb, cqe); |
406 | processed_rq2++; | 441 | processed_rq2++; |
407 | } else { /* RQ3 */ | 442 | } else { /* RQ3 */ |
408 | skb = get_skb_by_index(skb_arr_rq3, | 443 | skb = get_skb_by_index(skb_arr_rq3, |
@@ -412,7 +447,7 @@ static int ehea_poll(struct net_device *dev, int *budget) | |||
412 | ehea_error("rq3: skb=NULL"); | 447 | ehea_error("rq3: skb=NULL"); |
413 | break; | 448 | break; |
414 | } | 449 | } |
415 | ehea_fill_skb(dev, skb, cqe); | 450 | ehea_fill_skb(port->netdev, skb, cqe); |
416 | processed_rq3++; | 451 | processed_rq3++; |
417 | } | 452 | } |
418 | 453 | ||
@@ -421,9 +456,8 @@ static int ehea_poll(struct net_device *dev, int *budget) | |||
421 | cqe->vlan_tag); | 456 | cqe->vlan_tag); |
422 | else | 457 | else |
423 | netif_receive_skb(skb); | 458 | netif_receive_skb(skb); |
424 | 459 | } else { | |
425 | } else { /* Error occured */ | 460 | pr->p_stats.poll_receive_errors++; |
426 | pr->p_state.poll_receive_errors++; | ||
427 | port_reset = ehea_treat_poll_error(pr, rq, cqe, | 461 | port_reset = ehea_treat_poll_error(pr, rq, cqe, |
428 | &processed_rq2, | 462 | &processed_rq2, |
429 | &processed_rq3); | 463 | &processed_rq3); |
@@ -433,72 +467,32 @@ static int ehea_poll(struct net_device *dev, int *budget) | |||
433 | cqe = ehea_poll_rq1(qp, &wqe_index); | 467 | cqe = ehea_poll_rq1(qp, &wqe_index); |
434 | } | 468 | } |
435 | 469 | ||
436 | dev->quota -= processed; | ||
437 | *budget -= processed; | ||
438 | |||
439 | pr->p_state.ehea_poll += 1; | ||
440 | pr->rx_packets += processed; | 470 | pr->rx_packets += processed; |
471 | *budget -= processed; | ||
441 | 472 | ||
442 | ehea_refill_rq1(pr, last_wqe_index, processed_rq1); | 473 | ehea_refill_rq1(pr, last_wqe_index, processed_rq1); |
443 | ehea_refill_rq2(pr, processed_rq2); | 474 | ehea_refill_rq2(pr, processed_rq2); |
444 | ehea_refill_rq3(pr, processed_rq3); | 475 | ehea_refill_rq3(pr, processed_rq3); |
445 | 476 | ||
446 | intreq = ((pr->p_state.ehea_poll & 0xF) == 0xF); | 477 | cqe = ehea_poll_rq1(qp, &wqe_index); |
447 | 478 | return cqe; | |
448 | if (!cqe || intreq) { | ||
449 | netif_rx_complete(dev); | ||
450 | ehea_reset_cq_ep(pr->recv_cq); | ||
451 | ehea_reset_cq_n1(pr->recv_cq); | ||
452 | cqe = hw_qeit_get_valid(&qp->hw_rqueue1); | ||
453 | if (!cqe || intreq) | ||
454 | return 0; | ||
455 | if (!netif_rx_reschedule(dev, my_quota)) | ||
456 | return 0; | ||
457 | } | ||
458 | return 1; | ||
459 | } | 479 | } |
460 | 480 | ||
461 | void free_sent_skbs(struct ehea_cqe *cqe, struct ehea_port_res *pr) | 481 | static struct ehea_cqe *ehea_proc_cqes(struct ehea_port_res *pr, int my_quota) |
462 | { | 482 | { |
463 | struct sk_buff *skb; | 483 | struct sk_buff *skb; |
464 | int index, max_index_mask, i; | ||
465 | |||
466 | index = EHEA_BMASK_GET(EHEA_WR_ID_INDEX, cqe->wr_id); | ||
467 | max_index_mask = pr->sq_skba.len - 1; | ||
468 | for (i = 0; i < EHEA_BMASK_GET(EHEA_WR_ID_REFILL, cqe->wr_id); i++) { | ||
469 | skb = pr->sq_skba.arr[index]; | ||
470 | if (likely(skb)) { | ||
471 | dev_kfree_skb(skb); | ||
472 | pr->sq_skba.arr[index] = NULL; | ||
473 | } else { | ||
474 | ehea_error("skb=NULL, wr_id=%lX, loop=%d, index=%d", | ||
475 | cqe->wr_id, i, index); | ||
476 | } | ||
477 | index--; | ||
478 | index &= max_index_mask; | ||
479 | } | ||
480 | } | ||
481 | |||
482 | #define MAX_SENDCOMP_QUOTA 400 | ||
483 | void ehea_send_irq_tasklet(unsigned long data) | ||
484 | { | ||
485 | struct ehea_port_res *pr = (struct ehea_port_res*)data; | ||
486 | struct ehea_cq *send_cq = pr->send_cq; | 484 | struct ehea_cq *send_cq = pr->send_cq; |
487 | struct ehea_cqe *cqe; | 485 | struct ehea_cqe *cqe; |
488 | int quota = MAX_SENDCOMP_QUOTA; | 486 | int quota = my_quota; |
489 | int cqe_counter = 0; | 487 | int cqe_counter = 0; |
490 | int swqe_av = 0; | 488 | int swqe_av = 0; |
489 | int index; | ||
491 | unsigned long flags; | 490 | unsigned long flags; |
492 | 491 | ||
493 | do { | 492 | cqe = ehea_poll_cq(send_cq); |
494 | cqe = ehea_poll_cq(send_cq); | 493 | while(cqe && (quota > 0)) { |
495 | if (!cqe) { | 494 | ehea_inc_cq(send_cq); |
496 | ehea_reset_cq_ep(send_cq); | 495 | |
497 | ehea_reset_cq_n1(send_cq); | ||
498 | cqe = ehea_poll_cq(send_cq); | ||
499 | if (!cqe) | ||
500 | break; | ||
501 | } | ||
502 | cqe_counter++; | 496 | cqe_counter++; |
503 | rmb(); | 497 | rmb(); |
504 | if (cqe->status & EHEA_CQE_STAT_ERR_MASK) { | 498 | if (cqe->status & EHEA_CQE_STAT_ERR_MASK) { |
@@ -514,17 +508,25 @@ void ehea_send_irq_tasklet(unsigned long data) | |||
514 | ehea_dump(cqe, sizeof(*cqe), "CQE"); | 508 | ehea_dump(cqe, sizeof(*cqe), "CQE"); |
515 | 509 | ||
516 | if (likely(EHEA_BMASK_GET(EHEA_WR_ID_TYPE, cqe->wr_id) | 510 | if (likely(EHEA_BMASK_GET(EHEA_WR_ID_TYPE, cqe->wr_id) |
517 | == EHEA_SWQE2_TYPE)) | 511 | == EHEA_SWQE2_TYPE)) { |
518 | free_sent_skbs(cqe, pr); | 512 | |
513 | index = EHEA_BMASK_GET(EHEA_WR_ID_INDEX, cqe->wr_id); | ||
514 | skb = pr->sq_skba.arr[index]; | ||
515 | dev_kfree_skb(skb); | ||
516 | pr->sq_skba.arr[index] = NULL; | ||
517 | } | ||
519 | 518 | ||
520 | swqe_av += EHEA_BMASK_GET(EHEA_WR_ID_REFILL, cqe->wr_id); | 519 | swqe_av += EHEA_BMASK_GET(EHEA_WR_ID_REFILL, cqe->wr_id); |
521 | quota--; | 520 | quota--; |
522 | } while (quota > 0); | 521 | |
522 | cqe = ehea_poll_cq(send_cq); | ||
523 | }; | ||
523 | 524 | ||
524 | ehea_update_feca(send_cq, cqe_counter); | 525 | ehea_update_feca(send_cq, cqe_counter); |
525 | atomic_add(swqe_av, &pr->swqe_avail); | 526 | atomic_add(swqe_av, &pr->swqe_avail); |
526 | 527 | ||
527 | spin_lock_irqsave(&pr->netif_queue, flags); | 528 | spin_lock_irqsave(&pr->netif_queue, flags); |
529 | |||
528 | if (pr->queue_stopped && (atomic_read(&pr->swqe_avail) | 530 | if (pr->queue_stopped && (atomic_read(&pr->swqe_avail) |
529 | >= pr->swqe_refill_th)) { | 531 | >= pr->swqe_refill_th)) { |
530 | netif_wake_queue(pr->port->netdev); | 532 | netif_wake_queue(pr->port->netdev); |
@@ -532,22 +534,55 @@ void ehea_send_irq_tasklet(unsigned long data) | |||
532 | } | 534 | } |
533 | spin_unlock_irqrestore(&pr->netif_queue, flags); | 535 | spin_unlock_irqrestore(&pr->netif_queue, flags); |
534 | 536 | ||
535 | if (unlikely(cqe)) | 537 | return cqe; |
536 | tasklet_hi_schedule(&pr->send_comp_task); | ||
537 | } | 538 | } |
538 | 539 | ||
539 | static irqreturn_t ehea_send_irq_handler(int irq, void *param) | 540 | #define EHEA_NAPI_POLL_NUM_BEFORE_IRQ 16 |
541 | |||
542 | static int ehea_poll(struct net_device *dev, int *budget) | ||
540 | { | 543 | { |
541 | struct ehea_port_res *pr = param; | 544 | struct ehea_port_res *pr = dev->priv; |
542 | tasklet_hi_schedule(&pr->send_comp_task); | 545 | struct ehea_cqe *cqe; |
543 | return IRQ_HANDLED; | 546 | struct ehea_cqe *cqe_skb = NULL; |
547 | int force_irq, wqe_index; | ||
548 | |||
549 | cqe = ehea_poll_rq1(pr->qp, &wqe_index); | ||
550 | cqe_skb = ehea_poll_cq(pr->send_cq); | ||
551 | |||
552 | force_irq = (pr->poll_counter > EHEA_NAPI_POLL_NUM_BEFORE_IRQ); | ||
553 | |||
554 | if ((!cqe && !cqe_skb) || force_irq) { | ||
555 | pr->poll_counter = 0; | ||
556 | netif_rx_complete(dev); | ||
557 | ehea_reset_cq_ep(pr->recv_cq); | ||
558 | ehea_reset_cq_ep(pr->send_cq); | ||
559 | ehea_reset_cq_n1(pr->recv_cq); | ||
560 | ehea_reset_cq_n1(pr->send_cq); | ||
561 | cqe = ehea_poll_rq1(pr->qp, &wqe_index); | ||
562 | cqe_skb = ehea_poll_cq(pr->send_cq); | ||
563 | |||
564 | if (!cqe && !cqe_skb) | ||
565 | return 0; | ||
566 | |||
567 | if (!netif_rx_reschedule(dev, dev->quota)) | ||
568 | return 0; | ||
569 | } | ||
570 | |||
571 | cqe = ehea_proc_rwqes(dev, pr, budget); | ||
572 | cqe_skb = ehea_proc_cqes(pr, 300); | ||
573 | |||
574 | if (cqe || cqe_skb) | ||
575 | pr->poll_counter++; | ||
576 | |||
577 | return 1; | ||
544 | } | 578 | } |
545 | 579 | ||
546 | static irqreturn_t ehea_recv_irq_handler(int irq, void *param) | 580 | static irqreturn_t ehea_recv_irq_handler(int irq, void *param) |
547 | { | 581 | { |
548 | struct ehea_port_res *pr = param; | 582 | struct ehea_port_res *pr = param; |
549 | struct ehea_port *port = pr->port; | 583 | |
550 | netif_rx_schedule(port->netdev); | 584 | netif_rx_schedule(pr->d_netdev); |
585 | |||
551 | return IRQ_HANDLED; | 586 | return IRQ_HANDLED; |
552 | } | 587 | } |
553 | 588 | ||
@@ -580,7 +615,7 @@ static struct ehea_port *ehea_get_port(struct ehea_adapter *adapter, | |||
580 | { | 615 | { |
581 | int i; | 616 | int i; |
582 | 617 | ||
583 | for (i = 0; i < adapter->num_ports; i++) | 618 | for (i = 0; i < EHEA_MAX_PORTS; i++) |
584 | if (adapter->port[i]) | 619 | if (adapter->port[i]) |
585 | if (adapter->port[i]->logical_port_id == logical_port) | 620 | if (adapter->port[i]->logical_port_id == logical_port) |
586 | return adapter->port[i]; | 621 | return adapter->port[i]; |
@@ -650,19 +685,25 @@ int ehea_sense_port_attr(struct ehea_port *port) | |||
650 | } | 685 | } |
651 | 686 | ||
652 | port->autoneg = 1; | 687 | port->autoneg = 1; |
688 | port->num_mcs = cb0->num_default_qps; | ||
653 | 689 | ||
654 | /* Number of default QPs */ | 690 | /* Number of default QPs */ |
655 | port->num_def_qps = cb0->num_default_qps; | 691 | if (use_mcs) |
692 | port->num_def_qps = cb0->num_default_qps; | ||
693 | else | ||
694 | port->num_def_qps = 1; | ||
656 | 695 | ||
657 | if (!port->num_def_qps) { | 696 | if (!port->num_def_qps) { |
658 | ret = -EINVAL; | 697 | ret = -EINVAL; |
659 | goto out_free; | 698 | goto out_free; |
660 | } | 699 | } |
661 | 700 | ||
662 | if (port->num_def_qps >= EHEA_NUM_TX_QP) | 701 | port->num_tx_qps = num_tx_qps; |
702 | |||
703 | if (port->num_def_qps >= port->num_tx_qps) | ||
663 | port->num_add_tx_qps = 0; | 704 | port->num_add_tx_qps = 0; |
664 | else | 705 | else |
665 | port->num_add_tx_qps = EHEA_NUM_TX_QP - port->num_def_qps; | 706 | port->num_add_tx_qps = port->num_tx_qps - port->num_def_qps; |
666 | 707 | ||
667 | ret = 0; | 708 | ret = 0; |
668 | out_free: | 709 | out_free: |
@@ -882,23 +923,6 @@ static int ehea_reg_interrupts(struct net_device *dev) | |||
882 | struct ehea_port_res *pr; | 923 | struct ehea_port_res *pr; |
883 | int i, ret; | 924 | int i, ret; |
884 | 925 | ||
885 | for (i = 0; i < port->num_def_qps; i++) { | ||
886 | pr = &port->port_res[i]; | ||
887 | snprintf(pr->int_recv_name, EHEA_IRQ_NAME_SIZE - 1 | ||
888 | , "%s-recv%d", dev->name, i); | ||
889 | ret = ibmebus_request_irq(NULL, pr->recv_eq->attr.ist1, | ||
890 | ehea_recv_irq_handler, | ||
891 | IRQF_DISABLED, pr->int_recv_name, pr); | ||
892 | if (ret) { | ||
893 | ehea_error("failed registering irq for ehea_recv_int:" | ||
894 | "port_res_nr:%d, ist=%X", i, | ||
895 | pr->recv_eq->attr.ist1); | ||
896 | goto out_free_seq; | ||
897 | } | ||
898 | if (netif_msg_ifup(port)) | ||
899 | ehea_info("irq_handle 0x%X for funct ehea_recv_int %d " | ||
900 | "registered", pr->recv_eq->attr.ist1, i); | ||
901 | } | ||
902 | 926 | ||
903 | snprintf(port->int_aff_name, EHEA_IRQ_NAME_SIZE - 1, "%s-aff", | 927 | snprintf(port->int_aff_name, EHEA_IRQ_NAME_SIZE - 1, "%s-aff", |
904 | dev->name); | 928 | dev->name); |
@@ -916,41 +940,41 @@ static int ehea_reg_interrupts(struct net_device *dev) | |||
916 | ehea_info("irq_handle 0x%X for function qp_aff_irq_handler " | 940 | ehea_info("irq_handle 0x%X for function qp_aff_irq_handler " |
917 | "registered", port->qp_eq->attr.ist1); | 941 | "registered", port->qp_eq->attr.ist1); |
918 | 942 | ||
943 | |||
919 | for (i = 0; i < port->num_def_qps + port->num_add_tx_qps; i++) { | 944 | for (i = 0; i < port->num_def_qps + port->num_add_tx_qps; i++) { |
920 | pr = &port->port_res[i]; | 945 | pr = &port->port_res[i]; |
921 | snprintf(pr->int_send_name, EHEA_IRQ_NAME_SIZE - 1, | 946 | snprintf(pr->int_send_name, EHEA_IRQ_NAME_SIZE - 1, |
922 | "%s-send%d", dev->name, i); | 947 | "%s-queue%d", dev->name, i); |
923 | ret = ibmebus_request_irq(NULL, pr->send_eq->attr.ist1, | 948 | ret = ibmebus_request_irq(NULL, pr->eq->attr.ist1, |
924 | ehea_send_irq_handler, | 949 | ehea_recv_irq_handler, |
925 | IRQF_DISABLED, pr->int_send_name, | 950 | IRQF_DISABLED, pr->int_send_name, |
926 | pr); | 951 | pr); |
927 | if (ret) { | 952 | if (ret) { |
928 | ehea_error("failed registering irq for ehea_send " | 953 | ehea_error("failed registering irq for ehea_queue " |
929 | "port_res_nr:%d, ist=%X", i, | 954 | "port_res_nr:%d, ist=%X", i, |
930 | pr->send_eq->attr.ist1); | 955 | pr->eq->attr.ist1); |
931 | goto out_free_req; | 956 | goto out_free_req; |
932 | } | 957 | } |
933 | if (netif_msg_ifup(port)) | 958 | if (netif_msg_ifup(port)) |
934 | ehea_info("irq_handle 0x%X for function ehea_send_int " | 959 | ehea_info("irq_handle 0x%X for function ehea_queue_int " |
935 | "%d registered", pr->send_eq->attr.ist1, i); | 960 | "%d registered", pr->eq->attr.ist1, i); |
936 | } | 961 | } |
937 | out: | 962 | out: |
938 | return ret; | 963 | return ret; |
939 | 964 | ||
965 | |||
940 | out_free_req: | 966 | out_free_req: |
941 | while (--i >= 0) { | 967 | while (--i >= 0) { |
942 | u32 ist = port->port_res[i].send_eq->attr.ist1; | 968 | u32 ist = port->port_res[i].eq->attr.ist1; |
943 | ibmebus_free_irq(NULL, ist, &port->port_res[i]); | 969 | ibmebus_free_irq(NULL, ist, &port->port_res[i]); |
944 | } | 970 | } |
971 | |||
945 | out_free_qpeq: | 972 | out_free_qpeq: |
946 | ibmebus_free_irq(NULL, port->qp_eq->attr.ist1, port); | 973 | ibmebus_free_irq(NULL, port->qp_eq->attr.ist1, port); |
947 | i = port->num_def_qps; | 974 | i = port->num_def_qps; |
948 | out_free_seq: | 975 | |
949 | while (--i >= 0) { | ||
950 | u32 ist = port->port_res[i].recv_eq->attr.ist1; | ||
951 | ibmebus_free_irq(NULL, ist, &port->port_res[i]); | ||
952 | } | ||
953 | goto out; | 976 | goto out; |
977 | |||
954 | } | 978 | } |
955 | 979 | ||
956 | static void ehea_free_interrupts(struct net_device *dev) | 980 | static void ehea_free_interrupts(struct net_device *dev) |
@@ -960,21 +984,13 @@ static void ehea_free_interrupts(struct net_device *dev) | |||
960 | int i; | 984 | int i; |
961 | 985 | ||
962 | /* send */ | 986 | /* send */ |
987 | |||
963 | for (i = 0; i < port->num_def_qps + port->num_add_tx_qps; i++) { | 988 | for (i = 0; i < port->num_def_qps + port->num_add_tx_qps; i++) { |
964 | pr = &port->port_res[i]; | 989 | pr = &port->port_res[i]; |
965 | ibmebus_free_irq(NULL, pr->send_eq->attr.ist1, pr); | 990 | ibmebus_free_irq(NULL, pr->eq->attr.ist1, pr); |
966 | if (netif_msg_intr(port)) | 991 | if (netif_msg_intr(port)) |
967 | ehea_info("free send irq for res %d with handle 0x%X", | 992 | ehea_info("free send irq for res %d with handle 0x%X", |
968 | i, pr->send_eq->attr.ist1); | 993 | i, pr->eq->attr.ist1); |
969 | } | ||
970 | |||
971 | /* receive */ | ||
972 | for (i = 0; i < port->num_def_qps; i++) { | ||
973 | pr = &port->port_res[i]; | ||
974 | ibmebus_free_irq(NULL, pr->recv_eq->attr.ist1, pr); | ||
975 | if (netif_msg_intr(port)) | ||
976 | ehea_info("free recv irq for res %d with handle 0x%X", | ||
977 | i, pr->recv_eq->attr.ist1); | ||
978 | } | 994 | } |
979 | 995 | ||
980 | /* associated events */ | 996 | /* associated events */ |
@@ -1003,8 +1019,13 @@ static int ehea_configure_port(struct ehea_port *port) | |||
1003 | PXLY_RC_VLAN_FILTER) | 1019 | PXLY_RC_VLAN_FILTER) |
1004 | | EHEA_BMASK_SET(PXLY_RC_JUMBO_FRAME, 1); | 1020 | | EHEA_BMASK_SET(PXLY_RC_JUMBO_FRAME, 1); |
1005 | 1021 | ||
1006 | for (i = 0; i < port->num_def_qps; i++) | 1022 | for (i = 0; i < port->num_mcs; i++) |
1007 | cb0->default_qpn_arr[i] = port->port_res[0].qp->init_attr.qp_nr; | 1023 | if (use_mcs) |
1024 | cb0->default_qpn_arr[i] = | ||
1025 | port->port_res[i].qp->init_attr.qp_nr; | ||
1026 | else | ||
1027 | cb0->default_qpn_arr[i] = | ||
1028 | port->port_res[0].qp->init_attr.qp_nr; | ||
1008 | 1029 | ||
1009 | if (netif_msg_ifup(port)) | 1030 | if (netif_msg_ifup(port)) |
1010 | ehea_dump(cb0, sizeof(*cb0), "ehea_configure_port"); | 1031 | ehea_dump(cb0, sizeof(*cb0), "ehea_configure_port"); |
@@ -1027,52 +1048,35 @@ out: | |||
1027 | return ret; | 1048 | return ret; |
1028 | } | 1049 | } |
1029 | 1050 | ||
1030 | static int ehea_gen_smrs(struct ehea_port_res *pr) | 1051 | int ehea_gen_smrs(struct ehea_port_res *pr) |
1031 | { | 1052 | { |
1032 | u64 hret; | 1053 | int ret; |
1033 | struct ehea_adapter *adapter = pr->port->adapter; | 1054 | struct ehea_adapter *adapter = pr->port->adapter; |
1034 | 1055 | ||
1035 | hret = ehea_h_register_smr(adapter->handle, adapter->mr.handle, | 1056 | ret = ehea_gen_smr(adapter, &adapter->mr, &pr->send_mr); |
1036 | adapter->mr.vaddr, EHEA_MR_ACC_CTRL, | 1057 | if (ret) |
1037 | adapter->pd, &pr->send_mr); | ||
1038 | if (hret != H_SUCCESS) | ||
1039 | goto out; | 1058 | goto out; |
1040 | 1059 | ||
1041 | hret = ehea_h_register_smr(adapter->handle, adapter->mr.handle, | 1060 | ret = ehea_gen_smr(adapter, &adapter->mr, &pr->recv_mr); |
1042 | adapter->mr.vaddr, EHEA_MR_ACC_CTRL, | 1061 | if (ret) |
1043 | adapter->pd, &pr->recv_mr); | 1062 | goto out_free; |
1044 | if (hret != H_SUCCESS) | ||
1045 | goto out_freeres; | ||
1046 | 1063 | ||
1047 | return 0; | 1064 | return 0; |
1048 | 1065 | ||
1049 | out_freeres: | 1066 | out_free: |
1050 | hret = ehea_h_free_resource(adapter->handle, pr->send_mr.handle); | 1067 | ehea_rem_mr(&pr->send_mr); |
1051 | if (hret != H_SUCCESS) | ||
1052 | ehea_error("failed freeing SMR"); | ||
1053 | out: | 1068 | out: |
1069 | ehea_error("Generating SMRS failed\n"); | ||
1054 | return -EIO; | 1070 | return -EIO; |
1055 | } | 1071 | } |
1056 | 1072 | ||
1057 | static int ehea_rem_smrs(struct ehea_port_res *pr) | 1073 | int ehea_rem_smrs(struct ehea_port_res *pr) |
1058 | { | 1074 | { |
1059 | struct ehea_adapter *adapter = pr->port->adapter; | 1075 | if ((ehea_rem_mr(&pr->send_mr)) |
1060 | int ret = 0; | 1076 | || (ehea_rem_mr(&pr->recv_mr))) |
1061 | u64 hret; | 1077 | return -EIO; |
1062 | 1078 | else | |
1063 | hret = ehea_h_free_resource(adapter->handle, pr->send_mr.handle); | 1079 | return 0; |
1064 | if (hret != H_SUCCESS) { | ||
1065 | ret = -EIO; | ||
1066 | ehea_error("failed freeing send SMR for pr=%p", pr); | ||
1067 | } | ||
1068 | |||
1069 | hret = ehea_h_free_resource(adapter->handle, pr->recv_mr.handle); | ||
1070 | if (hret != H_SUCCESS) { | ||
1071 | ret = -EIO; | ||
1072 | ehea_error("failed freeing recv SMR for pr=%p", pr); | ||
1073 | } | ||
1074 | |||
1075 | return ret; | ||
1076 | } | 1080 | } |
1077 | 1081 | ||
1078 | static int ehea_init_q_skba(struct ehea_q_skb_arr *q_skba, int max_q_entries) | 1082 | static int ehea_init_q_skba(struct ehea_q_skb_arr *q_skba, int max_q_entries) |
@@ -1103,25 +1107,17 @@ static int ehea_init_port_res(struct ehea_port *port, struct ehea_port_res *pr, | |||
1103 | memset(pr, 0, sizeof(struct ehea_port_res)); | 1107 | memset(pr, 0, sizeof(struct ehea_port_res)); |
1104 | 1108 | ||
1105 | pr->port = port; | 1109 | pr->port = port; |
1106 | spin_lock_init(&pr->send_lock); | ||
1107 | spin_lock_init(&pr->recv_lock); | ||
1108 | spin_lock_init(&pr->xmit_lock); | 1110 | spin_lock_init(&pr->xmit_lock); |
1109 | spin_lock_init(&pr->netif_queue); | 1111 | spin_lock_init(&pr->netif_queue); |
1110 | 1112 | ||
1111 | pr->recv_eq = ehea_create_eq(adapter, eq_type, EHEA_MAX_ENTRIES_EQ, 0); | 1113 | pr->eq = ehea_create_eq(adapter, eq_type, EHEA_MAX_ENTRIES_EQ, 0); |
1112 | if (!pr->recv_eq) { | 1114 | if (!pr->eq) { |
1113 | ehea_error("create_eq failed (recv_eq)"); | 1115 | ehea_error("create_eq failed (eq)"); |
1114 | goto out_free; | ||
1115 | } | ||
1116 | |||
1117 | pr->send_eq = ehea_create_eq(adapter, eq_type, EHEA_MAX_ENTRIES_EQ, 0); | ||
1118 | if (!pr->send_eq) { | ||
1119 | ehea_error("create_eq failed (send_eq)"); | ||
1120 | goto out_free; | 1116 | goto out_free; |
1121 | } | 1117 | } |
1122 | 1118 | ||
1123 | pr->recv_cq = ehea_create_cq(adapter, pr_cfg->max_entries_rcq, | 1119 | pr->recv_cq = ehea_create_cq(adapter, pr_cfg->max_entries_rcq, |
1124 | pr->recv_eq->fw_handle, | 1120 | pr->eq->fw_handle, |
1125 | port->logical_port_id); | 1121 | port->logical_port_id); |
1126 | if (!pr->recv_cq) { | 1122 | if (!pr->recv_cq) { |
1127 | ehea_error("create_cq failed (cq_recv)"); | 1123 | ehea_error("create_cq failed (cq_recv)"); |
@@ -1129,7 +1125,7 @@ static int ehea_init_port_res(struct ehea_port *port, struct ehea_port_res *pr, | |||
1129 | } | 1125 | } |
1130 | 1126 | ||
1131 | pr->send_cq = ehea_create_cq(adapter, pr_cfg->max_entries_scq, | 1127 | pr->send_cq = ehea_create_cq(adapter, pr_cfg->max_entries_scq, |
1132 | pr->send_eq->fw_handle, | 1128 | pr->eq->fw_handle, |
1133 | port->logical_port_id); | 1129 | port->logical_port_id); |
1134 | if (!pr->send_cq) { | 1130 | if (!pr->send_cq) { |
1135 | ehea_error("create_cq failed (cq_send)"); | 1131 | ehea_error("create_cq failed (cq_send)"); |
@@ -1194,11 +1190,20 @@ static int ehea_init_port_res(struct ehea_port *port, struct ehea_port_res *pr, | |||
1194 | ret = -EIO; | 1190 | ret = -EIO; |
1195 | goto out_free; | 1191 | goto out_free; |
1196 | } | 1192 | } |
1197 | tasklet_init(&pr->send_comp_task, ehea_send_irq_tasklet, | 1193 | |
1198 | (unsigned long)pr); | ||
1199 | atomic_set(&pr->swqe_avail, init_attr->act_nr_send_wqes - 1); | 1194 | atomic_set(&pr->swqe_avail, init_attr->act_nr_send_wqes - 1); |
1200 | 1195 | ||
1201 | kfree(init_attr); | 1196 | kfree(init_attr); |
1197 | |||
1198 | pr->d_netdev = alloc_netdev(0, "", ether_setup); | ||
1199 | if (!pr->d_netdev) | ||
1200 | goto out_free; | ||
1201 | pr->d_netdev->priv = pr; | ||
1202 | pr->d_netdev->weight = 64; | ||
1203 | pr->d_netdev->poll = ehea_poll; | ||
1204 | set_bit(__LINK_STATE_START, &pr->d_netdev->state); | ||
1205 | strcpy(pr->d_netdev->name, port->netdev->name); | ||
1206 | |||
1202 | ret = 0; | 1207 | ret = 0; |
1203 | goto out; | 1208 | goto out; |
1204 | 1209 | ||
@@ -1211,8 +1216,7 @@ out_free: | |||
1211 | ehea_destroy_qp(pr->qp); | 1216 | ehea_destroy_qp(pr->qp); |
1212 | ehea_destroy_cq(pr->send_cq); | 1217 | ehea_destroy_cq(pr->send_cq); |
1213 | ehea_destroy_cq(pr->recv_cq); | 1218 | ehea_destroy_cq(pr->recv_cq); |
1214 | ehea_destroy_eq(pr->send_eq); | 1219 | ehea_destroy_eq(pr->eq); |
1215 | ehea_destroy_eq(pr->recv_eq); | ||
1216 | out: | 1220 | out: |
1217 | return ret; | 1221 | return ret; |
1218 | } | 1222 | } |
@@ -1221,13 +1225,14 @@ static int ehea_clean_portres(struct ehea_port *port, struct ehea_port_res *pr) | |||
1221 | { | 1225 | { |
1222 | int ret, i; | 1226 | int ret, i; |
1223 | 1227 | ||
1228 | free_netdev(pr->d_netdev); | ||
1229 | |||
1224 | ret = ehea_destroy_qp(pr->qp); | 1230 | ret = ehea_destroy_qp(pr->qp); |
1225 | 1231 | ||
1226 | if (!ret) { | 1232 | if (!ret) { |
1227 | ehea_destroy_cq(pr->send_cq); | 1233 | ehea_destroy_cq(pr->send_cq); |
1228 | ehea_destroy_cq(pr->recv_cq); | 1234 | ehea_destroy_cq(pr->recv_cq); |
1229 | ehea_destroy_eq(pr->send_eq); | 1235 | ehea_destroy_eq(pr->eq); |
1230 | ehea_destroy_eq(pr->recv_eq); | ||
1231 | 1236 | ||
1232 | for (i = 0; i < pr->rq1_skba.len; i++) | 1237 | for (i = 0; i < pr->rq1_skba.len; i++) |
1233 | if (pr->rq1_skba.arr[i]) | 1238 | if (pr->rq1_skba.arr[i]) |
@@ -1792,6 +1797,22 @@ static void ehea_xmit3(struct sk_buff *skb, struct net_device *dev, | |||
1792 | dev_kfree_skb(skb); | 1797 | dev_kfree_skb(skb); |
1793 | } | 1798 | } |
1794 | 1799 | ||
1800 | static inline int ehea_hash_skb(struct sk_buff *skb, int num_qps) | ||
1801 | { | ||
1802 | struct tcphdr *tcp; | ||
1803 | u32 tmp; | ||
1804 | |||
1805 | if ((skb->protocol == htons(ETH_P_IP)) && | ||
1806 | (skb->nh.iph->protocol == IPPROTO_TCP)) { | ||
1807 | tcp = (struct tcphdr*)(skb->nh.raw + (skb->nh.iph->ihl * 4)); | ||
1808 | tmp = (tcp->source + (tcp->dest << 16)) % 31; | ||
1809 | tmp += skb->nh.iph->daddr % 31; | ||
1810 | return tmp % num_qps; | ||
1811 | } | ||
1812 | else | ||
1813 | return 0; | ||
1814 | } | ||
1815 | |||
1795 | static int ehea_start_xmit(struct sk_buff *skb, struct net_device *dev) | 1816 | static int ehea_start_xmit(struct sk_buff *skb, struct net_device *dev) |
1796 | { | 1817 | { |
1797 | struct ehea_port *port = netdev_priv(dev); | 1818 | struct ehea_port *port = netdev_priv(dev); |
@@ -1799,9 +1820,17 @@ static int ehea_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
1799 | unsigned long flags; | 1820 | unsigned long flags; |
1800 | u32 lkey; | 1821 | u32 lkey; |
1801 | int swqe_index; | 1822 | int swqe_index; |
1802 | struct ehea_port_res *pr = &port->port_res[0]; | 1823 | struct ehea_port_res *pr; |
1824 | |||
1825 | pr = &port->port_res[ehea_hash_skb(skb, port->num_tx_qps)]; | ||
1803 | 1826 | ||
1804 | spin_lock(&pr->xmit_lock); | 1827 | if (!spin_trylock(&pr->xmit_lock)) |
1828 | return NETDEV_TX_BUSY; | ||
1829 | |||
1830 | if (pr->queue_stopped) { | ||
1831 | spin_unlock(&pr->xmit_lock); | ||
1832 | return NETDEV_TX_BUSY; | ||
1833 | } | ||
1805 | 1834 | ||
1806 | swqe = ehea_get_swqe(pr->qp, &swqe_index); | 1835 | swqe = ehea_get_swqe(pr->qp, &swqe_index); |
1807 | memset(swqe, 0, SWQE_HEADER_SIZE); | 1836 | memset(swqe, 0, SWQE_HEADER_SIZE); |
@@ -1824,6 +1853,7 @@ static int ehea_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
1824 | swqe->wr_id = | 1853 | swqe->wr_id = |
1825 | EHEA_BMASK_SET(EHEA_WR_ID_TYPE, EHEA_SWQE2_TYPE) | 1854 | EHEA_BMASK_SET(EHEA_WR_ID_TYPE, EHEA_SWQE2_TYPE) |
1826 | | EHEA_BMASK_SET(EHEA_WR_ID_COUNT, pr->swqe_id_counter) | 1855 | | EHEA_BMASK_SET(EHEA_WR_ID_COUNT, pr->swqe_id_counter) |
1856 | | EHEA_BMASK_SET(EHEA_WR_ID_REFILL, 1) | ||
1827 | | EHEA_BMASK_SET(EHEA_WR_ID_INDEX, pr->sq_skba.index); | 1857 | | EHEA_BMASK_SET(EHEA_WR_ID_INDEX, pr->sq_skba.index); |
1828 | pr->sq_skba.arr[pr->sq_skba.index] = skb; | 1858 | pr->sq_skba.arr[pr->sq_skba.index] = skb; |
1829 | 1859 | ||
@@ -1832,14 +1862,7 @@ static int ehea_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
1832 | 1862 | ||
1833 | lkey = pr->send_mr.lkey; | 1863 | lkey = pr->send_mr.lkey; |
1834 | ehea_xmit2(skb, dev, swqe, lkey); | 1864 | ehea_xmit2(skb, dev, swqe, lkey); |
1835 | 1865 | swqe->tx_control |= EHEA_SWQE_SIGNALLED_COMPLETION; | |
1836 | if (pr->swqe_count >= (EHEA_SIG_IV_LONG - 1)) { | ||
1837 | swqe->wr_id |= EHEA_BMASK_SET(EHEA_WR_ID_REFILL, | ||
1838 | EHEA_SIG_IV_LONG); | ||
1839 | swqe->tx_control |= EHEA_SWQE_SIGNALLED_COMPLETION; | ||
1840 | pr->swqe_count = 0; | ||
1841 | } else | ||
1842 | pr->swqe_count += 1; | ||
1843 | } | 1866 | } |
1844 | pr->swqe_id_counter += 1; | 1867 | pr->swqe_id_counter += 1; |
1845 | 1868 | ||
@@ -1859,6 +1882,7 @@ static int ehea_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
1859 | if (unlikely(atomic_read(&pr->swqe_avail) <= 1)) { | 1882 | if (unlikely(atomic_read(&pr->swqe_avail) <= 1)) { |
1860 | spin_lock_irqsave(&pr->netif_queue, flags); | 1883 | spin_lock_irqsave(&pr->netif_queue, flags); |
1861 | if (unlikely(atomic_read(&pr->swqe_avail) <= 1)) { | 1884 | if (unlikely(atomic_read(&pr->swqe_avail) <= 1)) { |
1885 | pr->p_stats.queue_stopped++; | ||
1862 | netif_stop_queue(dev); | 1886 | netif_stop_queue(dev); |
1863 | pr->queue_stopped = 1; | 1887 | pr->queue_stopped = 1; |
1864 | } | 1888 | } |
@@ -2060,7 +2084,7 @@ static int ehea_port_res_setup(struct ehea_port *port, int def_qps, | |||
2060 | } | 2084 | } |
2061 | 2085 | ||
2062 | pr_cfg.max_entries_rcq = rq1_entries + rq2_entries + rq3_entries; | 2086 | pr_cfg.max_entries_rcq = rq1_entries + rq2_entries + rq3_entries; |
2063 | pr_cfg.max_entries_scq = sq_entries; | 2087 | pr_cfg.max_entries_scq = sq_entries * 2; |
2064 | pr_cfg.max_entries_sq = sq_entries; | 2088 | pr_cfg.max_entries_sq = sq_entries; |
2065 | pr_cfg.max_entries_rq1 = rq1_entries; | 2089 | pr_cfg.max_entries_rq1 = rq1_entries; |
2066 | pr_cfg.max_entries_rq2 = rq2_entries; | 2090 | pr_cfg.max_entries_rq2 = rq2_entries; |
@@ -2109,6 +2133,28 @@ static int ehea_clean_all_portres(struct ehea_port *port) | |||
2109 | return ret; | 2133 | return ret; |
2110 | } | 2134 | } |
2111 | 2135 | ||
2136 | static void ehea_remove_adapter_mr (struct ehea_adapter *adapter) | ||
2137 | { | ||
2138 | int i; | ||
2139 | |||
2140 | for (i=0; i < EHEA_MAX_PORTS; i++) | ||
2141 | if (adapter->port[i]) | ||
2142 | return; | ||
2143 | |||
2144 | ehea_rem_mr(&adapter->mr); | ||
2145 | } | ||
2146 | |||
2147 | static int ehea_add_adapter_mr (struct ehea_adapter *adapter) | ||
2148 | { | ||
2149 | int i; | ||
2150 | |||
2151 | for (i=0; i < EHEA_MAX_PORTS; i++) | ||
2152 | if (adapter->port[i]) | ||
2153 | return 0; | ||
2154 | |||
2155 | return ehea_reg_kernel_mr(adapter, &adapter->mr); | ||
2156 | } | ||
2157 | |||
2112 | static int ehea_up(struct net_device *dev) | 2158 | static int ehea_up(struct net_device *dev) |
2113 | { | 2159 | { |
2114 | int ret, i; | 2160 | int ret, i; |
@@ -2208,8 +2254,10 @@ static int ehea_down(struct net_device *dev) | |||
2208 | ehea_drop_multicast_list(dev); | 2254 | ehea_drop_multicast_list(dev); |
2209 | ehea_free_interrupts(dev); | 2255 | ehea_free_interrupts(dev); |
2210 | 2256 | ||
2211 | for (i = 0; i < port->num_def_qps + port->num_add_tx_qps; i++) | 2257 | for (i = 0; i < port->num_def_qps; i++) |
2212 | tasklet_kill(&port->port_res[i].send_comp_task); | 2258 | while (test_bit(__LINK_STATE_RX_SCHED, |
2259 | &port->port_res[i].d_netdev->state)) | ||
2260 | msleep(1); | ||
2213 | 2261 | ||
2214 | ehea_broadcast_reg_helper(port, H_DEREG_BCMC); | 2262 | ehea_broadcast_reg_helper(port, H_DEREG_BCMC); |
2215 | ret = ehea_clean_all_portres(port); | 2263 | ret = ehea_clean_all_portres(port); |
@@ -2276,8 +2324,6 @@ static void ehea_tx_watchdog(struct net_device *dev) | |||
2276 | int ehea_sense_adapter_attr(struct ehea_adapter *adapter) | 2324 | int ehea_sense_adapter_attr(struct ehea_adapter *adapter) |
2277 | { | 2325 | { |
2278 | struct hcp_query_ehea *cb; | 2326 | struct hcp_query_ehea *cb; |
2279 | struct device_node *lhea_dn = NULL; | ||
2280 | struct device_node *eth_dn = NULL; | ||
2281 | u64 hret; | 2327 | u64 hret; |
2282 | int ret; | 2328 | int ret; |
2283 | 2329 | ||
@@ -2294,18 +2340,6 @@ int ehea_sense_adapter_attr(struct ehea_adapter *adapter) | |||
2294 | goto out_herr; | 2340 | goto out_herr; |
2295 | } | 2341 | } |
2296 | 2342 | ||
2297 | /* Determine the number of available logical ports | ||
2298 | * by counting the child nodes of the lhea OFDT entry | ||
2299 | */ | ||
2300 | adapter->num_ports = 0; | ||
2301 | lhea_dn = of_find_node_by_name(lhea_dn, "lhea"); | ||
2302 | do { | ||
2303 | eth_dn = of_get_next_child(lhea_dn, eth_dn); | ||
2304 | if (eth_dn) | ||
2305 | adapter->num_ports++; | ||
2306 | } while ( eth_dn ); | ||
2307 | of_node_put(lhea_dn); | ||
2308 | |||
2309 | adapter->max_mc_mac = cb->max_mc_mac - 1; | 2343 | adapter->max_mc_mac = cb->max_mc_mac - 1; |
2310 | ret = 0; | 2344 | ret = 0; |
2311 | 2345 | ||
@@ -2315,79 +2349,188 @@ out: | |||
2315 | return ret; | 2349 | return ret; |
2316 | } | 2350 | } |
2317 | 2351 | ||
2318 | static int ehea_setup_single_port(struct ehea_port *port, | 2352 | int ehea_get_jumboframe_status(struct ehea_port *port, int *jumbo) |
2319 | struct device_node *dn) | ||
2320 | { | 2353 | { |
2321 | int ret; | ||
2322 | u64 hret; | ||
2323 | struct net_device *dev = port->netdev; | ||
2324 | struct ehea_adapter *adapter = port->adapter; | ||
2325 | struct hcp_ehea_port_cb4 *cb4; | 2354 | struct hcp_ehea_port_cb4 *cb4; |
2326 | u32 *dn_log_port_id; | 2355 | u64 hret; |
2327 | int jumbo = 0; | 2356 | int ret = 0; |
2328 | |||
2329 | sema_init(&port->port_lock, 1); | ||
2330 | port->state = EHEA_PORT_DOWN; | ||
2331 | port->sig_comp_iv = sq_entries / 10; | ||
2332 | |||
2333 | if (!dn) { | ||
2334 | ehea_error("bad device node: dn=%p", dn); | ||
2335 | ret = -EINVAL; | ||
2336 | goto out; | ||
2337 | } | ||
2338 | |||
2339 | port->of_dev_node = dn; | ||
2340 | |||
2341 | /* Determine logical port id */ | ||
2342 | dn_log_port_id = (u32*)get_property(dn, "ibm,hea-port-no", NULL); | ||
2343 | |||
2344 | if (!dn_log_port_id) { | ||
2345 | ehea_error("bad device node: dn_log_port_id=%p", | ||
2346 | dn_log_port_id); | ||
2347 | ret = -EINVAL; | ||
2348 | goto out; | ||
2349 | } | ||
2350 | port->logical_port_id = *dn_log_port_id; | ||
2351 | |||
2352 | port->mc_list = kzalloc(sizeof(struct ehea_mc_list), GFP_KERNEL); | ||
2353 | if (!port->mc_list) { | ||
2354 | ret = -ENOMEM; | ||
2355 | goto out; | ||
2356 | } | ||
2357 | |||
2358 | INIT_LIST_HEAD(&port->mc_list->list); | ||
2359 | 2357 | ||
2360 | ret = ehea_sense_port_attr(port); | 2358 | *jumbo = 0; |
2361 | if (ret) | ||
2362 | goto out; | ||
2363 | 2359 | ||
2364 | /* Enable Jumbo frames */ | 2360 | /* (Try to) enable *jumbo frames */ |
2365 | cb4 = kzalloc(PAGE_SIZE, GFP_KERNEL); | 2361 | cb4 = kzalloc(PAGE_SIZE, GFP_KERNEL); |
2366 | if (!cb4) { | 2362 | if (!cb4) { |
2367 | ehea_error("no mem for cb4"); | 2363 | ehea_error("no mem for cb4"); |
2364 | ret = -ENOMEM; | ||
2365 | goto out; | ||
2368 | } else { | 2366 | } else { |
2369 | hret = ehea_h_query_ehea_port(adapter->handle, | 2367 | hret = ehea_h_query_ehea_port(port->adapter->handle, |
2370 | port->logical_port_id, | 2368 | port->logical_port_id, |
2371 | H_PORT_CB4, | 2369 | H_PORT_CB4, |
2372 | H_PORT_CB4_JUMBO, cb4); | 2370 | H_PORT_CB4_JUMBO, cb4); |
2373 | |||
2374 | if (hret == H_SUCCESS) { | 2371 | if (hret == H_SUCCESS) { |
2375 | if (cb4->jumbo_frame) | 2372 | if (cb4->jumbo_frame) |
2376 | jumbo = 1; | 2373 | *jumbo = 1; |
2377 | else { | 2374 | else { |
2378 | cb4->jumbo_frame = 1; | 2375 | cb4->jumbo_frame = 1; |
2379 | hret = ehea_h_modify_ehea_port(adapter->handle, | 2376 | hret = ehea_h_modify_ehea_port(port->adapter-> |
2377 | handle, | ||
2380 | port-> | 2378 | port-> |
2381 | logical_port_id, | 2379 | logical_port_id, |
2382 | H_PORT_CB4, | 2380 | H_PORT_CB4, |
2383 | H_PORT_CB4_JUMBO, | 2381 | H_PORT_CB4_JUMBO, |
2384 | cb4); | 2382 | cb4); |
2385 | if (hret == H_SUCCESS) | 2383 | if (hret == H_SUCCESS) |
2386 | jumbo = 1; | 2384 | *jumbo = 1; |
2387 | } | 2385 | } |
2388 | } | 2386 | } else |
2387 | ret = -EINVAL; | ||
2388 | |||
2389 | kfree(cb4); | 2389 | kfree(cb4); |
2390 | } | 2390 | } |
2391 | out: | ||
2392 | return ret; | ||
2393 | } | ||
2394 | |||
2395 | static ssize_t ehea_show_port_id(struct device *dev, | ||
2396 | struct device_attribute *attr, char *buf) | ||
2397 | { | ||
2398 | struct ehea_port *port = container_of(dev, struct ehea_port, ofdev.dev); | ||
2399 | return sprintf(buf, "0x%X", port->logical_port_id); | ||
2400 | } | ||
2401 | |||
2402 | static DEVICE_ATTR(log_port_id, S_IRUSR | S_IRGRP | S_IROTH, ehea_show_port_id, | ||
2403 | NULL); | ||
2404 | |||
2405 | static void __devinit logical_port_release(struct device *dev) | ||
2406 | { | ||
2407 | struct ehea_port *port = container_of(dev, struct ehea_port, ofdev.dev); | ||
2408 | of_node_put(port->ofdev.node); | ||
2409 | } | ||
2410 | |||
2411 | static int ehea_driver_sysfs_add(struct device *dev, | ||
2412 | struct device_driver *driver) | ||
2413 | { | ||
2414 | int ret; | ||
2415 | |||
2416 | ret = sysfs_create_link(&driver->kobj, &dev->kobj, | ||
2417 | kobject_name(&dev->kobj)); | ||
2418 | if (ret == 0) { | ||
2419 | ret = sysfs_create_link(&dev->kobj, &driver->kobj, | ||
2420 | "driver"); | ||
2421 | if (ret) | ||
2422 | sysfs_remove_link(&driver->kobj, | ||
2423 | kobject_name(&dev->kobj)); | ||
2424 | } | ||
2425 | return ret; | ||
2426 | } | ||
2427 | |||
2428 | static void ehea_driver_sysfs_remove(struct device *dev, | ||
2429 | struct device_driver *driver) | ||
2430 | { | ||
2431 | struct device_driver *drv = driver; | ||
2432 | |||
2433 | if (drv) { | ||
2434 | sysfs_remove_link(&drv->kobj, kobject_name(&dev->kobj)); | ||
2435 | sysfs_remove_link(&dev->kobj, "driver"); | ||
2436 | } | ||
2437 | } | ||
2438 | |||
2439 | static struct device *ehea_register_port(struct ehea_port *port, | ||
2440 | struct device_node *dn) | ||
2441 | { | ||
2442 | int ret; | ||
2443 | |||
2444 | port->ofdev.node = of_node_get(dn); | ||
2445 | port->ofdev.dev.parent = &port->adapter->ebus_dev->ofdev.dev; | ||
2446 | port->ofdev.dev.bus = &ibmebus_bus_type; | ||
2447 | |||
2448 | sprintf(port->ofdev.dev.bus_id, "port%d", port_name_cnt++); | ||
2449 | port->ofdev.dev.release = logical_port_release; | ||
2450 | |||
2451 | ret = of_device_register(&port->ofdev); | ||
2452 | if (ret) { | ||
2453 | ehea_error("failed to register device. ret=%d", ret); | ||
2454 | goto out; | ||
2455 | } | ||
2456 | |||
2457 | ret = device_create_file(&port->ofdev.dev, &dev_attr_log_port_id); | ||
2458 | if (ret) { | ||
2459 | ehea_error("failed to register attributes, ret=%d", ret); | ||
2460 | goto out_unreg_of_dev; | ||
2461 | } | ||
2462 | |||
2463 | ret = ehea_driver_sysfs_add(&port->ofdev.dev, &ehea_driver.driver); | ||
2464 | if (ret) { | ||
2465 | ehea_error("failed to register sysfs driver link"); | ||
2466 | goto out_rem_dev_file; | ||
2467 | } | ||
2468 | |||
2469 | return &port->ofdev.dev; | ||
2470 | |||
2471 | out_rem_dev_file: | ||
2472 | device_remove_file(&port->ofdev.dev, &dev_attr_log_port_id); | ||
2473 | out_unreg_of_dev: | ||
2474 | of_device_unregister(&port->ofdev); | ||
2475 | out: | ||
2476 | return NULL; | ||
2477 | } | ||
2478 | |||
2479 | static void ehea_unregister_port(struct ehea_port *port) | ||
2480 | { | ||
2481 | ehea_driver_sysfs_remove(&port->ofdev.dev, &ehea_driver.driver); | ||
2482 | device_remove_file(&port->ofdev.dev, &dev_attr_log_port_id); | ||
2483 | of_device_unregister(&port->ofdev); | ||
2484 | } | ||
2485 | |||
2486 | struct ehea_port *ehea_setup_single_port(struct ehea_adapter *adapter, | ||
2487 | u32 logical_port_id, | ||
2488 | struct device_node *dn) | ||
2489 | { | ||
2490 | int ret; | ||
2491 | struct net_device *dev; | ||
2492 | struct ehea_port *port; | ||
2493 | struct device *port_dev; | ||
2494 | int jumbo; | ||
2495 | |||
2496 | /* allocate memory for the port structures */ | ||
2497 | dev = alloc_etherdev(sizeof(struct ehea_port)); | ||
2498 | |||
2499 | if (!dev) { | ||
2500 | ehea_error("no mem for net_device"); | ||
2501 | ret = -ENOMEM; | ||
2502 | goto out_err; | ||
2503 | } | ||
2504 | |||
2505 | port = netdev_priv(dev); | ||
2506 | |||
2507 | sema_init(&port->port_lock, 1); | ||
2508 | port->state = EHEA_PORT_DOWN; | ||
2509 | port->sig_comp_iv = sq_entries / 10; | ||
2510 | |||
2511 | port->adapter = adapter; | ||
2512 | port->netdev = dev; | ||
2513 | port->logical_port_id = logical_port_id; | ||
2514 | |||
2515 | port->msg_enable = netif_msg_init(msg_level, EHEA_MSG_DEFAULT); | ||
2516 | |||
2517 | port->mc_list = kzalloc(sizeof(struct ehea_mc_list), GFP_KERNEL); | ||
2518 | if (!port->mc_list) { | ||
2519 | ret = -ENOMEM; | ||
2520 | goto out_free_ethdev; | ||
2521 | } | ||
2522 | |||
2523 | INIT_LIST_HEAD(&port->mc_list->list); | ||
2524 | |||
2525 | ret = ehea_sense_port_attr(port); | ||
2526 | if (ret) | ||
2527 | goto out_free_mc_list; | ||
2528 | |||
2529 | port_dev = ehea_register_port(port, dn); | ||
2530 | if (!port_dev) | ||
2531 | goto out_free_mc_list; | ||
2532 | |||
2533 | SET_NETDEV_DEV(dev, port_dev); | ||
2391 | 2534 | ||
2392 | /* initialize net_device structure */ | 2535 | /* initialize net_device structure */ |
2393 | SET_MODULE_OWNER(dev); | 2536 | SET_MODULE_OWNER(dev); |
@@ -2420,84 +2563,225 @@ static int ehea_setup_single_port(struct ehea_port *port, | |||
2420 | ret = register_netdev(dev); | 2563 | ret = register_netdev(dev); |
2421 | if (ret) { | 2564 | if (ret) { |
2422 | ehea_error("register_netdev failed. ret=%d", ret); | 2565 | ehea_error("register_netdev failed. ret=%d", ret); |
2423 | goto out_free; | 2566 | goto out_unreg_port; |
2424 | } | 2567 | } |
2425 | 2568 | ||
2569 | ret = ehea_get_jumboframe_status(port, &jumbo); | ||
2570 | if (ret) | ||
2571 | ehea_error("failed determining jumbo frame status for %s", | ||
2572 | port->netdev->name); | ||
2573 | |||
2426 | ehea_info("%s: Jumbo frames are %sabled", dev->name, | 2574 | ehea_info("%s: Jumbo frames are %sabled", dev->name, |
2427 | jumbo == 1 ? "en" : "dis"); | 2575 | jumbo == 1 ? "en" : "dis"); |
2428 | 2576 | ||
2429 | port->netdev = dev; | 2577 | return port; |
2430 | ret = 0; | ||
2431 | goto out; | ||
2432 | 2578 | ||
2433 | out_free: | 2579 | out_unreg_port: |
2580 | ehea_unregister_port(port); | ||
2581 | |||
2582 | out_free_mc_list: | ||
2434 | kfree(port->mc_list); | 2583 | kfree(port->mc_list); |
2435 | out: | 2584 | |
2436 | return ret; | 2585 | out_free_ethdev: |
2586 | free_netdev(dev); | ||
2587 | |||
2588 | out_err: | ||
2589 | ehea_error("setting up logical port with id=%d failed, ret=%d", | ||
2590 | logical_port_id, ret); | ||
2591 | return NULL; | ||
2592 | } | ||
2593 | |||
2594 | static void ehea_shutdown_single_port(struct ehea_port *port) | ||
2595 | { | ||
2596 | unregister_netdev(port->netdev); | ||
2597 | ehea_unregister_port(port); | ||
2598 | kfree(port->mc_list); | ||
2599 | free_netdev(port->netdev); | ||
2437 | } | 2600 | } |
2438 | 2601 | ||
2439 | static int ehea_setup_ports(struct ehea_adapter *adapter) | 2602 | static int ehea_setup_ports(struct ehea_adapter *adapter) |
2440 | { | 2603 | { |
2441 | int ret; | 2604 | struct device_node *lhea_dn; |
2442 | int port_setup_ok = 0; | 2605 | struct device_node *eth_dn = NULL; |
2606 | |||
2607 | u32 *dn_log_port_id; | ||
2608 | int i = 0; | ||
2609 | |||
2610 | lhea_dn = adapter->ebus_dev->ofdev.node; | ||
2611 | while ((eth_dn = of_get_next_child(lhea_dn, eth_dn))) { | ||
2612 | |||
2613 | dn_log_port_id = (u32*)get_property(eth_dn, "ibm,hea-port-no", | ||
2614 | NULL); | ||
2615 | if (!dn_log_port_id) { | ||
2616 | ehea_error("bad device node: eth_dn name=%s", | ||
2617 | eth_dn->full_name); | ||
2618 | continue; | ||
2619 | } | ||
2620 | |||
2621 | if (ehea_add_adapter_mr(adapter)) { | ||
2622 | ehea_error("creating MR failed"); | ||
2623 | of_node_put(eth_dn); | ||
2624 | return -EIO; | ||
2625 | } | ||
2626 | |||
2627 | adapter->port[i] = ehea_setup_single_port(adapter, | ||
2628 | *dn_log_port_id, | ||
2629 | eth_dn); | ||
2630 | if (adapter->port[i]) | ||
2631 | ehea_info("%s -> logical port id #%d", | ||
2632 | adapter->port[i]->netdev->name, | ||
2633 | *dn_log_port_id); | ||
2634 | else | ||
2635 | ehea_remove_adapter_mr(adapter); | ||
2636 | |||
2637 | i++; | ||
2638 | }; | ||
2639 | |||
2640 | return 0; | ||
2641 | } | ||
2642 | |||
2643 | static struct device_node *ehea_get_eth_dn(struct ehea_adapter *adapter, | ||
2644 | u32 logical_port_id) | ||
2645 | { | ||
2646 | struct device_node *lhea_dn; | ||
2647 | struct device_node *eth_dn = NULL; | ||
2648 | u32 *dn_log_port_id; | ||
2649 | |||
2650 | lhea_dn = adapter->ebus_dev->ofdev.node; | ||
2651 | while ((eth_dn = of_get_next_child(lhea_dn, eth_dn))) { | ||
2652 | |||
2653 | dn_log_port_id = (u32*)get_property(eth_dn, "ibm,hea-port-no", | ||
2654 | NULL); | ||
2655 | if (dn_log_port_id) | ||
2656 | if (*dn_log_port_id == logical_port_id) | ||
2657 | return eth_dn; | ||
2658 | }; | ||
2659 | |||
2660 | return NULL; | ||
2661 | } | ||
2662 | |||
2663 | static ssize_t ehea_probe_port(struct device *dev, | ||
2664 | struct device_attribute *attr, | ||
2665 | const char *buf, size_t count) | ||
2666 | { | ||
2667 | struct ehea_adapter *adapter = dev->driver_data; | ||
2443 | struct ehea_port *port; | 2668 | struct ehea_port *port; |
2444 | struct device_node *dn = NULL; | 2669 | struct device_node *eth_dn = NULL; |
2445 | struct net_device *dev; | ||
2446 | int i; | 2670 | int i; |
2447 | 2671 | ||
2448 | /* get port properties for all ports */ | 2672 | u32 logical_port_id; |
2449 | for (i = 0; i < adapter->num_ports; i++) { | ||
2450 | 2673 | ||
2451 | if (adapter->port[i]) | 2674 | sscanf(buf, "%X", &logical_port_id); |
2452 | continue; /* port already up and running */ | ||
2453 | 2675 | ||
2454 | /* allocate memory for the port structures */ | 2676 | port = ehea_get_port(adapter, logical_port_id); |
2455 | dev = alloc_etherdev(sizeof(struct ehea_port)); | ||
2456 | 2677 | ||
2457 | if (!dev) { | 2678 | if (port) { |
2458 | ehea_error("no mem for net_device"); | 2679 | ehea_info("adding port with logical port id=%d failed. port " |
2459 | break; | 2680 | "already configured as %s.", logical_port_id, |
2460 | } | 2681 | port->netdev->name); |
2682 | return -EINVAL; | ||
2683 | } | ||
2461 | 2684 | ||
2462 | port = netdev_priv(dev); | 2685 | eth_dn = ehea_get_eth_dn(adapter, logical_port_id); |
2463 | port->adapter = adapter; | ||
2464 | port->netdev = dev; | ||
2465 | adapter->port[i] = port; | ||
2466 | port->msg_enable = netif_msg_init(msg_level, EHEA_MSG_DEFAULT); | ||
2467 | 2686 | ||
2468 | dn = of_find_node_by_name(dn, "ethernet"); | 2687 | if (!eth_dn) { |
2469 | ret = ehea_setup_single_port(port, dn); | 2688 | ehea_info("no logical port with id %d found", logical_port_id); |
2470 | if (ret) { | 2689 | return -EINVAL; |
2471 | /* Free mem for this port struct. The others will be | ||
2472 | processed on rollback */ | ||
2473 | free_netdev(dev); | ||
2474 | adapter->port[i] = NULL; | ||
2475 | ehea_error("eHEA port %d setup failed, ret=%d", i, ret); | ||
2476 | } | ||
2477 | } | 2690 | } |
2478 | 2691 | ||
2479 | of_node_put(dn); | 2692 | if (ehea_add_adapter_mr(adapter)) { |
2693 | ehea_error("creating MR failed"); | ||
2694 | return -EIO; | ||
2695 | } | ||
2480 | 2696 | ||
2481 | /* Check for succesfully set up ports */ | 2697 | port = ehea_setup_single_port(adapter, logical_port_id, eth_dn); |
2482 | for (i = 0; i < adapter->num_ports; i++) | ||
2483 | if (adapter->port[i]) | ||
2484 | port_setup_ok++; | ||
2485 | 2698 | ||
2486 | if (port_setup_ok) | 2699 | of_node_put(eth_dn); |
2487 | ret = 0; /* At least some ports are setup correctly */ | 2700 | |
2488 | else | 2701 | if (port) { |
2489 | ret = -EINVAL; | 2702 | for (i=0; i < EHEA_MAX_PORTS; i++) |
2703 | if (!adapter->port[i]) { | ||
2704 | adapter->port[i] = port; | ||
2705 | break; | ||
2706 | } | ||
2707 | |||
2708 | ehea_info("added %s (logical port id=%d)", port->netdev->name, | ||
2709 | logical_port_id); | ||
2710 | } else { | ||
2711 | ehea_remove_adapter_mr(adapter); | ||
2712 | return -EIO; | ||
2713 | } | ||
2714 | |||
2715 | return (ssize_t) count; | ||
2716 | } | ||
2717 | |||
2718 | static ssize_t ehea_remove_port(struct device *dev, | ||
2719 | struct device_attribute *attr, | ||
2720 | const char *buf, size_t count) | ||
2721 | { | ||
2722 | struct ehea_adapter *adapter = dev->driver_data; | ||
2723 | struct ehea_port *port; | ||
2724 | int i; | ||
2725 | u32 logical_port_id; | ||
2726 | |||
2727 | sscanf(buf, "%X", &logical_port_id); | ||
2728 | |||
2729 | port = ehea_get_port(adapter, logical_port_id); | ||
2730 | |||
2731 | if (port) { | ||
2732 | ehea_info("removed %s (logical port id=%d)", port->netdev->name, | ||
2733 | logical_port_id); | ||
2734 | |||
2735 | ehea_shutdown_single_port(port); | ||
2736 | |||
2737 | for (i=0; i < EHEA_MAX_PORTS; i++) | ||
2738 | if (adapter->port[i] == port) { | ||
2739 | adapter->port[i] = NULL; | ||
2740 | break; | ||
2741 | } | ||
2742 | } else { | ||
2743 | ehea_error("removing port with logical port id=%d failed. port " | ||
2744 | "not configured.", logical_port_id); | ||
2745 | return -EINVAL; | ||
2746 | } | ||
2747 | |||
2748 | ehea_remove_adapter_mr(adapter); | ||
2749 | |||
2750 | return (ssize_t) count; | ||
2751 | } | ||
2752 | |||
2753 | static DEVICE_ATTR(probe_port, S_IWUSR, NULL, ehea_probe_port); | ||
2754 | static DEVICE_ATTR(remove_port, S_IWUSR, NULL, ehea_remove_port); | ||
2490 | 2755 | ||
2756 | int ehea_create_device_sysfs(struct ibmebus_dev *dev) | ||
2757 | { | ||
2758 | int ret = device_create_file(&dev->ofdev.dev, &dev_attr_probe_port); | ||
2759 | if (ret) | ||
2760 | goto out; | ||
2761 | |||
2762 | ret = device_create_file(&dev->ofdev.dev, &dev_attr_remove_port); | ||
2763 | out: | ||
2491 | return ret; | 2764 | return ret; |
2492 | } | 2765 | } |
2493 | 2766 | ||
2494 | static int __devinit ehea_probe(struct ibmebus_dev *dev, | 2767 | void ehea_remove_device_sysfs(struct ibmebus_dev *dev) |
2495 | const struct of_device_id *id) | 2768 | { |
2769 | device_remove_file(&dev->ofdev.dev, &dev_attr_probe_port); | ||
2770 | device_remove_file(&dev->ofdev.dev, &dev_attr_remove_port); | ||
2771 | } | ||
2772 | |||
2773 | static int __devinit ehea_probe_adapter(struct ibmebus_dev *dev, | ||
2774 | const struct of_device_id *id) | ||
2496 | { | 2775 | { |
2497 | struct ehea_adapter *adapter; | 2776 | struct ehea_adapter *adapter; |
2498 | u64 *adapter_handle; | 2777 | u64 *adapter_handle; |
2499 | int ret; | 2778 | int ret; |
2500 | 2779 | ||
2780 | if (!dev || !dev->ofdev.node) { | ||
2781 | ehea_error("Invalid ibmebus device probed"); | ||
2782 | return -EINVAL; | ||
2783 | } | ||
2784 | |||
2501 | adapter = kzalloc(sizeof(*adapter), GFP_KERNEL); | 2785 | adapter = kzalloc(sizeof(*adapter), GFP_KERNEL); |
2502 | if (!adapter) { | 2786 | if (!adapter) { |
2503 | ret = -ENOMEM; | 2787 | ret = -ENOMEM; |
@@ -2505,6 +2789,8 @@ static int __devinit ehea_probe(struct ibmebus_dev *dev, | |||
2505 | goto out; | 2789 | goto out; |
2506 | } | 2790 | } |
2507 | 2791 | ||
2792 | adapter->ebus_dev = dev; | ||
2793 | |||
2508 | adapter_handle = (u64*)get_property(dev->ofdev.node, "ibm,hea-handle", | 2794 | adapter_handle = (u64*)get_property(dev->ofdev.node, "ibm,hea-handle", |
2509 | NULL); | 2795 | NULL); |
2510 | if (adapter_handle) | 2796 | if (adapter_handle) |
@@ -2521,26 +2807,21 @@ static int __devinit ehea_probe(struct ibmebus_dev *dev, | |||
2521 | 2807 | ||
2522 | dev->ofdev.dev.driver_data = adapter; | 2808 | dev->ofdev.dev.driver_data = adapter; |
2523 | 2809 | ||
2524 | ret = ehea_reg_mr_adapter(adapter); | ||
2525 | if (ret) { | ||
2526 | dev_err(&dev->ofdev.dev, "reg_mr_adapter failed\n"); | ||
2527 | goto out_free_ad; | ||
2528 | } | ||
2529 | 2810 | ||
2530 | /* initialize adapter and ports */ | 2811 | /* initialize adapter and ports */ |
2531 | /* get adapter properties */ | 2812 | /* get adapter properties */ |
2532 | ret = ehea_sense_adapter_attr(adapter); | 2813 | ret = ehea_sense_adapter_attr(adapter); |
2533 | if (ret) { | 2814 | if (ret) { |
2534 | dev_err(&dev->ofdev.dev, "sense_adapter_attr failed: %d", ret); | 2815 | dev_err(&dev->ofdev.dev, "sense_adapter_attr failed: %d", ret); |
2535 | goto out_free_res; | 2816 | goto out_free_ad; |
2536 | } | 2817 | } |
2537 | dev_info(&dev->ofdev.dev, "%d eHEA ports found\n", adapter->num_ports); | ||
2538 | 2818 | ||
2539 | adapter->neq = ehea_create_eq(adapter, | 2819 | adapter->neq = ehea_create_eq(adapter, |
2540 | EHEA_NEQ, EHEA_MAX_ENTRIES_EQ, 1); | 2820 | EHEA_NEQ, EHEA_MAX_ENTRIES_EQ, 1); |
2541 | if (!adapter->neq) { | 2821 | if (!adapter->neq) { |
2822 | ret = -EIO; | ||
2542 | dev_err(&dev->ofdev.dev, "NEQ creation failed"); | 2823 | dev_err(&dev->ofdev.dev, "NEQ creation failed"); |
2543 | goto out_free_res; | 2824 | goto out_free_ad; |
2544 | } | 2825 | } |
2545 | 2826 | ||
2546 | tasklet_init(&adapter->neq_tasklet, ehea_neq_tasklet, | 2827 | tasklet_init(&adapter->neq_tasklet, ehea_neq_tasklet, |
@@ -2555,18 +2836,27 @@ static int __devinit ehea_probe(struct ibmebus_dev *dev, | |||
2555 | } | 2836 | } |
2556 | 2837 | ||
2557 | adapter->ehea_wq = create_workqueue("ehea_wq"); | 2838 | adapter->ehea_wq = create_workqueue("ehea_wq"); |
2558 | if (!adapter->ehea_wq) | 2839 | if (!adapter->ehea_wq) { |
2840 | ret = -EIO; | ||
2559 | goto out_free_irq; | 2841 | goto out_free_irq; |
2842 | } | ||
2843 | |||
2844 | ret = ehea_create_device_sysfs(dev); | ||
2845 | if (ret) | ||
2846 | goto out_kill_wq; | ||
2560 | 2847 | ||
2561 | ret = ehea_setup_ports(adapter); | 2848 | ret = ehea_setup_ports(adapter); |
2562 | if (ret) { | 2849 | if (ret) { |
2563 | dev_err(&dev->ofdev.dev, "setup_ports failed"); | 2850 | dev_err(&dev->ofdev.dev, "setup_ports failed"); |
2564 | goto out_kill_wq; | 2851 | goto out_rem_dev_sysfs; |
2565 | } | 2852 | } |
2566 | 2853 | ||
2567 | ret = 0; | 2854 | ret = 0; |
2568 | goto out; | 2855 | goto out; |
2569 | 2856 | ||
2857 | out_rem_dev_sysfs: | ||
2858 | ehea_remove_device_sysfs(dev); | ||
2859 | |||
2570 | out_kill_wq: | 2860 | out_kill_wq: |
2571 | destroy_workqueue(adapter->ehea_wq); | 2861 | destroy_workqueue(adapter->ehea_wq); |
2572 | 2862 | ||
@@ -2576,45 +2866,32 @@ out_free_irq: | |||
2576 | out_kill_eq: | 2866 | out_kill_eq: |
2577 | ehea_destroy_eq(adapter->neq); | 2867 | ehea_destroy_eq(adapter->neq); |
2578 | 2868 | ||
2579 | out_free_res: | ||
2580 | ehea_h_free_resource(adapter->handle, adapter->mr.handle); | ||
2581 | |||
2582 | out_free_ad: | 2869 | out_free_ad: |
2583 | kfree(adapter); | 2870 | kfree(adapter); |
2584 | out: | 2871 | out: |
2585 | return ret; | 2872 | return ret; |
2586 | } | 2873 | } |
2587 | 2874 | ||
2588 | static void ehea_shutdown_single_port(struct ehea_port *port) | ||
2589 | { | ||
2590 | unregister_netdev(port->netdev); | ||
2591 | kfree(port->mc_list); | ||
2592 | free_netdev(port->netdev); | ||
2593 | } | ||
2594 | |||
2595 | static int __devexit ehea_remove(struct ibmebus_dev *dev) | 2875 | static int __devexit ehea_remove(struct ibmebus_dev *dev) |
2596 | { | 2876 | { |
2597 | struct ehea_adapter *adapter = dev->ofdev.dev.driver_data; | 2877 | struct ehea_adapter *adapter = dev->ofdev.dev.driver_data; |
2598 | u64 hret; | ||
2599 | int i; | 2878 | int i; |
2600 | 2879 | ||
2601 | for (i = 0; i < adapter->num_ports; i++) | 2880 | for (i = 0; i < EHEA_MAX_PORTS; i++) |
2602 | if (adapter->port[i]) { | 2881 | if (adapter->port[i]) { |
2603 | ehea_shutdown_single_port(adapter->port[i]); | 2882 | ehea_shutdown_single_port(adapter->port[i]); |
2604 | adapter->port[i] = NULL; | 2883 | adapter->port[i] = NULL; |
2605 | } | 2884 | } |
2885 | |||
2886 | ehea_remove_device_sysfs(dev); | ||
2887 | |||
2606 | destroy_workqueue(adapter->ehea_wq); | 2888 | destroy_workqueue(adapter->ehea_wq); |
2607 | 2889 | ||
2608 | ibmebus_free_irq(NULL, adapter->neq->attr.ist1, adapter); | 2890 | ibmebus_free_irq(NULL, adapter->neq->attr.ist1, adapter); |
2609 | tasklet_kill(&adapter->neq_tasklet); | 2891 | tasklet_kill(&adapter->neq_tasklet); |
2610 | 2892 | ||
2611 | ehea_destroy_eq(adapter->neq); | 2893 | ehea_destroy_eq(adapter->neq); |
2612 | 2894 | ehea_remove_adapter_mr(adapter); | |
2613 | hret = ehea_h_free_resource(adapter->handle, adapter->mr.handle); | ||
2614 | if (hret) { | ||
2615 | dev_err(&dev->ofdev.dev, "free_resource_mr failed"); | ||
2616 | return -EIO; | ||
2617 | } | ||
2618 | kfree(adapter); | 2895 | kfree(adapter); |
2619 | return 0; | 2896 | return 0; |
2620 | } | 2897 | } |
@@ -2647,21 +2924,6 @@ static int check_module_parm(void) | |||
2647 | return ret; | 2924 | return ret; |
2648 | } | 2925 | } |
2649 | 2926 | ||
2650 | static struct of_device_id ehea_device_table[] = { | ||
2651 | { | ||
2652 | .name = "lhea", | ||
2653 | .compatible = "IBM,lhea", | ||
2654 | }, | ||
2655 | {}, | ||
2656 | }; | ||
2657 | |||
2658 | static struct ibmebus_driver ehea_driver = { | ||
2659 | .name = "ehea", | ||
2660 | .id_table = ehea_device_table, | ||
2661 | .probe = ehea_probe, | ||
2662 | .remove = ehea_remove, | ||
2663 | }; | ||
2664 | |||
2665 | int __init ehea_module_init(void) | 2927 | int __init ehea_module_init(void) |
2666 | { | 2928 | { |
2667 | int ret; | 2929 | int ret; |
diff --git a/drivers/net/ehea/ehea_phyp.c b/drivers/net/ehea/ehea_phyp.c index bc3c00547264..95c4a7f9cc88 100644 --- a/drivers/net/ehea/ehea_phyp.c +++ b/drivers/net/ehea/ehea_phyp.c | |||
@@ -478,12 +478,14 @@ u64 ehea_h_disable_and_get_hea(const u64 adapter_handle, const u64 qp_handle) | |||
478 | 0, 0, 0, 0, 0, 0); /* R7-R12 */ | 478 | 0, 0, 0, 0, 0, 0); /* R7-R12 */ |
479 | } | 479 | } |
480 | 480 | ||
481 | u64 ehea_h_free_resource(const u64 adapter_handle, const u64 res_handle) | 481 | u64 ehea_h_free_resource(const u64 adapter_handle, const u64 res_handle, |
482 | u64 force_bit) | ||
482 | { | 483 | { |
483 | return ehea_plpar_hcall_norets(H_FREE_RESOURCE, | 484 | return ehea_plpar_hcall_norets(H_FREE_RESOURCE, |
484 | adapter_handle, /* R4 */ | 485 | adapter_handle, /* R4 */ |
485 | res_handle, /* R5 */ | 486 | res_handle, /* R5 */ |
486 | 0, 0, 0, 0, 0); /* R6-R10 */ | 487 | force_bit, |
488 | 0, 0, 0, 0); /* R7-R10 */ | ||
487 | } | 489 | } |
488 | 490 | ||
489 | u64 ehea_h_alloc_resource_mr(const u64 adapter_handle, const u64 vaddr, | 491 | u64 ehea_h_alloc_resource_mr(const u64 adapter_handle, const u64 vaddr, |
diff --git a/drivers/net/ehea/ehea_phyp.h b/drivers/net/ehea/ehea_phyp.h index 90acddb068a1..d17a45a7e717 100644 --- a/drivers/net/ehea/ehea_phyp.h +++ b/drivers/net/ehea/ehea_phyp.h | |||
@@ -414,7 +414,11 @@ u64 ehea_h_register_rpage(const u64 adapter_handle, | |||
414 | 414 | ||
415 | u64 ehea_h_disable_and_get_hea(const u64 adapter_handle, const u64 qp_handle); | 415 | u64 ehea_h_disable_and_get_hea(const u64 adapter_handle, const u64 qp_handle); |
416 | 416 | ||
417 | u64 ehea_h_free_resource(const u64 adapter_handle, const u64 res_handle); | 417 | #define FORCE_FREE 1 |
418 | #define NORMAL_FREE 0 | ||
419 | |||
420 | u64 ehea_h_free_resource(const u64 adapter_handle, const u64 res_handle, | ||
421 | u64 force_bit); | ||
418 | 422 | ||
419 | u64 ehea_h_alloc_resource_mr(const u64 adapter_handle, const u64 vaddr, | 423 | u64 ehea_h_alloc_resource_mr(const u64 adapter_handle, const u64 vaddr, |
420 | const u64 length, const u32 access_ctrl, | 424 | const u64 length, const u32 access_ctrl, |
diff --git a/drivers/net/ehea/ehea_qmr.c b/drivers/net/ehea/ehea_qmr.c index 96ff3b679996..f24a8862977d 100644 --- a/drivers/net/ehea/ehea_qmr.c +++ b/drivers/net/ehea/ehea_qmr.c | |||
@@ -197,7 +197,7 @@ out_kill_hwq: | |||
197 | hw_queue_dtor(&cq->hw_queue); | 197 | hw_queue_dtor(&cq->hw_queue); |
198 | 198 | ||
199 | out_freeres: | 199 | out_freeres: |
200 | ehea_h_free_resource(adapter->handle, cq->fw_handle); | 200 | ehea_h_free_resource(adapter->handle, cq->fw_handle, FORCE_FREE); |
201 | 201 | ||
202 | out_freemem: | 202 | out_freemem: |
203 | kfree(cq); | 203 | kfree(cq); |
@@ -206,25 +206,38 @@ out_nomem: | |||
206 | return NULL; | 206 | return NULL; |
207 | } | 207 | } |
208 | 208 | ||
209 | int ehea_destroy_cq(struct ehea_cq *cq) | 209 | u64 ehea_destroy_cq_res(struct ehea_cq *cq, u64 force) |
210 | { | 210 | { |
211 | u64 adapter_handle, hret; | 211 | u64 hret; |
212 | u64 adapter_handle = cq->adapter->handle; | ||
213 | |||
214 | /* deregister all previous registered pages */ | ||
215 | hret = ehea_h_free_resource(adapter_handle, cq->fw_handle, force); | ||
216 | if (hret != H_SUCCESS) | ||
217 | return hret; | ||
218 | |||
219 | hw_queue_dtor(&cq->hw_queue); | ||
220 | kfree(cq); | ||
221 | |||
222 | return hret; | ||
223 | } | ||
212 | 224 | ||
225 | int ehea_destroy_cq(struct ehea_cq *cq) | ||
226 | { | ||
227 | u64 hret; | ||
213 | if (!cq) | 228 | if (!cq) |
214 | return 0; | 229 | return 0; |
215 | 230 | ||
216 | adapter_handle = cq->adapter->handle; | 231 | if ((hret = ehea_destroy_cq_res(cq, NORMAL_FREE)) == H_R_STATE) { |
232 | ehea_error_data(cq->adapter, cq->fw_handle); | ||
233 | hret = ehea_destroy_cq_res(cq, FORCE_FREE); | ||
234 | } | ||
217 | 235 | ||
218 | /* deregister all previous registered pages */ | ||
219 | hret = ehea_h_free_resource(adapter_handle, cq->fw_handle); | ||
220 | if (hret != H_SUCCESS) { | 236 | if (hret != H_SUCCESS) { |
221 | ehea_error("destroy CQ failed"); | 237 | ehea_error("destroy CQ failed"); |
222 | return -EIO; | 238 | return -EIO; |
223 | } | 239 | } |
224 | 240 | ||
225 | hw_queue_dtor(&cq->hw_queue); | ||
226 | kfree(cq); | ||
227 | |||
228 | return 0; | 241 | return 0; |
229 | } | 242 | } |
230 | 243 | ||
@@ -297,7 +310,7 @@ out_kill_hwq: | |||
297 | hw_queue_dtor(&eq->hw_queue); | 310 | hw_queue_dtor(&eq->hw_queue); |
298 | 311 | ||
299 | out_freeres: | 312 | out_freeres: |
300 | ehea_h_free_resource(adapter->handle, eq->fw_handle); | 313 | ehea_h_free_resource(adapter->handle, eq->fw_handle, FORCE_FREE); |
301 | 314 | ||
302 | out_freemem: | 315 | out_freemem: |
303 | kfree(eq); | 316 | kfree(eq); |
@@ -316,27 +329,41 @@ struct ehea_eqe *ehea_poll_eq(struct ehea_eq *eq) | |||
316 | return eqe; | 329 | return eqe; |
317 | } | 330 | } |
318 | 331 | ||
319 | int ehea_destroy_eq(struct ehea_eq *eq) | 332 | u64 ehea_destroy_eq_res(struct ehea_eq *eq, u64 force) |
320 | { | 333 | { |
321 | u64 hret; | 334 | u64 hret; |
322 | unsigned long flags; | 335 | unsigned long flags; |
323 | 336 | ||
324 | if (!eq) | ||
325 | return 0; | ||
326 | |||
327 | spin_lock_irqsave(&eq->spinlock, flags); | 337 | spin_lock_irqsave(&eq->spinlock, flags); |
328 | 338 | ||
329 | hret = ehea_h_free_resource(eq->adapter->handle, eq->fw_handle); | 339 | hret = ehea_h_free_resource(eq->adapter->handle, eq->fw_handle, force); |
330 | spin_unlock_irqrestore(&eq->spinlock, flags); | 340 | spin_unlock_irqrestore(&eq->spinlock, flags); |
331 | 341 | ||
332 | if (hret != H_SUCCESS) { | 342 | if (hret != H_SUCCESS) |
333 | ehea_error("destroy_eq failed"); | 343 | return hret; |
334 | return -EIO; | ||
335 | } | ||
336 | 344 | ||
337 | hw_queue_dtor(&eq->hw_queue); | 345 | hw_queue_dtor(&eq->hw_queue); |
338 | kfree(eq); | 346 | kfree(eq); |
339 | 347 | ||
348 | return hret; | ||
349 | } | ||
350 | |||
351 | int ehea_destroy_eq(struct ehea_eq *eq) | ||
352 | { | ||
353 | u64 hret; | ||
354 | if (!eq) | ||
355 | return 0; | ||
356 | |||
357 | if ((hret = ehea_destroy_eq_res(eq, NORMAL_FREE)) == H_R_STATE) { | ||
358 | ehea_error_data(eq->adapter, eq->fw_handle); | ||
359 | hret = ehea_destroy_eq_res(eq, FORCE_FREE); | ||
360 | } | ||
361 | |||
362 | if (hret != H_SUCCESS) { | ||
363 | ehea_error("destroy EQ failed"); | ||
364 | return -EIO; | ||
365 | } | ||
366 | |||
340 | return 0; | 367 | return 0; |
341 | } | 368 | } |
342 | 369 | ||
@@ -471,41 +498,56 @@ out_kill_hwsq: | |||
471 | 498 | ||
472 | out_freeres: | 499 | out_freeres: |
473 | ehea_h_disable_and_get_hea(adapter->handle, qp->fw_handle); | 500 | ehea_h_disable_and_get_hea(adapter->handle, qp->fw_handle); |
474 | ehea_h_free_resource(adapter->handle, qp->fw_handle); | 501 | ehea_h_free_resource(adapter->handle, qp->fw_handle, FORCE_FREE); |
475 | 502 | ||
476 | out_freemem: | 503 | out_freemem: |
477 | kfree(qp); | 504 | kfree(qp); |
478 | return NULL; | 505 | return NULL; |
479 | } | 506 | } |
480 | 507 | ||
481 | int ehea_destroy_qp(struct ehea_qp *qp) | 508 | u64 ehea_destroy_qp_res(struct ehea_qp *qp, u64 force) |
482 | { | 509 | { |
483 | u64 hret; | 510 | u64 hret; |
484 | struct ehea_qp_init_attr *qp_attr = &qp->init_attr; | 511 | struct ehea_qp_init_attr *qp_attr = &qp->init_attr; |
485 | 512 | ||
486 | if (!qp) | ||
487 | return 0; | ||
488 | 513 | ||
489 | ehea_h_disable_and_get_hea(qp->adapter->handle, qp->fw_handle); | 514 | ehea_h_disable_and_get_hea(qp->adapter->handle, qp->fw_handle); |
490 | hret = ehea_h_free_resource(qp->adapter->handle, qp->fw_handle); | 515 | hret = ehea_h_free_resource(qp->adapter->handle, qp->fw_handle, force); |
491 | if (hret != H_SUCCESS) { | 516 | if (hret != H_SUCCESS) |
492 | ehea_error("destroy_qp failed"); | 517 | return hret; |
493 | return -EIO; | ||
494 | } | ||
495 | 518 | ||
496 | hw_queue_dtor(&qp->hw_squeue); | 519 | hw_queue_dtor(&qp->hw_squeue); |
497 | hw_queue_dtor(&qp->hw_rqueue1); | 520 | hw_queue_dtor(&qp->hw_rqueue1); |
498 | 521 | ||
499 | if (qp_attr->rq_count > 1) | 522 | if (qp_attr->rq_count > 1) |
500 | hw_queue_dtor(&qp->hw_rqueue2); | 523 | hw_queue_dtor(&qp->hw_rqueue2); |
501 | if (qp_attr->rq_count > 2) | 524 | if (qp_attr->rq_count > 2) |
502 | hw_queue_dtor(&qp->hw_rqueue3); | 525 | hw_queue_dtor(&qp->hw_rqueue3); |
503 | kfree(qp); | 526 | kfree(qp); |
504 | 527 | ||
505 | return 0; | 528 | return hret; |
506 | } | 529 | } |
507 | 530 | ||
508 | int ehea_reg_mr_adapter(struct ehea_adapter *adapter) | 531 | int ehea_destroy_qp(struct ehea_qp *qp) |
532 | { | ||
533 | u64 hret; | ||
534 | if (!qp) | ||
535 | return 0; | ||
536 | |||
537 | if ((hret = ehea_destroy_qp_res(qp, NORMAL_FREE)) == H_R_STATE) { | ||
538 | ehea_error_data(qp->adapter, qp->fw_handle); | ||
539 | hret = ehea_destroy_qp_res(qp, FORCE_FREE); | ||
540 | } | ||
541 | |||
542 | if (hret != H_SUCCESS) { | ||
543 | ehea_error("destroy QP failed"); | ||
544 | return -EIO; | ||
545 | } | ||
546 | |||
547 | return 0; | ||
548 | } | ||
549 | |||
550 | int ehea_reg_kernel_mr(struct ehea_adapter *adapter, struct ehea_mr *mr) | ||
509 | { | 551 | { |
510 | int i, k, ret; | 552 | int i, k, ret; |
511 | u64 hret, pt_abs, start, end, nr_pages; | 553 | u64 hret, pt_abs, start, end, nr_pages; |
@@ -526,14 +568,14 @@ int ehea_reg_mr_adapter(struct ehea_adapter *adapter) | |||
526 | 568 | ||
527 | hret = ehea_h_alloc_resource_mr(adapter->handle, start, end - start, | 569 | hret = ehea_h_alloc_resource_mr(adapter->handle, start, end - start, |
528 | acc_ctrl, adapter->pd, | 570 | acc_ctrl, adapter->pd, |
529 | &adapter->mr.handle, &adapter->mr.lkey); | 571 | &mr->handle, &mr->lkey); |
530 | if (hret != H_SUCCESS) { | 572 | if (hret != H_SUCCESS) { |
531 | ehea_error("alloc_resource_mr failed"); | 573 | ehea_error("alloc_resource_mr failed"); |
532 | ret = -EIO; | 574 | ret = -EIO; |
533 | goto out; | 575 | goto out; |
534 | } | 576 | } |
535 | 577 | ||
536 | adapter->mr.vaddr = KERNELBASE; | 578 | mr->vaddr = KERNELBASE; |
537 | k = 0; | 579 | k = 0; |
538 | 580 | ||
539 | while (nr_pages > 0) { | 581 | while (nr_pages > 0) { |
@@ -545,7 +587,7 @@ int ehea_reg_mr_adapter(struct ehea_adapter *adapter) | |||
545 | EHEA_PAGESIZE))); | 587 | EHEA_PAGESIZE))); |
546 | 588 | ||
547 | hret = ehea_h_register_rpage_mr(adapter->handle, | 589 | hret = ehea_h_register_rpage_mr(adapter->handle, |
548 | adapter->mr.handle, 0, | 590 | mr->handle, 0, |
549 | 0, (u64)pt_abs, | 591 | 0, (u64)pt_abs, |
550 | num_pages); | 592 | num_pages); |
551 | nr_pages -= num_pages; | 593 | nr_pages -= num_pages; |
@@ -554,34 +596,68 @@ int ehea_reg_mr_adapter(struct ehea_adapter *adapter) | |||
554 | (k * EHEA_PAGESIZE))); | 596 | (k * EHEA_PAGESIZE))); |
555 | 597 | ||
556 | hret = ehea_h_register_rpage_mr(adapter->handle, | 598 | hret = ehea_h_register_rpage_mr(adapter->handle, |
557 | adapter->mr.handle, 0, | 599 | mr->handle, 0, |
558 | 0, abs_adr,1); | 600 | 0, abs_adr,1); |
559 | nr_pages--; | 601 | nr_pages--; |
560 | } | 602 | } |
561 | 603 | ||
562 | if ((hret != H_SUCCESS) && (hret != H_PAGE_REGISTERED)) { | 604 | if ((hret != H_SUCCESS) && (hret != H_PAGE_REGISTERED)) { |
563 | ehea_h_free_resource(adapter->handle, | 605 | ehea_h_free_resource(adapter->handle, |
564 | adapter->mr.handle); | 606 | mr->handle, FORCE_FREE); |
565 | ehea_error("register_rpage_mr failed: hret = %lX", | 607 | ehea_error("register_rpage_mr failed"); |
566 | hret); | ||
567 | ret = -EIO; | 608 | ret = -EIO; |
568 | goto out; | 609 | goto out; |
569 | } | 610 | } |
570 | } | 611 | } |
571 | 612 | ||
572 | if (hret != H_SUCCESS) { | 613 | if (hret != H_SUCCESS) { |
573 | ehea_h_free_resource(adapter->handle, adapter->mr.handle); | 614 | ehea_h_free_resource(adapter->handle, mr->handle, |
574 | ehea_error("register_rpage failed for last page: hret = %lX", | 615 | FORCE_FREE); |
575 | hret); | 616 | ehea_error("register_rpage failed for last page"); |
576 | ret = -EIO; | 617 | ret = -EIO; |
577 | goto out; | 618 | goto out; |
578 | } | 619 | } |
620 | |||
621 | mr->adapter = adapter; | ||
579 | ret = 0; | 622 | ret = 0; |
580 | out: | 623 | out: |
581 | kfree(pt); | 624 | kfree(pt); |
582 | return ret; | 625 | return ret; |
583 | } | 626 | } |
584 | 627 | ||
628 | int ehea_rem_mr(struct ehea_mr *mr) | ||
629 | { | ||
630 | u64 hret; | ||
631 | |||
632 | if (!mr || !mr->adapter) | ||
633 | return -EINVAL; | ||
634 | |||
635 | hret = ehea_h_free_resource(mr->adapter->handle, mr->handle, | ||
636 | FORCE_FREE); | ||
637 | if (hret != H_SUCCESS) { | ||
638 | ehea_error("destroy MR failed"); | ||
639 | return -EIO; | ||
640 | } | ||
641 | |||
642 | return 0; | ||
643 | } | ||
644 | |||
645 | int ehea_gen_smr(struct ehea_adapter *adapter, struct ehea_mr *old_mr, | ||
646 | struct ehea_mr *shared_mr) | ||
647 | { | ||
648 | u64 hret; | ||
649 | |||
650 | hret = ehea_h_register_smr(adapter->handle, old_mr->handle, | ||
651 | old_mr->vaddr, EHEA_MR_ACC_CTRL, | ||
652 | adapter->pd, shared_mr); | ||
653 | if (hret != H_SUCCESS) | ||
654 | return -EIO; | ||
655 | |||
656 | shared_mr->adapter = adapter; | ||
657 | |||
658 | return 0; | ||
659 | } | ||
660 | |||
585 | void print_error_data(u64 *data) | 661 | void print_error_data(u64 *data) |
586 | { | 662 | { |
587 | int length; | 663 | int length; |
@@ -597,6 +673,14 @@ void print_error_data(u64 *data) | |||
597 | ehea_error("QP (resource=%lX) state: AER=0x%lX, AERR=0x%lX, " | 673 | ehea_error("QP (resource=%lX) state: AER=0x%lX, AERR=0x%lX, " |
598 | "port=%lX", resource, data[6], data[12], data[22]); | 674 | "port=%lX", resource, data[6], data[12], data[22]); |
599 | 675 | ||
676 | if (type == 0x4) /* Completion Queue */ | ||
677 | ehea_error("CQ (resource=%lX) state: AER=0x%lX", resource, | ||
678 | data[6]); | ||
679 | |||
680 | if (type == 0x3) /* Event Queue */ | ||
681 | ehea_error("EQ (resource=%lX) state: AER=0x%lX", resource, | ||
682 | data[6]); | ||
683 | |||
600 | ehea_dump(data, length, "error data"); | 684 | ehea_dump(data, length, "error data"); |
601 | } | 685 | } |
602 | 686 | ||
diff --git a/drivers/net/ehea/ehea_qmr.h b/drivers/net/ehea/ehea_qmr.h index 1ff60983504d..c0eb3e03a102 100644 --- a/drivers/net/ehea/ehea_qmr.h +++ b/drivers/net/ehea/ehea_qmr.h | |||
@@ -142,6 +142,8 @@ struct ehea_rwqe { | |||
142 | #define EHEA_CQE_STAT_ERR_MASK 0x721F | 142 | #define EHEA_CQE_STAT_ERR_MASK 0x721F |
143 | #define EHEA_CQE_STAT_FAT_ERR_MASK 0x1F | 143 | #define EHEA_CQE_STAT_FAT_ERR_MASK 0x1F |
144 | #define EHEA_CQE_STAT_ERR_TCP 0x4000 | 144 | #define EHEA_CQE_STAT_ERR_TCP 0x4000 |
145 | #define EHEA_CQE_STAT_ERR_IP 0x2000 | ||
146 | #define EHEA_CQE_STAT_ERR_CRC 0x1000 | ||
145 | 147 | ||
146 | struct ehea_cqe { | 148 | struct ehea_cqe { |
147 | u64 wr_id; /* work request ID from WQE */ | 149 | u64 wr_id; /* work request ID from WQE */ |
@@ -320,6 +322,11 @@ static inline struct ehea_cqe *ehea_poll_rq1(struct ehea_qp *qp, int *wqe_index) | |||
320 | return hw_qeit_get_valid(queue); | 322 | return hw_qeit_get_valid(queue); |
321 | } | 323 | } |
322 | 324 | ||
325 | static inline void ehea_inc_cq(struct ehea_cq *cq) | ||
326 | { | ||
327 | hw_qeit_inc(&cq->hw_queue); | ||
328 | } | ||
329 | |||
323 | static inline void ehea_inc_rq1(struct ehea_qp *qp) | 330 | static inline void ehea_inc_rq1(struct ehea_qp *qp) |
324 | { | 331 | { |
325 | hw_qeit_inc(&qp->hw_rqueue1); | 332 | hw_qeit_inc(&qp->hw_rqueue1); |
@@ -327,7 +334,7 @@ static inline void ehea_inc_rq1(struct ehea_qp *qp) | |||
327 | 334 | ||
328 | static inline struct ehea_cqe *ehea_poll_cq(struct ehea_cq *my_cq) | 335 | static inline struct ehea_cqe *ehea_poll_cq(struct ehea_cq *my_cq) |
329 | { | 336 | { |
330 | return hw_qeit_get_inc_valid(&my_cq->hw_queue); | 337 | return hw_qeit_get_valid(&my_cq->hw_queue); |
331 | } | 338 | } |
332 | 339 | ||
333 | #define EHEA_CQ_REGISTER_ORIG 0 | 340 | #define EHEA_CQ_REGISTER_ORIG 0 |
@@ -356,7 +363,12 @@ struct ehea_qp *ehea_create_qp(struct ehea_adapter * adapter, u32 pd, | |||
356 | 363 | ||
357 | int ehea_destroy_qp(struct ehea_qp *qp); | 364 | int ehea_destroy_qp(struct ehea_qp *qp); |
358 | 365 | ||
359 | int ehea_reg_mr_adapter(struct ehea_adapter *adapter); | 366 | int ehea_reg_kernel_mr(struct ehea_adapter *adapter, struct ehea_mr *mr); |
367 | |||
368 | int ehea_gen_smr(struct ehea_adapter *adapter, struct ehea_mr *old_mr, | ||
369 | struct ehea_mr *shared_mr); | ||
370 | |||
371 | int ehea_rem_mr(struct ehea_mr *mr); | ||
360 | 372 | ||
361 | void ehea_error_data(struct ehea_adapter *adapter, u64 res_handle); | 373 | void ehea_error_data(struct ehea_adapter *adapter, u64 res_handle); |
362 | 374 | ||