Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 347929
b: refs/heads/master
c: 5be78ee
h: refs/heads/master
i:
  347927: 869df01
v: v3
  • Loading branch information
Vipul Pandya authored and Roland Dreier committed Dec 20, 2012
1 parent 6707d26 commit 075b61b
Show file tree
Hide file tree
Showing 7 changed files with 316 additions and 48 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: dca4faeb812f665dab0607d8e0660ae564387186
refs/heads/master: 5be78ee924ae8fb2b4a5b8d012a7d003849337ee
158 changes: 152 additions & 6 deletions trunk/drivers/infiniband/hw/cxgb4/cm.c
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,14 @@ static char *states[] = {
NULL,
};

static int nocong;
module_param(nocong, int, 0644);
MODULE_PARM_DESC(nocong, "Turn of congestion control (default=0)");

static int enable_ecn;
module_param(enable_ecn, int, 0644);
MODULE_PARM_DESC(enable_ecn, "Enable ECN (default=0/disabled)");

static int dack_mode = 1;
module_param(dack_mode, int, 0644);
MODULE_PARM_DESC(dack_mode, "Delayed ack mode (default=1)");
Expand Down Expand Up @@ -441,6 +449,50 @@ static int send_abort(struct c4iw_ep *ep, struct sk_buff *skb, gfp_t gfp)
return c4iw_l2t_send(&ep->com.dev->rdev, skb, ep->l2t);
}

#define VLAN_NONE 0xfff
#define FILTER_SEL_VLAN_NONE 0xffff
#define FILTER_SEL_WIDTH_P_FC (3+1) /* port uses 3 bits, FCoE one bit */
#define FILTER_SEL_WIDTH_VIN_P_FC \
(6 + 7 + FILTER_SEL_WIDTH_P_FC) /* 6 bits are unused, VF uses 7 bits*/
#define FILTER_SEL_WIDTH_TAG_P_FC \
(3 + FILTER_SEL_WIDTH_VIN_P_FC) /* PF uses 3 bits */
#define FILTER_SEL_WIDTH_VLD_TAG_P_FC (1 + FILTER_SEL_WIDTH_TAG_P_FC)

static unsigned int select_ntuple(struct c4iw_dev *dev, struct dst_entry *dst,
struct l2t_entry *l2t)
{
unsigned int ntuple = 0;
u32 viid;

switch (dev->rdev.lldi.filt_mode) {

/* default filter mode */
case HW_TPL_FR_MT_PR_IV_P_FC:
if (l2t->vlan == VLAN_NONE)
ntuple |= FILTER_SEL_VLAN_NONE << FILTER_SEL_WIDTH_P_FC;
else {
ntuple |= l2t->vlan << FILTER_SEL_WIDTH_P_FC;
ntuple |= 1 << FILTER_SEL_WIDTH_VLD_TAG_P_FC;
}
ntuple |= l2t->lport << S_PORT | IPPROTO_TCP <<
FILTER_SEL_WIDTH_VLD_TAG_P_FC;
break;
case HW_TPL_FR_MT_PR_OV_P_FC: {
viid = cxgb4_port_viid(l2t->neigh->dev);

ntuple |= FW_VIID_VIN_GET(viid) << FILTER_SEL_WIDTH_P_FC;
ntuple |= FW_VIID_PFN_GET(viid) << FILTER_SEL_WIDTH_VIN_P_FC;
ntuple |= FW_VIID_VIVLD_GET(viid) << FILTER_SEL_WIDTH_TAG_P_FC;
ntuple |= l2t->lport << S_PORT | IPPROTO_TCP <<
FILTER_SEL_WIDTH_VLD_TAG_P_FC;
break;
}
default:
break;
}
return ntuple;
}

static int send_connect(struct c4iw_ep *ep)
{
struct cpl_act_open_req *req;
Expand All @@ -463,7 +515,8 @@ static int send_connect(struct c4iw_ep *ep)

cxgb4_best_mtu(ep->com.dev->rdev.lldi.mtus, ep->mtu, &mtu_idx);
wscale = compute_wscale(rcv_win);
opt0 = KEEP_ALIVE(1) |
opt0 = (nocong ? NO_CONG(1) : 0) |
KEEP_ALIVE(1) |
DELACK(1) |
WND_SCALE(wscale) |
MSS_IDX(mtu_idx) |
Expand All @@ -474,6 +527,7 @@ static int send_connect(struct c4iw_ep *ep)
ULP_MODE(ULP_MODE_TCPDDP) |
RCV_BUFSIZ(rcv_win>>10);
opt2 = RX_CHANNEL(0) |
CCTRL_ECN(enable_ecn) |
RSS_QUEUE_VALID | RSS_QUEUE(ep->rss_qid);
if (enable_tcp_timestamps)
opt2 |= TSTAMPS_EN(1);
Expand All @@ -492,7 +546,7 @@ static int send_connect(struct c4iw_ep *ep)
req->local_ip = ep->com.local_addr.sin_addr.s_addr;
req->peer_ip = ep->com.remote_addr.sin_addr.s_addr;
req->opt0 = cpu_to_be64(opt0);
req->params = 0;
req->params = cpu_to_be32(select_ntuple(ep->com.dev, ep->dst, ep->l2t));
req->opt2 = cpu_to_be32(opt2);
return c4iw_l2t_send(&ep->com.dev->rdev, skb, ep->l2t);
}
Expand Down Expand Up @@ -1383,6 +1437,61 @@ static int abort_rpl(struct c4iw_dev *dev, struct sk_buff *skb)
return 0;
}

static void send_fw_act_open_req(struct c4iw_ep *ep, unsigned int atid)
{
struct sk_buff *skb;
struct fw_ofld_connection_wr *req;
unsigned int mtu_idx;
int wscale;

skb = get_skb(NULL, sizeof(*req), GFP_KERNEL);
req = (struct fw_ofld_connection_wr *)__skb_put(skb, sizeof(*req));
memset(req, 0, sizeof(*req));
req->op_compl = htonl(V_WR_OP(FW_OFLD_CONNECTION_WR));
req->len16_pkd = htonl(FW_WR_LEN16(DIV_ROUND_UP(sizeof(*req), 16)));
req->le.filter = cpu_to_be32(select_ntuple(ep->com.dev, ep->dst,
ep->l2t));
req->le.lport = ep->com.local_addr.sin_port;
req->le.pport = ep->com.remote_addr.sin_port;
req->le.u.ipv4.lip = ep->com.local_addr.sin_addr.s_addr;
req->le.u.ipv4.pip = ep->com.remote_addr.sin_addr.s_addr;
req->tcb.t_state_to_astid =
htonl(V_FW_OFLD_CONNECTION_WR_T_STATE(TCP_SYN_SENT) |
V_FW_OFLD_CONNECTION_WR_ASTID(atid));
req->tcb.cplrxdataack_cplpassacceptrpl =
htons(F_FW_OFLD_CONNECTION_WR_CPLRXDATAACK);
req->tcb.tx_max = jiffies;
cxgb4_best_mtu(ep->com.dev->rdev.lldi.mtus, ep->mtu, &mtu_idx);
wscale = compute_wscale(rcv_win);
req->tcb.opt0 = TCAM_BYPASS(1) |
(nocong ? NO_CONG(1) : 0) |
KEEP_ALIVE(1) |
DELACK(1) |
WND_SCALE(wscale) |
MSS_IDX(mtu_idx) |
L2T_IDX(ep->l2t->idx) |
TX_CHAN(ep->tx_chan) |
SMAC_SEL(ep->smac_idx) |
DSCP(ep->tos) |
ULP_MODE(ULP_MODE_TCPDDP) |
RCV_BUFSIZ(rcv_win >> 10);
req->tcb.opt2 = PACE(1) |
TX_QUEUE(ep->com.dev->rdev.lldi.tx_modq[ep->tx_chan]) |
RX_CHANNEL(0) |
CCTRL_ECN(enable_ecn) |
RSS_QUEUE_VALID | RSS_QUEUE(ep->rss_qid);
if (enable_tcp_timestamps)
req->tcb.opt2 |= TSTAMPS_EN(1);
if (enable_tcp_sack)
req->tcb.opt2 |= SACK_EN(1);
if (wscale && enable_tcp_window_scaling)
req->tcb.opt2 |= WND_SCALE_EN(1);
req->tcb.opt0 = cpu_to_be64(req->tcb.opt0);
req->tcb.opt2 = cpu_to_be32(req->tcb.opt2);
set_wr_txq(skb, CPL_PRIORITY_CONTROL, 0);
c4iw_l2t_send(&ep->com.dev->rdev, skb, ep->l2t);
}

/*
* Return whether a failed active open has allocated a TID
*/
Expand Down Expand Up @@ -1419,6 +1528,14 @@ static int act_open_rpl(struct c4iw_dev *dev, struct sk_buff *skb)
case CPL_ERR_CONN_RESET:
case CPL_ERR_CONN_TIMEDOUT:
break;
case CPL_ERR_TCAM_FULL:
mutex_lock(&dev->rdev.stats.lock);
dev->rdev.stats.tcam_full++;
mutex_unlock(&dev->rdev.stats.lock);
send_fw_act_open_req(ep,
GET_TID_TID(GET_AOPEN_ATID(ntohl(rpl->atid_status))));
return 0;
break;
default:
printk(KERN_INFO MOD "Active open failure - "
"atid %u status %u errno %d %pI4:%u->%pI4:%u\n",
Expand Down Expand Up @@ -1510,14 +1627,15 @@ static void accept_cr(struct c4iw_ep *ep, __be32 peer_ip, struct sk_buff *skb,
skb_get(skb);
cxgb4_best_mtu(ep->com.dev->rdev.lldi.mtus, ep->mtu, &mtu_idx);
wscale = compute_wscale(rcv_win);
opt0 = KEEP_ALIVE(1) |
opt0 = (nocong ? NO_CONG(1) : 0) |
KEEP_ALIVE(1) |
DELACK(1) |
WND_SCALE(wscale) |
MSS_IDX(mtu_idx) |
L2T_IDX(ep->l2t->idx) |
TX_CHAN(ep->tx_chan) |
SMAC_SEL(ep->smac_idx) |
DSCP(ep->tos) |
DSCP(ep->tos >> 2) |
ULP_MODE(ULP_MODE_TCPDDP) |
RCV_BUFSIZ(rcv_win>>10);
opt2 = RX_CHANNEL(0) |
Expand All @@ -1529,6 +1647,15 @@ static void accept_cr(struct c4iw_ep *ep, __be32 peer_ip, struct sk_buff *skb,
opt2 |= SACK_EN(1);
if (wscale && enable_tcp_window_scaling)
opt2 |= WND_SCALE_EN(1);
if (enable_ecn) {
const struct tcphdr *tcph;
u32 hlen = ntohl(req->hdr_len);

tcph = (const void *)(req + 1) + G_ETH_HDR_LEN(hlen) +
G_IP_HDR_LEN(hlen);
if (tcph->ece && tcph->cwr)
opt2 |= CCTRL_ECN(1);
}

rpl = cplhdr(skb);
INIT_TP_WR(rpl, ep->hwtid);
Expand Down Expand Up @@ -2647,21 +2774,40 @@ static int fw6_msg(struct c4iw_dev *dev, struct sk_buff *skb)
struct cpl_fw6_msg *rpl = cplhdr(skb);
struct c4iw_wr_wait *wr_waitp;
int ret;
u8 opcode;
struct cpl_fw6_msg_ofld_connection_wr_rpl *req;
struct c4iw_ep *ep;

PDBG("%s type %u\n", __func__, rpl->type);

switch (rpl->type) {
case 1:
case FW6_TYPE_WR_RPL:
ret = (int)((be64_to_cpu(rpl->data[0]) >> 8) & 0xff);
wr_waitp = (struct c4iw_wr_wait *)(__force unsigned long) rpl->data[1];
PDBG("%s wr_waitp %p ret %u\n", __func__, wr_waitp, ret);
if (wr_waitp)
c4iw_wake_up(wr_waitp, ret ? -ret : 0);
kfree_skb(skb);
break;
case 2:
case FW6_TYPE_CQE:
sched(dev, skb);
break;
case FW6_TYPE_OFLD_CONNECTION_WR_RPL:
opcode = *(const u8 *)rpl->data;
if (opcode == FW_OFLD_CONNECTION_WR) {
req =
(struct cpl_fw6_msg_ofld_connection_wr_rpl *)rpl->data;
if (req->t_state == TCP_SYN_SENT
&& (req->retval == FW_ENOMEM
|| req->retval == FW_EADDRINUSE)) {
ep = (struct c4iw_ep *)
lookup_atid(dev->rdev.lldi.tids,
req->tid);
c4iw_l2t_send(&dev->rdev, skb, ep->l2t);
return 0;
}
}
break;
default:
printk(KERN_ERR MOD "%s unexpected fw6 msg type %u\n", __func__,
rpl->type);
Expand Down
1 change: 1 addition & 0 deletions trunk/drivers/infiniband/hw/cxgb4/iw_cxgb4.h
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ struct c4iw_stats {
u64 db_empty;
u64 db_drop;
u64 db_state_transitions;
u64 tcam_full;
};

struct c4iw_rdev {
Expand Down
19 changes: 19 additions & 0 deletions trunk/drivers/net/ethernet/chelsio/cxgb4/t4_msg.h
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,10 @@ struct work_request_hdr {
__be64 wr_lo;
};

/* wr_hi fields */
#define S_WR_OP 24
#define V_WR_OP(x) ((__u64)(x) << S_WR_OP)

#define WR_HDR struct work_request_hdr wr

struct cpl_pass_open_req {
Expand All @@ -204,12 +208,14 @@ struct cpl_pass_open_req {
__be32 peer_ip;
__be64 opt0;
#define TX_CHAN(x) ((x) << 2)
#define NO_CONG(x) ((x) << 4)
#define DELACK(x) ((x) << 5)
#define ULP_MODE(x) ((x) << 8)
#define RCV_BUFSIZ(x) ((x) << 12)
#define DSCP(x) ((x) << 22)
#define SMAC_SEL(x) ((u64)(x) << 28)
#define L2T_IDX(x) ((u64)(x) << 36)
#define TCAM_BYPASS(x) ((u64)(x) << 48)
#define NAGLE(x) ((u64)(x) << 49)
#define WND_SCALE(x) ((u64)(x) << 50)
#define KEEP_ALIVE(x) ((u64)(x) << 54)
Expand Down Expand Up @@ -247,8 +253,10 @@ struct cpl_pass_accept_rpl {
#define RSS_QUEUE_VALID (1 << 10)
#define RX_COALESCE_VALID(x) ((x) << 11)
#define RX_COALESCE(x) ((x) << 12)
#define PACE(x) ((x) << 16)
#define TX_QUEUE(x) ((x) << 23)
#define RX_CHANNEL(x) ((x) << 26)
#define CCTRL_ECN(x) ((x) << 27)
#define WND_SCALE_EN(x) ((x) << 28)
#define TSTAMPS_EN(x) ((x) << 29)
#define SACK_EN(x) ((x) << 30)
Expand Down Expand Up @@ -635,6 +643,17 @@ struct cpl_fw6_msg {
/* cpl_fw6_msg.type values */
enum {
FW6_TYPE_CMD_RPL = 0,
FW6_TYPE_WR_RPL = 1,
FW6_TYPE_CQE = 2,
FW6_TYPE_OFLD_CONNECTION_WR_RPL = 3,
};

struct cpl_fw6_msg_ofld_connection_wr_rpl {
__u64 cookie;
__be32 tid; /* or atid in case of active failure */
__u8 t_state;
__u8 retval;
__u8 rsvd[2];
};

enum {
Expand Down
2 changes: 2 additions & 0 deletions trunk/drivers/net/ethernet/chelsio/cxgb4/t4_regs.h
Original file line number Diff line number Diff line change
Expand Up @@ -1097,4 +1097,6 @@

#define A_TP_TX_SCHED_PCMD 0x25

#define S_PORT 1

#endif /* __T4_REGS_H */
Loading

0 comments on commit 075b61b

Please sign in to comment.