diff options
author | Upinder Malhi <umalhi@cisco.com> | 2014-01-09 17:48:18 -0500 |
---|---|---|
committer | Roland Dreier <roland@purestorage.com> | 2014-01-14 03:44:44 -0500 |
commit | e45e614e4015a489d2f8013eaed45d498d884e86 (patch) | |
tree | 282626234d38d4cb3d32e74012c9fe4dd7b83723 /drivers/infiniband/hw/usnic/usnic_ib_qp_grp.c | |
parent | c7845bcafe4d2ecd5c479fa64d1b425c21dde17c (diff) |
IB/usnic: Add UDP support in usnic_ib_qp_grp.[hc]
UDP support for qp_grps/qps.
Signed-off-by: Upinder Malhi <umalhi@cisco.com>
Signed-off-by: Roland Dreier <roland@purestorage.com>
Diffstat (limited to 'drivers/infiniband/hw/usnic/usnic_ib_qp_grp.c')
-rw-r--r-- | drivers/infiniband/hw/usnic/usnic_ib_qp_grp.c | 88 |
1 files changed, 88 insertions, 0 deletions
diff --git a/drivers/infiniband/hw/usnic/usnic_ib_qp_grp.c b/drivers/infiniband/hw/usnic/usnic_ib_qp_grp.c index 2b7e0a1a07b4..d6667a198d0b 100644 --- a/drivers/infiniband/hw/usnic/usnic_ib_qp_grp.c +++ b/drivers/infiniband/hw/usnic/usnic_ib_qp_grp.c | |||
@@ -246,6 +246,80 @@ static void release_roce_custom_flow(struct usnic_ib_qp_grp_flow *qp_flow) | |||
246 | } | 246 | } |
247 | 247 | ||
248 | static struct usnic_ib_qp_grp_flow* | 248 | static struct usnic_ib_qp_grp_flow* |
249 | create_udp_flow(struct usnic_ib_qp_grp *qp_grp, | ||
250 | struct usnic_transport_spec *trans_spec) | ||
251 | { | ||
252 | struct socket *sock; | ||
253 | int sock_fd; | ||
254 | int err; | ||
255 | struct filter filter; | ||
256 | struct usnic_filter_action uaction; | ||
257 | struct usnic_ib_qp_grp_flow *qp_flow; | ||
258 | struct usnic_fwd_flow *flow; | ||
259 | enum usnic_transport_type trans_type; | ||
260 | uint32_t addr; | ||
261 | uint16_t port_num; | ||
262 | int proto; | ||
263 | |||
264 | trans_type = trans_spec->trans_type; | ||
265 | sock_fd = trans_spec->udp.sock_fd; | ||
266 | |||
267 | /* Get and check socket */ | ||
268 | sock = usnic_transport_get_socket(sock_fd); | ||
269 | if (IS_ERR_OR_NULL(sock)) | ||
270 | return ERR_CAST(sock); | ||
271 | |||
272 | err = usnic_transport_sock_get_addr(sock, &proto, &addr, &port_num); | ||
273 | if (err) | ||
274 | goto out_put_sock; | ||
275 | |||
276 | if (proto != IPPROTO_UDP) { | ||
277 | usnic_err("Protocol for fd %d is not UDP", sock_fd); | ||
278 | err = -EPERM; | ||
279 | goto out_put_sock; | ||
280 | } | ||
281 | |||
282 | /* Create flow */ | ||
283 | usnic_fwd_init_udp_filter(&filter, addr, port_num); | ||
284 | err = init_filter_action(qp_grp, &uaction); | ||
285 | if (err) | ||
286 | goto out_put_sock; | ||
287 | |||
288 | flow = usnic_fwd_alloc_flow(qp_grp->ufdev, &filter, &uaction); | ||
289 | if (IS_ERR_OR_NULL(flow)) { | ||
290 | usnic_err("Unable to alloc flow failed with err %ld\n", | ||
291 | PTR_ERR(flow)); | ||
292 | err = (flow) ? PTR_ERR(flow) : -EFAULT; | ||
293 | goto out_put_sock; | ||
294 | } | ||
295 | |||
296 | /* Create qp_flow */ | ||
297 | qp_flow = kzalloc(sizeof(*qp_flow), GFP_ATOMIC); | ||
298 | if (IS_ERR_OR_NULL(qp_flow)) { | ||
299 | err = (qp_flow) ? PTR_ERR(qp_flow) : -ENOMEM; | ||
300 | goto out_dealloc_flow; | ||
301 | } | ||
302 | qp_flow->flow = flow; | ||
303 | qp_flow->trans_type = trans_type; | ||
304 | qp_flow->udp.sock = sock; | ||
305 | qp_flow->qp_grp = qp_grp; | ||
306 | return qp_flow; | ||
307 | |||
308 | out_dealloc_flow: | ||
309 | usnic_fwd_dealloc_flow(flow); | ||
310 | out_put_sock: | ||
311 | usnic_transport_put_socket(sock); | ||
312 | return ERR_PTR(err); | ||
313 | } | ||
314 | |||
315 | static void release_udp_flow(struct usnic_ib_qp_grp_flow *qp_flow) | ||
316 | { | ||
317 | usnic_fwd_dealloc_flow(qp_flow->flow); | ||
318 | usnic_transport_put_socket(qp_flow->udp.sock); | ||
319 | kfree(qp_flow); | ||
320 | } | ||
321 | |||
322 | static struct usnic_ib_qp_grp_flow* | ||
249 | create_and_add_flow(struct usnic_ib_qp_grp *qp_grp, | 323 | create_and_add_flow(struct usnic_ib_qp_grp *qp_grp, |
250 | struct usnic_transport_spec *trans_spec) | 324 | struct usnic_transport_spec *trans_spec) |
251 | { | 325 | { |
@@ -257,6 +331,9 @@ create_and_add_flow(struct usnic_ib_qp_grp *qp_grp, | |||
257 | case USNIC_TRANSPORT_ROCE_CUSTOM: | 331 | case USNIC_TRANSPORT_ROCE_CUSTOM: |
258 | qp_flow = create_roce_custom_flow(qp_grp, trans_spec); | 332 | qp_flow = create_roce_custom_flow(qp_grp, trans_spec); |
259 | break; | 333 | break; |
334 | case USNIC_TRANSPORT_IPV4_UDP: | ||
335 | qp_flow = create_udp_flow(qp_grp, trans_spec); | ||
336 | break; | ||
260 | default: | 337 | default: |
261 | usnic_err("Unsupported transport %u\n", | 338 | usnic_err("Unsupported transport %u\n", |
262 | trans_spec->trans_type); | 339 | trans_spec->trans_type); |
@@ -278,6 +355,9 @@ static void release_and_remove_flow(struct usnic_ib_qp_grp_flow *qp_flow) | |||
278 | case USNIC_TRANSPORT_ROCE_CUSTOM: | 355 | case USNIC_TRANSPORT_ROCE_CUSTOM: |
279 | release_roce_custom_flow(qp_flow); | 356 | release_roce_custom_flow(qp_flow); |
280 | break; | 357 | break; |
358 | case USNIC_TRANSPORT_IPV4_UDP: | ||
359 | release_udp_flow(qp_flow); | ||
360 | break; | ||
281 | default: | 361 | default: |
282 | WARN(1, "Unsupported transport %u\n", | 362 | WARN(1, "Unsupported transport %u\n", |
283 | qp_flow->trans_type); | 363 | qp_flow->trans_type); |
@@ -544,11 +624,19 @@ static int qp_grp_id_from_flow(struct usnic_ib_qp_grp_flow *qp_flow, | |||
544 | uint32_t *id) | 624 | uint32_t *id) |
545 | { | 625 | { |
546 | enum usnic_transport_type trans_type = qp_flow->trans_type; | 626 | enum usnic_transport_type trans_type = qp_flow->trans_type; |
627 | int err; | ||
547 | 628 | ||
548 | switch (trans_type) { | 629 | switch (trans_type) { |
549 | case USNIC_TRANSPORT_ROCE_CUSTOM: | 630 | case USNIC_TRANSPORT_ROCE_CUSTOM: |
550 | *id = qp_flow->usnic_roce.port_num; | 631 | *id = qp_flow->usnic_roce.port_num; |
551 | break; | 632 | break; |
633 | case USNIC_TRANSPORT_IPV4_UDP: | ||
634 | err = usnic_transport_sock_get_addr(qp_flow->udp.sock, | ||
635 | NULL, NULL, | ||
636 | (uint16_t *) id); | ||
637 | if (err) | ||
638 | return err; | ||
639 | break; | ||
552 | default: | 640 | default: |
553 | usnic_err("Unsupported transport %u\n", trans_type); | 641 | usnic_err("Unsupported transport %u\n", trans_type); |
554 | return -EINVAL; | 642 | return -EINVAL; |