diff options
22 files changed, 2234 insertions, 214 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) |
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_cm.c b/drivers/infiniband/ulp/ipoib/ipoib_cm.c index 72ae63f0072d..03103d2bd641 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_cm.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_cm.c | |||
@@ -752,6 +752,9 @@ void ipoib_cm_send(struct net_device *dev, struct sk_buff *skb, struct ipoib_cm_ | |||
752 | dev->trans_start = jiffies; | 752 | dev->trans_start = jiffies; |
753 | ++tx->tx_head; | 753 | ++tx->tx_head; |
754 | 754 | ||
755 | skb_orphan(skb); | ||
756 | skb_dst_drop(skb); | ||
757 | |||
755 | if (++priv->tx_outstanding == ipoib_sendq_size) { | 758 | if (++priv->tx_outstanding == ipoib_sendq_size) { |
756 | ipoib_dbg(priv, "TX ring 0x%x full, stopping kernel net queue\n", | 759 | ipoib_dbg(priv, "TX ring 0x%x full, stopping kernel net queue\n", |
757 | tx->qp->qp_num); | 760 | tx->qp->qp_num); |
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_ib.c b/drivers/infiniband/ulp/ipoib/ipoib_ib.c index f10221f40803..a1bca70e20aa 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_ib.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_ib.c | |||
@@ -615,8 +615,9 @@ void ipoib_send(struct net_device *dev, struct sk_buff *skb, | |||
615 | 615 | ||
616 | address->last_send = priv->tx_head; | 616 | address->last_send = priv->tx_head; |
617 | ++priv->tx_head; | 617 | ++priv->tx_head; |
618 | skb_orphan(skb); | ||
619 | 618 | ||
619 | skb_orphan(skb); | ||
620 | skb_dst_drop(skb); | ||
620 | } | 621 | } |
621 | 622 | ||
622 | if (unlikely(priv->tx_outstanding > MAX_SEND_CQE)) | 623 | if (unlikely(priv->tx_outstanding > MAX_SEND_CQE)) |
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h index 378988b5709a..6db997c78a5f 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h | |||
@@ -35,6 +35,8 @@ | |||
35 | #ifndef __CXGB4_H__ | 35 | #ifndef __CXGB4_H__ |
36 | #define __CXGB4_H__ | 36 | #define __CXGB4_H__ |
37 | 37 | ||
38 | #include "t4_hw.h" | ||
39 | |||
38 | #include <linux/bitops.h> | 40 | #include <linux/bitops.h> |
39 | #include <linux/cache.h> | 41 | #include <linux/cache.h> |
40 | #include <linux/interrupt.h> | 42 | #include <linux/interrupt.h> |
@@ -212,6 +214,8 @@ struct tp_err_stats { | |||
212 | struct tp_params { | 214 | struct tp_params { |
213 | unsigned int ntxchan; /* # of Tx channels */ | 215 | unsigned int ntxchan; /* # of Tx channels */ |
214 | unsigned int tre; /* log2 of core clocks per TP tick */ | 216 | unsigned int tre; /* log2 of core clocks per TP tick */ |
217 | unsigned short tx_modq_map; /* TX modulation scheduler queue to */ | ||
218 | /* channel map */ | ||
215 | 219 | ||
216 | uint32_t dack_re; /* DACK timer resolution */ | 220 | uint32_t dack_re; /* DACK timer resolution */ |
217 | unsigned short tx_modq[NCHAN]; /* channel to modulation queue map */ | 221 | unsigned short tx_modq[NCHAN]; /* channel to modulation queue map */ |
@@ -526,6 +530,7 @@ struct adapter { | |||
526 | struct net_device *port[MAX_NPORTS]; | 530 | struct net_device *port[MAX_NPORTS]; |
527 | u8 chan_map[NCHAN]; /* channel -> port map */ | 531 | u8 chan_map[NCHAN]; /* channel -> port map */ |
528 | 532 | ||
533 | u32 filter_mode; | ||
529 | unsigned int l2t_start; | 534 | unsigned int l2t_start; |
530 | unsigned int l2t_end; | 535 | unsigned int l2t_end; |
531 | struct l2t_data *l2t; | 536 | struct l2t_data *l2t; |
@@ -545,6 +550,129 @@ struct adapter { | |||
545 | spinlock_t stats_lock; | 550 | spinlock_t stats_lock; |
546 | }; | 551 | }; |
547 | 552 | ||
553 | /* Defined bit width of user definable filter tuples | ||
554 | */ | ||
555 | #define ETHTYPE_BITWIDTH 16 | ||
556 | #define FRAG_BITWIDTH 1 | ||
557 | #define MACIDX_BITWIDTH 9 | ||
558 | #define FCOE_BITWIDTH 1 | ||
559 | #define IPORT_BITWIDTH 3 | ||
560 | #define MATCHTYPE_BITWIDTH 3 | ||
561 | #define PROTO_BITWIDTH 8 | ||
562 | #define TOS_BITWIDTH 8 | ||
563 | #define PF_BITWIDTH 8 | ||
564 | #define VF_BITWIDTH 8 | ||
565 | #define IVLAN_BITWIDTH 16 | ||
566 | #define OVLAN_BITWIDTH 16 | ||
567 | |||
568 | /* Filter matching rules. These consist of a set of ingress packet field | ||
569 | * (value, mask) tuples. The associated ingress packet field matches the | ||
570 | * tuple when ((field & mask) == value). (Thus a wildcard "don't care" field | ||
571 | * rule can be constructed by specifying a tuple of (0, 0).) A filter rule | ||
572 | * matches an ingress packet when all of the individual individual field | ||
573 | * matching rules are true. | ||
574 | * | ||
575 | * Partial field masks are always valid, however, while it may be easy to | ||
576 | * understand their meanings for some fields (e.g. IP address to match a | ||
577 | * subnet), for others making sensible partial masks is less intuitive (e.g. | ||
578 | * MPS match type) ... | ||
579 | * | ||
580 | * Most of the following data structures are modeled on T4 capabilities. | ||
581 | * Drivers for earlier chips use the subsets which make sense for those chips. | ||
582 | * We really need to come up with a hardware-independent mechanism to | ||
583 | * represent hardware filter capabilities ... | ||
584 | */ | ||
585 | struct ch_filter_tuple { | ||
586 | /* Compressed header matching field rules. The TP_VLAN_PRI_MAP | ||
587 | * register selects which of these fields will participate in the | ||
588 | * filter match rules -- up to a maximum of 36 bits. Because | ||
589 | * TP_VLAN_PRI_MAP is a global register, all filters must use the same | ||
590 | * set of fields. | ||
591 | */ | ||
592 | uint32_t ethtype:ETHTYPE_BITWIDTH; /* Ethernet type */ | ||
593 | uint32_t frag:FRAG_BITWIDTH; /* IP fragmentation header */ | ||
594 | uint32_t ivlan_vld:1; /* inner VLAN valid */ | ||
595 | uint32_t ovlan_vld:1; /* outer VLAN valid */ | ||
596 | uint32_t pfvf_vld:1; /* PF/VF valid */ | ||
597 | uint32_t macidx:MACIDX_BITWIDTH; /* exact match MAC index */ | ||
598 | uint32_t fcoe:FCOE_BITWIDTH; /* FCoE packet */ | ||
599 | uint32_t iport:IPORT_BITWIDTH; /* ingress port */ | ||
600 | uint32_t matchtype:MATCHTYPE_BITWIDTH; /* MPS match type */ | ||
601 | uint32_t proto:PROTO_BITWIDTH; /* protocol type */ | ||
602 | uint32_t tos:TOS_BITWIDTH; /* TOS/Traffic Type */ | ||
603 | uint32_t pf:PF_BITWIDTH; /* PCI-E PF ID */ | ||
604 | uint32_t vf:VF_BITWIDTH; /* PCI-E VF ID */ | ||
605 | uint32_t ivlan:IVLAN_BITWIDTH; /* inner VLAN */ | ||
606 | uint32_t ovlan:OVLAN_BITWIDTH; /* outer VLAN */ | ||
607 | |||
608 | /* Uncompressed header matching field rules. These are always | ||
609 | * available for field rules. | ||
610 | */ | ||
611 | uint8_t lip[16]; /* local IP address (IPv4 in [3:0]) */ | ||
612 | uint8_t fip[16]; /* foreign IP address (IPv4 in [3:0]) */ | ||
613 | uint16_t lport; /* local port */ | ||
614 | uint16_t fport; /* foreign port */ | ||
615 | }; | ||
616 | |||
617 | /* A filter ioctl command. | ||
618 | */ | ||
619 | struct ch_filter_specification { | ||
620 | /* Administrative fields for filter. | ||
621 | */ | ||
622 | uint32_t hitcnts:1; /* count filter hits in TCB */ | ||
623 | uint32_t prio:1; /* filter has priority over active/server */ | ||
624 | |||
625 | /* Fundamental filter typing. This is the one element of filter | ||
626 | * matching that doesn't exist as a (value, mask) tuple. | ||
627 | */ | ||
628 | uint32_t type:1; /* 0 => IPv4, 1 => IPv6 */ | ||
629 | |||
630 | /* Packet dispatch information. Ingress packets which match the | ||
631 | * filter rules will be dropped, passed to the host or switched back | ||
632 | * out as egress packets. | ||
633 | */ | ||
634 | uint32_t action:2; /* drop, pass, switch */ | ||
635 | |||
636 | uint32_t rpttid:1; /* report TID in RSS hash field */ | ||
637 | |||
638 | uint32_t dirsteer:1; /* 0 => RSS, 1 => steer to iq */ | ||
639 | uint32_t iq:10; /* ingress queue */ | ||
640 | |||
641 | uint32_t maskhash:1; /* dirsteer=0: store RSS hash in TCB */ | ||
642 | uint32_t dirsteerhash:1;/* dirsteer=1: 0 => TCB contains RSS hash */ | ||
643 | /* 1 => TCB contains IQ ID */ | ||
644 | |||
645 | /* Switch proxy/rewrite fields. An ingress packet which matches a | ||
646 | * filter with "switch" set will be looped back out as an egress | ||
647 | * packet -- potentially with some Ethernet header rewriting. | ||
648 | */ | ||
649 | uint32_t eport:2; /* egress port to switch packet out */ | ||
650 | uint32_t newdmac:1; /* rewrite destination MAC address */ | ||
651 | uint32_t newsmac:1; /* rewrite source MAC address */ | ||
652 | uint32_t newvlan:2; /* rewrite VLAN Tag */ | ||
653 | uint8_t dmac[ETH_ALEN]; /* new destination MAC address */ | ||
654 | uint8_t smac[ETH_ALEN]; /* new source MAC address */ | ||
655 | uint16_t vlan; /* VLAN Tag to insert */ | ||
656 | |||
657 | /* Filter rule value/mask pairs. | ||
658 | */ | ||
659 | struct ch_filter_tuple val; | ||
660 | struct ch_filter_tuple mask; | ||
661 | }; | ||
662 | |||
663 | enum { | ||
664 | FILTER_PASS = 0, /* default */ | ||
665 | FILTER_DROP, | ||
666 | FILTER_SWITCH | ||
667 | }; | ||
668 | |||
669 | enum { | ||
670 | VLAN_NOCHANGE = 0, /* default */ | ||
671 | VLAN_REMOVE, | ||
672 | VLAN_INSERT, | ||
673 | VLAN_REWRITE | ||
674 | }; | ||
675 | |||
548 | static inline u32 t4_read_reg(struct adapter *adap, u32 reg_addr) | 676 | static inline u32 t4_read_reg(struct adapter *adap, u32 reg_addr) |
549 | { | 677 | { |
550 | return readl(adap->regs + reg_addr); | 678 | return readl(adap->regs + reg_addr); |
@@ -701,6 +829,12 @@ static inline int t4_wr_mbox_ns(struct adapter *adap, int mbox, const void *cmd, | |||
701 | void t4_write_indirect(struct adapter *adap, unsigned int addr_reg, | 829 | void t4_write_indirect(struct adapter *adap, unsigned int addr_reg, |
702 | unsigned int data_reg, const u32 *vals, | 830 | unsigned int data_reg, const u32 *vals, |
703 | unsigned int nregs, unsigned int start_idx); | 831 | unsigned int nregs, unsigned int start_idx); |
832 | void t4_read_indirect(struct adapter *adap, unsigned int addr_reg, | ||
833 | unsigned int data_reg, u32 *vals, unsigned int nregs, | ||
834 | unsigned int start_idx); | ||
835 | |||
836 | struct fw_filter_wr; | ||
837 | |||
704 | void t4_intr_enable(struct adapter *adapter); | 838 | void t4_intr_enable(struct adapter *adapter); |
705 | void t4_intr_disable(struct adapter *adapter); | 839 | void t4_intr_disable(struct adapter *adapter); |
706 | int t4_slow_intr_handler(struct adapter *adapter); | 840 | int t4_slow_intr_handler(struct adapter *adapter); |
@@ -737,6 +871,8 @@ void t4_tp_get_tcp_stats(struct adapter *adap, struct tp_tcp_stats *v4, | |||
737 | void t4_load_mtus(struct adapter *adap, const unsigned short *mtus, | 871 | void t4_load_mtus(struct adapter *adap, const unsigned short *mtus, |
738 | const unsigned short *alpha, const unsigned short *beta); | 872 | const unsigned short *alpha, const unsigned short *beta); |
739 | 873 | ||
874 | void t4_mk_filtdelwr(unsigned int ftid, struct fw_filter_wr *wr, int qid); | ||
875 | |||
740 | void t4_wol_magic_enable(struct adapter *adap, unsigned int port, | 876 | void t4_wol_magic_enable(struct adapter *adap, unsigned int port, |
741 | const u8 *addr); | 877 | const u8 *addr); |
742 | int t4_wol_pat_enable(struct adapter *adap, unsigned int port, unsigned int map, | 878 | int t4_wol_pat_enable(struct adapter *adap, unsigned int port, unsigned int map, |
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c index a27b4ae20f43..f0718e1a8369 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c | |||
@@ -175,6 +175,30 @@ enum { | |||
175 | MIN_FL_ENTRIES = 16 | 175 | MIN_FL_ENTRIES = 16 |
176 | }; | 176 | }; |
177 | 177 | ||
178 | /* Host shadow copy of ingress filter entry. This is in host native format | ||
179 | * and doesn't match the ordering or bit order, etc. of the hardware of the | ||
180 | * firmware command. The use of bit-field structure elements is purely to | ||
181 | * remind ourselves of the field size limitations and save memory in the case | ||
182 | * where the filter table is large. | ||
183 | */ | ||
184 | struct filter_entry { | ||
185 | /* Administrative fields for filter. | ||
186 | */ | ||
187 | u32 valid:1; /* filter allocated and valid */ | ||
188 | u32 locked:1; /* filter is administratively locked */ | ||
189 | |||
190 | u32 pending:1; /* filter action is pending firmware reply */ | ||
191 | u32 smtidx:8; /* Source MAC Table index for smac */ | ||
192 | struct l2t_entry *l2t; /* Layer Two Table entry for dmac */ | ||
193 | |||
194 | /* The filter itself. Most of this is a straight copy of information | ||
195 | * provided by the extended ioctl(). Some fields are translated to | ||
196 | * internal forms -- for instance the Ingress Queue ID passed in from | ||
197 | * the ioctl() is translated into the Absolute Ingress Queue ID. | ||
198 | */ | ||
199 | struct ch_filter_specification fs; | ||
200 | }; | ||
201 | |||
178 | #define DFLT_MSG_ENABLE (NETIF_MSG_DRV | NETIF_MSG_PROBE | NETIF_MSG_LINK | \ | 202 | #define DFLT_MSG_ENABLE (NETIF_MSG_DRV | NETIF_MSG_PROBE | NETIF_MSG_LINK | \ |
179 | NETIF_MSG_TIMER | NETIF_MSG_IFDOWN | NETIF_MSG_IFUP |\ | 203 | NETIF_MSG_TIMER | NETIF_MSG_IFDOWN | NETIF_MSG_IFUP |\ |
180 | NETIF_MSG_RX_ERR | NETIF_MSG_TX_ERR) | 204 | NETIF_MSG_RX_ERR | NETIF_MSG_TX_ERR) |
@@ -325,6 +349,9 @@ enum { | |||
325 | 349 | ||
326 | static unsigned int tp_vlan_pri_map = TP_VLAN_PRI_MAP_DEFAULT; | 350 | static unsigned int tp_vlan_pri_map = TP_VLAN_PRI_MAP_DEFAULT; |
327 | 351 | ||
352 | module_param(tp_vlan_pri_map, uint, 0644); | ||
353 | MODULE_PARM_DESC(tp_vlan_pri_map, "global compressed filter configuration"); | ||
354 | |||
328 | static struct dentry *cxgb4_debugfs_root; | 355 | static struct dentry *cxgb4_debugfs_root; |
329 | 356 | ||
330 | static LIST_HEAD(adapter_list); | 357 | static LIST_HEAD(adapter_list); |
@@ -506,8 +533,67 @@ static int link_start(struct net_device *dev) | |||
506 | return ret; | 533 | return ret; |
507 | } | 534 | } |
508 | 535 | ||
509 | /* | 536 | /* Clear a filter and release any of its resources that we own. This also |
510 | * Response queue handler for the FW event queue. | 537 | * clears the filter's "pending" status. |
538 | */ | ||
539 | static void clear_filter(struct adapter *adap, struct filter_entry *f) | ||
540 | { | ||
541 | /* If the new or old filter have loopback rewriteing rules then we'll | ||
542 | * need to free any existing Layer Two Table (L2T) entries of the old | ||
543 | * filter rule. The firmware will handle freeing up any Source MAC | ||
544 | * Table (SMT) entries used for rewriting Source MAC Addresses in | ||
545 | * loopback rules. | ||
546 | */ | ||
547 | if (f->l2t) | ||
548 | cxgb4_l2t_release(f->l2t); | ||
549 | |||
550 | /* The zeroing of the filter rule below clears the filter valid, | ||
551 | * pending, locked flags, l2t pointer, etc. so it's all we need for | ||
552 | * this operation. | ||
553 | */ | ||
554 | memset(f, 0, sizeof(*f)); | ||
555 | } | ||
556 | |||
557 | /* Handle a filter write/deletion reply. | ||
558 | */ | ||
559 | static void filter_rpl(struct adapter *adap, const struct cpl_set_tcb_rpl *rpl) | ||
560 | { | ||
561 | unsigned int idx = GET_TID(rpl); | ||
562 | unsigned int nidx = idx - adap->tids.ftid_base; | ||
563 | unsigned int ret; | ||
564 | struct filter_entry *f; | ||
565 | |||
566 | if (idx >= adap->tids.ftid_base && nidx < | ||
567 | (adap->tids.nftids + adap->tids.nsftids)) { | ||
568 | idx = nidx; | ||
569 | ret = GET_TCB_COOKIE(rpl->cookie); | ||
570 | f = &adap->tids.ftid_tab[idx]; | ||
571 | |||
572 | if (ret == FW_FILTER_WR_FLT_DELETED) { | ||
573 | /* Clear the filter when we get confirmation from the | ||
574 | * hardware that the filter has been deleted. | ||
575 | */ | ||
576 | clear_filter(adap, f); | ||
577 | } else if (ret == FW_FILTER_WR_SMT_TBL_FULL) { | ||
578 | dev_err(adap->pdev_dev, "filter %u setup failed due to full SMT\n", | ||
579 | idx); | ||
580 | clear_filter(adap, f); | ||
581 | } else if (ret == FW_FILTER_WR_FLT_ADDED) { | ||
582 | f->smtidx = (be64_to_cpu(rpl->oldval) >> 24) & 0xff; | ||
583 | f->pending = 0; /* asynchronous setup completed */ | ||
584 | f->valid = 1; | ||
585 | } else { | ||
586 | /* Something went wrong. Issue a warning about the | ||
587 | * problem and clear everything out. | ||
588 | */ | ||
589 | dev_err(adap->pdev_dev, "filter %u setup failed with error %u\n", | ||
590 | idx, ret); | ||
591 | clear_filter(adap, f); | ||
592 | } | ||
593 | } | ||
594 | } | ||
595 | |||
596 | /* Response queue handler for the FW event queue. | ||
511 | */ | 597 | */ |
512 | static int fwevtq_handler(struct sge_rspq *q, const __be64 *rsp, | 598 | static int fwevtq_handler(struct sge_rspq *q, const __be64 *rsp, |
513 | const struct pkt_gl *gl) | 599 | const struct pkt_gl *gl) |
@@ -542,6 +628,10 @@ static int fwevtq_handler(struct sge_rspq *q, const __be64 *rsp, | |||
542 | const struct cpl_l2t_write_rpl *p = (void *)rsp; | 628 | const struct cpl_l2t_write_rpl *p = (void *)rsp; |
543 | 629 | ||
544 | do_l2t_write_rpl(q->adap, p); | 630 | do_l2t_write_rpl(q->adap, p); |
631 | } else if (opcode == CPL_SET_TCB_RPL) { | ||
632 | const struct cpl_set_tcb_rpl *p = (void *)rsp; | ||
633 | |||
634 | filter_rpl(q->adap, p); | ||
545 | } else | 635 | } else |
546 | dev_err(q->adap->pdev_dev, | 636 | dev_err(q->adap->pdev_dev, |
547 | "unexpected CPL %#x on FW event queue\n", opcode); | 637 | "unexpected CPL %#x on FW event queue\n", opcode); |
@@ -983,6 +1073,148 @@ static void t4_free_mem(void *addr) | |||
983 | kfree(addr); | 1073 | kfree(addr); |
984 | } | 1074 | } |
985 | 1075 | ||
1076 | /* Send a Work Request to write the filter at a specified index. We construct | ||
1077 | * a Firmware Filter Work Request to have the work done and put the indicated | ||
1078 | * filter into "pending" mode which will prevent any further actions against | ||
1079 | * it till we get a reply from the firmware on the completion status of the | ||
1080 | * request. | ||
1081 | */ | ||
1082 | static int set_filter_wr(struct adapter *adapter, int fidx) | ||
1083 | { | ||
1084 | struct filter_entry *f = &adapter->tids.ftid_tab[fidx]; | ||
1085 | struct sk_buff *skb; | ||
1086 | struct fw_filter_wr *fwr; | ||
1087 | unsigned int ftid; | ||
1088 | |||
1089 | /* If the new filter requires loopback Destination MAC and/or VLAN | ||
1090 | * rewriting then we need to allocate a Layer 2 Table (L2T) entry for | ||
1091 | * the filter. | ||
1092 | */ | ||
1093 | if (f->fs.newdmac || f->fs.newvlan) { | ||
1094 | /* allocate L2T entry for new filter */ | ||
1095 | f->l2t = t4_l2t_alloc_switching(adapter->l2t); | ||
1096 | if (f->l2t == NULL) | ||
1097 | return -EAGAIN; | ||
1098 | if (t4_l2t_set_switching(adapter, f->l2t, f->fs.vlan, | ||
1099 | f->fs.eport, f->fs.dmac)) { | ||
1100 | cxgb4_l2t_release(f->l2t); | ||
1101 | f->l2t = NULL; | ||
1102 | return -ENOMEM; | ||
1103 | } | ||
1104 | } | ||
1105 | |||
1106 | ftid = adapter->tids.ftid_base + fidx; | ||
1107 | |||
1108 | skb = alloc_skb(sizeof(*fwr), GFP_KERNEL | __GFP_NOFAIL); | ||
1109 | fwr = (struct fw_filter_wr *)__skb_put(skb, sizeof(*fwr)); | ||
1110 | memset(fwr, 0, sizeof(*fwr)); | ||
1111 | |||
1112 | /* It would be nice to put most of the following in t4_hw.c but most | ||
1113 | * of the work is translating the cxgbtool ch_filter_specification | ||
1114 | * into the Work Request and the definition of that structure is | ||
1115 | * currently in cxgbtool.h which isn't appropriate to pull into the | ||
1116 | * common code. We may eventually try to come up with a more neutral | ||
1117 | * filter specification structure but for now it's easiest to simply | ||
1118 | * put this fairly direct code in line ... | ||
1119 | */ | ||
1120 | fwr->op_pkd = htonl(FW_WR_OP(FW_FILTER_WR)); | ||
1121 | fwr->len16_pkd = htonl(FW_WR_LEN16(sizeof(*fwr)/16)); | ||
1122 | fwr->tid_to_iq = | ||
1123 | htonl(V_FW_FILTER_WR_TID(ftid) | | ||
1124 | V_FW_FILTER_WR_RQTYPE(f->fs.type) | | ||
1125 | V_FW_FILTER_WR_NOREPLY(0) | | ||
1126 | V_FW_FILTER_WR_IQ(f->fs.iq)); | ||
1127 | fwr->del_filter_to_l2tix = | ||
1128 | htonl(V_FW_FILTER_WR_RPTTID(f->fs.rpttid) | | ||
1129 | V_FW_FILTER_WR_DROP(f->fs.action == FILTER_DROP) | | ||
1130 | V_FW_FILTER_WR_DIRSTEER(f->fs.dirsteer) | | ||
1131 | V_FW_FILTER_WR_MASKHASH(f->fs.maskhash) | | ||
1132 | V_FW_FILTER_WR_DIRSTEERHASH(f->fs.dirsteerhash) | | ||
1133 | V_FW_FILTER_WR_LPBK(f->fs.action == FILTER_SWITCH) | | ||
1134 | V_FW_FILTER_WR_DMAC(f->fs.newdmac) | | ||
1135 | V_FW_FILTER_WR_SMAC(f->fs.newsmac) | | ||
1136 | V_FW_FILTER_WR_INSVLAN(f->fs.newvlan == VLAN_INSERT || | ||
1137 | f->fs.newvlan == VLAN_REWRITE) | | ||
1138 | V_FW_FILTER_WR_RMVLAN(f->fs.newvlan == VLAN_REMOVE || | ||
1139 | f->fs.newvlan == VLAN_REWRITE) | | ||
1140 | V_FW_FILTER_WR_HITCNTS(f->fs.hitcnts) | | ||
1141 | V_FW_FILTER_WR_TXCHAN(f->fs.eport) | | ||
1142 | V_FW_FILTER_WR_PRIO(f->fs.prio) | | ||
1143 | V_FW_FILTER_WR_L2TIX(f->l2t ? f->l2t->idx : 0)); | ||
1144 | fwr->ethtype = htons(f->fs.val.ethtype); | ||
1145 | fwr->ethtypem = htons(f->fs.mask.ethtype); | ||
1146 | fwr->frag_to_ovlan_vldm = | ||
1147 | (V_FW_FILTER_WR_FRAG(f->fs.val.frag) | | ||
1148 | V_FW_FILTER_WR_FRAGM(f->fs.mask.frag) | | ||
1149 | V_FW_FILTER_WR_IVLAN_VLD(f->fs.val.ivlan_vld) | | ||
1150 | V_FW_FILTER_WR_OVLAN_VLD(f->fs.val.ovlan_vld) | | ||
1151 | V_FW_FILTER_WR_IVLAN_VLDM(f->fs.mask.ivlan_vld) | | ||
1152 | V_FW_FILTER_WR_OVLAN_VLDM(f->fs.mask.ovlan_vld)); | ||
1153 | fwr->smac_sel = 0; | ||
1154 | fwr->rx_chan_rx_rpl_iq = | ||
1155 | htons(V_FW_FILTER_WR_RX_CHAN(0) | | ||
1156 | V_FW_FILTER_WR_RX_RPL_IQ(adapter->sge.fw_evtq.abs_id)); | ||
1157 | fwr->maci_to_matchtypem = | ||
1158 | htonl(V_FW_FILTER_WR_MACI(f->fs.val.macidx) | | ||
1159 | V_FW_FILTER_WR_MACIM(f->fs.mask.macidx) | | ||
1160 | V_FW_FILTER_WR_FCOE(f->fs.val.fcoe) | | ||
1161 | V_FW_FILTER_WR_FCOEM(f->fs.mask.fcoe) | | ||
1162 | V_FW_FILTER_WR_PORT(f->fs.val.iport) | | ||
1163 | V_FW_FILTER_WR_PORTM(f->fs.mask.iport) | | ||
1164 | V_FW_FILTER_WR_MATCHTYPE(f->fs.val.matchtype) | | ||
1165 | V_FW_FILTER_WR_MATCHTYPEM(f->fs.mask.matchtype)); | ||
1166 | fwr->ptcl = f->fs.val.proto; | ||
1167 | fwr->ptclm = f->fs.mask.proto; | ||
1168 | fwr->ttyp = f->fs.val.tos; | ||
1169 | fwr->ttypm = f->fs.mask.tos; | ||
1170 | fwr->ivlan = htons(f->fs.val.ivlan); | ||
1171 | fwr->ivlanm = htons(f->fs.mask.ivlan); | ||
1172 | fwr->ovlan = htons(f->fs.val.ovlan); | ||
1173 | fwr->ovlanm = htons(f->fs.mask.ovlan); | ||
1174 | memcpy(fwr->lip, f->fs.val.lip, sizeof(fwr->lip)); | ||
1175 | memcpy(fwr->lipm, f->fs.mask.lip, sizeof(fwr->lipm)); | ||
1176 | memcpy(fwr->fip, f->fs.val.fip, sizeof(fwr->fip)); | ||
1177 | memcpy(fwr->fipm, f->fs.mask.fip, sizeof(fwr->fipm)); | ||
1178 | fwr->lp = htons(f->fs.val.lport); | ||
1179 | fwr->lpm = htons(f->fs.mask.lport); | ||
1180 | fwr->fp = htons(f->fs.val.fport); | ||
1181 | fwr->fpm = htons(f->fs.mask.fport); | ||
1182 | if (f->fs.newsmac) | ||
1183 | memcpy(fwr->sma, f->fs.smac, sizeof(fwr->sma)); | ||
1184 | |||
1185 | /* Mark the filter as "pending" and ship off the Filter Work Request. | ||
1186 | * When we get the Work Request Reply we'll clear the pending status. | ||
1187 | */ | ||
1188 | f->pending = 1; | ||
1189 | set_wr_txq(skb, CPL_PRIORITY_CONTROL, f->fs.val.iport & 0x3); | ||
1190 | t4_ofld_send(adapter, skb); | ||
1191 | return 0; | ||
1192 | } | ||
1193 | |||
1194 | /* Delete the filter at a specified index. | ||
1195 | */ | ||
1196 | static int del_filter_wr(struct adapter *adapter, int fidx) | ||
1197 | { | ||
1198 | struct filter_entry *f = &adapter->tids.ftid_tab[fidx]; | ||
1199 | struct sk_buff *skb; | ||
1200 | struct fw_filter_wr *fwr; | ||
1201 | unsigned int len, ftid; | ||
1202 | |||
1203 | len = sizeof(*fwr); | ||
1204 | ftid = adapter->tids.ftid_base + fidx; | ||
1205 | |||
1206 | skb = alloc_skb(len, GFP_KERNEL | __GFP_NOFAIL); | ||
1207 | fwr = (struct fw_filter_wr *)__skb_put(skb, len); | ||
1208 | t4_mk_filtdelwr(ftid, fwr, adapter->sge.fw_evtq.abs_id); | ||
1209 | |||
1210 | /* Mark the filter as "pending" and ship off the Filter Work Request. | ||
1211 | * When we get the Work Request Reply we'll clear the pending status. | ||
1212 | */ | ||
1213 | f->pending = 1; | ||
1214 | t4_mgmt_tx(adapter, skb); | ||
1215 | return 0; | ||
1216 | } | ||
1217 | |||
986 | static inline int is_offload(const struct adapter *adap) | 1218 | static inline int is_offload(const struct adapter *adap) |
987 | { | 1219 | { |
988 | return adap->params.offload; | 1220 | return adap->params.offload; |
@@ -2195,7 +2427,7 @@ int cxgb4_alloc_atid(struct tid_info *t, void *data) | |||
2195 | if (t->afree) { | 2427 | if (t->afree) { |
2196 | union aopen_entry *p = t->afree; | 2428 | union aopen_entry *p = t->afree; |
2197 | 2429 | ||
2198 | atid = p - t->atid_tab; | 2430 | atid = (p - t->atid_tab) + t->atid_base; |
2199 | t->afree = p->next; | 2431 | t->afree = p->next; |
2200 | p->data = data; | 2432 | p->data = data; |
2201 | t->atids_in_use++; | 2433 | t->atids_in_use++; |
@@ -2210,7 +2442,7 @@ EXPORT_SYMBOL(cxgb4_alloc_atid); | |||
2210 | */ | 2442 | */ |
2211 | void cxgb4_free_atid(struct tid_info *t, unsigned int atid) | 2443 | void cxgb4_free_atid(struct tid_info *t, unsigned int atid) |
2212 | { | 2444 | { |
2213 | union aopen_entry *p = &t->atid_tab[atid]; | 2445 | union aopen_entry *p = &t->atid_tab[atid - t->atid_base]; |
2214 | 2446 | ||
2215 | spin_lock_bh(&t->atid_lock); | 2447 | spin_lock_bh(&t->atid_lock); |
2216 | p->next = t->afree; | 2448 | p->next = t->afree; |
@@ -2249,8 +2481,34 @@ int cxgb4_alloc_stid(struct tid_info *t, int family, void *data) | |||
2249 | } | 2481 | } |
2250 | EXPORT_SYMBOL(cxgb4_alloc_stid); | 2482 | EXPORT_SYMBOL(cxgb4_alloc_stid); |
2251 | 2483 | ||
2252 | /* | 2484 | /* Allocate a server filter TID and set it to the supplied value. |
2253 | * Release a server TID. | 2485 | */ |
2486 | int cxgb4_alloc_sftid(struct tid_info *t, int family, void *data) | ||
2487 | { | ||
2488 | int stid; | ||
2489 | |||
2490 | spin_lock_bh(&t->stid_lock); | ||
2491 | if (family == PF_INET) { | ||
2492 | stid = find_next_zero_bit(t->stid_bmap, | ||
2493 | t->nstids + t->nsftids, t->nstids); | ||
2494 | if (stid < (t->nstids + t->nsftids)) | ||
2495 | __set_bit(stid, t->stid_bmap); | ||
2496 | else | ||
2497 | stid = -1; | ||
2498 | } else { | ||
2499 | stid = -1; | ||
2500 | } | ||
2501 | if (stid >= 0) { | ||
2502 | t->stid_tab[stid].data = data; | ||
2503 | stid += t->stid_base; | ||
2504 | t->stids_in_use++; | ||
2505 | } | ||
2506 | spin_unlock_bh(&t->stid_lock); | ||
2507 | return stid; | ||
2508 | } | ||
2509 | EXPORT_SYMBOL(cxgb4_alloc_sftid); | ||
2510 | |||
2511 | /* Release a server TID. | ||
2254 | */ | 2512 | */ |
2255 | void cxgb4_free_stid(struct tid_info *t, unsigned int stid, int family) | 2513 | void cxgb4_free_stid(struct tid_info *t, unsigned int stid, int family) |
2256 | { | 2514 | { |
@@ -2362,18 +2620,26 @@ EXPORT_SYMBOL(cxgb4_remove_tid); | |||
2362 | static int tid_init(struct tid_info *t) | 2620 | static int tid_init(struct tid_info *t) |
2363 | { | 2621 | { |
2364 | size_t size; | 2622 | size_t size; |
2623 | unsigned int stid_bmap_size; | ||
2365 | unsigned int natids = t->natids; | 2624 | unsigned int natids = t->natids; |
2366 | 2625 | ||
2367 | size = t->ntids * sizeof(*t->tid_tab) + natids * sizeof(*t->atid_tab) + | 2626 | stid_bmap_size = BITS_TO_LONGS(t->nstids + t->nsftids); |
2627 | size = t->ntids * sizeof(*t->tid_tab) + | ||
2628 | natids * sizeof(*t->atid_tab) + | ||
2368 | t->nstids * sizeof(*t->stid_tab) + | 2629 | t->nstids * sizeof(*t->stid_tab) + |
2369 | BITS_TO_LONGS(t->nstids) * sizeof(long); | 2630 | t->nsftids * sizeof(*t->stid_tab) + |
2631 | stid_bmap_size * sizeof(long) + | ||
2632 | t->nftids * sizeof(*t->ftid_tab) + | ||
2633 | t->nsftids * sizeof(*t->ftid_tab); | ||
2634 | |||
2370 | t->tid_tab = t4_alloc_mem(size); | 2635 | t->tid_tab = t4_alloc_mem(size); |
2371 | if (!t->tid_tab) | 2636 | if (!t->tid_tab) |
2372 | return -ENOMEM; | 2637 | return -ENOMEM; |
2373 | 2638 | ||
2374 | t->atid_tab = (union aopen_entry *)&t->tid_tab[t->ntids]; | 2639 | t->atid_tab = (union aopen_entry *)&t->tid_tab[t->ntids]; |
2375 | t->stid_tab = (struct serv_entry *)&t->atid_tab[natids]; | 2640 | t->stid_tab = (struct serv_entry *)&t->atid_tab[natids]; |
2376 | t->stid_bmap = (unsigned long *)&t->stid_tab[t->nstids]; | 2641 | t->stid_bmap = (unsigned long *)&t->stid_tab[t->nstids + t->nsftids]; |
2642 | t->ftid_tab = (struct filter_entry *)&t->stid_bmap[stid_bmap_size]; | ||
2377 | spin_lock_init(&t->stid_lock); | 2643 | spin_lock_init(&t->stid_lock); |
2378 | spin_lock_init(&t->atid_lock); | 2644 | spin_lock_init(&t->atid_lock); |
2379 | 2645 | ||
@@ -2388,7 +2654,7 @@ static int tid_init(struct tid_info *t) | |||
2388 | t->atid_tab[natids - 1].next = &t->atid_tab[natids]; | 2654 | t->atid_tab[natids - 1].next = &t->atid_tab[natids]; |
2389 | t->afree = t->atid_tab; | 2655 | t->afree = t->atid_tab; |
2390 | } | 2656 | } |
2391 | bitmap_zero(t->stid_bmap, t->nstids); | 2657 | bitmap_zero(t->stid_bmap, t->nstids + t->nsftids); |
2392 | return 0; | 2658 | return 0; |
2393 | } | 2659 | } |
2394 | 2660 | ||
@@ -2404,7 +2670,8 @@ static int tid_init(struct tid_info *t) | |||
2404 | * Returns <0 on error and one of the %NET_XMIT_* values on success. | 2670 | * Returns <0 on error and one of the %NET_XMIT_* values on success. |
2405 | */ | 2671 | */ |
2406 | int cxgb4_create_server(const struct net_device *dev, unsigned int stid, | 2672 | int cxgb4_create_server(const struct net_device *dev, unsigned int stid, |
2407 | __be32 sip, __be16 sport, unsigned int queue) | 2673 | __be32 sip, __be16 sport, __be16 vlan, |
2674 | unsigned int queue) | ||
2408 | { | 2675 | { |
2409 | unsigned int chan; | 2676 | unsigned int chan; |
2410 | struct sk_buff *skb; | 2677 | struct sk_buff *skb; |
@@ -2750,6 +3017,7 @@ static void uld_attach(struct adapter *adap, unsigned int uld) | |||
2750 | { | 3017 | { |
2751 | void *handle; | 3018 | void *handle; |
2752 | struct cxgb4_lld_info lli; | 3019 | struct cxgb4_lld_info lli; |
3020 | unsigned short i; | ||
2753 | 3021 | ||
2754 | lli.pdev = adap->pdev; | 3022 | lli.pdev = adap->pdev; |
2755 | lli.l2t = adap->l2t; | 3023 | lli.l2t = adap->l2t; |
@@ -2776,10 +3044,16 @@ static void uld_attach(struct adapter *adap, unsigned int uld) | |||
2776 | lli.ucq_density = 1 << QUEUESPERPAGEPF0_GET( | 3044 | lli.ucq_density = 1 << QUEUESPERPAGEPF0_GET( |
2777 | t4_read_reg(adap, SGE_INGRESS_QUEUES_PER_PAGE_PF) >> | 3045 | t4_read_reg(adap, SGE_INGRESS_QUEUES_PER_PAGE_PF) >> |
2778 | (adap->fn * 4)); | 3046 | (adap->fn * 4)); |
3047 | lli.filt_mode = adap->filter_mode; | ||
3048 | /* MODQ_REQ_MAP sets queues 0-3 to chan 0-3 */ | ||
3049 | for (i = 0; i < NCHAN; i++) | ||
3050 | lli.tx_modq[i] = i; | ||
2779 | lli.gts_reg = adap->regs + MYPF_REG(SGE_PF_GTS); | 3051 | lli.gts_reg = adap->regs + MYPF_REG(SGE_PF_GTS); |
2780 | lli.db_reg = adap->regs + MYPF_REG(SGE_PF_KDOORBELL); | 3052 | lli.db_reg = adap->regs + MYPF_REG(SGE_PF_KDOORBELL); |
2781 | lli.fw_vers = adap->params.fw_vers; | 3053 | lli.fw_vers = adap->params.fw_vers; |
2782 | lli.dbfifo_int_thresh = dbfifo_int_thresh; | 3054 | lli.dbfifo_int_thresh = dbfifo_int_thresh; |
3055 | lli.sge_pktshift = adap->sge.pktshift; | ||
3056 | lli.enable_fw_ofld_conn = adap->flags & FW_OFLD_CONN; | ||
2783 | 3057 | ||
2784 | handle = ulds[uld].add(&lli); | 3058 | handle = ulds[uld].add(&lli); |
2785 | if (IS_ERR(handle)) { | 3059 | if (IS_ERR(handle)) { |
@@ -2999,6 +3273,126 @@ static int cxgb_close(struct net_device *dev) | |||
2999 | return t4_enable_vi(adapter, adapter->fn, pi->viid, false, false); | 3273 | return t4_enable_vi(adapter, adapter->fn, pi->viid, false, false); |
3000 | } | 3274 | } |
3001 | 3275 | ||
3276 | /* Return an error number if the indicated filter isn't writable ... | ||
3277 | */ | ||
3278 | static int writable_filter(struct filter_entry *f) | ||
3279 | { | ||
3280 | if (f->locked) | ||
3281 | return -EPERM; | ||
3282 | if (f->pending) | ||
3283 | return -EBUSY; | ||
3284 | |||
3285 | return 0; | ||
3286 | } | ||
3287 | |||
3288 | /* Delete the filter at the specified index (if valid). The checks for all | ||
3289 | * the common problems with doing this like the filter being locked, currently | ||
3290 | * pending in another operation, etc. | ||
3291 | */ | ||
3292 | static int delete_filter(struct adapter *adapter, unsigned int fidx) | ||
3293 | { | ||
3294 | struct filter_entry *f; | ||
3295 | int ret; | ||
3296 | |||
3297 | if (fidx >= adapter->tids.nftids + adapter->tids.nsftids) | ||
3298 | return -EINVAL; | ||
3299 | |||
3300 | f = &adapter->tids.ftid_tab[fidx]; | ||
3301 | ret = writable_filter(f); | ||
3302 | if (ret) | ||
3303 | return ret; | ||
3304 | if (f->valid) | ||
3305 | return del_filter_wr(adapter, fidx); | ||
3306 | |||
3307 | return 0; | ||
3308 | } | ||
3309 | |||
3310 | int cxgb4_create_server_filter(const struct net_device *dev, unsigned int stid, | ||
3311 | __be32 sip, __be16 sport, __be16 vlan, | ||
3312 | unsigned int queue, unsigned char port, unsigned char mask) | ||
3313 | { | ||
3314 | int ret; | ||
3315 | struct filter_entry *f; | ||
3316 | struct adapter *adap; | ||
3317 | int i; | ||
3318 | u8 *val; | ||
3319 | |||
3320 | adap = netdev2adap(dev); | ||
3321 | |||
3322 | /* Adjust stid to correct filter index */ | ||
3323 | stid -= adap->tids.nstids; | ||
3324 | stid += adap->tids.nftids; | ||
3325 | |||
3326 | /* Check to make sure the filter requested is writable ... | ||
3327 | */ | ||
3328 | f = &adap->tids.ftid_tab[stid]; | ||
3329 | ret = writable_filter(f); | ||
3330 | if (ret) | ||
3331 | return ret; | ||
3332 | |||
3333 | /* Clear out any old resources being used by the filter before | ||
3334 | * we start constructing the new filter. | ||
3335 | */ | ||
3336 | if (f->valid) | ||
3337 | clear_filter(adap, f); | ||
3338 | |||
3339 | /* Clear out filter specifications */ | ||
3340 | memset(&f->fs, 0, sizeof(struct ch_filter_specification)); | ||
3341 | f->fs.val.lport = cpu_to_be16(sport); | ||
3342 | f->fs.mask.lport = ~0; | ||
3343 | val = (u8 *)&sip; | ||
3344 | if ((val[0] | val[1] | val[2] | val[3]) != 0) { | ||
3345 | for (i = 0; i < 4; i++) { | ||
3346 | f->fs.val.lip[i] = val[i]; | ||
3347 | f->fs.mask.lip[i] = ~0; | ||
3348 | } | ||
3349 | if (adap->filter_mode & F_PORT) { | ||
3350 | f->fs.val.iport = port; | ||
3351 | f->fs.mask.iport = mask; | ||
3352 | } | ||
3353 | } | ||
3354 | |||
3355 | f->fs.dirsteer = 1; | ||
3356 | f->fs.iq = queue; | ||
3357 | /* Mark filter as locked */ | ||
3358 | f->locked = 1; | ||
3359 | f->fs.rpttid = 1; | ||
3360 | |||
3361 | ret = set_filter_wr(adap, stid); | ||
3362 | if (ret) { | ||
3363 | clear_filter(adap, f); | ||
3364 | return ret; | ||
3365 | } | ||
3366 | |||
3367 | return 0; | ||
3368 | } | ||
3369 | EXPORT_SYMBOL(cxgb4_create_server_filter); | ||
3370 | |||
3371 | int cxgb4_remove_server_filter(const struct net_device *dev, unsigned int stid, | ||
3372 | unsigned int queue, bool ipv6) | ||
3373 | { | ||
3374 | int ret; | ||
3375 | struct filter_entry *f; | ||
3376 | struct adapter *adap; | ||
3377 | |||
3378 | adap = netdev2adap(dev); | ||
3379 | |||
3380 | /* Adjust stid to correct filter index */ | ||
3381 | stid -= adap->tids.nstids; | ||
3382 | stid += adap->tids.nftids; | ||
3383 | |||
3384 | f = &adap->tids.ftid_tab[stid]; | ||
3385 | /* Unlock the filter */ | ||
3386 | f->locked = 0; | ||
3387 | |||
3388 | ret = delete_filter(adap, stid); | ||
3389 | if (ret) | ||
3390 | return ret; | ||
3391 | |||
3392 | return 0; | ||
3393 | } | ||
3394 | EXPORT_SYMBOL(cxgb4_remove_server_filter); | ||
3395 | |||
3002 | static struct rtnl_link_stats64 *cxgb_get_stats(struct net_device *dev, | 3396 | static struct rtnl_link_stats64 *cxgb_get_stats(struct net_device *dev, |
3003 | struct rtnl_link_stats64 *ns) | 3397 | struct rtnl_link_stats64 *ns) |
3004 | { | 3398 | { |
@@ -3245,6 +3639,34 @@ static int adap_init1(struct adapter *adap, struct fw_caps_config_cmd *c) | |||
3245 | v = t4_read_reg(adap, TP_PIO_DATA); | 3639 | v = t4_read_reg(adap, TP_PIO_DATA); |
3246 | t4_write_reg(adap, TP_PIO_DATA, v & ~CSUM_HAS_PSEUDO_HDR); | 3640 | t4_write_reg(adap, TP_PIO_DATA, v & ~CSUM_HAS_PSEUDO_HDR); |
3247 | 3641 | ||
3642 | /* first 4 Tx modulation queues point to consecutive Tx channels */ | ||
3643 | adap->params.tp.tx_modq_map = 0xE4; | ||
3644 | t4_write_reg(adap, A_TP_TX_MOD_QUEUE_REQ_MAP, | ||
3645 | V_TX_MOD_QUEUE_REQ_MAP(adap->params.tp.tx_modq_map)); | ||
3646 | |||
3647 | /* associate each Tx modulation queue with consecutive Tx channels */ | ||
3648 | v = 0x84218421; | ||
3649 | t4_write_indirect(adap, TP_PIO_ADDR, TP_PIO_DATA, | ||
3650 | &v, 1, A_TP_TX_SCHED_HDR); | ||
3651 | t4_write_indirect(adap, TP_PIO_ADDR, TP_PIO_DATA, | ||
3652 | &v, 1, A_TP_TX_SCHED_FIFO); | ||
3653 | t4_write_indirect(adap, TP_PIO_ADDR, TP_PIO_DATA, | ||
3654 | &v, 1, A_TP_TX_SCHED_PCMD); | ||
3655 | |||
3656 | #define T4_TX_MODQ_10G_WEIGHT_DEFAULT 16 /* in KB units */ | ||
3657 | if (is_offload(adap)) { | ||
3658 | t4_write_reg(adap, A_TP_TX_MOD_QUEUE_WEIGHT0, | ||
3659 | V_TX_MODQ_WEIGHT0(T4_TX_MODQ_10G_WEIGHT_DEFAULT) | | ||
3660 | V_TX_MODQ_WEIGHT1(T4_TX_MODQ_10G_WEIGHT_DEFAULT) | | ||
3661 | V_TX_MODQ_WEIGHT2(T4_TX_MODQ_10G_WEIGHT_DEFAULT) | | ||
3662 | V_TX_MODQ_WEIGHT3(T4_TX_MODQ_10G_WEIGHT_DEFAULT)); | ||
3663 | t4_write_reg(adap, A_TP_TX_MOD_CHANNEL_WEIGHT, | ||
3664 | V_TX_MODQ_WEIGHT0(T4_TX_MODQ_10G_WEIGHT_DEFAULT) | | ||
3665 | V_TX_MODQ_WEIGHT1(T4_TX_MODQ_10G_WEIGHT_DEFAULT) | | ||
3666 | V_TX_MODQ_WEIGHT2(T4_TX_MODQ_10G_WEIGHT_DEFAULT) | | ||
3667 | V_TX_MODQ_WEIGHT3(T4_TX_MODQ_10G_WEIGHT_DEFAULT)); | ||
3668 | } | ||
3669 | |||
3248 | /* get basic stuff going */ | 3670 | /* get basic stuff going */ |
3249 | return t4_early_init(adap, adap->fn); | 3671 | return t4_early_init(adap, adap->fn); |
3250 | } | 3672 | } |
@@ -4035,6 +4457,10 @@ static int adap_init0(struct adapter *adap) | |||
4035 | for (j = 0; j < NCHAN; j++) | 4457 | for (j = 0; j < NCHAN; j++) |
4036 | adap->params.tp.tx_modq[j] = j; | 4458 | adap->params.tp.tx_modq[j] = j; |
4037 | 4459 | ||
4460 | t4_read_indirect(adap, TP_PIO_ADDR, TP_PIO_DATA, | ||
4461 | &adap->filter_mode, 1, | ||
4462 | TP_VLAN_PRI_MAP); | ||
4463 | |||
4038 | adap->flags |= FW_OK; | 4464 | adap->flags |= FW_OK; |
4039 | return 0; | 4465 | return 0; |
4040 | 4466 | ||
@@ -4661,6 +5087,17 @@ static void remove_one(struct pci_dev *pdev) | |||
4661 | if (adapter->debugfs_root) | 5087 | if (adapter->debugfs_root) |
4662 | debugfs_remove_recursive(adapter->debugfs_root); | 5088 | debugfs_remove_recursive(adapter->debugfs_root); |
4663 | 5089 | ||
5090 | /* If we allocated filters, free up state associated with any | ||
5091 | * valid filters ... | ||
5092 | */ | ||
5093 | if (adapter->tids.ftid_tab) { | ||
5094 | struct filter_entry *f = &adapter->tids.ftid_tab[0]; | ||
5095 | for (i = 0; i < (adapter->tids.nftids + | ||
5096 | adapter->tids.nsftids); i++, f++) | ||
5097 | if (f->valid) | ||
5098 | clear_filter(adapter, f); | ||
5099 | } | ||
5100 | |||
4664 | if (adapter->flags & FULL_INIT_DONE) | 5101 | if (adapter->flags & FULL_INIT_DONE) |
4665 | cxgb_down(adapter); | 5102 | cxgb_down(adapter); |
4666 | 5103 | ||
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.h b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.h index 39bec73ff87c..e2bbc7f3e2de 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.h +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.h | |||
@@ -38,6 +38,7 @@ | |||
38 | #include <linux/cache.h> | 38 | #include <linux/cache.h> |
39 | #include <linux/spinlock.h> | 39 | #include <linux/spinlock.h> |
40 | #include <linux/skbuff.h> | 40 | #include <linux/skbuff.h> |
41 | #include <linux/inetdevice.h> | ||
41 | #include <linux/atomic.h> | 42 | #include <linux/atomic.h> |
42 | 43 | ||
43 | /* CPL message priority levels */ | 44 | /* CPL message priority levels */ |
@@ -97,7 +98,9 @@ struct tid_info { | |||
97 | 98 | ||
98 | union aopen_entry *atid_tab; | 99 | union aopen_entry *atid_tab; |
99 | unsigned int natids; | 100 | unsigned int natids; |
101 | unsigned int atid_base; | ||
100 | 102 | ||
103 | struct filter_entry *ftid_tab; | ||
101 | unsigned int nftids; | 104 | unsigned int nftids; |
102 | unsigned int ftid_base; | 105 | unsigned int ftid_base; |
103 | unsigned int aftid_base; | 106 | unsigned int aftid_base; |
@@ -129,7 +132,7 @@ static inline void *lookup_atid(const struct tid_info *t, unsigned int atid) | |||
129 | static inline void *lookup_stid(const struct tid_info *t, unsigned int stid) | 132 | static inline void *lookup_stid(const struct tid_info *t, unsigned int stid) |
130 | { | 133 | { |
131 | stid -= t->stid_base; | 134 | stid -= t->stid_base; |
132 | return stid < t->nstids ? t->stid_tab[stid].data : NULL; | 135 | return stid < (t->nstids + t->nsftids) ? t->stid_tab[stid].data : NULL; |
133 | } | 136 | } |
134 | 137 | ||
135 | static inline void cxgb4_insert_tid(struct tid_info *t, void *data, | 138 | static inline void cxgb4_insert_tid(struct tid_info *t, void *data, |
@@ -141,6 +144,7 @@ static inline void cxgb4_insert_tid(struct tid_info *t, void *data, | |||
141 | 144 | ||
142 | int cxgb4_alloc_atid(struct tid_info *t, void *data); | 145 | int cxgb4_alloc_atid(struct tid_info *t, void *data); |
143 | int cxgb4_alloc_stid(struct tid_info *t, int family, void *data); | 146 | int cxgb4_alloc_stid(struct tid_info *t, int family, void *data); |
147 | int cxgb4_alloc_sftid(struct tid_info *t, int family, void *data); | ||
144 | void cxgb4_free_atid(struct tid_info *t, unsigned int atid); | 148 | void cxgb4_free_atid(struct tid_info *t, unsigned int atid); |
145 | void cxgb4_free_stid(struct tid_info *t, unsigned int stid, int family); | 149 | void cxgb4_free_stid(struct tid_info *t, unsigned int stid, int family); |
146 | void cxgb4_remove_tid(struct tid_info *t, unsigned int qid, unsigned int tid); | 150 | void cxgb4_remove_tid(struct tid_info *t, unsigned int qid, unsigned int tid); |
@@ -148,8 +152,14 @@ void cxgb4_remove_tid(struct tid_info *t, unsigned int qid, unsigned int tid); | |||
148 | struct in6_addr; | 152 | struct in6_addr; |
149 | 153 | ||
150 | int cxgb4_create_server(const struct net_device *dev, unsigned int stid, | 154 | int cxgb4_create_server(const struct net_device *dev, unsigned int stid, |
151 | __be32 sip, __be16 sport, unsigned int queue); | 155 | __be32 sip, __be16 sport, __be16 vlan, |
152 | 156 | unsigned int queue); | |
157 | int cxgb4_create_server_filter(const struct net_device *dev, unsigned int stid, | ||
158 | __be32 sip, __be16 sport, __be16 vlan, | ||
159 | unsigned int queue, | ||
160 | unsigned char port, unsigned char mask); | ||
161 | int cxgb4_remove_server_filter(const struct net_device *dev, unsigned int stid, | ||
162 | unsigned int queue, bool ipv6); | ||
153 | static inline void set_wr_txq(struct sk_buff *skb, int prio, int queue) | 163 | static inline void set_wr_txq(struct sk_buff *skb, int prio, int queue) |
154 | { | 164 | { |
155 | skb_set_queue_mapping(skb, (queue << 1) | prio); | 165 | skb_set_queue_mapping(skb, (queue << 1) | prio); |
@@ -221,9 +231,16 @@ struct cxgb4_lld_info { | |||
221 | unsigned int iscsi_iolen; /* iSCSI max I/O length */ | 231 | unsigned int iscsi_iolen; /* iSCSI max I/O length */ |
222 | unsigned short udb_density; /* # of user DB/page */ | 232 | unsigned short udb_density; /* # of user DB/page */ |
223 | unsigned short ucq_density; /* # of user CQs/page */ | 233 | unsigned short ucq_density; /* # of user CQs/page */ |
234 | unsigned short filt_mode; /* filter optional components */ | ||
235 | unsigned short tx_modq[NCHAN]; /* maps each tx channel to a */ | ||
236 | /* scheduler queue */ | ||
224 | void __iomem *gts_reg; /* address of GTS register */ | 237 | void __iomem *gts_reg; /* address of GTS register */ |
225 | void __iomem *db_reg; /* address of kernel doorbell */ | 238 | void __iomem *db_reg; /* address of kernel doorbell */ |
226 | int dbfifo_int_thresh; /* doorbell fifo int threshold */ | 239 | int dbfifo_int_thresh; /* doorbell fifo int threshold */ |
240 | unsigned int sge_pktshift; /* Padding between CPL and */ | ||
241 | /* packet data */ | ||
242 | bool enable_fw_ofld_conn; /* Enable connection through fw */ | ||
243 | /* WR */ | ||
227 | }; | 244 | }; |
228 | 245 | ||
229 | struct cxgb4_uld_info { | 246 | struct cxgb4_uld_info { |
diff --git a/drivers/net/ethernet/chelsio/cxgb4/l2t.c b/drivers/net/ethernet/chelsio/cxgb4/l2t.c index 6ac77a62f361..29878098101e 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/l2t.c +++ b/drivers/net/ethernet/chelsio/cxgb4/l2t.c | |||
@@ -484,6 +484,38 @@ void t4_l2t_update(struct adapter *adap, struct neighbour *neigh) | |||
484 | handle_failed_resolution(adap, arpq); | 484 | handle_failed_resolution(adap, arpq); |
485 | } | 485 | } |
486 | 486 | ||
487 | /* Allocate an L2T entry for use by a switching rule. Such need to be | ||
488 | * explicitly freed and while busy they are not on any hash chain, so normal | ||
489 | * address resolution updates do not see them. | ||
490 | */ | ||
491 | struct l2t_entry *t4_l2t_alloc_switching(struct l2t_data *d) | ||
492 | { | ||
493 | struct l2t_entry *e; | ||
494 | |||
495 | write_lock_bh(&d->lock); | ||
496 | e = alloc_l2e(d); | ||
497 | if (e) { | ||
498 | spin_lock(&e->lock); /* avoid race with t4_l2t_free */ | ||
499 | e->state = L2T_STATE_SWITCHING; | ||
500 | atomic_set(&e->refcnt, 1); | ||
501 | spin_unlock(&e->lock); | ||
502 | } | ||
503 | write_unlock_bh(&d->lock); | ||
504 | return e; | ||
505 | } | ||
506 | |||
507 | /* Sets/updates the contents of a switching L2T entry that has been allocated | ||
508 | * with an earlier call to @t4_l2t_alloc_switching. | ||
509 | */ | ||
510 | int t4_l2t_set_switching(struct adapter *adap, struct l2t_entry *e, u16 vlan, | ||
511 | u8 port, u8 *eth_addr) | ||
512 | { | ||
513 | e->vlan = vlan; | ||
514 | e->lport = port; | ||
515 | memcpy(e->dmac, eth_addr, ETH_ALEN); | ||
516 | return write_l2e(adap, e, 0); | ||
517 | } | ||
518 | |||
487 | struct l2t_data *t4_init_l2t(void) | 519 | struct l2t_data *t4_init_l2t(void) |
488 | { | 520 | { |
489 | int i; | 521 | int i; |
diff --git a/drivers/net/ethernet/chelsio/cxgb4/l2t.h b/drivers/net/ethernet/chelsio/cxgb4/l2t.h index 02b31d0c6410..108c0f1fce1c 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/l2t.h +++ b/drivers/net/ethernet/chelsio/cxgb4/l2t.h | |||
@@ -100,6 +100,9 @@ struct l2t_entry *cxgb4_l2t_get(struct l2t_data *d, struct neighbour *neigh, | |||
100 | unsigned int priority); | 100 | unsigned int priority); |
101 | 101 | ||
102 | void t4_l2t_update(struct adapter *adap, struct neighbour *neigh); | 102 | void t4_l2t_update(struct adapter *adap, struct neighbour *neigh); |
103 | struct l2t_entry *t4_l2t_alloc_switching(struct l2t_data *d); | ||
104 | int t4_l2t_set_switching(struct adapter *adap, struct l2t_entry *e, u16 vlan, | ||
105 | u8 port, u8 *eth_addr); | ||
103 | struct l2t_data *t4_init_l2t(void); | 106 | struct l2t_data *t4_init_l2t(void); |
104 | void do_l2t_write_rpl(struct adapter *p, const struct cpl_l2t_write_rpl *rpl); | 107 | void do_l2t_write_rpl(struct adapter *p, const struct cpl_l2t_write_rpl *rpl); |
105 | 108 | ||
diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c index 8d9c7547b070..22f3af5166bf 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c +++ b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c | |||
@@ -109,7 +109,7 @@ void t4_set_reg_field(struct adapter *adapter, unsigned int addr, u32 mask, | |||
109 | * Reads registers that are accessed indirectly through an address/data | 109 | * Reads registers that are accessed indirectly through an address/data |
110 | * register pair. | 110 | * register pair. |
111 | */ | 111 | */ |
112 | static void t4_read_indirect(struct adapter *adap, unsigned int addr_reg, | 112 | void t4_read_indirect(struct adapter *adap, unsigned int addr_reg, |
113 | unsigned int data_reg, u32 *vals, | 113 | unsigned int data_reg, u32 *vals, |
114 | unsigned int nregs, unsigned int start_idx) | 114 | unsigned int nregs, unsigned int start_idx) |
115 | { | 115 | { |
@@ -2268,6 +2268,26 @@ int t4_wol_pat_enable(struct adapter *adap, unsigned int port, unsigned int map, | |||
2268 | return 0; | 2268 | return 0; |
2269 | } | 2269 | } |
2270 | 2270 | ||
2271 | /* t4_mk_filtdelwr - create a delete filter WR | ||
2272 | * @ftid: the filter ID | ||
2273 | * @wr: the filter work request to populate | ||
2274 | * @qid: ingress queue to receive the delete notification | ||
2275 | * | ||
2276 | * Creates a filter work request to delete the supplied filter. If @qid is | ||
2277 | * negative the delete notification is suppressed. | ||
2278 | */ | ||
2279 | void t4_mk_filtdelwr(unsigned int ftid, struct fw_filter_wr *wr, int qid) | ||
2280 | { | ||
2281 | memset(wr, 0, sizeof(*wr)); | ||
2282 | wr->op_pkd = htonl(FW_WR_OP(FW_FILTER_WR)); | ||
2283 | wr->len16_pkd = htonl(FW_WR_LEN16(sizeof(*wr) / 16)); | ||
2284 | wr->tid_to_iq = htonl(V_FW_FILTER_WR_TID(ftid) | | ||
2285 | V_FW_FILTER_WR_NOREPLY(qid < 0)); | ||
2286 | wr->del_filter_to_l2tix = htonl(F_FW_FILTER_WR_DEL_FILTER); | ||
2287 | if (qid >= 0) | ||
2288 | wr->rx_chan_rx_rpl_iq = htons(V_FW_FILTER_WR_RX_RPL_IQ(qid)); | ||
2289 | } | ||
2290 | |||
2271 | #define INIT_CMD(var, cmd, rd_wr) do { \ | 2291 | #define INIT_CMD(var, cmd, rd_wr) do { \ |
2272 | (var).op_to_write = htonl(FW_CMD_OP(FW_##cmd##_CMD) | \ | 2292 | (var).op_to_write = htonl(FW_CMD_OP(FW_##cmd##_CMD) | \ |
2273 | FW_CMD_REQUEST | FW_CMD_##rd_wr); \ | 2293 | FW_CMD_REQUEST | FW_CMD_##rd_wr); \ |
diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_msg.h b/drivers/net/ethernet/chelsio/cxgb4/t4_msg.h index b760808fd6d9..261d17703adc 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/t4_msg.h +++ b/drivers/net/ethernet/chelsio/cxgb4/t4_msg.h | |||
@@ -193,8 +193,24 @@ struct work_request_hdr { | |||
193 | __be64 wr_lo; | 193 | __be64 wr_lo; |
194 | }; | 194 | }; |
195 | 195 | ||
196 | /* wr_hi fields */ | ||
197 | #define S_WR_OP 24 | ||
198 | #define V_WR_OP(x) ((__u64)(x) << S_WR_OP) | ||
199 | |||
196 | #define WR_HDR struct work_request_hdr wr | 200 | #define WR_HDR struct work_request_hdr wr |
197 | 201 | ||
202 | /* option 0 fields */ | ||
203 | #define S_MSS_IDX 60 | ||
204 | #define M_MSS_IDX 0xF | ||
205 | #define V_MSS_IDX(x) ((__u64)(x) << S_MSS_IDX) | ||
206 | #define G_MSS_IDX(x) (((x) >> S_MSS_IDX) & M_MSS_IDX) | ||
207 | |||
208 | /* option 2 fields */ | ||
209 | #define S_RSS_QUEUE 0 | ||
210 | #define M_RSS_QUEUE 0x3FF | ||
211 | #define V_RSS_QUEUE(x) ((x) << S_RSS_QUEUE) | ||
212 | #define G_RSS_QUEUE(x) (((x) >> S_RSS_QUEUE) & M_RSS_QUEUE) | ||
213 | |||
198 | struct cpl_pass_open_req { | 214 | struct cpl_pass_open_req { |
199 | WR_HDR; | 215 | WR_HDR; |
200 | union opcode_tid ot; | 216 | union opcode_tid ot; |
@@ -204,12 +220,14 @@ struct cpl_pass_open_req { | |||
204 | __be32 peer_ip; | 220 | __be32 peer_ip; |
205 | __be64 opt0; | 221 | __be64 opt0; |
206 | #define TX_CHAN(x) ((x) << 2) | 222 | #define TX_CHAN(x) ((x) << 2) |
223 | #define NO_CONG(x) ((x) << 4) | ||
207 | #define DELACK(x) ((x) << 5) | 224 | #define DELACK(x) ((x) << 5) |
208 | #define ULP_MODE(x) ((x) << 8) | 225 | #define ULP_MODE(x) ((x) << 8) |
209 | #define RCV_BUFSIZ(x) ((x) << 12) | 226 | #define RCV_BUFSIZ(x) ((x) << 12) |
210 | #define DSCP(x) ((x) << 22) | 227 | #define DSCP(x) ((x) << 22) |
211 | #define SMAC_SEL(x) ((u64)(x) << 28) | 228 | #define SMAC_SEL(x) ((u64)(x) << 28) |
212 | #define L2T_IDX(x) ((u64)(x) << 36) | 229 | #define L2T_IDX(x) ((u64)(x) << 36) |
230 | #define TCAM_BYPASS(x) ((u64)(x) << 48) | ||
213 | #define NAGLE(x) ((u64)(x) << 49) | 231 | #define NAGLE(x) ((u64)(x) << 49) |
214 | #define WND_SCALE(x) ((u64)(x) << 50) | 232 | #define WND_SCALE(x) ((u64)(x) << 50) |
215 | #define KEEP_ALIVE(x) ((u64)(x) << 54) | 233 | #define KEEP_ALIVE(x) ((u64)(x) << 54) |
@@ -247,8 +265,10 @@ struct cpl_pass_accept_rpl { | |||
247 | #define RSS_QUEUE_VALID (1 << 10) | 265 | #define RSS_QUEUE_VALID (1 << 10) |
248 | #define RX_COALESCE_VALID(x) ((x) << 11) | 266 | #define RX_COALESCE_VALID(x) ((x) << 11) |
249 | #define RX_COALESCE(x) ((x) << 12) | 267 | #define RX_COALESCE(x) ((x) << 12) |
268 | #define PACE(x) ((x) << 16) | ||
250 | #define TX_QUEUE(x) ((x) << 23) | 269 | #define TX_QUEUE(x) ((x) << 23) |
251 | #define RX_CHANNEL(x) ((x) << 26) | 270 | #define RX_CHANNEL(x) ((x) << 26) |
271 | #define CCTRL_ECN(x) ((x) << 27) | ||
252 | #define WND_SCALE_EN(x) ((x) << 28) | 272 | #define WND_SCALE_EN(x) ((x) << 28) |
253 | #define TSTAMPS_EN(x) ((x) << 29) | 273 | #define TSTAMPS_EN(x) ((x) << 29) |
254 | #define SACK_EN(x) ((x) << 30) | 274 | #define SACK_EN(x) ((x) << 30) |
@@ -292,6 +312,9 @@ struct cpl_pass_establish { | |||
292 | union opcode_tid ot; | 312 | union opcode_tid ot; |
293 | __be32 rsvd; | 313 | __be32 rsvd; |
294 | __be32 tos_stid; | 314 | __be32 tos_stid; |
315 | #define PASS_OPEN_TID(x) ((x) << 0) | ||
316 | #define PASS_OPEN_TOS(x) ((x) << 24) | ||
317 | #define GET_PASS_OPEN_TID(x) (((x) >> 0) & 0xFFFFFF) | ||
295 | #define GET_POPEN_TID(x) ((x) & 0xffffff) | 318 | #define GET_POPEN_TID(x) ((x) & 0xffffff) |
296 | #define GET_POPEN_TOS(x) (((x) >> 24) & 0xff) | 319 | #define GET_POPEN_TOS(x) (((x) >> 24) & 0xff) |
297 | __be16 mac_idx; | 320 | __be16 mac_idx; |
@@ -332,6 +355,7 @@ struct cpl_set_tcb_field { | |||
332 | __be16 word_cookie; | 355 | __be16 word_cookie; |
333 | #define TCB_WORD(x) ((x) << 0) | 356 | #define TCB_WORD(x) ((x) << 0) |
334 | #define TCB_COOKIE(x) ((x) << 5) | 357 | #define TCB_COOKIE(x) ((x) << 5) |
358 | #define GET_TCB_COOKIE(x) (((x) >> 5) & 7) | ||
335 | __be64 mask; | 359 | __be64 mask; |
336 | __be64 val; | 360 | __be64 val; |
337 | }; | 361 | }; |
@@ -536,6 +560,37 @@ struct cpl_rx_pkt { | |||
536 | __be16 err_vec; | 560 | __be16 err_vec; |
537 | }; | 561 | }; |
538 | 562 | ||
563 | /* rx_pkt.l2info fields */ | ||
564 | #define S_RX_ETHHDR_LEN 0 | ||
565 | #define M_RX_ETHHDR_LEN 0x1F | ||
566 | #define V_RX_ETHHDR_LEN(x) ((x) << S_RX_ETHHDR_LEN) | ||
567 | #define G_RX_ETHHDR_LEN(x) (((x) >> S_RX_ETHHDR_LEN) & M_RX_ETHHDR_LEN) | ||
568 | |||
569 | #define S_RX_MACIDX 8 | ||
570 | #define M_RX_MACIDX 0x1FF | ||
571 | #define V_RX_MACIDX(x) ((x) << S_RX_MACIDX) | ||
572 | #define G_RX_MACIDX(x) (((x) >> S_RX_MACIDX) & M_RX_MACIDX) | ||
573 | |||
574 | #define S_RXF_SYN 21 | ||
575 | #define V_RXF_SYN(x) ((x) << S_RXF_SYN) | ||
576 | #define F_RXF_SYN V_RXF_SYN(1U) | ||
577 | |||
578 | #define S_RX_CHAN 28 | ||
579 | #define M_RX_CHAN 0xF | ||
580 | #define V_RX_CHAN(x) ((x) << S_RX_CHAN) | ||
581 | #define G_RX_CHAN(x) (((x) >> S_RX_CHAN) & M_RX_CHAN) | ||
582 | |||
583 | /* rx_pkt.hdr_len fields */ | ||
584 | #define S_RX_TCPHDR_LEN 0 | ||
585 | #define M_RX_TCPHDR_LEN 0x3F | ||
586 | #define V_RX_TCPHDR_LEN(x) ((x) << S_RX_TCPHDR_LEN) | ||
587 | #define G_RX_TCPHDR_LEN(x) (((x) >> S_RX_TCPHDR_LEN) & M_RX_TCPHDR_LEN) | ||
588 | |||
589 | #define S_RX_IPHDR_LEN 6 | ||
590 | #define M_RX_IPHDR_LEN 0x3FF | ||
591 | #define V_RX_IPHDR_LEN(x) ((x) << S_RX_IPHDR_LEN) | ||
592 | #define G_RX_IPHDR_LEN(x) (((x) >> S_RX_IPHDR_LEN) & M_RX_IPHDR_LEN) | ||
593 | |||
539 | struct cpl_trace_pkt { | 594 | struct cpl_trace_pkt { |
540 | u8 opcode; | 595 | u8 opcode; |
541 | u8 intf; | 596 | u8 intf; |
@@ -634,6 +689,17 @@ struct cpl_fw6_msg { | |||
634 | /* cpl_fw6_msg.type values */ | 689 | /* cpl_fw6_msg.type values */ |
635 | enum { | 690 | enum { |
636 | FW6_TYPE_CMD_RPL = 0, | 691 | FW6_TYPE_CMD_RPL = 0, |
692 | FW6_TYPE_WR_RPL = 1, | ||
693 | FW6_TYPE_CQE = 2, | ||
694 | FW6_TYPE_OFLD_CONNECTION_WR_RPL = 3, | ||
695 | }; | ||
696 | |||
697 | struct cpl_fw6_msg_ofld_connection_wr_rpl { | ||
698 | __u64 cookie; | ||
699 | __be32 tid; /* or atid in case of active failure */ | ||
700 | __u8 t_state; | ||
701 | __u8 retval; | ||
702 | __u8 rsvd[2]; | ||
637 | }; | 703 | }; |
638 | 704 | ||
639 | enum { | 705 | enum { |
diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_regs.h b/drivers/net/ethernet/chelsio/cxgb4/t4_regs.h index 75393f5cff41..83ec5f7844ac 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/t4_regs.h +++ b/drivers/net/ethernet/chelsio/cxgb4/t4_regs.h | |||
@@ -1064,4 +1064,41 @@ | |||
1064 | #define ADDRESS(x) ((x) << ADDRESS_SHIFT) | 1064 | #define ADDRESS(x) ((x) << ADDRESS_SHIFT) |
1065 | 1065 | ||
1066 | #define XGMAC_PORT_INT_CAUSE 0x10dc | 1066 | #define XGMAC_PORT_INT_CAUSE 0x10dc |
1067 | |||
1068 | #define A_TP_TX_MOD_QUEUE_REQ_MAP 0x7e28 | ||
1069 | |||
1070 | #define A_TP_TX_MOD_CHANNEL_WEIGHT 0x7e34 | ||
1071 | |||
1072 | #define S_TX_MOD_QUEUE_REQ_MAP 0 | ||
1073 | #define M_TX_MOD_QUEUE_REQ_MAP 0xffffU | ||
1074 | #define V_TX_MOD_QUEUE_REQ_MAP(x) ((x) << S_TX_MOD_QUEUE_REQ_MAP) | ||
1075 | |||
1076 | #define A_TP_TX_MOD_QUEUE_WEIGHT0 0x7e30 | ||
1077 | |||
1078 | #define S_TX_MODQ_WEIGHT3 24 | ||
1079 | #define M_TX_MODQ_WEIGHT3 0xffU | ||
1080 | #define V_TX_MODQ_WEIGHT3(x) ((x) << S_TX_MODQ_WEIGHT3) | ||
1081 | |||
1082 | #define S_TX_MODQ_WEIGHT2 16 | ||
1083 | #define M_TX_MODQ_WEIGHT2 0xffU | ||
1084 | #define V_TX_MODQ_WEIGHT2(x) ((x) << S_TX_MODQ_WEIGHT2) | ||
1085 | |||
1086 | #define S_TX_MODQ_WEIGHT1 8 | ||
1087 | #define M_TX_MODQ_WEIGHT1 0xffU | ||
1088 | #define V_TX_MODQ_WEIGHT1(x) ((x) << S_TX_MODQ_WEIGHT1) | ||
1089 | |||
1090 | #define S_TX_MODQ_WEIGHT0 0 | ||
1091 | #define M_TX_MODQ_WEIGHT0 0xffU | ||
1092 | #define V_TX_MODQ_WEIGHT0(x) ((x) << S_TX_MODQ_WEIGHT0) | ||
1093 | |||
1094 | #define A_TP_TX_SCHED_HDR 0x23 | ||
1095 | |||
1096 | #define A_TP_TX_SCHED_FIFO 0x24 | ||
1097 | |||
1098 | #define A_TP_TX_SCHED_PCMD 0x25 | ||
1099 | |||
1100 | #define S_PORT 1 | ||
1101 | #define V_PORT(x) ((x) << S_PORT) | ||
1102 | #define F_PORT V_PORT(1U) | ||
1103 | |||
1067 | #endif /* __T4_REGS_H */ | 1104 | #endif /* __T4_REGS_H */ |
diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h b/drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h index 0abc864cdd3a..a0dcccd846c9 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h +++ b/drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h | |||
@@ -35,6 +35,45 @@ | |||
35 | #ifndef _T4FW_INTERFACE_H_ | 35 | #ifndef _T4FW_INTERFACE_H_ |
36 | #define _T4FW_INTERFACE_H_ | 36 | #define _T4FW_INTERFACE_H_ |
37 | 37 | ||
38 | enum fw_retval { | ||
39 | FW_SUCCESS = 0, /* completed sucessfully */ | ||
40 | FW_EPERM = 1, /* operation not permitted */ | ||
41 | FW_ENOENT = 2, /* no such file or directory */ | ||
42 | FW_EIO = 5, /* input/output error; hw bad */ | ||
43 | FW_ENOEXEC = 8, /* exec format error; inv microcode */ | ||
44 | FW_EAGAIN = 11, /* try again */ | ||
45 | FW_ENOMEM = 12, /* out of memory */ | ||
46 | FW_EFAULT = 14, /* bad address; fw bad */ | ||
47 | FW_EBUSY = 16, /* resource busy */ | ||
48 | FW_EEXIST = 17, /* file exists */ | ||
49 | FW_EINVAL = 22, /* invalid argument */ | ||
50 | FW_ENOSPC = 28, /* no space left on device */ | ||
51 | FW_ENOSYS = 38, /* functionality not implemented */ | ||
52 | FW_EPROTO = 71, /* protocol error */ | ||
53 | FW_EADDRINUSE = 98, /* address already in use */ | ||
54 | FW_EADDRNOTAVAIL = 99, /* cannot assigned requested address */ | ||
55 | FW_ENETDOWN = 100, /* network is down */ | ||
56 | FW_ENETUNREACH = 101, /* network is unreachable */ | ||
57 | FW_ENOBUFS = 105, /* no buffer space available */ | ||
58 | FW_ETIMEDOUT = 110, /* timeout */ | ||
59 | FW_EINPROGRESS = 115, /* fw internal */ | ||
60 | FW_SCSI_ABORT_REQUESTED = 128, /* */ | ||
61 | FW_SCSI_ABORT_TIMEDOUT = 129, /* */ | ||
62 | FW_SCSI_ABORTED = 130, /* */ | ||
63 | FW_SCSI_CLOSE_REQUESTED = 131, /* */ | ||
64 | FW_ERR_LINK_DOWN = 132, /* */ | ||
65 | FW_RDEV_NOT_READY = 133, /* */ | ||
66 | FW_ERR_RDEV_LOST = 134, /* */ | ||
67 | FW_ERR_RDEV_LOGO = 135, /* */ | ||
68 | FW_FCOE_NO_XCHG = 136, /* */ | ||
69 | FW_SCSI_RSP_ERR = 137, /* */ | ||
70 | FW_ERR_RDEV_IMPL_LOGO = 138, /* */ | ||
71 | FW_SCSI_UNDER_FLOW_ERR = 139, /* */ | ||
72 | FW_SCSI_OVER_FLOW_ERR = 140, /* */ | ||
73 | FW_SCSI_DDP_ERR = 141, /* DDP error*/ | ||
74 | FW_SCSI_TASK_ERR = 142, /* No SCSI tasks available */ | ||
75 | }; | ||
76 | |||
38 | #define FW_T4VF_SGE_BASE_ADDR 0x0000 | 77 | #define FW_T4VF_SGE_BASE_ADDR 0x0000 |
39 | #define FW_T4VF_MPS_BASE_ADDR 0x0100 | 78 | #define FW_T4VF_MPS_BASE_ADDR 0x0100 |
40 | #define FW_T4VF_PL_BASE_ADDR 0x0200 | 79 | #define FW_T4VF_PL_BASE_ADDR 0x0200 |
@@ -46,6 +85,7 @@ enum fw_wr_opcodes { | |||
46 | FW_ULPTX_WR = 0x04, | 85 | FW_ULPTX_WR = 0x04, |
47 | FW_TP_WR = 0x05, | 86 | FW_TP_WR = 0x05, |
48 | FW_ETH_TX_PKT_WR = 0x08, | 87 | FW_ETH_TX_PKT_WR = 0x08, |
88 | FW_OFLD_CONNECTION_WR = 0x2f, | ||
49 | FW_FLOWC_WR = 0x0a, | 89 | FW_FLOWC_WR = 0x0a, |
50 | FW_OFLD_TX_DATA_WR = 0x0b, | 90 | FW_OFLD_TX_DATA_WR = 0x0b, |
51 | FW_CMD_WR = 0x10, | 91 | FW_CMD_WR = 0x10, |
@@ -81,6 +121,282 @@ struct fw_wr_hdr { | |||
81 | #define FW_WR_LEN16(x) ((x) << 0) | 121 | #define FW_WR_LEN16(x) ((x) << 0) |
82 | 122 | ||
83 | #define HW_TPL_FR_MT_PR_IV_P_FC 0X32B | 123 | #define HW_TPL_FR_MT_PR_IV_P_FC 0X32B |
124 | #define HW_TPL_FR_MT_PR_OV_P_FC 0X327 | ||
125 | |||
126 | /* filter wr reply code in cookie in CPL_SET_TCB_RPL */ | ||
127 | enum fw_filter_wr_cookie { | ||
128 | FW_FILTER_WR_SUCCESS, | ||
129 | FW_FILTER_WR_FLT_ADDED, | ||
130 | FW_FILTER_WR_FLT_DELETED, | ||
131 | FW_FILTER_WR_SMT_TBL_FULL, | ||
132 | FW_FILTER_WR_EINVAL, | ||
133 | }; | ||
134 | |||
135 | struct fw_filter_wr { | ||
136 | __be32 op_pkd; | ||
137 | __be32 len16_pkd; | ||
138 | __be64 r3; | ||
139 | __be32 tid_to_iq; | ||
140 | __be32 del_filter_to_l2tix; | ||
141 | __be16 ethtype; | ||
142 | __be16 ethtypem; | ||
143 | __u8 frag_to_ovlan_vldm; | ||
144 | __u8 smac_sel; | ||
145 | __be16 rx_chan_rx_rpl_iq; | ||
146 | __be32 maci_to_matchtypem; | ||
147 | __u8 ptcl; | ||
148 | __u8 ptclm; | ||
149 | __u8 ttyp; | ||
150 | __u8 ttypm; | ||
151 | __be16 ivlan; | ||
152 | __be16 ivlanm; | ||
153 | __be16 ovlan; | ||
154 | __be16 ovlanm; | ||
155 | __u8 lip[16]; | ||
156 | __u8 lipm[16]; | ||
157 | __u8 fip[16]; | ||
158 | __u8 fipm[16]; | ||
159 | __be16 lp; | ||
160 | __be16 lpm; | ||
161 | __be16 fp; | ||
162 | __be16 fpm; | ||
163 | __be16 r7; | ||
164 | __u8 sma[6]; | ||
165 | }; | ||
166 | |||
167 | #define S_FW_FILTER_WR_TID 12 | ||
168 | #define M_FW_FILTER_WR_TID 0xfffff | ||
169 | #define V_FW_FILTER_WR_TID(x) ((x) << S_FW_FILTER_WR_TID) | ||
170 | #define G_FW_FILTER_WR_TID(x) \ | ||
171 | (((x) >> S_FW_FILTER_WR_TID) & M_FW_FILTER_WR_TID) | ||
172 | |||
173 | #define S_FW_FILTER_WR_RQTYPE 11 | ||
174 | #define M_FW_FILTER_WR_RQTYPE 0x1 | ||
175 | #define V_FW_FILTER_WR_RQTYPE(x) ((x) << S_FW_FILTER_WR_RQTYPE) | ||
176 | #define G_FW_FILTER_WR_RQTYPE(x) \ | ||
177 | (((x) >> S_FW_FILTER_WR_RQTYPE) & M_FW_FILTER_WR_RQTYPE) | ||
178 | #define F_FW_FILTER_WR_RQTYPE V_FW_FILTER_WR_RQTYPE(1U) | ||
179 | |||
180 | #define S_FW_FILTER_WR_NOREPLY 10 | ||
181 | #define M_FW_FILTER_WR_NOREPLY 0x1 | ||
182 | #define V_FW_FILTER_WR_NOREPLY(x) ((x) << S_FW_FILTER_WR_NOREPLY) | ||
183 | #define G_FW_FILTER_WR_NOREPLY(x) \ | ||
184 | (((x) >> S_FW_FILTER_WR_NOREPLY) & M_FW_FILTER_WR_NOREPLY) | ||
185 | #define F_FW_FILTER_WR_NOREPLY V_FW_FILTER_WR_NOREPLY(1U) | ||
186 | |||
187 | #define S_FW_FILTER_WR_IQ 0 | ||
188 | #define M_FW_FILTER_WR_IQ 0x3ff | ||
189 | #define V_FW_FILTER_WR_IQ(x) ((x) << S_FW_FILTER_WR_IQ) | ||
190 | #define G_FW_FILTER_WR_IQ(x) \ | ||
191 | (((x) >> S_FW_FILTER_WR_IQ) & M_FW_FILTER_WR_IQ) | ||
192 | |||
193 | #define S_FW_FILTER_WR_DEL_FILTER 31 | ||
194 | #define M_FW_FILTER_WR_DEL_FILTER 0x1 | ||
195 | #define V_FW_FILTER_WR_DEL_FILTER(x) ((x) << S_FW_FILTER_WR_DEL_FILTER) | ||
196 | #define G_FW_FILTER_WR_DEL_FILTER(x) \ | ||
197 | (((x) >> S_FW_FILTER_WR_DEL_FILTER) & M_FW_FILTER_WR_DEL_FILTER) | ||
198 | #define F_FW_FILTER_WR_DEL_FILTER V_FW_FILTER_WR_DEL_FILTER(1U) | ||
199 | |||
200 | #define S_FW_FILTER_WR_RPTTID 25 | ||
201 | #define M_FW_FILTER_WR_RPTTID 0x1 | ||
202 | #define V_FW_FILTER_WR_RPTTID(x) ((x) << S_FW_FILTER_WR_RPTTID) | ||
203 | #define G_FW_FILTER_WR_RPTTID(x) \ | ||
204 | (((x) >> S_FW_FILTER_WR_RPTTID) & M_FW_FILTER_WR_RPTTID) | ||
205 | #define F_FW_FILTER_WR_RPTTID V_FW_FILTER_WR_RPTTID(1U) | ||
206 | |||
207 | #define S_FW_FILTER_WR_DROP 24 | ||
208 | #define M_FW_FILTER_WR_DROP 0x1 | ||
209 | #define V_FW_FILTER_WR_DROP(x) ((x) << S_FW_FILTER_WR_DROP) | ||
210 | #define G_FW_FILTER_WR_DROP(x) \ | ||
211 | (((x) >> S_FW_FILTER_WR_DROP) & M_FW_FILTER_WR_DROP) | ||
212 | #define F_FW_FILTER_WR_DROP V_FW_FILTER_WR_DROP(1U) | ||
213 | |||
214 | #define S_FW_FILTER_WR_DIRSTEER 23 | ||
215 | #define M_FW_FILTER_WR_DIRSTEER 0x1 | ||
216 | #define V_FW_FILTER_WR_DIRSTEER(x) ((x) << S_FW_FILTER_WR_DIRSTEER) | ||
217 | #define G_FW_FILTER_WR_DIRSTEER(x) \ | ||
218 | (((x) >> S_FW_FILTER_WR_DIRSTEER) & M_FW_FILTER_WR_DIRSTEER) | ||
219 | #define F_FW_FILTER_WR_DIRSTEER V_FW_FILTER_WR_DIRSTEER(1U) | ||
220 | |||
221 | #define S_FW_FILTER_WR_MASKHASH 22 | ||
222 | #define M_FW_FILTER_WR_MASKHASH 0x1 | ||
223 | #define V_FW_FILTER_WR_MASKHASH(x) ((x) << S_FW_FILTER_WR_MASKHASH) | ||
224 | #define G_FW_FILTER_WR_MASKHASH(x) \ | ||
225 | (((x) >> S_FW_FILTER_WR_MASKHASH) & M_FW_FILTER_WR_MASKHASH) | ||
226 | #define F_FW_FILTER_WR_MASKHASH V_FW_FILTER_WR_MASKHASH(1U) | ||
227 | |||
228 | #define S_FW_FILTER_WR_DIRSTEERHASH 21 | ||
229 | #define M_FW_FILTER_WR_DIRSTEERHASH 0x1 | ||
230 | #define V_FW_FILTER_WR_DIRSTEERHASH(x) ((x) << S_FW_FILTER_WR_DIRSTEERHASH) | ||
231 | #define G_FW_FILTER_WR_DIRSTEERHASH(x) \ | ||
232 | (((x) >> S_FW_FILTER_WR_DIRSTEERHASH) & M_FW_FILTER_WR_DIRSTEERHASH) | ||
233 | #define F_FW_FILTER_WR_DIRSTEERHASH V_FW_FILTER_WR_DIRSTEERHASH(1U) | ||
234 | |||
235 | #define S_FW_FILTER_WR_LPBK 20 | ||
236 | #define M_FW_FILTER_WR_LPBK 0x1 | ||
237 | #define V_FW_FILTER_WR_LPBK(x) ((x) << S_FW_FILTER_WR_LPBK) | ||
238 | #define G_FW_FILTER_WR_LPBK(x) \ | ||
239 | (((x) >> S_FW_FILTER_WR_LPBK) & M_FW_FILTER_WR_LPBK) | ||
240 | #define F_FW_FILTER_WR_LPBK V_FW_FILTER_WR_LPBK(1U) | ||
241 | |||
242 | #define S_FW_FILTER_WR_DMAC 19 | ||
243 | #define M_FW_FILTER_WR_DMAC 0x1 | ||
244 | #define V_FW_FILTER_WR_DMAC(x) ((x) << S_FW_FILTER_WR_DMAC) | ||
245 | #define G_FW_FILTER_WR_DMAC(x) \ | ||
246 | (((x) >> S_FW_FILTER_WR_DMAC) & M_FW_FILTER_WR_DMAC) | ||
247 | #define F_FW_FILTER_WR_DMAC V_FW_FILTER_WR_DMAC(1U) | ||
248 | |||
249 | #define S_FW_FILTER_WR_SMAC 18 | ||
250 | #define M_FW_FILTER_WR_SMAC 0x1 | ||
251 | #define V_FW_FILTER_WR_SMAC(x) ((x) << S_FW_FILTER_WR_SMAC) | ||
252 | #define G_FW_FILTER_WR_SMAC(x) \ | ||
253 | (((x) >> S_FW_FILTER_WR_SMAC) & M_FW_FILTER_WR_SMAC) | ||
254 | #define F_FW_FILTER_WR_SMAC V_FW_FILTER_WR_SMAC(1U) | ||
255 | |||
256 | #define S_FW_FILTER_WR_INSVLAN 17 | ||
257 | #define M_FW_FILTER_WR_INSVLAN 0x1 | ||
258 | #define V_FW_FILTER_WR_INSVLAN(x) ((x) << S_FW_FILTER_WR_INSVLAN) | ||
259 | #define G_FW_FILTER_WR_INSVLAN(x) \ | ||
260 | (((x) >> S_FW_FILTER_WR_INSVLAN) & M_FW_FILTER_WR_INSVLAN) | ||
261 | #define F_FW_FILTER_WR_INSVLAN V_FW_FILTER_WR_INSVLAN(1U) | ||
262 | |||
263 | #define S_FW_FILTER_WR_RMVLAN 16 | ||
264 | #define M_FW_FILTER_WR_RMVLAN 0x1 | ||
265 | #define V_FW_FILTER_WR_RMVLAN(x) ((x) << S_FW_FILTER_WR_RMVLAN) | ||
266 | #define G_FW_FILTER_WR_RMVLAN(x) \ | ||
267 | (((x) >> S_FW_FILTER_WR_RMVLAN) & M_FW_FILTER_WR_RMVLAN) | ||
268 | #define F_FW_FILTER_WR_RMVLAN V_FW_FILTER_WR_RMVLAN(1U) | ||
269 | |||
270 | #define S_FW_FILTER_WR_HITCNTS 15 | ||
271 | #define M_FW_FILTER_WR_HITCNTS 0x1 | ||
272 | #define V_FW_FILTER_WR_HITCNTS(x) ((x) << S_FW_FILTER_WR_HITCNTS) | ||
273 | #define G_FW_FILTER_WR_HITCNTS(x) \ | ||
274 | (((x) >> S_FW_FILTER_WR_HITCNTS) & M_FW_FILTER_WR_HITCNTS) | ||
275 | #define F_FW_FILTER_WR_HITCNTS V_FW_FILTER_WR_HITCNTS(1U) | ||
276 | |||
277 | #define S_FW_FILTER_WR_TXCHAN 13 | ||
278 | #define M_FW_FILTER_WR_TXCHAN 0x3 | ||
279 | #define V_FW_FILTER_WR_TXCHAN(x) ((x) << S_FW_FILTER_WR_TXCHAN) | ||
280 | #define G_FW_FILTER_WR_TXCHAN(x) \ | ||
281 | (((x) >> S_FW_FILTER_WR_TXCHAN) & M_FW_FILTER_WR_TXCHAN) | ||
282 | |||
283 | #define S_FW_FILTER_WR_PRIO 12 | ||
284 | #define M_FW_FILTER_WR_PRIO 0x1 | ||
285 | #define V_FW_FILTER_WR_PRIO(x) ((x) << S_FW_FILTER_WR_PRIO) | ||
286 | #define G_FW_FILTER_WR_PRIO(x) \ | ||
287 | (((x) >> S_FW_FILTER_WR_PRIO) & M_FW_FILTER_WR_PRIO) | ||
288 | #define F_FW_FILTER_WR_PRIO V_FW_FILTER_WR_PRIO(1U) | ||
289 | |||
290 | #define S_FW_FILTER_WR_L2TIX 0 | ||
291 | #define M_FW_FILTER_WR_L2TIX 0xfff | ||
292 | #define V_FW_FILTER_WR_L2TIX(x) ((x) << S_FW_FILTER_WR_L2TIX) | ||
293 | #define G_FW_FILTER_WR_L2TIX(x) \ | ||
294 | (((x) >> S_FW_FILTER_WR_L2TIX) & M_FW_FILTER_WR_L2TIX) | ||
295 | |||
296 | #define S_FW_FILTER_WR_FRAG 7 | ||
297 | #define M_FW_FILTER_WR_FRAG 0x1 | ||
298 | #define V_FW_FILTER_WR_FRAG(x) ((x) << S_FW_FILTER_WR_FRAG) | ||
299 | #define G_FW_FILTER_WR_FRAG(x) \ | ||
300 | (((x) >> S_FW_FILTER_WR_FRAG) & M_FW_FILTER_WR_FRAG) | ||
301 | #define F_FW_FILTER_WR_FRAG V_FW_FILTER_WR_FRAG(1U) | ||
302 | |||
303 | #define S_FW_FILTER_WR_FRAGM 6 | ||
304 | #define M_FW_FILTER_WR_FRAGM 0x1 | ||
305 | #define V_FW_FILTER_WR_FRAGM(x) ((x) << S_FW_FILTER_WR_FRAGM) | ||
306 | #define G_FW_FILTER_WR_FRAGM(x) \ | ||
307 | (((x) >> S_FW_FILTER_WR_FRAGM) & M_FW_FILTER_WR_FRAGM) | ||
308 | #define F_FW_FILTER_WR_FRAGM V_FW_FILTER_WR_FRAGM(1U) | ||
309 | |||
310 | #define S_FW_FILTER_WR_IVLAN_VLD 5 | ||
311 | #define M_FW_FILTER_WR_IVLAN_VLD 0x1 | ||
312 | #define V_FW_FILTER_WR_IVLAN_VLD(x) ((x) << S_FW_FILTER_WR_IVLAN_VLD) | ||
313 | #define G_FW_FILTER_WR_IVLAN_VLD(x) \ | ||
314 | (((x) >> S_FW_FILTER_WR_IVLAN_VLD) & M_FW_FILTER_WR_IVLAN_VLD) | ||
315 | #define F_FW_FILTER_WR_IVLAN_VLD V_FW_FILTER_WR_IVLAN_VLD(1U) | ||
316 | |||
317 | #define S_FW_FILTER_WR_OVLAN_VLD 4 | ||
318 | #define M_FW_FILTER_WR_OVLAN_VLD 0x1 | ||
319 | #define V_FW_FILTER_WR_OVLAN_VLD(x) ((x) << S_FW_FILTER_WR_OVLAN_VLD) | ||
320 | #define G_FW_FILTER_WR_OVLAN_VLD(x) \ | ||
321 | (((x) >> S_FW_FILTER_WR_OVLAN_VLD) & M_FW_FILTER_WR_OVLAN_VLD) | ||
322 | #define F_FW_FILTER_WR_OVLAN_VLD V_FW_FILTER_WR_OVLAN_VLD(1U) | ||
323 | |||
324 | #define S_FW_FILTER_WR_IVLAN_VLDM 3 | ||
325 | #define M_FW_FILTER_WR_IVLAN_VLDM 0x1 | ||
326 | #define V_FW_FILTER_WR_IVLAN_VLDM(x) ((x) << S_FW_FILTER_WR_IVLAN_VLDM) | ||
327 | #define G_FW_FILTER_WR_IVLAN_VLDM(x) \ | ||
328 | (((x) >> S_FW_FILTER_WR_IVLAN_VLDM) & M_FW_FILTER_WR_IVLAN_VLDM) | ||
329 | #define F_FW_FILTER_WR_IVLAN_VLDM V_FW_FILTER_WR_IVLAN_VLDM(1U) | ||
330 | |||
331 | #define S_FW_FILTER_WR_OVLAN_VLDM 2 | ||
332 | #define M_FW_FILTER_WR_OVLAN_VLDM 0x1 | ||
333 | #define V_FW_FILTER_WR_OVLAN_VLDM(x) ((x) << S_FW_FILTER_WR_OVLAN_VLDM) | ||
334 | #define G_FW_FILTER_WR_OVLAN_VLDM(x) \ | ||
335 | (((x) >> S_FW_FILTER_WR_OVLAN_VLDM) & M_FW_FILTER_WR_OVLAN_VLDM) | ||
336 | #define F_FW_FILTER_WR_OVLAN_VLDM V_FW_FILTER_WR_OVLAN_VLDM(1U) | ||
337 | |||
338 | #define S_FW_FILTER_WR_RX_CHAN 15 | ||
339 | #define M_FW_FILTER_WR_RX_CHAN 0x1 | ||
340 | #define V_FW_FILTER_WR_RX_CHAN(x) ((x) << S_FW_FILTER_WR_RX_CHAN) | ||
341 | #define G_FW_FILTER_WR_RX_CHAN(x) \ | ||
342 | (((x) >> S_FW_FILTER_WR_RX_CHAN) & M_FW_FILTER_WR_RX_CHAN) | ||
343 | #define F_FW_FILTER_WR_RX_CHAN V_FW_FILTER_WR_RX_CHAN(1U) | ||
344 | |||
345 | #define S_FW_FILTER_WR_RX_RPL_IQ 0 | ||
346 | #define M_FW_FILTER_WR_RX_RPL_IQ 0x3ff | ||
347 | #define V_FW_FILTER_WR_RX_RPL_IQ(x) ((x) << S_FW_FILTER_WR_RX_RPL_IQ) | ||
348 | #define G_FW_FILTER_WR_RX_RPL_IQ(x) \ | ||
349 | (((x) >> S_FW_FILTER_WR_RX_RPL_IQ) & M_FW_FILTER_WR_RX_RPL_IQ) | ||
350 | |||
351 | #define S_FW_FILTER_WR_MACI 23 | ||
352 | #define M_FW_FILTER_WR_MACI 0x1ff | ||
353 | #define V_FW_FILTER_WR_MACI(x) ((x) << S_FW_FILTER_WR_MACI) | ||
354 | #define G_FW_FILTER_WR_MACI(x) \ | ||
355 | (((x) >> S_FW_FILTER_WR_MACI) & M_FW_FILTER_WR_MACI) | ||
356 | |||
357 | #define S_FW_FILTER_WR_MACIM 14 | ||
358 | #define M_FW_FILTER_WR_MACIM 0x1ff | ||
359 | #define V_FW_FILTER_WR_MACIM(x) ((x) << S_FW_FILTER_WR_MACIM) | ||
360 | #define G_FW_FILTER_WR_MACIM(x) \ | ||
361 | (((x) >> S_FW_FILTER_WR_MACIM) & M_FW_FILTER_WR_MACIM) | ||
362 | |||
363 | #define S_FW_FILTER_WR_FCOE 13 | ||
364 | #define M_FW_FILTER_WR_FCOE 0x1 | ||
365 | #define V_FW_FILTER_WR_FCOE(x) ((x) << S_FW_FILTER_WR_FCOE) | ||
366 | #define G_FW_FILTER_WR_FCOE(x) \ | ||
367 | (((x) >> S_FW_FILTER_WR_FCOE) & M_FW_FILTER_WR_FCOE) | ||
368 | #define F_FW_FILTER_WR_FCOE V_FW_FILTER_WR_FCOE(1U) | ||
369 | |||
370 | #define S_FW_FILTER_WR_FCOEM 12 | ||
371 | #define M_FW_FILTER_WR_FCOEM 0x1 | ||
372 | #define V_FW_FILTER_WR_FCOEM(x) ((x) << S_FW_FILTER_WR_FCOEM) | ||
373 | #define G_FW_FILTER_WR_FCOEM(x) \ | ||
374 | (((x) >> S_FW_FILTER_WR_FCOEM) & M_FW_FILTER_WR_FCOEM) | ||
375 | #define F_FW_FILTER_WR_FCOEM V_FW_FILTER_WR_FCOEM(1U) | ||
376 | |||
377 | #define S_FW_FILTER_WR_PORT 9 | ||
378 | #define M_FW_FILTER_WR_PORT 0x7 | ||
379 | #define V_FW_FILTER_WR_PORT(x) ((x) << S_FW_FILTER_WR_PORT) | ||
380 | #define G_FW_FILTER_WR_PORT(x) \ | ||
381 | (((x) >> S_FW_FILTER_WR_PORT) & M_FW_FILTER_WR_PORT) | ||
382 | |||
383 | #define S_FW_FILTER_WR_PORTM 6 | ||
384 | #define M_FW_FILTER_WR_PORTM 0x7 | ||
385 | #define V_FW_FILTER_WR_PORTM(x) ((x) << S_FW_FILTER_WR_PORTM) | ||
386 | #define G_FW_FILTER_WR_PORTM(x) \ | ||
387 | (((x) >> S_FW_FILTER_WR_PORTM) & M_FW_FILTER_WR_PORTM) | ||
388 | |||
389 | #define S_FW_FILTER_WR_MATCHTYPE 3 | ||
390 | #define M_FW_FILTER_WR_MATCHTYPE 0x7 | ||
391 | #define V_FW_FILTER_WR_MATCHTYPE(x) ((x) << S_FW_FILTER_WR_MATCHTYPE) | ||
392 | #define G_FW_FILTER_WR_MATCHTYPE(x) \ | ||
393 | (((x) >> S_FW_FILTER_WR_MATCHTYPE) & M_FW_FILTER_WR_MATCHTYPE) | ||
394 | |||
395 | #define S_FW_FILTER_WR_MATCHTYPEM 0 | ||
396 | #define M_FW_FILTER_WR_MATCHTYPEM 0x7 | ||
397 | #define V_FW_FILTER_WR_MATCHTYPEM(x) ((x) << S_FW_FILTER_WR_MATCHTYPEM) | ||
398 | #define G_FW_FILTER_WR_MATCHTYPEM(x) \ | ||
399 | (((x) >> S_FW_FILTER_WR_MATCHTYPEM) & M_FW_FILTER_WR_MATCHTYPEM) | ||
84 | 400 | ||
85 | struct fw_ulptx_wr { | 401 | struct fw_ulptx_wr { |
86 | __be32 op_to_compl; | 402 | __be32 op_to_compl; |
@@ -100,6 +416,108 @@ struct fw_eth_tx_pkt_wr { | |||
100 | __be64 r3; | 416 | __be64 r3; |
101 | }; | 417 | }; |
102 | 418 | ||
419 | struct fw_ofld_connection_wr { | ||
420 | __be32 op_compl; | ||
421 | __be32 len16_pkd; | ||
422 | __u64 cookie; | ||
423 | __be64 r2; | ||
424 | __be64 r3; | ||
425 | struct fw_ofld_connection_le { | ||
426 | __be32 version_cpl; | ||
427 | __be32 filter; | ||
428 | __be32 r1; | ||
429 | __be16 lport; | ||
430 | __be16 pport; | ||
431 | union fw_ofld_connection_leip { | ||
432 | struct fw_ofld_connection_le_ipv4 { | ||
433 | __be32 pip; | ||
434 | __be32 lip; | ||
435 | __be64 r0; | ||
436 | __be64 r1; | ||
437 | __be64 r2; | ||
438 | } ipv4; | ||
439 | struct fw_ofld_connection_le_ipv6 { | ||
440 | __be64 pip_hi; | ||
441 | __be64 pip_lo; | ||
442 | __be64 lip_hi; | ||
443 | __be64 lip_lo; | ||
444 | } ipv6; | ||
445 | } u; | ||
446 | } le; | ||
447 | struct fw_ofld_connection_tcb { | ||
448 | __be32 t_state_to_astid; | ||
449 | __be16 cplrxdataack_cplpassacceptrpl; | ||
450 | __be16 rcv_adv; | ||
451 | __be32 rcv_nxt; | ||
452 | __be32 tx_max; | ||
453 | __be64 opt0; | ||
454 | __be32 opt2; | ||
455 | __be32 r1; | ||
456 | __be64 r2; | ||
457 | __be64 r3; | ||
458 | } tcb; | ||
459 | }; | ||
460 | |||
461 | #define S_FW_OFLD_CONNECTION_WR_VERSION 31 | ||
462 | #define M_FW_OFLD_CONNECTION_WR_VERSION 0x1 | ||
463 | #define V_FW_OFLD_CONNECTION_WR_VERSION(x) \ | ||
464 | ((x) << S_FW_OFLD_CONNECTION_WR_VERSION) | ||
465 | #define G_FW_OFLD_CONNECTION_WR_VERSION(x) \ | ||
466 | (((x) >> S_FW_OFLD_CONNECTION_WR_VERSION) & \ | ||
467 | M_FW_OFLD_CONNECTION_WR_VERSION) | ||
468 | #define F_FW_OFLD_CONNECTION_WR_VERSION \ | ||
469 | V_FW_OFLD_CONNECTION_WR_VERSION(1U) | ||
470 | |||
471 | #define S_FW_OFLD_CONNECTION_WR_CPL 30 | ||
472 | #define M_FW_OFLD_CONNECTION_WR_CPL 0x1 | ||
473 | #define V_FW_OFLD_CONNECTION_WR_CPL(x) ((x) << S_FW_OFLD_CONNECTION_WR_CPL) | ||
474 | #define G_FW_OFLD_CONNECTION_WR_CPL(x) \ | ||
475 | (((x) >> S_FW_OFLD_CONNECTION_WR_CPL) & M_FW_OFLD_CONNECTION_WR_CPL) | ||
476 | #define F_FW_OFLD_CONNECTION_WR_CPL V_FW_OFLD_CONNECTION_WR_CPL(1U) | ||
477 | |||
478 | #define S_FW_OFLD_CONNECTION_WR_T_STATE 28 | ||
479 | #define M_FW_OFLD_CONNECTION_WR_T_STATE 0xf | ||
480 | #define V_FW_OFLD_CONNECTION_WR_T_STATE(x) \ | ||
481 | ((x) << S_FW_OFLD_CONNECTION_WR_T_STATE) | ||
482 | #define G_FW_OFLD_CONNECTION_WR_T_STATE(x) \ | ||
483 | (((x) >> S_FW_OFLD_CONNECTION_WR_T_STATE) & \ | ||
484 | M_FW_OFLD_CONNECTION_WR_T_STATE) | ||
485 | |||
486 | #define S_FW_OFLD_CONNECTION_WR_RCV_SCALE 24 | ||
487 | #define M_FW_OFLD_CONNECTION_WR_RCV_SCALE 0xf | ||
488 | #define V_FW_OFLD_CONNECTION_WR_RCV_SCALE(x) \ | ||
489 | ((x) << S_FW_OFLD_CONNECTION_WR_RCV_SCALE) | ||
490 | #define G_FW_OFLD_CONNECTION_WR_RCV_SCALE(x) \ | ||
491 | (((x) >> S_FW_OFLD_CONNECTION_WR_RCV_SCALE) & \ | ||
492 | M_FW_OFLD_CONNECTION_WR_RCV_SCALE) | ||
493 | |||
494 | #define S_FW_OFLD_CONNECTION_WR_ASTID 0 | ||
495 | #define M_FW_OFLD_CONNECTION_WR_ASTID 0xffffff | ||
496 | #define V_FW_OFLD_CONNECTION_WR_ASTID(x) \ | ||
497 | ((x) << S_FW_OFLD_CONNECTION_WR_ASTID) | ||
498 | #define G_FW_OFLD_CONNECTION_WR_ASTID(x) \ | ||
499 | (((x) >> S_FW_OFLD_CONNECTION_WR_ASTID) & M_FW_OFLD_CONNECTION_WR_ASTID) | ||
500 | |||
501 | #define S_FW_OFLD_CONNECTION_WR_CPLRXDATAACK 15 | ||
502 | #define M_FW_OFLD_CONNECTION_WR_CPLRXDATAACK 0x1 | ||
503 | #define V_FW_OFLD_CONNECTION_WR_CPLRXDATAACK(x) \ | ||
504 | ((x) << S_FW_OFLD_CONNECTION_WR_CPLRXDATAACK) | ||
505 | #define G_FW_OFLD_CONNECTION_WR_CPLRXDATAACK(x) \ | ||
506 | (((x) >> S_FW_OFLD_CONNECTION_WR_CPLRXDATAACK) & \ | ||
507 | M_FW_OFLD_CONNECTION_WR_CPLRXDATAACK) | ||
508 | #define F_FW_OFLD_CONNECTION_WR_CPLRXDATAACK \ | ||
509 | V_FW_OFLD_CONNECTION_WR_CPLRXDATAACK(1U) | ||
510 | |||
511 | #define S_FW_OFLD_CONNECTION_WR_CPLPASSACCEPTRPL 14 | ||
512 | #define M_FW_OFLD_CONNECTION_WR_CPLPASSACCEPTRPL 0x1 | ||
513 | #define V_FW_OFLD_CONNECTION_WR_CPLPASSACCEPTRPL(x) \ | ||
514 | ((x) << S_FW_OFLD_CONNECTION_WR_CPLPASSACCEPTRPL) | ||
515 | #define G_FW_OFLD_CONNECTION_WR_CPLPASSACCEPTRPL(x) \ | ||
516 | (((x) >> S_FW_OFLD_CONNECTION_WR_CPLPASSACCEPTRPL) & \ | ||
517 | M_FW_OFLD_CONNECTION_WR_CPLPASSACCEPTRPL) | ||
518 | #define F_FW_OFLD_CONNECTION_WR_CPLPASSACCEPTRPL \ | ||
519 | V_FW_OFLD_CONNECTION_WR_CPLPASSACCEPTRPL(1U) | ||
520 | |||
103 | enum fw_flowc_mnem { | 521 | enum fw_flowc_mnem { |
104 | FW_FLOWC_MNEM_PFNVFN, /* PFN [15:8] VFN [7:0] */ | 522 | FW_FLOWC_MNEM_PFNVFN, /* PFN [15:8] VFN [7:0] */ |
105 | FW_FLOWC_MNEM_CH, | 523 | FW_FLOWC_MNEM_CH, |
diff --git a/drivers/net/ethernet/mellanox/mlx4/fw.c b/drivers/net/ethernet/mellanox/mlx4/fw.c index 9a9de51ecc91..8b3d0512a46b 100644 --- a/drivers/net/ethernet/mellanox/mlx4/fw.c +++ b/drivers/net/ethernet/mellanox/mlx4/fw.c | |||
@@ -1338,6 +1338,7 @@ int mlx4_QUERY_HCA(struct mlx4_dev *dev, | |||
1338 | { | 1338 | { |
1339 | struct mlx4_cmd_mailbox *mailbox; | 1339 | struct mlx4_cmd_mailbox *mailbox; |
1340 | __be32 *outbox; | 1340 | __be32 *outbox; |
1341 | u32 dword_field; | ||
1341 | int err; | 1342 | int err; |
1342 | u8 byte_field; | 1343 | u8 byte_field; |
1343 | 1344 | ||
@@ -1372,10 +1373,18 @@ int mlx4_QUERY_HCA(struct mlx4_dev *dev, | |||
1372 | MLX4_GET(param->rdmarc_base, outbox, INIT_HCA_RDMARC_BASE_OFFSET); | 1373 | MLX4_GET(param->rdmarc_base, outbox, INIT_HCA_RDMARC_BASE_OFFSET); |
1373 | MLX4_GET(param->log_rd_per_qp, outbox, INIT_HCA_LOG_RD_OFFSET); | 1374 | MLX4_GET(param->log_rd_per_qp, outbox, INIT_HCA_LOG_RD_OFFSET); |
1374 | 1375 | ||
1376 | MLX4_GET(dword_field, outbox, INIT_HCA_FLAGS_OFFSET); | ||
1377 | if (dword_field & (1 << INIT_HCA_DEVICE_MANAGED_FLOW_STEERING_EN)) { | ||
1378 | param->steering_mode = MLX4_STEERING_MODE_DEVICE_MANAGED; | ||
1379 | } else { | ||
1380 | MLX4_GET(byte_field, outbox, INIT_HCA_UC_STEERING_OFFSET); | ||
1381 | if (byte_field & 0x8) | ||
1382 | param->steering_mode = MLX4_STEERING_MODE_B0; | ||
1383 | else | ||
1384 | param->steering_mode = MLX4_STEERING_MODE_A0; | ||
1385 | } | ||
1375 | /* steering attributes */ | 1386 | /* steering attributes */ |
1376 | if (dev->caps.steering_mode == | 1387 | if (param->steering_mode == MLX4_STEERING_MODE_DEVICE_MANAGED) { |
1377 | MLX4_STEERING_MODE_DEVICE_MANAGED) { | ||
1378 | |||
1379 | MLX4_GET(param->mc_base, outbox, INIT_HCA_FS_BASE_OFFSET); | 1388 | MLX4_GET(param->mc_base, outbox, INIT_HCA_FS_BASE_OFFSET); |
1380 | MLX4_GET(param->log_mc_entry_sz, outbox, | 1389 | MLX4_GET(param->log_mc_entry_sz, outbox, |
1381 | INIT_HCA_FS_LOG_ENTRY_SZ_OFFSET); | 1390 | INIT_HCA_FS_LOG_ENTRY_SZ_OFFSET); |
diff --git a/drivers/net/ethernet/mellanox/mlx4/fw.h b/drivers/net/ethernet/mellanox/mlx4/fw.h index 2c2e7ade2a34..dbf2f69cc59f 100644 --- a/drivers/net/ethernet/mellanox/mlx4/fw.h +++ b/drivers/net/ethernet/mellanox/mlx4/fw.h | |||
@@ -172,6 +172,7 @@ struct mlx4_init_hca_param { | |||
172 | u8 log_uar_sz; | 172 | u8 log_uar_sz; |
173 | u8 uar_page_sz; /* log pg sz in 4k chunks */ | 173 | u8 uar_page_sz; /* log pg sz in 4k chunks */ |
174 | u8 fs_hash_enable_bits; | 174 | u8 fs_hash_enable_bits; |
175 | u8 steering_mode; /* for QUERY_HCA */ | ||
175 | u64 dev_cap_enabled; | 176 | u64 dev_cap_enabled; |
176 | }; | 177 | }; |
177 | 178 | ||
diff --git a/drivers/net/ethernet/mellanox/mlx4/main.c b/drivers/net/ethernet/mellanox/mlx4/main.c index b2acbe7706a3..e1bafffbc3b1 100644 --- a/drivers/net/ethernet/mellanox/mlx4/main.c +++ b/drivers/net/ethernet/mellanox/mlx4/main.c | |||
@@ -85,15 +85,15 @@ static int probe_vf; | |||
85 | module_param(probe_vf, int, 0644); | 85 | module_param(probe_vf, int, 0644); |
86 | MODULE_PARM_DESC(probe_vf, "number of vfs to probe by pf driver (num_vfs > 0)"); | 86 | MODULE_PARM_DESC(probe_vf, "number of vfs to probe by pf driver (num_vfs > 0)"); |
87 | 87 | ||
88 | int mlx4_log_num_mgm_entry_size = 10; | 88 | int mlx4_log_num_mgm_entry_size = MLX4_DEFAULT_MGM_LOG_ENTRY_SIZE; |
89 | module_param_named(log_num_mgm_entry_size, | 89 | module_param_named(log_num_mgm_entry_size, |
90 | mlx4_log_num_mgm_entry_size, int, 0444); | 90 | mlx4_log_num_mgm_entry_size, int, 0444); |
91 | MODULE_PARM_DESC(log_num_mgm_entry_size, "log mgm size, that defines the num" | 91 | MODULE_PARM_DESC(log_num_mgm_entry_size, "log mgm size, that defines the num" |
92 | " of qp per mcg, for example:" | 92 | " of qp per mcg, for example:" |
93 | " 10 gives 248.range: 9<=" | 93 | " 10 gives 248.range: 7 <=" |
94 | " log_num_mgm_entry_size <= 12." | 94 | " log_num_mgm_entry_size <= 12." |
95 | " Not in use with device managed" | 95 | " To activate device managed" |
96 | " flow steering"); | 96 | " flow steering when available, set to -1"); |
97 | 97 | ||
98 | static bool enable_64b_cqe_eqe; | 98 | static bool enable_64b_cqe_eqe; |
99 | module_param(enable_64b_cqe_eqe, bool, 0444); | 99 | module_param(enable_64b_cqe_eqe, bool, 0444); |
@@ -281,28 +281,6 @@ static int mlx4_dev_cap(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap) | |||
281 | dev->caps.max_gso_sz = dev_cap->max_gso_sz; | 281 | dev->caps.max_gso_sz = dev_cap->max_gso_sz; |
282 | dev->caps.max_rss_tbl_sz = dev_cap->max_rss_tbl_sz; | 282 | dev->caps.max_rss_tbl_sz = dev_cap->max_rss_tbl_sz; |
283 | 283 | ||
284 | if (dev_cap->flags2 & MLX4_DEV_CAP_FLAG2_FS_EN) { | ||
285 | dev->caps.steering_mode = MLX4_STEERING_MODE_DEVICE_MANAGED; | ||
286 | dev->caps.num_qp_per_mgm = dev_cap->fs_max_num_qp_per_entry; | ||
287 | dev->caps.fs_log_max_ucast_qp_range_size = | ||
288 | dev_cap->fs_log_max_ucast_qp_range_size; | ||
289 | } else { | ||
290 | if (dev->caps.flags & MLX4_DEV_CAP_FLAG_VEP_UC_STEER && | ||
291 | dev->caps.flags & MLX4_DEV_CAP_FLAG_VEP_MC_STEER) { | ||
292 | dev->caps.steering_mode = MLX4_STEERING_MODE_B0; | ||
293 | } else { | ||
294 | dev->caps.steering_mode = MLX4_STEERING_MODE_A0; | ||
295 | |||
296 | if (dev->caps.flags & MLX4_DEV_CAP_FLAG_VEP_UC_STEER || | ||
297 | dev->caps.flags & MLX4_DEV_CAP_FLAG_VEP_MC_STEER) | ||
298 | mlx4_warn(dev, "Must have UC_STEER and MC_STEER flags " | ||
299 | "set to use B0 steering. Falling back to A0 steering mode.\n"); | ||
300 | } | ||
301 | dev->caps.num_qp_per_mgm = mlx4_get_qp_per_mgm(dev); | ||
302 | } | ||
303 | mlx4_dbg(dev, "Steering mode is: %s\n", | ||
304 | mlx4_steering_mode_str(dev->caps.steering_mode)); | ||
305 | |||
306 | /* Sense port always allowed on supported devices for ConnectX-1 and -2 */ | 284 | /* Sense port always allowed on supported devices for ConnectX-1 and -2 */ |
307 | if (mlx4_priv(dev)->pci_dev_data & MLX4_PCI_DEV_FORCE_SENSE_PORT) | 285 | if (mlx4_priv(dev)->pci_dev_data & MLX4_PCI_DEV_FORCE_SENSE_PORT) |
308 | dev->caps.flags |= MLX4_DEV_CAP_FLAG_SENSE_SUPPORT; | 286 | dev->caps.flags |= MLX4_DEV_CAP_FLAG_SENSE_SUPPORT; |
@@ -493,6 +471,23 @@ int mlx4_is_slave_active(struct mlx4_dev *dev, int slave) | |||
493 | } | 471 | } |
494 | EXPORT_SYMBOL(mlx4_is_slave_active); | 472 | EXPORT_SYMBOL(mlx4_is_slave_active); |
495 | 473 | ||
474 | static void slave_adjust_steering_mode(struct mlx4_dev *dev, | ||
475 | struct mlx4_dev_cap *dev_cap, | ||
476 | struct mlx4_init_hca_param *hca_param) | ||
477 | { | ||
478 | dev->caps.steering_mode = hca_param->steering_mode; | ||
479 | if (dev->caps.steering_mode == MLX4_STEERING_MODE_DEVICE_MANAGED) { | ||
480 | dev->caps.num_qp_per_mgm = dev_cap->fs_max_num_qp_per_entry; | ||
481 | dev->caps.fs_log_max_ucast_qp_range_size = | ||
482 | dev_cap->fs_log_max_ucast_qp_range_size; | ||
483 | } else | ||
484 | dev->caps.num_qp_per_mgm = | ||
485 | 4 * ((1 << hca_param->log_mc_entry_sz)/16 - 2); | ||
486 | |||
487 | mlx4_dbg(dev, "Steering mode is: %s\n", | ||
488 | mlx4_steering_mode_str(dev->caps.steering_mode)); | ||
489 | } | ||
490 | |||
496 | static int mlx4_slave_cap(struct mlx4_dev *dev) | 491 | static int mlx4_slave_cap(struct mlx4_dev *dev) |
497 | { | 492 | { |
498 | int err; | 493 | int err; |
@@ -635,6 +630,8 @@ static int mlx4_slave_cap(struct mlx4_dev *dev) | |||
635 | dev->caps.cqe_size = 32; | 630 | dev->caps.cqe_size = 32; |
636 | } | 631 | } |
637 | 632 | ||
633 | slave_adjust_steering_mode(dev, &dev_cap, &hca_param); | ||
634 | |||
638 | return 0; | 635 | return 0; |
639 | 636 | ||
640 | err_mem: | 637 | err_mem: |
@@ -1321,6 +1318,59 @@ static void mlx4_parav_master_pf_caps(struct mlx4_dev *dev) | |||
1321 | } | 1318 | } |
1322 | } | 1319 | } |
1323 | 1320 | ||
1321 | static int choose_log_fs_mgm_entry_size(int qp_per_entry) | ||
1322 | { | ||
1323 | int i = MLX4_MIN_MGM_LOG_ENTRY_SIZE; | ||
1324 | |||
1325 | for (i = MLX4_MIN_MGM_LOG_ENTRY_SIZE; i <= MLX4_MAX_MGM_LOG_ENTRY_SIZE; | ||
1326 | i++) { | ||
1327 | if (qp_per_entry <= 4 * ((1 << i) / 16 - 2)) | ||
1328 | break; | ||
1329 | } | ||
1330 | |||
1331 | return (i <= MLX4_MAX_MGM_LOG_ENTRY_SIZE) ? i : -1; | ||
1332 | } | ||
1333 | |||
1334 | static void choose_steering_mode(struct mlx4_dev *dev, | ||
1335 | struct mlx4_dev_cap *dev_cap) | ||
1336 | { | ||
1337 | if (mlx4_log_num_mgm_entry_size == -1 && | ||
1338 | dev_cap->flags2 & MLX4_DEV_CAP_FLAG2_FS_EN && | ||
1339 | (!mlx4_is_mfunc(dev) || | ||
1340 | (dev_cap->fs_max_num_qp_per_entry >= (num_vfs + 1))) && | ||
1341 | choose_log_fs_mgm_entry_size(dev_cap->fs_max_num_qp_per_entry) >= | ||
1342 | MLX4_MIN_MGM_LOG_ENTRY_SIZE) { | ||
1343 | dev->oper_log_mgm_entry_size = | ||
1344 | choose_log_fs_mgm_entry_size(dev_cap->fs_max_num_qp_per_entry); | ||
1345 | dev->caps.steering_mode = MLX4_STEERING_MODE_DEVICE_MANAGED; | ||
1346 | dev->caps.num_qp_per_mgm = dev_cap->fs_max_num_qp_per_entry; | ||
1347 | dev->caps.fs_log_max_ucast_qp_range_size = | ||
1348 | dev_cap->fs_log_max_ucast_qp_range_size; | ||
1349 | } else { | ||
1350 | if (dev->caps.flags & MLX4_DEV_CAP_FLAG_VEP_UC_STEER && | ||
1351 | dev->caps.flags & MLX4_DEV_CAP_FLAG_VEP_MC_STEER) | ||
1352 | dev->caps.steering_mode = MLX4_STEERING_MODE_B0; | ||
1353 | else { | ||
1354 | dev->caps.steering_mode = MLX4_STEERING_MODE_A0; | ||
1355 | |||
1356 | if (dev->caps.flags & MLX4_DEV_CAP_FLAG_VEP_UC_STEER || | ||
1357 | dev->caps.flags & MLX4_DEV_CAP_FLAG_VEP_MC_STEER) | ||
1358 | mlx4_warn(dev, "Must have both UC_STEER and MC_STEER flags " | ||
1359 | "set to use B0 steering. Falling back to A0 steering mode.\n"); | ||
1360 | } | ||
1361 | dev->oper_log_mgm_entry_size = | ||
1362 | mlx4_log_num_mgm_entry_size > 0 ? | ||
1363 | mlx4_log_num_mgm_entry_size : | ||
1364 | MLX4_DEFAULT_MGM_LOG_ENTRY_SIZE; | ||
1365 | dev->caps.num_qp_per_mgm = mlx4_get_qp_per_mgm(dev); | ||
1366 | } | ||
1367 | mlx4_dbg(dev, "Steering mode is: %s, oper_log_mgm_entry_size = %d, " | ||
1368 | "modparam log_num_mgm_entry_size = %d\n", | ||
1369 | mlx4_steering_mode_str(dev->caps.steering_mode), | ||
1370 | dev->oper_log_mgm_entry_size, | ||
1371 | mlx4_log_num_mgm_entry_size); | ||
1372 | } | ||
1373 | |||
1324 | static int mlx4_init_hca(struct mlx4_dev *dev) | 1374 | static int mlx4_init_hca(struct mlx4_dev *dev) |
1325 | { | 1375 | { |
1326 | struct mlx4_priv *priv = mlx4_priv(dev); | 1376 | struct mlx4_priv *priv = mlx4_priv(dev); |
@@ -1360,6 +1410,8 @@ static int mlx4_init_hca(struct mlx4_dev *dev) | |||
1360 | goto err_stop_fw; | 1410 | goto err_stop_fw; |
1361 | } | 1411 | } |
1362 | 1412 | ||
1413 | choose_steering_mode(dev, &dev_cap); | ||
1414 | |||
1363 | if (mlx4_is_master(dev)) | 1415 | if (mlx4_is_master(dev)) |
1364 | mlx4_parav_master_pf_caps(dev); | 1416 | mlx4_parav_master_pf_caps(dev); |
1365 | 1417 | ||
@@ -2452,6 +2504,17 @@ static int __init mlx4_verify_params(void) | |||
2452 | port_type_array[0] = true; | 2504 | port_type_array[0] = true; |
2453 | } | 2505 | } |
2454 | 2506 | ||
2507 | if (mlx4_log_num_mgm_entry_size != -1 && | ||
2508 | (mlx4_log_num_mgm_entry_size < MLX4_MIN_MGM_LOG_ENTRY_SIZE || | ||
2509 | mlx4_log_num_mgm_entry_size > MLX4_MAX_MGM_LOG_ENTRY_SIZE)) { | ||
2510 | pr_warning("mlx4_core: mlx4_log_num_mgm_entry_size (%d) not " | ||
2511 | "in legal range (-1 or %d..%d)\n", | ||
2512 | mlx4_log_num_mgm_entry_size, | ||
2513 | MLX4_MIN_MGM_LOG_ENTRY_SIZE, | ||
2514 | MLX4_MAX_MGM_LOG_ENTRY_SIZE); | ||
2515 | return -1; | ||
2516 | } | ||
2517 | |||
2455 | return 0; | 2518 | return 0; |
2456 | } | 2519 | } |
2457 | 2520 | ||
diff --git a/drivers/net/ethernet/mellanox/mlx4/mcg.c b/drivers/net/ethernet/mellanox/mlx4/mcg.c index e151c21baf2b..1ee4db3c6400 100644 --- a/drivers/net/ethernet/mellanox/mlx4/mcg.c +++ b/drivers/net/ethernet/mellanox/mlx4/mcg.c | |||
@@ -54,12 +54,7 @@ struct mlx4_mgm { | |||
54 | 54 | ||
55 | int mlx4_get_mgm_entry_size(struct mlx4_dev *dev) | 55 | int mlx4_get_mgm_entry_size(struct mlx4_dev *dev) |
56 | { | 56 | { |
57 | if (dev->caps.steering_mode == | 57 | return 1 << dev->oper_log_mgm_entry_size; |
58 | MLX4_STEERING_MODE_DEVICE_MANAGED) | ||
59 | return 1 << MLX4_FS_MGM_LOG_ENTRY_SIZE; | ||
60 | else | ||
61 | return min((1 << mlx4_log_num_mgm_entry_size), | ||
62 | MLX4_MAX_MGM_ENTRY_SIZE); | ||
63 | } | 58 | } |
64 | 59 | ||
65 | int mlx4_get_qp_per_mgm(struct mlx4_dev *dev) | 60 | int mlx4_get_qp_per_mgm(struct mlx4_dev *dev) |
diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4.h b/drivers/net/ethernet/mellanox/mlx4/mlx4.h index 1cf42036d7bb..116c5c29d2d1 100644 --- a/drivers/net/ethernet/mellanox/mlx4/mlx4.h +++ b/drivers/net/ethernet/mellanox/mlx4/mlx4.h | |||
@@ -94,8 +94,10 @@ enum { | |||
94 | }; | 94 | }; |
95 | 95 | ||
96 | enum { | 96 | enum { |
97 | MLX4_MAX_MGM_ENTRY_SIZE = 0x1000, | 97 | MLX4_DEFAULT_MGM_LOG_ENTRY_SIZE = 10, |
98 | MLX4_MAX_QP_PER_MGM = 4 * (MLX4_MAX_MGM_ENTRY_SIZE / 16 - 2), | 98 | MLX4_MIN_MGM_LOG_ENTRY_SIZE = 7, |
99 | MLX4_MAX_MGM_LOG_ENTRY_SIZE = 12, | ||
100 | MLX4_MAX_QP_PER_MGM = 4 * ((1 << MLX4_MAX_MGM_LOG_ENTRY_SIZE) / 16 - 2), | ||
99 | MLX4_MTT_ENTRY_PER_SEG = 8, | 101 | MLX4_MTT_ENTRY_PER_SEG = 8, |
100 | }; | 102 | }; |
101 | 103 | ||
diff --git a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c index b05705f50f0f..561ed2a22a17 100644 --- a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c +++ b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c | |||
@@ -3071,6 +3071,7 @@ int mlx4_QP_FLOW_STEERING_ATTACH_wrapper(struct mlx4_dev *dev, int slave, | |||
3071 | struct mlx4_resource_tracker *tracker = &priv->mfunc.master.res_tracker; | 3071 | struct mlx4_resource_tracker *tracker = &priv->mfunc.master.res_tracker; |
3072 | struct list_head *rlist = &tracker->slave_list[slave].res_list[RES_MAC]; | 3072 | struct list_head *rlist = &tracker->slave_list[slave].res_list[RES_MAC]; |
3073 | int err; | 3073 | int err; |
3074 | int qpn; | ||
3074 | struct mlx4_net_trans_rule_hw_ctrl *ctrl; | 3075 | struct mlx4_net_trans_rule_hw_ctrl *ctrl; |
3075 | struct _rule_hw *rule_header; | 3076 | struct _rule_hw *rule_header; |
3076 | int header_id; | 3077 | int header_id; |
@@ -3080,13 +3081,21 @@ int mlx4_QP_FLOW_STEERING_ATTACH_wrapper(struct mlx4_dev *dev, int slave, | |||
3080 | return -EOPNOTSUPP; | 3081 | return -EOPNOTSUPP; |
3081 | 3082 | ||
3082 | ctrl = (struct mlx4_net_trans_rule_hw_ctrl *)inbox->buf; | 3083 | ctrl = (struct mlx4_net_trans_rule_hw_ctrl *)inbox->buf; |
3084 | qpn = be32_to_cpu(ctrl->qpn) & 0xffffff; | ||
3085 | err = get_res(dev, slave, qpn, RES_QP, NULL); | ||
3086 | if (err) { | ||
3087 | pr_err("Steering rule with qpn 0x%x rejected.\n", qpn); | ||
3088 | return err; | ||
3089 | } | ||
3083 | rule_header = (struct _rule_hw *)(ctrl + 1); | 3090 | rule_header = (struct _rule_hw *)(ctrl + 1); |
3084 | header_id = map_hw_to_sw_id(be16_to_cpu(rule_header->id)); | 3091 | header_id = map_hw_to_sw_id(be16_to_cpu(rule_header->id)); |
3085 | 3092 | ||
3086 | switch (header_id) { | 3093 | switch (header_id) { |
3087 | case MLX4_NET_TRANS_RULE_ID_ETH: | 3094 | case MLX4_NET_TRANS_RULE_ID_ETH: |
3088 | if (validate_eth_header_mac(slave, rule_header, rlist)) | 3095 | if (validate_eth_header_mac(slave, rule_header, rlist)) { |
3089 | return -EINVAL; | 3096 | err = -EINVAL; |
3097 | goto err_put; | ||
3098 | } | ||
3090 | break; | 3099 | break; |
3091 | case MLX4_NET_TRANS_RULE_ID_IB: | 3100 | case MLX4_NET_TRANS_RULE_ID_IB: |
3092 | break; | 3101 | break; |
@@ -3094,14 +3103,17 @@ int mlx4_QP_FLOW_STEERING_ATTACH_wrapper(struct mlx4_dev *dev, int slave, | |||
3094 | case MLX4_NET_TRANS_RULE_ID_TCP: | 3103 | case MLX4_NET_TRANS_RULE_ID_TCP: |
3095 | case MLX4_NET_TRANS_RULE_ID_UDP: | 3104 | case MLX4_NET_TRANS_RULE_ID_UDP: |
3096 | pr_warn("Can't attach FS rule without L2 headers, adding L2 header.\n"); | 3105 | pr_warn("Can't attach FS rule without L2 headers, adding L2 header.\n"); |
3097 | if (add_eth_header(dev, slave, inbox, rlist, header_id)) | 3106 | if (add_eth_header(dev, slave, inbox, rlist, header_id)) { |
3098 | return -EINVAL; | 3107 | err = -EINVAL; |
3108 | goto err_put; | ||
3109 | } | ||
3099 | vhcr->in_modifier += | 3110 | vhcr->in_modifier += |
3100 | sizeof(struct mlx4_net_trans_rule_hw_eth) >> 2; | 3111 | sizeof(struct mlx4_net_trans_rule_hw_eth) >> 2; |
3101 | break; | 3112 | break; |
3102 | default: | 3113 | default: |
3103 | pr_err("Corrupted mailbox.\n"); | 3114 | pr_err("Corrupted mailbox.\n"); |
3104 | return -EINVAL; | 3115 | err = -EINVAL; |
3116 | goto err_put; | ||
3105 | } | 3117 | } |
3106 | 3118 | ||
3107 | err = mlx4_cmd_imm(dev, inbox->dma, &vhcr->out_param, | 3119 | err = mlx4_cmd_imm(dev, inbox->dma, &vhcr->out_param, |
@@ -3109,16 +3121,18 @@ int mlx4_QP_FLOW_STEERING_ATTACH_wrapper(struct mlx4_dev *dev, int slave, | |||
3109 | MLX4_QP_FLOW_STEERING_ATTACH, MLX4_CMD_TIME_CLASS_A, | 3121 | MLX4_QP_FLOW_STEERING_ATTACH, MLX4_CMD_TIME_CLASS_A, |
3110 | MLX4_CMD_NATIVE); | 3122 | MLX4_CMD_NATIVE); |
3111 | if (err) | 3123 | if (err) |
3112 | return err; | 3124 | goto err_put; |
3113 | 3125 | ||
3114 | err = add_res_range(dev, slave, vhcr->out_param, 1, RES_FS_RULE, 0); | 3126 | err = add_res_range(dev, slave, vhcr->out_param, 1, RES_FS_RULE, 0); |
3115 | if (err) { | 3127 | if (err) { |
3116 | mlx4_err(dev, "Fail to add flow steering resources.\n "); | 3128 | mlx4_err(dev, "Fail to add flow steering resources.\n "); |
3117 | /* detach rule*/ | 3129 | /* detach rule*/ |
3118 | mlx4_cmd(dev, vhcr->out_param, 0, 0, | 3130 | mlx4_cmd(dev, vhcr->out_param, 0, 0, |
3119 | MLX4_QP_FLOW_STEERING_ATTACH, MLX4_CMD_TIME_CLASS_A, | 3131 | MLX4_QP_FLOW_STEERING_DETACH, MLX4_CMD_TIME_CLASS_A, |
3120 | MLX4_CMD_NATIVE); | 3132 | MLX4_CMD_NATIVE); |
3121 | } | 3133 | } |
3134 | err_put: | ||
3135 | put_res(dev, slave, qpn, RES_QP); | ||
3122 | return err; | 3136 | return err; |
3123 | } | 3137 | } |
3124 | 3138 | ||
diff --git a/drivers/scsi/csiostor/t4fw_api_stor.h b/drivers/scsi/csiostor/t4fw_api_stor.h index 1223e0d5fc07..097e52c0f8e1 100644 --- a/drivers/scsi/csiostor/t4fw_api_stor.h +++ b/drivers/scsi/csiostor/t4fw_api_stor.h | |||
@@ -40,45 +40,6 @@ | |||
40 | * R E T U R N V A L U E S | 40 | * R E T U R N V A L U E S |
41 | ********************************/ | 41 | ********************************/ |
42 | 42 | ||
43 | enum fw_retval { | ||
44 | FW_SUCCESS = 0, /* completed sucessfully */ | ||
45 | FW_EPERM = 1, /* operation not permitted */ | ||
46 | FW_ENOENT = 2, /* no such file or directory */ | ||
47 | FW_EIO = 5, /* input/output error; hw bad */ | ||
48 | FW_ENOEXEC = 8, /* exec format error; inv microcode */ | ||
49 | FW_EAGAIN = 11, /* try again */ | ||
50 | FW_ENOMEM = 12, /* out of memory */ | ||
51 | FW_EFAULT = 14, /* bad address; fw bad */ | ||
52 | FW_EBUSY = 16, /* resource busy */ | ||
53 | FW_EEXIST = 17, /* file exists */ | ||
54 | FW_EINVAL = 22, /* invalid argument */ | ||
55 | FW_ENOSPC = 28, /* no space left on device */ | ||
56 | FW_ENOSYS = 38, /* functionality not implemented */ | ||
57 | FW_EPROTO = 71, /* protocol error */ | ||
58 | FW_EADDRINUSE = 98, /* address already in use */ | ||
59 | FW_EADDRNOTAVAIL = 99, /* cannot assigned requested address */ | ||
60 | FW_ENETDOWN = 100, /* network is down */ | ||
61 | FW_ENETUNREACH = 101, /* network is unreachable */ | ||
62 | FW_ENOBUFS = 105, /* no buffer space available */ | ||
63 | FW_ETIMEDOUT = 110, /* timeout */ | ||
64 | FW_EINPROGRESS = 115, /* fw internal */ | ||
65 | FW_SCSI_ABORT_REQUESTED = 128, /* */ | ||
66 | FW_SCSI_ABORT_TIMEDOUT = 129, /* */ | ||
67 | FW_SCSI_ABORTED = 130, /* */ | ||
68 | FW_SCSI_CLOSE_REQUESTED = 131, /* */ | ||
69 | FW_ERR_LINK_DOWN = 132, /* */ | ||
70 | FW_RDEV_NOT_READY = 133, /* */ | ||
71 | FW_ERR_RDEV_LOST = 134, /* */ | ||
72 | FW_ERR_RDEV_LOGO = 135, /* */ | ||
73 | FW_FCOE_NO_XCHG = 136, /* */ | ||
74 | FW_SCSI_RSP_ERR = 137, /* */ | ||
75 | FW_ERR_RDEV_IMPL_LOGO = 138, /* */ | ||
76 | FW_SCSI_UNDER_FLOW_ERR = 139, /* */ | ||
77 | FW_SCSI_OVER_FLOW_ERR = 140, /* */ | ||
78 | FW_SCSI_DDP_ERR = 141, /* DDP error*/ | ||
79 | FW_SCSI_TASK_ERR = 142, /* No SCSI tasks available */ | ||
80 | }; | ||
81 | |||
82 | enum fw_fcoe_link_sub_op { | 43 | enum fw_fcoe_link_sub_op { |
83 | FCOE_LINK_DOWN = 0x0, | 44 | FCOE_LINK_DOWN = 0x0, |
84 | FCOE_LINK_UP = 0x1, | 45 | FCOE_LINK_UP = 0x1, |
diff --git a/include/linux/mlx4/device.h b/include/linux/mlx4/device.h index 21821da2abfd..20ea939c22a6 100644 --- a/include/linux/mlx4/device.h +++ b/include/linux/mlx4/device.h | |||
@@ -625,6 +625,7 @@ struct mlx4_dev { | |||
625 | u8 rev_id; | 625 | u8 rev_id; |
626 | char board_id[MLX4_BOARD_ID_LEN]; | 626 | char board_id[MLX4_BOARD_ID_LEN]; |
627 | int num_vfs; | 627 | int num_vfs; |
628 | int oper_log_mgm_entry_size; | ||
628 | u64 regid_promisc_array[MLX4_MAX_PORTS + 1]; | 629 | u64 regid_promisc_array[MLX4_MAX_PORTS + 1]; |
629 | u64 regid_allmulti_array[MLX4_MAX_PORTS + 1]; | 630 | u64 regid_allmulti_array[MLX4_MAX_PORTS + 1]; |
630 | }; | 631 | }; |