diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-12-21 19:40:26 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-12-21 19:40:26 -0500 |
commit | 184e2516614f7055d4c3a2e63fd8a3eb95fff6d6 (patch) | |
tree | 9822dd3cc97f8cfed3cbda6167818b60355cc7ec /drivers/infiniband/hw | |
parent | 0264405b84505f60ae00625f261e75a32c7ddf56 (diff) | |
parent | d72623b665d84b1e07fe43854e83387fce8dd134 (diff) |
Merge tag 'rdma-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/roland/infiniband
Pull more infiniband changes from Roland Dreier:
"Second batch of InfiniBand/RDMA changes for 3.8:
- cxgb4 changes to fix lookup engine hash collisions
- mlx4 changes to make flow steering usable
- fix to IPoIB to avoid pinning dst reference for too long"
* tag 'rdma-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/roland/infiniband:
RDMA/cxgb4: Fix bug for active and passive LE hash collision path
RDMA/cxgb4: Fix LE hash collision bug for passive open connection
RDMA/cxgb4: Fix LE hash collision bug for active open connection
mlx4_core: Allow choosing flow steering mode
mlx4_core: Adjustments to Flow Steering activation logic for SR-IOV
mlx4_core: Fix error flow in the flow steering wrapper
mlx4_core: Add QPN enforcement for flow steering rules set by VFs
cxgb4: Add LE hash collision bug fix path in LLD driver
cxgb4: Add T4 filter support
IPoIB: Call skb_dst_drop() once skb is enqueued for sending
Diffstat (limited to 'drivers/infiniband/hw')
-rw-r--r-- | drivers/infiniband/hw/cxgb4/cm.c | 791 | ||||
-rw-r--r-- | drivers/infiniband/hw/cxgb4/device.c | 210 | ||||
-rw-r--r-- | drivers/infiniband/hw/cxgb4/iw_cxgb4.h | 33 |
3 files changed, 919 insertions, 115 deletions
diff --git a/drivers/infiniband/hw/cxgb4/cm.c b/drivers/infiniband/hw/cxgb4/cm.c index 5de86968379d..c13745cde7fa 100644 --- a/drivers/infiniband/hw/cxgb4/cm.c +++ b/drivers/infiniband/hw/cxgb4/cm.c | |||
@@ -38,10 +38,12 @@ | |||
38 | #include <linux/inetdevice.h> | 38 | #include <linux/inetdevice.h> |
39 | #include <linux/ip.h> | 39 | #include <linux/ip.h> |
40 | #include <linux/tcp.h> | 40 | #include <linux/tcp.h> |
41 | #include <linux/if_vlan.h> | ||
41 | 42 | ||
42 | #include <net/neighbour.h> | 43 | #include <net/neighbour.h> |
43 | #include <net/netevent.h> | 44 | #include <net/netevent.h> |
44 | #include <net/route.h> | 45 | #include <net/route.h> |
46 | #include <net/tcp.h> | ||
45 | 47 | ||
46 | #include "iw_cxgb4.h" | 48 | #include "iw_cxgb4.h" |
47 | 49 | ||
@@ -61,6 +63,14 @@ static char *states[] = { | |||
61 | NULL, | 63 | NULL, |
62 | }; | 64 | }; |
63 | 65 | ||
66 | static int nocong; | ||
67 | module_param(nocong, int, 0644); | ||
68 | MODULE_PARM_DESC(nocong, "Turn of congestion control (default=0)"); | ||
69 | |||
70 | static int enable_ecn; | ||
71 | module_param(enable_ecn, int, 0644); | ||
72 | MODULE_PARM_DESC(enable_ecn, "Enable ECN (default=0/disabled)"); | ||
73 | |||
64 | static int dack_mode = 1; | 74 | static int dack_mode = 1; |
65 | module_param(dack_mode, int, 0644); | 75 | module_param(dack_mode, int, 0644); |
66 | MODULE_PARM_DESC(dack_mode, "Delayed ack mode (default=1)"); | 76 | MODULE_PARM_DESC(dack_mode, "Delayed ack mode (default=1)"); |
@@ -265,6 +275,7 @@ void _c4iw_free_ep(struct kref *kref) | |||
265 | cxgb4_remove_tid(ep->com.dev->rdev.lldi.tids, 0, ep->hwtid); | 275 | cxgb4_remove_tid(ep->com.dev->rdev.lldi.tids, 0, ep->hwtid); |
266 | dst_release(ep->dst); | 276 | dst_release(ep->dst); |
267 | cxgb4_l2t_release(ep->l2t); | 277 | cxgb4_l2t_release(ep->l2t); |
278 | remove_handle(ep->com.dev, &ep->com.dev->hwtid_idr, ep->hwtid); | ||
268 | } | 279 | } |
269 | kfree(ep); | 280 | kfree(ep); |
270 | } | 281 | } |
@@ -441,6 +452,50 @@ static int send_abort(struct c4iw_ep *ep, struct sk_buff *skb, gfp_t gfp) | |||
441 | return c4iw_l2t_send(&ep->com.dev->rdev, skb, ep->l2t); | 452 | return c4iw_l2t_send(&ep->com.dev->rdev, skb, ep->l2t); |
442 | } | 453 | } |
443 | 454 | ||
455 | #define VLAN_NONE 0xfff | ||
456 | #define FILTER_SEL_VLAN_NONE 0xffff | ||
457 | #define FILTER_SEL_WIDTH_P_FC (3+1) /* port uses 3 bits, FCoE one bit */ | ||
458 | #define FILTER_SEL_WIDTH_VIN_P_FC \ | ||
459 | (6 + 7 + FILTER_SEL_WIDTH_P_FC) /* 6 bits are unused, VF uses 7 bits*/ | ||
460 | #define FILTER_SEL_WIDTH_TAG_P_FC \ | ||
461 | (3 + FILTER_SEL_WIDTH_VIN_P_FC) /* PF uses 3 bits */ | ||
462 | #define FILTER_SEL_WIDTH_VLD_TAG_P_FC (1 + FILTER_SEL_WIDTH_TAG_P_FC) | ||
463 | |||
464 | static unsigned int select_ntuple(struct c4iw_dev *dev, struct dst_entry *dst, | ||
465 | struct l2t_entry *l2t) | ||
466 | { | ||
467 | unsigned int ntuple = 0; | ||
468 | u32 viid; | ||
469 | |||
470 | switch (dev->rdev.lldi.filt_mode) { | ||
471 | |||
472 | /* default filter mode */ | ||
473 | case HW_TPL_FR_MT_PR_IV_P_FC: | ||
474 | if (l2t->vlan == VLAN_NONE) | ||
475 | ntuple |= FILTER_SEL_VLAN_NONE << FILTER_SEL_WIDTH_P_FC; | ||
476 | else { | ||
477 | ntuple |= l2t->vlan << FILTER_SEL_WIDTH_P_FC; | ||
478 | ntuple |= 1 << FILTER_SEL_WIDTH_VLD_TAG_P_FC; | ||
479 | } | ||
480 | ntuple |= l2t->lport << S_PORT | IPPROTO_TCP << | ||
481 | FILTER_SEL_WIDTH_VLD_TAG_P_FC; | ||
482 | break; | ||
483 | case HW_TPL_FR_MT_PR_OV_P_FC: { | ||
484 | viid = cxgb4_port_viid(l2t->neigh->dev); | ||
485 | |||
486 | ntuple |= FW_VIID_VIN_GET(viid) << FILTER_SEL_WIDTH_P_FC; | ||
487 | ntuple |= FW_VIID_PFN_GET(viid) << FILTER_SEL_WIDTH_VIN_P_FC; | ||
488 | ntuple |= FW_VIID_VIVLD_GET(viid) << FILTER_SEL_WIDTH_TAG_P_FC; | ||
489 | ntuple |= l2t->lport << S_PORT | IPPROTO_TCP << | ||
490 | FILTER_SEL_WIDTH_VLD_TAG_P_FC; | ||
491 | break; | ||
492 | } | ||
493 | default: | ||
494 | break; | ||
495 | } | ||
496 | return ntuple; | ||
497 | } | ||
498 | |||
444 | static int send_connect(struct c4iw_ep *ep) | 499 | static int send_connect(struct c4iw_ep *ep) |
445 | { | 500 | { |
446 | struct cpl_act_open_req *req; | 501 | struct cpl_act_open_req *req; |
@@ -463,7 +518,8 @@ static int send_connect(struct c4iw_ep *ep) | |||
463 | 518 | ||
464 | cxgb4_best_mtu(ep->com.dev->rdev.lldi.mtus, ep->mtu, &mtu_idx); | 519 | cxgb4_best_mtu(ep->com.dev->rdev.lldi.mtus, ep->mtu, &mtu_idx); |
465 | wscale = compute_wscale(rcv_win); | 520 | wscale = compute_wscale(rcv_win); |
466 | opt0 = KEEP_ALIVE(1) | | 521 | opt0 = (nocong ? NO_CONG(1) : 0) | |
522 | KEEP_ALIVE(1) | | ||
467 | DELACK(1) | | 523 | DELACK(1) | |
468 | WND_SCALE(wscale) | | 524 | WND_SCALE(wscale) | |
469 | MSS_IDX(mtu_idx) | | 525 | MSS_IDX(mtu_idx) | |
@@ -474,6 +530,7 @@ static int send_connect(struct c4iw_ep *ep) | |||
474 | ULP_MODE(ULP_MODE_TCPDDP) | | 530 | ULP_MODE(ULP_MODE_TCPDDP) | |
475 | RCV_BUFSIZ(rcv_win>>10); | 531 | RCV_BUFSIZ(rcv_win>>10); |
476 | opt2 = RX_CHANNEL(0) | | 532 | opt2 = RX_CHANNEL(0) | |
533 | CCTRL_ECN(enable_ecn) | | ||
477 | RSS_QUEUE_VALID | RSS_QUEUE(ep->rss_qid); | 534 | RSS_QUEUE_VALID | RSS_QUEUE(ep->rss_qid); |
478 | if (enable_tcp_timestamps) | 535 | if (enable_tcp_timestamps) |
479 | opt2 |= TSTAMPS_EN(1); | 536 | opt2 |= TSTAMPS_EN(1); |
@@ -492,8 +549,9 @@ static int send_connect(struct c4iw_ep *ep) | |||
492 | req->local_ip = ep->com.local_addr.sin_addr.s_addr; | 549 | req->local_ip = ep->com.local_addr.sin_addr.s_addr; |
493 | req->peer_ip = ep->com.remote_addr.sin_addr.s_addr; | 550 | req->peer_ip = ep->com.remote_addr.sin_addr.s_addr; |
494 | req->opt0 = cpu_to_be64(opt0); | 551 | req->opt0 = cpu_to_be64(opt0); |
495 | req->params = 0; | 552 | req->params = cpu_to_be32(select_ntuple(ep->com.dev, ep->dst, ep->l2t)); |
496 | req->opt2 = cpu_to_be32(opt2); | 553 | req->opt2 = cpu_to_be32(opt2); |
554 | set_bit(ACT_OPEN_REQ, &ep->com.history); | ||
497 | return c4iw_l2t_send(&ep->com.dev->rdev, skb, ep->l2t); | 555 | return c4iw_l2t_send(&ep->com.dev->rdev, skb, ep->l2t); |
498 | } | 556 | } |
499 | 557 | ||
@@ -770,6 +828,7 @@ static int act_establish(struct c4iw_dev *dev, struct sk_buff *skb) | |||
770 | /* setup the hwtid for this connection */ | 828 | /* setup the hwtid for this connection */ |
771 | ep->hwtid = tid; | 829 | ep->hwtid = tid; |
772 | cxgb4_insert_tid(t, ep, tid); | 830 | cxgb4_insert_tid(t, ep, tid); |
831 | insert_handle(dev, &dev->hwtid_idr, ep, ep->hwtid); | ||
773 | 832 | ||
774 | ep->snd_seq = be32_to_cpu(req->snd_isn); | 833 | ep->snd_seq = be32_to_cpu(req->snd_isn); |
775 | ep->rcv_seq = be32_to_cpu(req->rcv_isn); | 834 | ep->rcv_seq = be32_to_cpu(req->rcv_isn); |
@@ -777,7 +836,9 @@ static int act_establish(struct c4iw_dev *dev, struct sk_buff *skb) | |||
777 | set_emss(ep, ntohs(req->tcp_opt)); | 836 | set_emss(ep, ntohs(req->tcp_opt)); |
778 | 837 | ||
779 | /* dealloc the atid */ | 838 | /* dealloc the atid */ |
839 | remove_handle(ep->com.dev, &ep->com.dev->atid_idr, atid); | ||
780 | cxgb4_free_atid(t, atid); | 840 | cxgb4_free_atid(t, atid); |
841 | set_bit(ACT_ESTAB, &ep->com.history); | ||
781 | 842 | ||
782 | /* start MPA negotiation */ | 843 | /* start MPA negotiation */ |
783 | send_flowc(ep, NULL); | 844 | send_flowc(ep, NULL); |
@@ -803,6 +864,7 @@ static void close_complete_upcall(struct c4iw_ep *ep) | |||
803 | ep->com.cm_id->rem_ref(ep->com.cm_id); | 864 | ep->com.cm_id->rem_ref(ep->com.cm_id); |
804 | ep->com.cm_id = NULL; | 865 | ep->com.cm_id = NULL; |
805 | ep->com.qp = NULL; | 866 | ep->com.qp = NULL; |
867 | set_bit(CLOSE_UPCALL, &ep->com.history); | ||
806 | } | 868 | } |
807 | } | 869 | } |
808 | 870 | ||
@@ -811,6 +873,7 @@ static int abort_connection(struct c4iw_ep *ep, struct sk_buff *skb, gfp_t gfp) | |||
811 | PDBG("%s ep %p tid %u\n", __func__, ep, ep->hwtid); | 873 | PDBG("%s ep %p tid %u\n", __func__, ep, ep->hwtid); |
812 | close_complete_upcall(ep); | 874 | close_complete_upcall(ep); |
813 | state_set(&ep->com, ABORTING); | 875 | state_set(&ep->com, ABORTING); |
876 | set_bit(ABORT_CONN, &ep->com.history); | ||
814 | return send_abort(ep, skb, gfp); | 877 | return send_abort(ep, skb, gfp); |
815 | } | 878 | } |
816 | 879 | ||
@@ -825,6 +888,7 @@ static void peer_close_upcall(struct c4iw_ep *ep) | |||
825 | PDBG("peer close delivered ep %p cm_id %p tid %u\n", | 888 | PDBG("peer close delivered ep %p cm_id %p tid %u\n", |
826 | ep, ep->com.cm_id, ep->hwtid); | 889 | ep, ep->com.cm_id, ep->hwtid); |
827 | ep->com.cm_id->event_handler(ep->com.cm_id, &event); | 890 | ep->com.cm_id->event_handler(ep->com.cm_id, &event); |
891 | set_bit(DISCONN_UPCALL, &ep->com.history); | ||
828 | } | 892 | } |
829 | } | 893 | } |
830 | 894 | ||
@@ -843,6 +907,7 @@ static void peer_abort_upcall(struct c4iw_ep *ep) | |||
843 | ep->com.cm_id->rem_ref(ep->com.cm_id); | 907 | ep->com.cm_id->rem_ref(ep->com.cm_id); |
844 | ep->com.cm_id = NULL; | 908 | ep->com.cm_id = NULL; |
845 | ep->com.qp = NULL; | 909 | ep->com.qp = NULL; |
910 | set_bit(ABORT_UPCALL, &ep->com.history); | ||
846 | } | 911 | } |
847 | } | 912 | } |
848 | 913 | ||
@@ -875,6 +940,7 @@ static void connect_reply_upcall(struct c4iw_ep *ep, int status) | |||
875 | 940 | ||
876 | PDBG("%s ep %p tid %u status %d\n", __func__, ep, | 941 | PDBG("%s ep %p tid %u status %d\n", __func__, ep, |
877 | ep->hwtid, status); | 942 | ep->hwtid, status); |
943 | set_bit(CONN_RPL_UPCALL, &ep->com.history); | ||
878 | ep->com.cm_id->event_handler(ep->com.cm_id, &event); | 944 | ep->com.cm_id->event_handler(ep->com.cm_id, &event); |
879 | 945 | ||
880 | if (status < 0) { | 946 | if (status < 0) { |
@@ -915,6 +981,7 @@ static void connect_request_upcall(struct c4iw_ep *ep) | |||
915 | ep->parent_ep->com.cm_id, | 981 | ep->parent_ep->com.cm_id, |
916 | &event); | 982 | &event); |
917 | } | 983 | } |
984 | set_bit(CONNREQ_UPCALL, &ep->com.history); | ||
918 | c4iw_put_ep(&ep->parent_ep->com); | 985 | c4iw_put_ep(&ep->parent_ep->com); |
919 | ep->parent_ep = NULL; | 986 | ep->parent_ep = NULL; |
920 | } | 987 | } |
@@ -931,6 +998,7 @@ static void established_upcall(struct c4iw_ep *ep) | |||
931 | if (ep->com.cm_id) { | 998 | if (ep->com.cm_id) { |
932 | PDBG("%s ep %p tid %u\n", __func__, ep, ep->hwtid); | 999 | PDBG("%s ep %p tid %u\n", __func__, ep, ep->hwtid); |
933 | ep->com.cm_id->event_handler(ep->com.cm_id, &event); | 1000 | ep->com.cm_id->event_handler(ep->com.cm_id, &event); |
1001 | set_bit(ESTAB_UPCALL, &ep->com.history); | ||
934 | } | 1002 | } |
935 | } | 1003 | } |
936 | 1004 | ||
@@ -1316,6 +1384,7 @@ static int rx_data(struct c4iw_dev *dev, struct sk_buff *skb) | |||
1316 | unsigned int dlen = ntohs(hdr->len); | 1384 | unsigned int dlen = ntohs(hdr->len); |
1317 | unsigned int tid = GET_TID(hdr); | 1385 | unsigned int tid = GET_TID(hdr); |
1318 | struct tid_info *t = dev->rdev.lldi.tids; | 1386 | struct tid_info *t = dev->rdev.lldi.tids; |
1387 | __u8 status = hdr->status; | ||
1319 | 1388 | ||
1320 | ep = lookup_tid(t, tid); | 1389 | ep = lookup_tid(t, tid); |
1321 | PDBG("%s ep %p tid %u dlen %u\n", __func__, ep, ep->hwtid, dlen); | 1390 | PDBG("%s ep %p tid %u dlen %u\n", __func__, ep, ep->hwtid, dlen); |
@@ -1338,9 +1407,9 @@ static int rx_data(struct c4iw_dev *dev, struct sk_buff *skb) | |||
1338 | case MPA_REP_SENT: | 1407 | case MPA_REP_SENT: |
1339 | break; | 1408 | break; |
1340 | default: | 1409 | default: |
1341 | printk(KERN_ERR MOD "%s Unexpected streaming data." | 1410 | pr_err("%s Unexpected streaming data." \ |
1342 | " ep %p state %d tid %u\n", | 1411 | " ep %p state %d tid %u status %d\n", |
1343 | __func__, ep, state_read(&ep->com), ep->hwtid); | 1412 | __func__, ep, state_read(&ep->com), ep->hwtid, status); |
1344 | 1413 | ||
1345 | /* | 1414 | /* |
1346 | * The ep will timeout and inform the ULP of the failure. | 1415 | * The ep will timeout and inform the ULP of the failure. |
@@ -1383,6 +1452,63 @@ static int abort_rpl(struct c4iw_dev *dev, struct sk_buff *skb) | |||
1383 | return 0; | 1452 | return 0; |
1384 | } | 1453 | } |
1385 | 1454 | ||
1455 | static void send_fw_act_open_req(struct c4iw_ep *ep, unsigned int atid) | ||
1456 | { | ||
1457 | struct sk_buff *skb; | ||
1458 | struct fw_ofld_connection_wr *req; | ||
1459 | unsigned int mtu_idx; | ||
1460 | int wscale; | ||
1461 | |||
1462 | skb = get_skb(NULL, sizeof(*req), GFP_KERNEL); | ||
1463 | req = (struct fw_ofld_connection_wr *)__skb_put(skb, sizeof(*req)); | ||
1464 | memset(req, 0, sizeof(*req)); | ||
1465 | req->op_compl = htonl(V_WR_OP(FW_OFLD_CONNECTION_WR)); | ||
1466 | req->len16_pkd = htonl(FW_WR_LEN16(DIV_ROUND_UP(sizeof(*req), 16))); | ||
1467 | req->le.filter = cpu_to_be32(select_ntuple(ep->com.dev, ep->dst, | ||
1468 | ep->l2t)); | ||
1469 | req->le.lport = ep->com.local_addr.sin_port; | ||
1470 | req->le.pport = ep->com.remote_addr.sin_port; | ||
1471 | req->le.u.ipv4.lip = ep->com.local_addr.sin_addr.s_addr; | ||
1472 | req->le.u.ipv4.pip = ep->com.remote_addr.sin_addr.s_addr; | ||
1473 | req->tcb.t_state_to_astid = | ||
1474 | htonl(V_FW_OFLD_CONNECTION_WR_T_STATE(TCP_SYN_SENT) | | ||
1475 | V_FW_OFLD_CONNECTION_WR_ASTID(atid)); | ||
1476 | req->tcb.cplrxdataack_cplpassacceptrpl = | ||
1477 | htons(F_FW_OFLD_CONNECTION_WR_CPLRXDATAACK); | ||
1478 | req->tcb.tx_max = jiffies; | ||
1479 | req->tcb.rcv_adv = htons(1); | ||
1480 | cxgb4_best_mtu(ep->com.dev->rdev.lldi.mtus, ep->mtu, &mtu_idx); | ||
1481 | wscale = compute_wscale(rcv_win); | ||
1482 | req->tcb.opt0 = TCAM_BYPASS(1) | | ||
1483 | (nocong ? NO_CONG(1) : 0) | | ||
1484 | KEEP_ALIVE(1) | | ||
1485 | DELACK(1) | | ||
1486 | WND_SCALE(wscale) | | ||
1487 | MSS_IDX(mtu_idx) | | ||
1488 | L2T_IDX(ep->l2t->idx) | | ||
1489 | TX_CHAN(ep->tx_chan) | | ||
1490 | SMAC_SEL(ep->smac_idx) | | ||
1491 | DSCP(ep->tos) | | ||
1492 | ULP_MODE(ULP_MODE_TCPDDP) | | ||
1493 | RCV_BUFSIZ(rcv_win >> 10); | ||
1494 | req->tcb.opt2 = PACE(1) | | ||
1495 | TX_QUEUE(ep->com.dev->rdev.lldi.tx_modq[ep->tx_chan]) | | ||
1496 | RX_CHANNEL(0) | | ||
1497 | CCTRL_ECN(enable_ecn) | | ||
1498 | RSS_QUEUE_VALID | RSS_QUEUE(ep->rss_qid); | ||
1499 | if (enable_tcp_timestamps) | ||
1500 | req->tcb.opt2 |= TSTAMPS_EN(1); | ||
1501 | if (enable_tcp_sack) | ||
1502 | req->tcb.opt2 |= SACK_EN(1); | ||
1503 | if (wscale && enable_tcp_window_scaling) | ||
1504 | req->tcb.opt2 |= WND_SCALE_EN(1); | ||
1505 | req->tcb.opt0 = cpu_to_be64(req->tcb.opt0); | ||
1506 | req->tcb.opt2 = cpu_to_be32(req->tcb.opt2); | ||
1507 | set_wr_txq(skb, CPL_PRIORITY_CONTROL, ep->ctrlq_idx); | ||
1508 | set_bit(ACT_OFLD_CONN, &ep->com.history); | ||
1509 | c4iw_l2t_send(&ep->com.dev->rdev, skb, ep->l2t); | ||
1510 | } | ||
1511 | |||
1386 | /* | 1512 | /* |
1387 | * Return whether a failed active open has allocated a TID | 1513 | * Return whether a failed active open has allocated a TID |
1388 | */ | 1514 | */ |
@@ -1392,6 +1518,111 @@ static inline int act_open_has_tid(int status) | |||
1392 | status != CPL_ERR_ARP_MISS; | 1518 | status != CPL_ERR_ARP_MISS; |
1393 | } | 1519 | } |
1394 | 1520 | ||
1521 | #define ACT_OPEN_RETRY_COUNT 2 | ||
1522 | |||
1523 | static int c4iw_reconnect(struct c4iw_ep *ep) | ||
1524 | { | ||
1525 | int err = 0; | ||
1526 | struct rtable *rt; | ||
1527 | struct port_info *pi; | ||
1528 | struct net_device *pdev; | ||
1529 | int step; | ||
1530 | struct neighbour *neigh; | ||
1531 | |||
1532 | PDBG("%s qp %p cm_id %p\n", __func__, ep->com.qp, ep->com.cm_id); | ||
1533 | init_timer(&ep->timer); | ||
1534 | |||
1535 | /* | ||
1536 | * Allocate an active TID to initiate a TCP connection. | ||
1537 | */ | ||
1538 | ep->atid = cxgb4_alloc_atid(ep->com.dev->rdev.lldi.tids, ep); | ||
1539 | if (ep->atid == -1) { | ||
1540 | pr_err("%s - cannot alloc atid.\n", __func__); | ||
1541 | err = -ENOMEM; | ||
1542 | goto fail2; | ||
1543 | } | ||
1544 | insert_handle(ep->com.dev, &ep->com.dev->atid_idr, ep, ep->atid); | ||
1545 | |||
1546 | /* find a route */ | ||
1547 | rt = find_route(ep->com.dev, | ||
1548 | ep->com.cm_id->local_addr.sin_addr.s_addr, | ||
1549 | ep->com.cm_id->remote_addr.sin_addr.s_addr, | ||
1550 | ep->com.cm_id->local_addr.sin_port, | ||
1551 | ep->com.cm_id->remote_addr.sin_port, 0); | ||
1552 | if (!rt) { | ||
1553 | pr_err("%s - cannot find route.\n", __func__); | ||
1554 | err = -EHOSTUNREACH; | ||
1555 | goto fail3; | ||
1556 | } | ||
1557 | ep->dst = &rt->dst; | ||
1558 | |||
1559 | neigh = dst_neigh_lookup(ep->dst, | ||
1560 | &ep->com.cm_id->remote_addr.sin_addr.s_addr); | ||
1561 | /* get a l2t entry */ | ||
1562 | if (neigh->dev->flags & IFF_LOOPBACK) { | ||
1563 | PDBG("%s LOOPBACK\n", __func__); | ||
1564 | pdev = ip_dev_find(&init_net, | ||
1565 | ep->com.cm_id->remote_addr.sin_addr.s_addr); | ||
1566 | ep->l2t = cxgb4_l2t_get(ep->com.dev->rdev.lldi.l2t, | ||
1567 | neigh, pdev, 0); | ||
1568 | pi = (struct port_info *)netdev_priv(pdev); | ||
1569 | ep->mtu = pdev->mtu; | ||
1570 | ep->tx_chan = cxgb4_port_chan(pdev); | ||
1571 | ep->smac_idx = (cxgb4_port_viid(pdev) & 0x7F) << 1; | ||
1572 | dev_put(pdev); | ||
1573 | } else { | ||
1574 | ep->l2t = cxgb4_l2t_get(ep->com.dev->rdev.lldi.l2t, | ||
1575 | neigh, neigh->dev, 0); | ||
1576 | pi = (struct port_info *)netdev_priv(neigh->dev); | ||
1577 | ep->mtu = dst_mtu(ep->dst); | ||
1578 | ep->tx_chan = cxgb4_port_chan(neigh->dev); | ||
1579 | ep->smac_idx = (cxgb4_port_viid(neigh->dev) & | ||
1580 | 0x7F) << 1; | ||
1581 | } | ||
1582 | |||
1583 | step = ep->com.dev->rdev.lldi.ntxq / ep->com.dev->rdev.lldi.nchan; | ||
1584 | ep->txq_idx = pi->port_id * step; | ||
1585 | ep->ctrlq_idx = pi->port_id; | ||
1586 | step = ep->com.dev->rdev.lldi.nrxq / ep->com.dev->rdev.lldi.nchan; | ||
1587 | ep->rss_qid = ep->com.dev->rdev.lldi.rxq_ids[pi->port_id * step]; | ||
1588 | |||
1589 | if (!ep->l2t) { | ||
1590 | pr_err("%s - cannot alloc l2e.\n", __func__); | ||
1591 | err = -ENOMEM; | ||
1592 | goto fail4; | ||
1593 | } | ||
1594 | |||
1595 | PDBG("%s txq_idx %u tx_chan %u smac_idx %u rss_qid %u l2t_idx %u\n", | ||
1596 | __func__, ep->txq_idx, ep->tx_chan, ep->smac_idx, ep->rss_qid, | ||
1597 | ep->l2t->idx); | ||
1598 | |||
1599 | state_set(&ep->com, CONNECTING); | ||
1600 | ep->tos = 0; | ||
1601 | |||
1602 | /* send connect request to rnic */ | ||
1603 | err = send_connect(ep); | ||
1604 | if (!err) | ||
1605 | goto out; | ||
1606 | |||
1607 | cxgb4_l2t_release(ep->l2t); | ||
1608 | fail4: | ||
1609 | dst_release(ep->dst); | ||
1610 | fail3: | ||
1611 | remove_handle(ep->com.dev, &ep->com.dev->atid_idr, ep->atid); | ||
1612 | cxgb4_free_atid(ep->com.dev->rdev.lldi.tids, ep->atid); | ||
1613 | fail2: | ||
1614 | /* | ||
1615 | * remember to send notification to upper layer. | ||
1616 | * We are in here so the upper layer is not aware that this is | ||
1617 | * re-connect attempt and so, upper layer is still waiting for | ||
1618 | * response of 1st connect request. | ||
1619 | */ | ||
1620 | connect_reply_upcall(ep, -ECONNRESET); | ||
1621 | c4iw_put_ep(&ep->com); | ||
1622 | out: | ||
1623 | return err; | ||
1624 | } | ||
1625 | |||
1395 | static int act_open_rpl(struct c4iw_dev *dev, struct sk_buff *skb) | 1626 | static int act_open_rpl(struct c4iw_dev *dev, struct sk_buff *skb) |
1396 | { | 1627 | { |
1397 | struct c4iw_ep *ep; | 1628 | struct c4iw_ep *ep; |
@@ -1412,6 +1643,8 @@ static int act_open_rpl(struct c4iw_dev *dev, struct sk_buff *skb) | |||
1412 | return 0; | 1643 | return 0; |
1413 | } | 1644 | } |
1414 | 1645 | ||
1646 | set_bit(ACT_OPEN_RPL, &ep->com.history); | ||
1647 | |||
1415 | /* | 1648 | /* |
1416 | * Log interesting failures. | 1649 | * Log interesting failures. |
1417 | */ | 1650 | */ |
@@ -1419,6 +1652,29 @@ static int act_open_rpl(struct c4iw_dev *dev, struct sk_buff *skb) | |||
1419 | case CPL_ERR_CONN_RESET: | 1652 | case CPL_ERR_CONN_RESET: |
1420 | case CPL_ERR_CONN_TIMEDOUT: | 1653 | case CPL_ERR_CONN_TIMEDOUT: |
1421 | break; | 1654 | break; |
1655 | case CPL_ERR_TCAM_FULL: | ||
1656 | if (dev->rdev.lldi.enable_fw_ofld_conn) { | ||
1657 | mutex_lock(&dev->rdev.stats.lock); | ||
1658 | dev->rdev.stats.tcam_full++; | ||
1659 | mutex_unlock(&dev->rdev.stats.lock); | ||
1660 | send_fw_act_open_req(ep, | ||
1661 | GET_TID_TID(GET_AOPEN_ATID( | ||
1662 | ntohl(rpl->atid_status)))); | ||
1663 | return 0; | ||
1664 | } | ||
1665 | break; | ||
1666 | case CPL_ERR_CONN_EXIST: | ||
1667 | if (ep->retry_count++ < ACT_OPEN_RETRY_COUNT) { | ||
1668 | set_bit(ACT_RETRY_INUSE, &ep->com.history); | ||
1669 | remove_handle(ep->com.dev, &ep->com.dev->atid_idr, | ||
1670 | atid); | ||
1671 | cxgb4_free_atid(t, atid); | ||
1672 | dst_release(ep->dst); | ||
1673 | cxgb4_l2t_release(ep->l2t); | ||
1674 | c4iw_reconnect(ep); | ||
1675 | return 0; | ||
1676 | } | ||
1677 | break; | ||
1422 | default: | 1678 | default: |
1423 | printk(KERN_INFO MOD "Active open failure - " | 1679 | printk(KERN_INFO MOD "Active open failure - " |
1424 | "atid %u status %u errno %d %pI4:%u->%pI4:%u\n", | 1680 | "atid %u status %u errno %d %pI4:%u->%pI4:%u\n", |
@@ -1436,6 +1692,7 @@ static int act_open_rpl(struct c4iw_dev *dev, struct sk_buff *skb) | |||
1436 | if (status && act_open_has_tid(status)) | 1692 | if (status && act_open_has_tid(status)) |
1437 | cxgb4_remove_tid(ep->com.dev->rdev.lldi.tids, 0, GET_TID(rpl)); | 1693 | cxgb4_remove_tid(ep->com.dev->rdev.lldi.tids, 0, GET_TID(rpl)); |
1438 | 1694 | ||
1695 | remove_handle(ep->com.dev, &ep->com.dev->atid_idr, atid); | ||
1439 | cxgb4_free_atid(t, atid); | 1696 | cxgb4_free_atid(t, atid); |
1440 | dst_release(ep->dst); | 1697 | dst_release(ep->dst); |
1441 | cxgb4_l2t_release(ep->l2t); | 1698 | cxgb4_l2t_release(ep->l2t); |
@@ -1452,13 +1709,14 @@ static int pass_open_rpl(struct c4iw_dev *dev, struct sk_buff *skb) | |||
1452 | struct c4iw_listen_ep *ep = lookup_stid(t, stid); | 1709 | struct c4iw_listen_ep *ep = lookup_stid(t, stid); |
1453 | 1710 | ||
1454 | if (!ep) { | 1711 | if (!ep) { |
1455 | printk(KERN_ERR MOD "stid %d lookup failure!\n", stid); | 1712 | PDBG("%s stid %d lookup failure!\n", __func__, stid); |
1456 | return 0; | 1713 | goto out; |
1457 | } | 1714 | } |
1458 | PDBG("%s ep %p status %d error %d\n", __func__, ep, | 1715 | PDBG("%s ep %p status %d error %d\n", __func__, ep, |
1459 | rpl->status, status2errno(rpl->status)); | 1716 | rpl->status, status2errno(rpl->status)); |
1460 | c4iw_wake_up(&ep->com.wr_wait, status2errno(rpl->status)); | 1717 | c4iw_wake_up(&ep->com.wr_wait, status2errno(rpl->status)); |
1461 | 1718 | ||
1719 | out: | ||
1462 | return 0; | 1720 | return 0; |
1463 | } | 1721 | } |
1464 | 1722 | ||
@@ -1510,14 +1768,15 @@ static void accept_cr(struct c4iw_ep *ep, __be32 peer_ip, struct sk_buff *skb, | |||
1510 | skb_get(skb); | 1768 | skb_get(skb); |
1511 | cxgb4_best_mtu(ep->com.dev->rdev.lldi.mtus, ep->mtu, &mtu_idx); | 1769 | cxgb4_best_mtu(ep->com.dev->rdev.lldi.mtus, ep->mtu, &mtu_idx); |
1512 | wscale = compute_wscale(rcv_win); | 1770 | wscale = compute_wscale(rcv_win); |
1513 | opt0 = KEEP_ALIVE(1) | | 1771 | opt0 = (nocong ? NO_CONG(1) : 0) | |
1772 | KEEP_ALIVE(1) | | ||
1514 | DELACK(1) | | 1773 | DELACK(1) | |
1515 | WND_SCALE(wscale) | | 1774 | WND_SCALE(wscale) | |
1516 | MSS_IDX(mtu_idx) | | 1775 | MSS_IDX(mtu_idx) | |
1517 | L2T_IDX(ep->l2t->idx) | | 1776 | L2T_IDX(ep->l2t->idx) | |
1518 | TX_CHAN(ep->tx_chan) | | 1777 | TX_CHAN(ep->tx_chan) | |
1519 | SMAC_SEL(ep->smac_idx) | | 1778 | SMAC_SEL(ep->smac_idx) | |
1520 | DSCP(ep->tos) | | 1779 | DSCP(ep->tos >> 2) | |
1521 | ULP_MODE(ULP_MODE_TCPDDP) | | 1780 | ULP_MODE(ULP_MODE_TCPDDP) | |
1522 | RCV_BUFSIZ(rcv_win>>10); | 1781 | RCV_BUFSIZ(rcv_win>>10); |
1523 | opt2 = RX_CHANNEL(0) | | 1782 | opt2 = RX_CHANNEL(0) | |
@@ -1529,6 +1788,15 @@ static void accept_cr(struct c4iw_ep *ep, __be32 peer_ip, struct sk_buff *skb, | |||
1529 | opt2 |= SACK_EN(1); | 1788 | opt2 |= SACK_EN(1); |
1530 | if (wscale && enable_tcp_window_scaling) | 1789 | if (wscale && enable_tcp_window_scaling) |
1531 | opt2 |= WND_SCALE_EN(1); | 1790 | opt2 |= WND_SCALE_EN(1); |
1791 | if (enable_ecn) { | ||
1792 | const struct tcphdr *tcph; | ||
1793 | u32 hlen = ntohl(req->hdr_len); | ||
1794 | |||
1795 | tcph = (const void *)(req + 1) + G_ETH_HDR_LEN(hlen) + | ||
1796 | G_IP_HDR_LEN(hlen); | ||
1797 | if (tcph->ece && tcph->cwr) | ||
1798 | opt2 |= CCTRL_ECN(1); | ||
1799 | } | ||
1532 | 1800 | ||
1533 | rpl = cplhdr(skb); | 1801 | rpl = cplhdr(skb); |
1534 | INIT_TP_WR(rpl, ep->hwtid); | 1802 | INIT_TP_WR(rpl, ep->hwtid); |
@@ -1645,22 +1913,30 @@ out: | |||
1645 | 1913 | ||
1646 | static int pass_accept_req(struct c4iw_dev *dev, struct sk_buff *skb) | 1914 | static int pass_accept_req(struct c4iw_dev *dev, struct sk_buff *skb) |
1647 | { | 1915 | { |
1648 | struct c4iw_ep *child_ep, *parent_ep; | 1916 | struct c4iw_ep *child_ep = NULL, *parent_ep; |
1649 | struct cpl_pass_accept_req *req = cplhdr(skb); | 1917 | struct cpl_pass_accept_req *req = cplhdr(skb); |
1650 | unsigned int stid = GET_POPEN_TID(ntohl(req->tos_stid)); | 1918 | unsigned int stid = GET_POPEN_TID(ntohl(req->tos_stid)); |
1651 | struct tid_info *t = dev->rdev.lldi.tids; | 1919 | struct tid_info *t = dev->rdev.lldi.tids; |
1652 | unsigned int hwtid = GET_TID(req); | 1920 | unsigned int hwtid = GET_TID(req); |
1653 | struct dst_entry *dst; | 1921 | struct dst_entry *dst; |
1654 | struct rtable *rt; | 1922 | struct rtable *rt; |
1655 | __be32 local_ip, peer_ip; | 1923 | __be32 local_ip, peer_ip = 0; |
1656 | __be16 local_port, peer_port; | 1924 | __be16 local_port, peer_port; |
1657 | int err; | 1925 | int err; |
1926 | u16 peer_mss = ntohs(req->tcpopt.mss); | ||
1658 | 1927 | ||
1659 | parent_ep = lookup_stid(t, stid); | 1928 | parent_ep = lookup_stid(t, stid); |
1660 | PDBG("%s parent ep %p tid %u\n", __func__, parent_ep, hwtid); | 1929 | if (!parent_ep) { |
1661 | 1930 | PDBG("%s connect request on invalid stid %d\n", __func__, stid); | |
1931 | goto reject; | ||
1932 | } | ||
1662 | get_4tuple(req, &local_ip, &peer_ip, &local_port, &peer_port); | 1933 | get_4tuple(req, &local_ip, &peer_ip, &local_port, &peer_port); |
1663 | 1934 | ||
1935 | PDBG("%s parent ep %p hwtid %u laddr 0x%x raddr 0x%x lport %d " \ | ||
1936 | "rport %d peer_mss %d\n", __func__, parent_ep, hwtid, | ||
1937 | ntohl(local_ip), ntohl(peer_ip), ntohs(local_port), | ||
1938 | ntohs(peer_port), peer_mss); | ||
1939 | |||
1664 | if (state_read(&parent_ep->com) != LISTEN) { | 1940 | if (state_read(&parent_ep->com) != LISTEN) { |
1665 | printk(KERN_ERR "%s - listening ep not in LISTEN\n", | 1941 | printk(KERN_ERR "%s - listening ep not in LISTEN\n", |
1666 | __func__); | 1942 | __func__); |
@@ -1694,6 +1970,9 @@ static int pass_accept_req(struct c4iw_dev *dev, struct sk_buff *skb) | |||
1694 | goto reject; | 1970 | goto reject; |
1695 | } | 1971 | } |
1696 | 1972 | ||
1973 | if (peer_mss && child_ep->mtu > (peer_mss + 40)) | ||
1974 | child_ep->mtu = peer_mss + 40; | ||
1975 | |||
1697 | state_set(&child_ep->com, CONNECTING); | 1976 | state_set(&child_ep->com, CONNECTING); |
1698 | child_ep->com.dev = dev; | 1977 | child_ep->com.dev = dev; |
1699 | child_ep->com.cm_id = NULL; | 1978 | child_ep->com.cm_id = NULL; |
@@ -1715,6 +1994,7 @@ static int pass_accept_req(struct c4iw_dev *dev, struct sk_buff *skb) | |||
1715 | init_timer(&child_ep->timer); | 1994 | init_timer(&child_ep->timer); |
1716 | cxgb4_insert_tid(t, child_ep, hwtid); | 1995 | cxgb4_insert_tid(t, child_ep, hwtid); |
1717 | accept_cr(child_ep, peer_ip, skb, req); | 1996 | accept_cr(child_ep, peer_ip, skb, req); |
1997 | set_bit(PASS_ACCEPT_REQ, &child_ep->com.history); | ||
1718 | goto out; | 1998 | goto out; |
1719 | reject: | 1999 | reject: |
1720 | reject_cr(dev, hwtid, peer_ip, skb); | 2000 | reject_cr(dev, hwtid, peer_ip, skb); |
@@ -1734,12 +2014,17 @@ static int pass_establish(struct c4iw_dev *dev, struct sk_buff *skb) | |||
1734 | ep->snd_seq = be32_to_cpu(req->snd_isn); | 2014 | ep->snd_seq = be32_to_cpu(req->snd_isn); |
1735 | ep->rcv_seq = be32_to_cpu(req->rcv_isn); | 2015 | ep->rcv_seq = be32_to_cpu(req->rcv_isn); |
1736 | 2016 | ||
2017 | PDBG("%s ep %p hwtid %u tcp_opt 0x%02x\n", __func__, ep, tid, | ||
2018 | ntohs(req->tcp_opt)); | ||
2019 | |||
1737 | set_emss(ep, ntohs(req->tcp_opt)); | 2020 | set_emss(ep, ntohs(req->tcp_opt)); |
2021 | insert_handle(dev, &dev->hwtid_idr, ep, ep->hwtid); | ||
1738 | 2022 | ||
1739 | dst_confirm(ep->dst); | 2023 | dst_confirm(ep->dst); |
1740 | state_set(&ep->com, MPA_REQ_WAIT); | 2024 | state_set(&ep->com, MPA_REQ_WAIT); |
1741 | start_ep_timer(ep); | 2025 | start_ep_timer(ep); |
1742 | send_flowc(ep, skb); | 2026 | send_flowc(ep, skb); |
2027 | set_bit(PASS_ESTAB, &ep->com.history); | ||
1743 | 2028 | ||
1744 | return 0; | 2029 | return 0; |
1745 | } | 2030 | } |
@@ -1759,6 +2044,7 @@ static int peer_close(struct c4iw_dev *dev, struct sk_buff *skb) | |||
1759 | PDBG("%s ep %p tid %u\n", __func__, ep, ep->hwtid); | 2044 | PDBG("%s ep %p tid %u\n", __func__, ep, ep->hwtid); |
1760 | dst_confirm(ep->dst); | 2045 | dst_confirm(ep->dst); |
1761 | 2046 | ||
2047 | set_bit(PEER_CLOSE, &ep->com.history); | ||
1762 | mutex_lock(&ep->com.mutex); | 2048 | mutex_lock(&ep->com.mutex); |
1763 | switch (ep->com.state) { | 2049 | switch (ep->com.state) { |
1764 | case MPA_REQ_WAIT: | 2050 | case MPA_REQ_WAIT: |
@@ -1838,74 +2124,6 @@ static int is_neg_adv_abort(unsigned int status) | |||
1838 | status == CPL_ERR_PERSIST_NEG_ADVICE; | 2124 | status == CPL_ERR_PERSIST_NEG_ADVICE; |
1839 | } | 2125 | } |
1840 | 2126 | ||
1841 | static int c4iw_reconnect(struct c4iw_ep *ep) | ||
1842 | { | ||
1843 | struct rtable *rt; | ||
1844 | int err = 0; | ||
1845 | |||
1846 | PDBG("%s qp %p cm_id %p\n", __func__, ep->com.qp, ep->com.cm_id); | ||
1847 | init_timer(&ep->timer); | ||
1848 | |||
1849 | /* | ||
1850 | * Allocate an active TID to initiate a TCP connection. | ||
1851 | */ | ||
1852 | ep->atid = cxgb4_alloc_atid(ep->com.dev->rdev.lldi.tids, ep); | ||
1853 | if (ep->atid == -1) { | ||
1854 | printk(KERN_ERR MOD "%s - cannot alloc atid.\n", __func__); | ||
1855 | err = -ENOMEM; | ||
1856 | goto fail2; | ||
1857 | } | ||
1858 | |||
1859 | /* find a route */ | ||
1860 | rt = find_route(ep->com.dev, | ||
1861 | ep->com.cm_id->local_addr.sin_addr.s_addr, | ||
1862 | ep->com.cm_id->remote_addr.sin_addr.s_addr, | ||
1863 | ep->com.cm_id->local_addr.sin_port, | ||
1864 | ep->com.cm_id->remote_addr.sin_port, 0); | ||
1865 | if (!rt) { | ||
1866 | printk(KERN_ERR MOD "%s - cannot find route.\n", __func__); | ||
1867 | err = -EHOSTUNREACH; | ||
1868 | goto fail3; | ||
1869 | } | ||
1870 | ep->dst = &rt->dst; | ||
1871 | |||
1872 | err = import_ep(ep, ep->com.cm_id->remote_addr.sin_addr.s_addr, | ||
1873 | ep->dst, ep->com.dev, false); | ||
1874 | if (err) { | ||
1875 | printk(KERN_ERR MOD "%s - cannot alloc l2e.\n", __func__); | ||
1876 | goto fail4; | ||
1877 | } | ||
1878 | |||
1879 | PDBG("%s txq_idx %u tx_chan %u smac_idx %u rss_qid %u l2t_idx %u\n", | ||
1880 | __func__, ep->txq_idx, ep->tx_chan, ep->smac_idx, ep->rss_qid, | ||
1881 | ep->l2t->idx); | ||
1882 | |||
1883 | state_set(&ep->com, CONNECTING); | ||
1884 | ep->tos = 0; | ||
1885 | |||
1886 | /* send connect request to rnic */ | ||
1887 | err = send_connect(ep); | ||
1888 | if (!err) | ||
1889 | goto out; | ||
1890 | |||
1891 | cxgb4_l2t_release(ep->l2t); | ||
1892 | fail4: | ||
1893 | dst_release(ep->dst); | ||
1894 | fail3: | ||
1895 | cxgb4_free_atid(ep->com.dev->rdev.lldi.tids, ep->atid); | ||
1896 | fail2: | ||
1897 | /* | ||
1898 | * remember to send notification to upper layer. | ||
1899 | * We are in here so the upper layer is not aware that this is | ||
1900 | * re-connect attempt and so, upper layer is still waiting for | ||
1901 | * response of 1st connect request. | ||
1902 | */ | ||
1903 | connect_reply_upcall(ep, -ECONNRESET); | ||
1904 | c4iw_put_ep(&ep->com); | ||
1905 | out: | ||
1906 | return err; | ||
1907 | } | ||
1908 | |||
1909 | static int peer_abort(struct c4iw_dev *dev, struct sk_buff *skb) | 2127 | static int peer_abort(struct c4iw_dev *dev, struct sk_buff *skb) |
1910 | { | 2128 | { |
1911 | struct cpl_abort_req_rss *req = cplhdr(skb); | 2129 | struct cpl_abort_req_rss *req = cplhdr(skb); |
@@ -1926,6 +2144,7 @@ static int peer_abort(struct c4iw_dev *dev, struct sk_buff *skb) | |||
1926 | } | 2144 | } |
1927 | PDBG("%s ep %p tid %u state %u\n", __func__, ep, ep->hwtid, | 2145 | PDBG("%s ep %p tid %u state %u\n", __func__, ep, ep->hwtid, |
1928 | ep->com.state); | 2146 | ep->com.state); |
2147 | set_bit(PEER_ABORT, &ep->com.history); | ||
1929 | 2148 | ||
1930 | /* | 2149 | /* |
1931 | * Wake up any threads in rdma_init() or rdma_fini(). | 2150 | * Wake up any threads in rdma_init() or rdma_fini(). |
@@ -2140,6 +2359,7 @@ int c4iw_reject_cr(struct iw_cm_id *cm_id, const void *pdata, u8 pdata_len) | |||
2140 | c4iw_put_ep(&ep->com); | 2359 | c4iw_put_ep(&ep->com); |
2141 | return -ECONNRESET; | 2360 | return -ECONNRESET; |
2142 | } | 2361 | } |
2362 | set_bit(ULP_REJECT, &ep->com.history); | ||
2143 | BUG_ON(state_read(&ep->com) != MPA_REQ_RCVD); | 2363 | BUG_ON(state_read(&ep->com) != MPA_REQ_RCVD); |
2144 | if (mpa_rev == 0) | 2364 | if (mpa_rev == 0) |
2145 | abort_connection(ep, NULL, GFP_KERNEL); | 2365 | abort_connection(ep, NULL, GFP_KERNEL); |
@@ -2169,6 +2389,7 @@ int c4iw_accept_cr(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param) | |||
2169 | BUG_ON(state_read(&ep->com) != MPA_REQ_RCVD); | 2389 | BUG_ON(state_read(&ep->com) != MPA_REQ_RCVD); |
2170 | BUG_ON(!qp); | 2390 | BUG_ON(!qp); |
2171 | 2391 | ||
2392 | set_bit(ULP_ACCEPT, &ep->com.history); | ||
2172 | if ((conn_param->ord > c4iw_max_read_depth) || | 2393 | if ((conn_param->ord > c4iw_max_read_depth) || |
2173 | (conn_param->ird > c4iw_max_read_depth)) { | 2394 | (conn_param->ird > c4iw_max_read_depth)) { |
2174 | abort_connection(ep, NULL, GFP_KERNEL); | 2395 | abort_connection(ep, NULL, GFP_KERNEL); |
@@ -2292,6 +2513,7 @@ int c4iw_connect(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param) | |||
2292 | err = -ENOMEM; | 2513 | err = -ENOMEM; |
2293 | goto fail2; | 2514 | goto fail2; |
2294 | } | 2515 | } |
2516 | insert_handle(dev, &dev->atid_idr, ep, ep->atid); | ||
2295 | 2517 | ||
2296 | PDBG("%s saddr 0x%x sport 0x%x raddr 0x%x rport 0x%x\n", __func__, | 2518 | PDBG("%s saddr 0x%x sport 0x%x raddr 0x%x rport 0x%x\n", __func__, |
2297 | ntohl(cm_id->local_addr.sin_addr.s_addr), | 2519 | ntohl(cm_id->local_addr.sin_addr.s_addr), |
@@ -2337,6 +2559,7 @@ int c4iw_connect(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param) | |||
2337 | fail4: | 2559 | fail4: |
2338 | dst_release(ep->dst); | 2560 | dst_release(ep->dst); |
2339 | fail3: | 2561 | fail3: |
2562 | remove_handle(ep->com.dev, &ep->com.dev->atid_idr, ep->atid); | ||
2340 | cxgb4_free_atid(ep->com.dev->rdev.lldi.tids, ep->atid); | 2563 | cxgb4_free_atid(ep->com.dev->rdev.lldi.tids, ep->atid); |
2341 | fail2: | 2564 | fail2: |
2342 | cm_id->rem_ref(cm_id); | 2565 | cm_id->rem_ref(cm_id); |
@@ -2351,7 +2574,6 @@ int c4iw_create_listen(struct iw_cm_id *cm_id, int backlog) | |||
2351 | struct c4iw_dev *dev = to_c4iw_dev(cm_id->device); | 2574 | struct c4iw_dev *dev = to_c4iw_dev(cm_id->device); |
2352 | struct c4iw_listen_ep *ep; | 2575 | struct c4iw_listen_ep *ep; |
2353 | 2576 | ||
2354 | |||
2355 | might_sleep(); | 2577 | might_sleep(); |
2356 | 2578 | ||
2357 | ep = alloc_ep(sizeof(*ep), GFP_KERNEL); | 2579 | ep = alloc_ep(sizeof(*ep), GFP_KERNEL); |
@@ -2370,30 +2592,54 @@ int c4iw_create_listen(struct iw_cm_id *cm_id, int backlog) | |||
2370 | /* | 2592 | /* |
2371 | * Allocate a server TID. | 2593 | * Allocate a server TID. |
2372 | */ | 2594 | */ |
2373 | ep->stid = cxgb4_alloc_stid(dev->rdev.lldi.tids, PF_INET, ep); | 2595 | if (dev->rdev.lldi.enable_fw_ofld_conn) |
2596 | ep->stid = cxgb4_alloc_sftid(dev->rdev.lldi.tids, PF_INET, ep); | ||
2597 | else | ||
2598 | ep->stid = cxgb4_alloc_stid(dev->rdev.lldi.tids, PF_INET, ep); | ||
2599 | |||
2374 | if (ep->stid == -1) { | 2600 | if (ep->stid == -1) { |
2375 | printk(KERN_ERR MOD "%s - cannot alloc stid.\n", __func__); | 2601 | printk(KERN_ERR MOD "%s - cannot alloc stid.\n", __func__); |
2376 | err = -ENOMEM; | 2602 | err = -ENOMEM; |
2377 | goto fail2; | 2603 | goto fail2; |
2378 | } | 2604 | } |
2379 | 2605 | insert_handle(dev, &dev->stid_idr, ep, ep->stid); | |
2380 | state_set(&ep->com, LISTEN); | 2606 | state_set(&ep->com, LISTEN); |
2381 | c4iw_init_wr_wait(&ep->com.wr_wait); | 2607 | if (dev->rdev.lldi.enable_fw_ofld_conn) { |
2382 | err = cxgb4_create_server(ep->com.dev->rdev.lldi.ports[0], ep->stid, | 2608 | do { |
2383 | ep->com.local_addr.sin_addr.s_addr, | 2609 | err = cxgb4_create_server_filter( |
2384 | ep->com.local_addr.sin_port, | 2610 | ep->com.dev->rdev.lldi.ports[0], ep->stid, |
2385 | ep->com.dev->rdev.lldi.rxq_ids[0]); | 2611 | ep->com.local_addr.sin_addr.s_addr, |
2386 | if (err) | 2612 | ep->com.local_addr.sin_port, |
2387 | goto fail3; | 2613 | 0, |
2388 | 2614 | ep->com.dev->rdev.lldi.rxq_ids[0], | |
2389 | /* wait for pass_open_rpl */ | 2615 | 0, |
2390 | err = c4iw_wait_for_reply(&ep->com.dev->rdev, &ep->com.wr_wait, 0, 0, | 2616 | 0); |
2391 | __func__); | 2617 | if (err == -EBUSY) { |
2618 | set_current_state(TASK_UNINTERRUPTIBLE); | ||
2619 | schedule_timeout(usecs_to_jiffies(100)); | ||
2620 | } | ||
2621 | } while (err == -EBUSY); | ||
2622 | } else { | ||
2623 | c4iw_init_wr_wait(&ep->com.wr_wait); | ||
2624 | err = cxgb4_create_server(ep->com.dev->rdev.lldi.ports[0], | ||
2625 | ep->stid, ep->com.local_addr.sin_addr.s_addr, | ||
2626 | ep->com.local_addr.sin_port, | ||
2627 | 0, | ||
2628 | ep->com.dev->rdev.lldi.rxq_ids[0]); | ||
2629 | if (!err) | ||
2630 | err = c4iw_wait_for_reply(&ep->com.dev->rdev, | ||
2631 | &ep->com.wr_wait, | ||
2632 | 0, 0, __func__); | ||
2633 | } | ||
2392 | if (!err) { | 2634 | if (!err) { |
2393 | cm_id->provider_data = ep; | 2635 | cm_id->provider_data = ep; |
2394 | goto out; | 2636 | goto out; |
2395 | } | 2637 | } |
2396 | fail3: | 2638 | pr_err("%s cxgb4_create_server/filter failed err %d " \ |
2639 | "stid %d laddr %08x lport %d\n", \ | ||
2640 | __func__, err, ep->stid, | ||
2641 | ntohl(ep->com.local_addr.sin_addr.s_addr), | ||
2642 | ntohs(ep->com.local_addr.sin_port)); | ||
2397 | cxgb4_free_stid(ep->com.dev->rdev.lldi.tids, ep->stid, PF_INET); | 2643 | cxgb4_free_stid(ep->com.dev->rdev.lldi.tids, ep->stid, PF_INET); |
2398 | fail2: | 2644 | fail2: |
2399 | cm_id->rem_ref(cm_id); | 2645 | cm_id->rem_ref(cm_id); |
@@ -2412,12 +2658,19 @@ int c4iw_destroy_listen(struct iw_cm_id *cm_id) | |||
2412 | 2658 | ||
2413 | might_sleep(); | 2659 | might_sleep(); |
2414 | state_set(&ep->com, DEAD); | 2660 | state_set(&ep->com, DEAD); |
2415 | c4iw_init_wr_wait(&ep->com.wr_wait); | 2661 | if (ep->com.dev->rdev.lldi.enable_fw_ofld_conn) { |
2416 | err = listen_stop(ep); | 2662 | err = cxgb4_remove_server_filter( |
2417 | if (err) | 2663 | ep->com.dev->rdev.lldi.ports[0], ep->stid, |
2418 | goto done; | 2664 | ep->com.dev->rdev.lldi.rxq_ids[0], 0); |
2419 | err = c4iw_wait_for_reply(&ep->com.dev->rdev, &ep->com.wr_wait, 0, 0, | 2665 | } else { |
2420 | __func__); | 2666 | c4iw_init_wr_wait(&ep->com.wr_wait); |
2667 | err = listen_stop(ep); | ||
2668 | if (err) | ||
2669 | goto done; | ||
2670 | err = c4iw_wait_for_reply(&ep->com.dev->rdev, &ep->com.wr_wait, | ||
2671 | 0, 0, __func__); | ||
2672 | } | ||
2673 | remove_handle(ep->com.dev, &ep->com.dev->stid_idr, ep->stid); | ||
2421 | cxgb4_free_stid(ep->com.dev->rdev.lldi.tids, ep->stid, PF_INET); | 2674 | cxgb4_free_stid(ep->com.dev->rdev.lldi.tids, ep->stid, PF_INET); |
2422 | done: | 2675 | done: |
2423 | cm_id->rem_ref(cm_id); | 2676 | cm_id->rem_ref(cm_id); |
@@ -2481,10 +2734,13 @@ int c4iw_ep_disconnect(struct c4iw_ep *ep, int abrupt, gfp_t gfp) | |||
2481 | 2734 | ||
2482 | if (close) { | 2735 | if (close) { |
2483 | if (abrupt) { | 2736 | if (abrupt) { |
2737 | set_bit(EP_DISC_ABORT, &ep->com.history); | ||
2484 | close_complete_upcall(ep); | 2738 | close_complete_upcall(ep); |
2485 | ret = send_abort(ep, NULL, gfp); | 2739 | ret = send_abort(ep, NULL, gfp); |
2486 | } else | 2740 | } else { |
2741 | set_bit(EP_DISC_CLOSE, &ep->com.history); | ||
2487 | ret = send_halfclose(ep, gfp); | 2742 | ret = send_halfclose(ep, gfp); |
2743 | } | ||
2488 | if (ret) | 2744 | if (ret) |
2489 | fatal = 1; | 2745 | fatal = 1; |
2490 | } | 2746 | } |
@@ -2494,10 +2750,323 @@ int c4iw_ep_disconnect(struct c4iw_ep *ep, int abrupt, gfp_t gfp) | |||
2494 | return ret; | 2750 | return ret; |
2495 | } | 2751 | } |
2496 | 2752 | ||
2497 | static int async_event(struct c4iw_dev *dev, struct sk_buff *skb) | 2753 | static void active_ofld_conn_reply(struct c4iw_dev *dev, struct sk_buff *skb, |
2754 | struct cpl_fw6_msg_ofld_connection_wr_rpl *req) | ||
2755 | { | ||
2756 | struct c4iw_ep *ep; | ||
2757 | int atid = be32_to_cpu(req->tid); | ||
2758 | |||
2759 | ep = (struct c4iw_ep *)lookup_atid(dev->rdev.lldi.tids, req->tid); | ||
2760 | if (!ep) | ||
2761 | return; | ||
2762 | |||
2763 | switch (req->retval) { | ||
2764 | case FW_ENOMEM: | ||
2765 | set_bit(ACT_RETRY_NOMEM, &ep->com.history); | ||
2766 | if (ep->retry_count++ < ACT_OPEN_RETRY_COUNT) { | ||
2767 | send_fw_act_open_req(ep, atid); | ||
2768 | return; | ||
2769 | } | ||
2770 | case FW_EADDRINUSE: | ||
2771 | set_bit(ACT_RETRY_INUSE, &ep->com.history); | ||
2772 | if (ep->retry_count++ < ACT_OPEN_RETRY_COUNT) { | ||
2773 | send_fw_act_open_req(ep, atid); | ||
2774 | return; | ||
2775 | } | ||
2776 | break; | ||
2777 | default: | ||
2778 | pr_info("%s unexpected ofld conn wr retval %d\n", | ||
2779 | __func__, req->retval); | ||
2780 | break; | ||
2781 | } | ||
2782 | pr_err("active ofld_connect_wr failure %d atid %d\n", | ||
2783 | req->retval, atid); | ||
2784 | mutex_lock(&dev->rdev.stats.lock); | ||
2785 | dev->rdev.stats.act_ofld_conn_fails++; | ||
2786 | mutex_unlock(&dev->rdev.stats.lock); | ||
2787 | connect_reply_upcall(ep, status2errno(req->retval)); | ||
2788 | state_set(&ep->com, DEAD); | ||
2789 | remove_handle(dev, &dev->atid_idr, atid); | ||
2790 | cxgb4_free_atid(dev->rdev.lldi.tids, atid); | ||
2791 | dst_release(ep->dst); | ||
2792 | cxgb4_l2t_release(ep->l2t); | ||
2793 | c4iw_put_ep(&ep->com); | ||
2794 | } | ||
2795 | |||
2796 | static void passive_ofld_conn_reply(struct c4iw_dev *dev, struct sk_buff *skb, | ||
2797 | struct cpl_fw6_msg_ofld_connection_wr_rpl *req) | ||
2798 | { | ||
2799 | struct sk_buff *rpl_skb; | ||
2800 | struct cpl_pass_accept_req *cpl; | ||
2801 | int ret; | ||
2802 | |||
2803 | rpl_skb = (struct sk_buff *)cpu_to_be64(req->cookie); | ||
2804 | BUG_ON(!rpl_skb); | ||
2805 | if (req->retval) { | ||
2806 | PDBG("%s passive open failure %d\n", __func__, req->retval); | ||
2807 | mutex_lock(&dev->rdev.stats.lock); | ||
2808 | dev->rdev.stats.pas_ofld_conn_fails++; | ||
2809 | mutex_unlock(&dev->rdev.stats.lock); | ||
2810 | kfree_skb(rpl_skb); | ||
2811 | } else { | ||
2812 | cpl = (struct cpl_pass_accept_req *)cplhdr(rpl_skb); | ||
2813 | OPCODE_TID(cpl) = htonl(MK_OPCODE_TID(CPL_PASS_ACCEPT_REQ, | ||
2814 | htonl(req->tid))); | ||
2815 | ret = pass_accept_req(dev, rpl_skb); | ||
2816 | if (!ret) | ||
2817 | kfree_skb(rpl_skb); | ||
2818 | } | ||
2819 | return; | ||
2820 | } | ||
2821 | |||
2822 | static int deferred_fw6_msg(struct c4iw_dev *dev, struct sk_buff *skb) | ||
2498 | { | 2823 | { |
2499 | struct cpl_fw6_msg *rpl = cplhdr(skb); | 2824 | struct cpl_fw6_msg *rpl = cplhdr(skb); |
2500 | c4iw_ev_dispatch(dev, (struct t4_cqe *)&rpl->data[0]); | 2825 | struct cpl_fw6_msg_ofld_connection_wr_rpl *req; |
2826 | |||
2827 | switch (rpl->type) { | ||
2828 | case FW6_TYPE_CQE: | ||
2829 | c4iw_ev_dispatch(dev, (struct t4_cqe *)&rpl->data[0]); | ||
2830 | break; | ||
2831 | case FW6_TYPE_OFLD_CONNECTION_WR_RPL: | ||
2832 | req = (struct cpl_fw6_msg_ofld_connection_wr_rpl *)rpl->data; | ||
2833 | switch (req->t_state) { | ||
2834 | case TCP_SYN_SENT: | ||
2835 | active_ofld_conn_reply(dev, skb, req); | ||
2836 | break; | ||
2837 | case TCP_SYN_RECV: | ||
2838 | passive_ofld_conn_reply(dev, skb, req); | ||
2839 | break; | ||
2840 | default: | ||
2841 | pr_err("%s unexpected ofld conn wr state %d\n", | ||
2842 | __func__, req->t_state); | ||
2843 | break; | ||
2844 | } | ||
2845 | break; | ||
2846 | } | ||
2847 | return 0; | ||
2848 | } | ||
2849 | |||
2850 | static void build_cpl_pass_accept_req(struct sk_buff *skb, int stid , u8 tos) | ||
2851 | { | ||
2852 | u32 l2info; | ||
2853 | u16 vlantag, len, hdr_len; | ||
2854 | u8 intf; | ||
2855 | struct cpl_rx_pkt *cpl = cplhdr(skb); | ||
2856 | struct cpl_pass_accept_req *req; | ||
2857 | struct tcp_options_received tmp_opt; | ||
2858 | |||
2859 | /* Store values from cpl_rx_pkt in temporary location. */ | ||
2860 | vlantag = cpl->vlan; | ||
2861 | len = cpl->len; | ||
2862 | l2info = cpl->l2info; | ||
2863 | hdr_len = cpl->hdr_len; | ||
2864 | intf = cpl->iff; | ||
2865 | |||
2866 | __skb_pull(skb, sizeof(*req) + sizeof(struct rss_header)); | ||
2867 | |||
2868 | /* | ||
2869 | * We need to parse the TCP options from SYN packet. | ||
2870 | * to generate cpl_pass_accept_req. | ||
2871 | */ | ||
2872 | memset(&tmp_opt, 0, sizeof(tmp_opt)); | ||
2873 | tcp_clear_options(&tmp_opt); | ||
2874 | tcp_parse_options(skb, &tmp_opt, 0, 0, NULL); | ||
2875 | |||
2876 | req = (struct cpl_pass_accept_req *)__skb_push(skb, sizeof(*req)); | ||
2877 | memset(req, 0, sizeof(*req)); | ||
2878 | req->l2info = cpu_to_be16(V_SYN_INTF(intf) | | ||
2879 | V_SYN_MAC_IDX(G_RX_MACIDX(htonl(l2info))) | | ||
2880 | F_SYN_XACT_MATCH); | ||
2881 | req->hdr_len = cpu_to_be32(V_SYN_RX_CHAN(G_RX_CHAN(htonl(l2info))) | | ||
2882 | V_TCP_HDR_LEN(G_RX_TCPHDR_LEN(htons(hdr_len))) | | ||
2883 | V_IP_HDR_LEN(G_RX_IPHDR_LEN(htons(hdr_len))) | | ||
2884 | V_ETH_HDR_LEN(G_RX_ETHHDR_LEN(htonl(l2info)))); | ||
2885 | req->vlan = vlantag; | ||
2886 | req->len = len; | ||
2887 | req->tos_stid = cpu_to_be32(PASS_OPEN_TID(stid) | | ||
2888 | PASS_OPEN_TOS(tos)); | ||
2889 | req->tcpopt.mss = htons(tmp_opt.mss_clamp); | ||
2890 | if (tmp_opt.wscale_ok) | ||
2891 | req->tcpopt.wsf = tmp_opt.snd_wscale; | ||
2892 | req->tcpopt.tstamp = tmp_opt.saw_tstamp; | ||
2893 | if (tmp_opt.sack_ok) | ||
2894 | req->tcpopt.sack = 1; | ||
2895 | OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_PASS_ACCEPT_REQ, 0)); | ||
2896 | return; | ||
2897 | } | ||
2898 | |||
2899 | static void send_fw_pass_open_req(struct c4iw_dev *dev, struct sk_buff *skb, | ||
2900 | __be32 laddr, __be16 lport, | ||
2901 | __be32 raddr, __be16 rport, | ||
2902 | u32 rcv_isn, u32 filter, u16 window, | ||
2903 | u32 rss_qid, u8 port_id) | ||
2904 | { | ||
2905 | struct sk_buff *req_skb; | ||
2906 | struct fw_ofld_connection_wr *req; | ||
2907 | struct cpl_pass_accept_req *cpl = cplhdr(skb); | ||
2908 | |||
2909 | req_skb = alloc_skb(sizeof(struct fw_ofld_connection_wr), GFP_KERNEL); | ||
2910 | req = (struct fw_ofld_connection_wr *)__skb_put(req_skb, sizeof(*req)); | ||
2911 | memset(req, 0, sizeof(*req)); | ||
2912 | req->op_compl = htonl(V_WR_OP(FW_OFLD_CONNECTION_WR) | FW_WR_COMPL(1)); | ||
2913 | req->len16_pkd = htonl(FW_WR_LEN16(DIV_ROUND_UP(sizeof(*req), 16))); | ||
2914 | req->le.version_cpl = htonl(F_FW_OFLD_CONNECTION_WR_CPL); | ||
2915 | req->le.filter = filter; | ||
2916 | req->le.lport = lport; | ||
2917 | req->le.pport = rport; | ||
2918 | req->le.u.ipv4.lip = laddr; | ||
2919 | req->le.u.ipv4.pip = raddr; | ||
2920 | req->tcb.rcv_nxt = htonl(rcv_isn + 1); | ||
2921 | req->tcb.rcv_adv = htons(window); | ||
2922 | req->tcb.t_state_to_astid = | ||
2923 | htonl(V_FW_OFLD_CONNECTION_WR_T_STATE(TCP_SYN_RECV) | | ||
2924 | V_FW_OFLD_CONNECTION_WR_RCV_SCALE(cpl->tcpopt.wsf) | | ||
2925 | V_FW_OFLD_CONNECTION_WR_ASTID( | ||
2926 | GET_PASS_OPEN_TID(ntohl(cpl->tos_stid)))); | ||
2927 | |||
2928 | /* | ||
2929 | * We store the qid in opt2 which will be used by the firmware | ||
2930 | * to send us the wr response. | ||
2931 | */ | ||
2932 | req->tcb.opt2 = htonl(V_RSS_QUEUE(rss_qid)); | ||
2933 | |||
2934 | /* | ||
2935 | * We initialize the MSS index in TCB to 0xF. | ||
2936 | * So that when driver sends cpl_pass_accept_rpl | ||
2937 | * TCB picks up the correct value. If this was 0 | ||
2938 | * TP will ignore any value > 0 for MSS index. | ||
2939 | */ | ||
2940 | req->tcb.opt0 = cpu_to_be64(V_MSS_IDX(0xF)); | ||
2941 | req->cookie = cpu_to_be64((u64)skb); | ||
2942 | |||
2943 | set_wr_txq(req_skb, CPL_PRIORITY_CONTROL, port_id); | ||
2944 | cxgb4_ofld_send(dev->rdev.lldi.ports[0], req_skb); | ||
2945 | } | ||
2946 | |||
2947 | /* | ||
2948 | * Handler for CPL_RX_PKT message. Need to handle cpl_rx_pkt | ||
2949 | * messages when a filter is being used instead of server to | ||
2950 | * redirect a syn packet. When packets hit filter they are redirected | ||
2951 | * to the offload queue and driver tries to establish the connection | ||
2952 | * using firmware work request. | ||
2953 | */ | ||
2954 | static int rx_pkt(struct c4iw_dev *dev, struct sk_buff *skb) | ||
2955 | { | ||
2956 | int stid; | ||
2957 | unsigned int filter; | ||
2958 | struct ethhdr *eh = NULL; | ||
2959 | struct vlan_ethhdr *vlan_eh = NULL; | ||
2960 | struct iphdr *iph; | ||
2961 | struct tcphdr *tcph; | ||
2962 | struct rss_header *rss = (void *)skb->data; | ||
2963 | struct cpl_rx_pkt *cpl = (void *)skb->data; | ||
2964 | struct cpl_pass_accept_req *req = (void *)(rss + 1); | ||
2965 | struct l2t_entry *e; | ||
2966 | struct dst_entry *dst; | ||
2967 | struct rtable *rt; | ||
2968 | struct c4iw_ep *lep; | ||
2969 | u16 window; | ||
2970 | struct port_info *pi; | ||
2971 | struct net_device *pdev; | ||
2972 | u16 rss_qid; | ||
2973 | int step; | ||
2974 | u32 tx_chan; | ||
2975 | struct neighbour *neigh; | ||
2976 | |||
2977 | /* Drop all non-SYN packets */ | ||
2978 | if (!(cpl->l2info & cpu_to_be32(F_RXF_SYN))) | ||
2979 | goto reject; | ||
2980 | |||
2981 | /* | ||
2982 | * Drop all packets which did not hit the filter. | ||
2983 | * Unlikely to happen. | ||
2984 | */ | ||
2985 | if (!(rss->filter_hit && rss->filter_tid)) | ||
2986 | goto reject; | ||
2987 | |||
2988 | /* | ||
2989 | * Calculate the server tid from filter hit index from cpl_rx_pkt. | ||
2990 | */ | ||
2991 | stid = cpu_to_be32(rss->hash_val) - dev->rdev.lldi.tids->sftid_base | ||
2992 | + dev->rdev.lldi.tids->nstids; | ||
2993 | |||
2994 | lep = (struct c4iw_ep *)lookup_stid(dev->rdev.lldi.tids, stid); | ||
2995 | if (!lep) { | ||
2996 | PDBG("%s connect request on invalid stid %d\n", __func__, stid); | ||
2997 | goto reject; | ||
2998 | } | ||
2999 | |||
3000 | if (G_RX_ETHHDR_LEN(ntohl(cpl->l2info)) == ETH_HLEN) { | ||
3001 | eh = (struct ethhdr *)(req + 1); | ||
3002 | iph = (struct iphdr *)(eh + 1); | ||
3003 | } else { | ||
3004 | vlan_eh = (struct vlan_ethhdr *)(req + 1); | ||
3005 | iph = (struct iphdr *)(vlan_eh + 1); | ||
3006 | skb->vlan_tci = ntohs(cpl->vlan); | ||
3007 | } | ||
3008 | |||
3009 | if (iph->version != 0x4) | ||
3010 | goto reject; | ||
3011 | |||
3012 | tcph = (struct tcphdr *)(iph + 1); | ||
3013 | skb_set_network_header(skb, (void *)iph - (void *)rss); | ||
3014 | skb_set_transport_header(skb, (void *)tcph - (void *)rss); | ||
3015 | skb_get(skb); | ||
3016 | |||
3017 | PDBG("%s lip 0x%x lport %u pip 0x%x pport %u tos %d\n", __func__, | ||
3018 | ntohl(iph->daddr), ntohs(tcph->dest), ntohl(iph->saddr), | ||
3019 | ntohs(tcph->source), iph->tos); | ||
3020 | |||
3021 | rt = find_route(dev, iph->daddr, iph->saddr, tcph->dest, tcph->source, | ||
3022 | iph->tos); | ||
3023 | if (!rt) { | ||
3024 | pr_err("%s - failed to find dst entry!\n", | ||
3025 | __func__); | ||
3026 | goto reject; | ||
3027 | } | ||
3028 | dst = &rt->dst; | ||
3029 | neigh = dst_neigh_lookup_skb(dst, skb); | ||
3030 | |||
3031 | if (neigh->dev->flags & IFF_LOOPBACK) { | ||
3032 | pdev = ip_dev_find(&init_net, iph->daddr); | ||
3033 | e = cxgb4_l2t_get(dev->rdev.lldi.l2t, neigh, | ||
3034 | pdev, 0); | ||
3035 | pi = (struct port_info *)netdev_priv(pdev); | ||
3036 | tx_chan = cxgb4_port_chan(pdev); | ||
3037 | dev_put(pdev); | ||
3038 | } else { | ||
3039 | e = cxgb4_l2t_get(dev->rdev.lldi.l2t, neigh, | ||
3040 | neigh->dev, 0); | ||
3041 | pi = (struct port_info *)netdev_priv(neigh->dev); | ||
3042 | tx_chan = cxgb4_port_chan(neigh->dev); | ||
3043 | } | ||
3044 | if (!e) { | ||
3045 | pr_err("%s - failed to allocate l2t entry!\n", | ||
3046 | __func__); | ||
3047 | goto free_dst; | ||
3048 | } | ||
3049 | |||
3050 | step = dev->rdev.lldi.nrxq / dev->rdev.lldi.nchan; | ||
3051 | rss_qid = dev->rdev.lldi.rxq_ids[pi->port_id * step]; | ||
3052 | window = htons(tcph->window); | ||
3053 | |||
3054 | /* Calcuate filter portion for LE region. */ | ||
3055 | filter = cpu_to_be32(select_ntuple(dev, dst, e)); | ||
3056 | |||
3057 | /* | ||
3058 | * Synthesize the cpl_pass_accept_req. We have everything except the | ||
3059 | * TID. Once firmware sends a reply with TID we update the TID field | ||
3060 | * in cpl and pass it through the regular cpl_pass_accept_req path. | ||
3061 | */ | ||
3062 | build_cpl_pass_accept_req(skb, stid, iph->tos); | ||
3063 | send_fw_pass_open_req(dev, skb, iph->daddr, tcph->dest, iph->saddr, | ||
3064 | tcph->source, ntohl(tcph->seq), filter, window, | ||
3065 | rss_qid, pi->port_id); | ||
3066 | cxgb4_l2t_release(e); | ||
3067 | free_dst: | ||
3068 | dst_release(dst); | ||
3069 | reject: | ||
2501 | return 0; | 3070 | return 0; |
2502 | } | 3071 | } |
2503 | 3072 | ||
@@ -2520,7 +3089,8 @@ static c4iw_handler_func work_handlers[NUM_CPL_CMDS] = { | |||
2520 | [CPL_CLOSE_CON_RPL] = close_con_rpl, | 3089 | [CPL_CLOSE_CON_RPL] = close_con_rpl, |
2521 | [CPL_RDMA_TERMINATE] = terminate, | 3090 | [CPL_RDMA_TERMINATE] = terminate, |
2522 | [CPL_FW4_ACK] = fw4_ack, | 3091 | [CPL_FW4_ACK] = fw4_ack, |
2523 | [CPL_FW6_MSG] = async_event | 3092 | [CPL_FW6_MSG] = deferred_fw6_msg, |
3093 | [CPL_RX_PKT] = rx_pkt | ||
2524 | }; | 3094 | }; |
2525 | 3095 | ||
2526 | static void process_timeout(struct c4iw_ep *ep) | 3096 | static void process_timeout(struct c4iw_ep *ep) |
@@ -2531,6 +3101,7 @@ static void process_timeout(struct c4iw_ep *ep) | |||
2531 | mutex_lock(&ep->com.mutex); | 3101 | mutex_lock(&ep->com.mutex); |
2532 | PDBG("%s ep %p tid %u state %d\n", __func__, ep, ep->hwtid, | 3102 | PDBG("%s ep %p tid %u state %d\n", __func__, ep, ep->hwtid, |
2533 | ep->com.state); | 3103 | ep->com.state); |
3104 | set_bit(TIMEDOUT, &ep->com.history); | ||
2534 | switch (ep->com.state) { | 3105 | switch (ep->com.state) { |
2535 | case MPA_REQ_SENT: | 3106 | case MPA_REQ_SENT: |
2536 | __state_set(&ep->com, ABORTING); | 3107 | __state_set(&ep->com, ABORTING); |
@@ -2651,7 +3222,7 @@ static int fw6_msg(struct c4iw_dev *dev, struct sk_buff *skb) | |||
2651 | PDBG("%s type %u\n", __func__, rpl->type); | 3222 | PDBG("%s type %u\n", __func__, rpl->type); |
2652 | 3223 | ||
2653 | switch (rpl->type) { | 3224 | switch (rpl->type) { |
2654 | case 1: | 3225 | case FW6_TYPE_WR_RPL: |
2655 | ret = (int)((be64_to_cpu(rpl->data[0]) >> 8) & 0xff); | 3226 | ret = (int)((be64_to_cpu(rpl->data[0]) >> 8) & 0xff); |
2656 | wr_waitp = (struct c4iw_wr_wait *)(__force unsigned long) rpl->data[1]; | 3227 | wr_waitp = (struct c4iw_wr_wait *)(__force unsigned long) rpl->data[1]; |
2657 | PDBG("%s wr_waitp %p ret %u\n", __func__, wr_waitp, ret); | 3228 | PDBG("%s wr_waitp %p ret %u\n", __func__, wr_waitp, ret); |
@@ -2659,7 +3230,8 @@ static int fw6_msg(struct c4iw_dev *dev, struct sk_buff *skb) | |||
2659 | c4iw_wake_up(wr_waitp, ret ? -ret : 0); | 3230 | c4iw_wake_up(wr_waitp, ret ? -ret : 0); |
2660 | kfree_skb(skb); | 3231 | kfree_skb(skb); |
2661 | break; | 3232 | break; |
2662 | case 2: | 3233 | case FW6_TYPE_CQE: |
3234 | case FW6_TYPE_OFLD_CONNECTION_WR_RPL: | ||
2663 | sched(dev, skb); | 3235 | sched(dev, skb); |
2664 | break; | 3236 | break; |
2665 | default: | 3237 | default: |
@@ -2722,7 +3294,8 @@ c4iw_handler_func c4iw_handlers[NUM_CPL_CMDS] = { | |||
2722 | [CPL_RDMA_TERMINATE] = sched, | 3294 | [CPL_RDMA_TERMINATE] = sched, |
2723 | [CPL_FW4_ACK] = sched, | 3295 | [CPL_FW4_ACK] = sched, |
2724 | [CPL_SET_TCB_RPL] = set_tcb_rpl, | 3296 | [CPL_SET_TCB_RPL] = set_tcb_rpl, |
2725 | [CPL_FW6_MSG] = fw6_msg | 3297 | [CPL_FW6_MSG] = fw6_msg, |
3298 | [CPL_RX_PKT] = sched | ||
2726 | }; | 3299 | }; |
2727 | 3300 | ||
2728 | int __init c4iw_cm_init(void) | 3301 | int __init c4iw_cm_init(void) |
diff --git a/drivers/infiniband/hw/cxgb4/device.c b/drivers/infiniband/hw/cxgb4/device.c index cb4ecd783700..ba11c76c0b5a 100644 --- a/drivers/infiniband/hw/cxgb4/device.c +++ b/drivers/infiniband/hw/cxgb4/device.c | |||
@@ -279,6 +279,11 @@ static int stats_show(struct seq_file *seq, void *v) | |||
279 | seq_printf(seq, " DB State: %s Transitions %llu\n", | 279 | seq_printf(seq, " DB State: %s Transitions %llu\n", |
280 | db_state_str[dev->db_state], | 280 | db_state_str[dev->db_state], |
281 | dev->rdev.stats.db_state_transitions); | 281 | dev->rdev.stats.db_state_transitions); |
282 | seq_printf(seq, "TCAM_FULL: %10llu\n", dev->rdev.stats.tcam_full); | ||
283 | seq_printf(seq, "ACT_OFLD_CONN_FAILS: %10llu\n", | ||
284 | dev->rdev.stats.act_ofld_conn_fails); | ||
285 | seq_printf(seq, "PAS_OFLD_CONN_FAILS: %10llu\n", | ||
286 | dev->rdev.stats.pas_ofld_conn_fails); | ||
282 | return 0; | 287 | return 0; |
283 | } | 288 | } |
284 | 289 | ||
@@ -309,6 +314,9 @@ static ssize_t stats_clear(struct file *file, const char __user *buf, | |||
309 | dev->rdev.stats.db_empty = 0; | 314 | dev->rdev.stats.db_empty = 0; |
310 | dev->rdev.stats.db_drop = 0; | 315 | dev->rdev.stats.db_drop = 0; |
311 | dev->rdev.stats.db_state_transitions = 0; | 316 | dev->rdev.stats.db_state_transitions = 0; |
317 | dev->rdev.stats.tcam_full = 0; | ||
318 | dev->rdev.stats.act_ofld_conn_fails = 0; | ||
319 | dev->rdev.stats.pas_ofld_conn_fails = 0; | ||
312 | mutex_unlock(&dev->rdev.stats.lock); | 320 | mutex_unlock(&dev->rdev.stats.lock); |
313 | return count; | 321 | return count; |
314 | } | 322 | } |
@@ -322,6 +330,113 @@ static const struct file_operations stats_debugfs_fops = { | |||
322 | .write = stats_clear, | 330 | .write = stats_clear, |
323 | }; | 331 | }; |
324 | 332 | ||
333 | static int dump_ep(int id, void *p, void *data) | ||
334 | { | ||
335 | struct c4iw_ep *ep = p; | ||
336 | struct c4iw_debugfs_data *epd = data; | ||
337 | int space; | ||
338 | int cc; | ||
339 | |||
340 | space = epd->bufsize - epd->pos - 1; | ||
341 | if (space == 0) | ||
342 | return 1; | ||
343 | |||
344 | cc = snprintf(epd->buf + epd->pos, space, | ||
345 | "ep %p cm_id %p qp %p state %d flags 0x%lx history 0x%lx " | ||
346 | "hwtid %d atid %d %pI4:%d <-> %pI4:%d\n", | ||
347 | ep, ep->com.cm_id, ep->com.qp, (int)ep->com.state, | ||
348 | ep->com.flags, ep->com.history, ep->hwtid, ep->atid, | ||
349 | &ep->com.local_addr.sin_addr.s_addr, | ||
350 | ntohs(ep->com.local_addr.sin_port), | ||
351 | &ep->com.remote_addr.sin_addr.s_addr, | ||
352 | ntohs(ep->com.remote_addr.sin_port)); | ||
353 | if (cc < space) | ||
354 | epd->pos += cc; | ||
355 | return 0; | ||
356 | } | ||
357 | |||
358 | static int dump_listen_ep(int id, void *p, void *data) | ||
359 | { | ||
360 | struct c4iw_listen_ep *ep = p; | ||
361 | struct c4iw_debugfs_data *epd = data; | ||
362 | int space; | ||
363 | int cc; | ||
364 | |||
365 | space = epd->bufsize - epd->pos - 1; | ||
366 | if (space == 0) | ||
367 | return 1; | ||
368 | |||
369 | cc = snprintf(epd->buf + epd->pos, space, | ||
370 | "ep %p cm_id %p state %d flags 0x%lx stid %d backlog %d " | ||
371 | "%pI4:%d\n", ep, ep->com.cm_id, (int)ep->com.state, | ||
372 | ep->com.flags, ep->stid, ep->backlog, | ||
373 | &ep->com.local_addr.sin_addr.s_addr, | ||
374 | ntohs(ep->com.local_addr.sin_port)); | ||
375 | if (cc < space) | ||
376 | epd->pos += cc; | ||
377 | return 0; | ||
378 | } | ||
379 | |||
380 | static int ep_release(struct inode *inode, struct file *file) | ||
381 | { | ||
382 | struct c4iw_debugfs_data *epd = file->private_data; | ||
383 | if (!epd) { | ||
384 | pr_info("%s null qpd?\n", __func__); | ||
385 | return 0; | ||
386 | } | ||
387 | vfree(epd->buf); | ||
388 | kfree(epd); | ||
389 | return 0; | ||
390 | } | ||
391 | |||
392 | static int ep_open(struct inode *inode, struct file *file) | ||
393 | { | ||
394 | struct c4iw_debugfs_data *epd; | ||
395 | int ret = 0; | ||
396 | int count = 1; | ||
397 | |||
398 | epd = kmalloc(sizeof(*epd), GFP_KERNEL); | ||
399 | if (!epd) { | ||
400 | ret = -ENOMEM; | ||
401 | goto out; | ||
402 | } | ||
403 | epd->devp = inode->i_private; | ||
404 | epd->pos = 0; | ||
405 | |||
406 | spin_lock_irq(&epd->devp->lock); | ||
407 | idr_for_each(&epd->devp->hwtid_idr, count_idrs, &count); | ||
408 | idr_for_each(&epd->devp->atid_idr, count_idrs, &count); | ||
409 | idr_for_each(&epd->devp->stid_idr, count_idrs, &count); | ||
410 | spin_unlock_irq(&epd->devp->lock); | ||
411 | |||
412 | epd->bufsize = count * 160; | ||
413 | epd->buf = vmalloc(epd->bufsize); | ||
414 | if (!epd->buf) { | ||
415 | ret = -ENOMEM; | ||
416 | goto err1; | ||
417 | } | ||
418 | |||
419 | spin_lock_irq(&epd->devp->lock); | ||
420 | idr_for_each(&epd->devp->hwtid_idr, dump_ep, epd); | ||
421 | idr_for_each(&epd->devp->atid_idr, dump_ep, epd); | ||
422 | idr_for_each(&epd->devp->stid_idr, dump_listen_ep, epd); | ||
423 | spin_unlock_irq(&epd->devp->lock); | ||
424 | |||
425 | file->private_data = epd; | ||
426 | goto out; | ||
427 | err1: | ||
428 | kfree(epd); | ||
429 | out: | ||
430 | return ret; | ||
431 | } | ||
432 | |||
433 | static const struct file_operations ep_debugfs_fops = { | ||
434 | .owner = THIS_MODULE, | ||
435 | .open = ep_open, | ||
436 | .release = ep_release, | ||
437 | .read = debugfs_read, | ||
438 | }; | ||
439 | |||
325 | static int setup_debugfs(struct c4iw_dev *devp) | 440 | static int setup_debugfs(struct c4iw_dev *devp) |
326 | { | 441 | { |
327 | struct dentry *de; | 442 | struct dentry *de; |
@@ -344,6 +459,11 @@ static int setup_debugfs(struct c4iw_dev *devp) | |||
344 | if (de && de->d_inode) | 459 | if (de && de->d_inode) |
345 | de->d_inode->i_size = 4096; | 460 | de->d_inode->i_size = 4096; |
346 | 461 | ||
462 | de = debugfs_create_file("eps", S_IWUSR, devp->debugfs_root, | ||
463 | (void *)devp, &ep_debugfs_fops); | ||
464 | if (de && de->d_inode) | ||
465 | de->d_inode->i_size = 4096; | ||
466 | |||
347 | return 0; | 467 | return 0; |
348 | } | 468 | } |
349 | 469 | ||
@@ -475,6 +595,9 @@ static void c4iw_dealloc(struct uld_ctx *ctx) | |||
475 | idr_destroy(&ctx->dev->cqidr); | 595 | idr_destroy(&ctx->dev->cqidr); |
476 | idr_destroy(&ctx->dev->qpidr); | 596 | idr_destroy(&ctx->dev->qpidr); |
477 | idr_destroy(&ctx->dev->mmidr); | 597 | idr_destroy(&ctx->dev->mmidr); |
598 | idr_destroy(&ctx->dev->hwtid_idr); | ||
599 | idr_destroy(&ctx->dev->stid_idr); | ||
600 | idr_destroy(&ctx->dev->atid_idr); | ||
478 | iounmap(ctx->dev->rdev.oc_mw_kva); | 601 | iounmap(ctx->dev->rdev.oc_mw_kva); |
479 | ib_dealloc_device(&ctx->dev->ibdev); | 602 | ib_dealloc_device(&ctx->dev->ibdev); |
480 | ctx->dev = NULL; | 603 | ctx->dev = NULL; |
@@ -532,6 +655,9 @@ static struct c4iw_dev *c4iw_alloc(const struct cxgb4_lld_info *infop) | |||
532 | idr_init(&devp->cqidr); | 655 | idr_init(&devp->cqidr); |
533 | idr_init(&devp->qpidr); | 656 | idr_init(&devp->qpidr); |
534 | idr_init(&devp->mmidr); | 657 | idr_init(&devp->mmidr); |
658 | idr_init(&devp->hwtid_idr); | ||
659 | idr_init(&devp->stid_idr); | ||
660 | idr_init(&devp->atid_idr); | ||
535 | spin_lock_init(&devp->lock); | 661 | spin_lock_init(&devp->lock); |
536 | mutex_init(&devp->rdev.stats.lock); | 662 | mutex_init(&devp->rdev.stats.lock); |
537 | mutex_init(&devp->db_mutex); | 663 | mutex_init(&devp->db_mutex); |
@@ -577,14 +703,76 @@ out: | |||
577 | return ctx; | 703 | return ctx; |
578 | } | 704 | } |
579 | 705 | ||
706 | static inline struct sk_buff *copy_gl_to_skb_pkt(const struct pkt_gl *gl, | ||
707 | const __be64 *rsp, | ||
708 | u32 pktshift) | ||
709 | { | ||
710 | struct sk_buff *skb; | ||
711 | |||
712 | /* | ||
713 | * Allocate space for cpl_pass_accept_req which will be synthesized by | ||
714 | * driver. Once the driver synthesizes the request the skb will go | ||
715 | * through the regular cpl_pass_accept_req processing. | ||
716 | * The math here assumes sizeof cpl_pass_accept_req >= sizeof | ||
717 | * cpl_rx_pkt. | ||
718 | */ | ||
719 | skb = alloc_skb(gl->tot_len + sizeof(struct cpl_pass_accept_req) + | ||
720 | sizeof(struct rss_header) - pktshift, GFP_ATOMIC); | ||
721 | if (unlikely(!skb)) | ||
722 | return NULL; | ||
723 | |||
724 | __skb_put(skb, gl->tot_len + sizeof(struct cpl_pass_accept_req) + | ||
725 | sizeof(struct rss_header) - pktshift); | ||
726 | |||
727 | /* | ||
728 | * This skb will contain: | ||
729 | * rss_header from the rspq descriptor (1 flit) | ||
730 | * cpl_rx_pkt struct from the rspq descriptor (2 flits) | ||
731 | * space for the difference between the size of an | ||
732 | * rx_pkt and pass_accept_req cpl (1 flit) | ||
733 | * the packet data from the gl | ||
734 | */ | ||
735 | skb_copy_to_linear_data(skb, rsp, sizeof(struct cpl_pass_accept_req) + | ||
736 | sizeof(struct rss_header)); | ||
737 | skb_copy_to_linear_data_offset(skb, sizeof(struct rss_header) + | ||
738 | sizeof(struct cpl_pass_accept_req), | ||
739 | gl->va + pktshift, | ||
740 | gl->tot_len - pktshift); | ||
741 | return skb; | ||
742 | } | ||
743 | |||
744 | static inline int recv_rx_pkt(struct c4iw_dev *dev, const struct pkt_gl *gl, | ||
745 | const __be64 *rsp) | ||
746 | { | ||
747 | unsigned int opcode = *(u8 *)rsp; | ||
748 | struct sk_buff *skb; | ||
749 | |||
750 | if (opcode != CPL_RX_PKT) | ||
751 | goto out; | ||
752 | |||
753 | skb = copy_gl_to_skb_pkt(gl , rsp, dev->rdev.lldi.sge_pktshift); | ||
754 | if (skb == NULL) | ||
755 | goto out; | ||
756 | |||
757 | if (c4iw_handlers[opcode] == NULL) { | ||
758 | pr_info("%s no handler opcode 0x%x...\n", __func__, | ||
759 | opcode); | ||
760 | kfree_skb(skb); | ||
761 | goto out; | ||
762 | } | ||
763 | c4iw_handlers[opcode](dev, skb); | ||
764 | return 1; | ||
765 | out: | ||
766 | return 0; | ||
767 | } | ||
768 | |||
580 | static int c4iw_uld_rx_handler(void *handle, const __be64 *rsp, | 769 | static int c4iw_uld_rx_handler(void *handle, const __be64 *rsp, |
581 | const struct pkt_gl *gl) | 770 | const struct pkt_gl *gl) |
582 | { | 771 | { |
583 | struct uld_ctx *ctx = handle; | 772 | struct uld_ctx *ctx = handle; |
584 | struct c4iw_dev *dev = ctx->dev; | 773 | struct c4iw_dev *dev = ctx->dev; |
585 | struct sk_buff *skb; | 774 | struct sk_buff *skb; |
586 | const struct cpl_act_establish *rpl; | 775 | u8 opcode; |
587 | unsigned int opcode; | ||
588 | 776 | ||
589 | if (gl == NULL) { | 777 | if (gl == NULL) { |
590 | /* omit RSS and rsp_ctrl at end of descriptor */ | 778 | /* omit RSS and rsp_ctrl at end of descriptor */ |
@@ -601,19 +789,29 @@ static int c4iw_uld_rx_handler(void *handle, const __be64 *rsp, | |||
601 | u32 qid = be32_to_cpu(rc->pldbuflen_qid); | 789 | u32 qid = be32_to_cpu(rc->pldbuflen_qid); |
602 | c4iw_ev_handler(dev, qid); | 790 | c4iw_ev_handler(dev, qid); |
603 | return 0; | 791 | return 0; |
792 | } else if (unlikely(*(u8 *)rsp != *(u8 *)gl->va)) { | ||
793 | if (recv_rx_pkt(dev, gl, rsp)) | ||
794 | return 0; | ||
795 | |||
796 | pr_info("%s: unexpected FL contents at %p, " \ | ||
797 | "RSS %#llx, FL %#llx, len %u\n", | ||
798 | pci_name(ctx->lldi.pdev), gl->va, | ||
799 | (unsigned long long)be64_to_cpu(*rsp), | ||
800 | (unsigned long long)be64_to_cpu(*(u64 *)gl->va), | ||
801 | gl->tot_len); | ||
802 | |||
803 | return 0; | ||
604 | } else { | 804 | } else { |
605 | skb = cxgb4_pktgl_to_skb(gl, 128, 128); | 805 | skb = cxgb4_pktgl_to_skb(gl, 128, 128); |
606 | if (unlikely(!skb)) | 806 | if (unlikely(!skb)) |
607 | goto nomem; | 807 | goto nomem; |
608 | } | 808 | } |
609 | 809 | ||
610 | rpl = cplhdr(skb); | 810 | opcode = *(u8 *)rsp; |
611 | opcode = rpl->ot.opcode; | ||
612 | |||
613 | if (c4iw_handlers[opcode]) | 811 | if (c4iw_handlers[opcode]) |
614 | c4iw_handlers[opcode](dev, skb); | 812 | c4iw_handlers[opcode](dev, skb); |
615 | else | 813 | else |
616 | printk(KERN_INFO "%s no handler opcode 0x%x...\n", __func__, | 814 | pr_info("%s no handler opcode 0x%x...\n", __func__, |
617 | opcode); | 815 | opcode); |
618 | 816 | ||
619 | return 0; | 817 | return 0; |
diff --git a/drivers/infiniband/hw/cxgb4/iw_cxgb4.h b/drivers/infiniband/hw/cxgb4/iw_cxgb4.h index 9beb3a9f0336..9c1644fb0259 100644 --- a/drivers/infiniband/hw/cxgb4/iw_cxgb4.h +++ b/drivers/infiniband/hw/cxgb4/iw_cxgb4.h | |||
@@ -130,6 +130,9 @@ struct c4iw_stats { | |||
130 | u64 db_empty; | 130 | u64 db_empty; |
131 | u64 db_drop; | 131 | u64 db_drop; |
132 | u64 db_state_transitions; | 132 | u64 db_state_transitions; |
133 | u64 tcam_full; | ||
134 | u64 act_ofld_conn_fails; | ||
135 | u64 pas_ofld_conn_fails; | ||
133 | }; | 136 | }; |
134 | 137 | ||
135 | struct c4iw_rdev { | 138 | struct c4iw_rdev { |
@@ -223,6 +226,9 @@ struct c4iw_dev { | |||
223 | struct dentry *debugfs_root; | 226 | struct dentry *debugfs_root; |
224 | enum db_state db_state; | 227 | enum db_state db_state; |
225 | int qpcnt; | 228 | int qpcnt; |
229 | struct idr hwtid_idr; | ||
230 | struct idr atid_idr; | ||
231 | struct idr stid_idr; | ||
226 | }; | 232 | }; |
227 | 233 | ||
228 | static inline struct c4iw_dev *to_c4iw_dev(struct ib_device *ibdev) | 234 | static inline struct c4iw_dev *to_c4iw_dev(struct ib_device *ibdev) |
@@ -712,6 +718,31 @@ enum c4iw_ep_flags { | |||
712 | CLOSE_SENT = 3, | 718 | CLOSE_SENT = 3, |
713 | }; | 719 | }; |
714 | 720 | ||
721 | enum c4iw_ep_history { | ||
722 | ACT_OPEN_REQ = 0, | ||
723 | ACT_OFLD_CONN = 1, | ||
724 | ACT_OPEN_RPL = 2, | ||
725 | ACT_ESTAB = 3, | ||
726 | PASS_ACCEPT_REQ = 4, | ||
727 | PASS_ESTAB = 5, | ||
728 | ABORT_UPCALL = 6, | ||
729 | ESTAB_UPCALL = 7, | ||
730 | CLOSE_UPCALL = 8, | ||
731 | ULP_ACCEPT = 9, | ||
732 | ULP_REJECT = 10, | ||
733 | TIMEDOUT = 11, | ||
734 | PEER_ABORT = 12, | ||
735 | PEER_CLOSE = 13, | ||
736 | CONNREQ_UPCALL = 14, | ||
737 | ABORT_CONN = 15, | ||
738 | DISCONN_UPCALL = 16, | ||
739 | EP_DISC_CLOSE = 17, | ||
740 | EP_DISC_ABORT = 18, | ||
741 | CONN_RPL_UPCALL = 19, | ||
742 | ACT_RETRY_NOMEM = 20, | ||
743 | ACT_RETRY_INUSE = 21 | ||
744 | }; | ||
745 | |||
715 | struct c4iw_ep_common { | 746 | struct c4iw_ep_common { |
716 | struct iw_cm_id *cm_id; | 747 | struct iw_cm_id *cm_id; |
717 | struct c4iw_qp *qp; | 748 | struct c4iw_qp *qp; |
@@ -723,6 +754,7 @@ struct c4iw_ep_common { | |||
723 | struct sockaddr_in remote_addr; | 754 | struct sockaddr_in remote_addr; |
724 | struct c4iw_wr_wait wr_wait; | 755 | struct c4iw_wr_wait wr_wait; |
725 | unsigned long flags; | 756 | unsigned long flags; |
757 | unsigned long history; | ||
726 | }; | 758 | }; |
727 | 759 | ||
728 | struct c4iw_listen_ep { | 760 | struct c4iw_listen_ep { |
@@ -760,6 +792,7 @@ struct c4iw_ep { | |||
760 | u8 tos; | 792 | u8 tos; |
761 | u8 retry_with_mpa_v1; | 793 | u8 retry_with_mpa_v1; |
762 | u8 tried_with_mpa_v1; | 794 | u8 tried_with_mpa_v1; |
795 | unsigned int retry_count; | ||
763 | }; | 796 | }; |
764 | 797 | ||
765 | static inline struct c4iw_ep *to_ep(struct iw_cm_id *cm_id) | 798 | static inline struct c4iw_ep *to_ep(struct iw_cm_id *cm_id) |