Commit ba9cee6a authored by Hariprasad Shenai's avatar Hariprasad Shenai Committed by David S. Miller

cxgb4/iw_cxgb4: TOS support

This series provides support for iWARP applications to specify a TOS
value and have that map to a VLAN Priority for iw_cxgb4 iWARP connections.

In iw_cxgb4, when allocating an L2T entry, pass the skb_priority based
on the tos value in the cm_id. Also pass the correct tos value during
connection setup so the passive side gets the client's desired tos.
When sending the FLOWC work request to FW, if the egress device is
in a vlan, then use the vlan priority bits as the scheduling class.
This allows associating RDMA connections with scheduling classes to
provide traffic shaping per flow.
Signed-off-by: default avatarSteve Wise <swise@opengridcomputing.com>
Signed-off-by: default avatarHariprasad Shenai <hariprasad@chelsio.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 6102c66e
...@@ -485,12 +485,19 @@ static void send_flowc(struct c4iw_ep *ep, struct sk_buff *skb) ...@@ -485,12 +485,19 @@ static void send_flowc(struct c4iw_ep *ep, struct sk_buff *skb)
unsigned int flowclen = 80; unsigned int flowclen = 80;
struct fw_flowc_wr *flowc; struct fw_flowc_wr *flowc;
int i; int i;
u16 vlan = ep->l2t->vlan;
int nparams;
if (vlan == CPL_L2T_VLAN_NONE)
nparams = 8;
else
nparams = 9;
skb = get_skb(skb, flowclen, GFP_KERNEL); skb = get_skb(skb, flowclen, GFP_KERNEL);
flowc = (struct fw_flowc_wr *)__skb_put(skb, flowclen); flowc = (struct fw_flowc_wr *)__skb_put(skb, flowclen);
flowc->op_to_nparams = cpu_to_be32(FW_WR_OP_V(FW_FLOWC_WR) | flowc->op_to_nparams = cpu_to_be32(FW_WR_OP_V(FW_FLOWC_WR) |
FW_FLOWC_WR_NPARAMS_V(8)); FW_FLOWC_WR_NPARAMS_V(nparams));
flowc->flowid_len16 = cpu_to_be32(FW_WR_LEN16_V(DIV_ROUND_UP(flowclen, flowc->flowid_len16 = cpu_to_be32(FW_WR_LEN16_V(DIV_ROUND_UP(flowclen,
16)) | FW_WR_FLOWID_V(ep->hwtid)); 16)) | FW_WR_FLOWID_V(ep->hwtid));
...@@ -511,9 +518,17 @@ static void send_flowc(struct c4iw_ep *ep, struct sk_buff *skb) ...@@ -511,9 +518,17 @@ static void send_flowc(struct c4iw_ep *ep, struct sk_buff *skb)
flowc->mnemval[6].val = cpu_to_be32(ep->snd_win); flowc->mnemval[6].val = cpu_to_be32(ep->snd_win);
flowc->mnemval[7].mnemonic = FW_FLOWC_MNEM_MSS; flowc->mnemval[7].mnemonic = FW_FLOWC_MNEM_MSS;
flowc->mnemval[7].val = cpu_to_be32(ep->emss); flowc->mnemval[7].val = cpu_to_be32(ep->emss);
if (nparams == 9) {
u16 pri;
pri = (vlan & VLAN_PRIO_MASK) >> VLAN_PRIO_SHIFT;
flowc->mnemval[8].mnemonic = FW_FLOWC_MNEM_SCHEDCLASS;
flowc->mnemval[8].val = cpu_to_be32(pri);
} else {
/* Pad WR to 16 byte boundary */ /* Pad WR to 16 byte boundary */
flowc->mnemval[8].mnemonic = 0; flowc->mnemval[8].mnemonic = 0;
flowc->mnemval[8].val = 0; flowc->mnemval[8].val = 0;
}
for (i = 0; i < 9; i++) { for (i = 0; i < 9; i++) {
flowc->mnemval[i].r4[0] = 0; flowc->mnemval[i].r4[0] = 0;
flowc->mnemval[i].r4[1] = 0; flowc->mnemval[i].r4[1] = 0;
...@@ -710,7 +725,7 @@ static int send_connect(struct c4iw_ep *ep) ...@@ -710,7 +725,7 @@ static int send_connect(struct c4iw_ep *ep)
L2T_IDX_V(ep->l2t->idx) | L2T_IDX_V(ep->l2t->idx) |
TX_CHAN_V(ep->tx_chan) | TX_CHAN_V(ep->tx_chan) |
SMAC_SEL_V(ep->smac_idx) | SMAC_SEL_V(ep->smac_idx) |
DSCP_V(ep->tos) | DSCP_V(ep->tos >> 2) |
ULP_MODE_V(ULP_MODE_TCPDDP) | ULP_MODE_V(ULP_MODE_TCPDDP) |
RCV_BUFSIZ_V(win); RCV_BUFSIZ_V(win);
opt2 = RX_CHANNEL_V(0) | opt2 = RX_CHANNEL_V(0) |
...@@ -1864,7 +1879,7 @@ static void send_fw_act_open_req(struct c4iw_ep *ep, unsigned int atid) ...@@ -1864,7 +1879,7 @@ static void send_fw_act_open_req(struct c4iw_ep *ep, unsigned int atid)
L2T_IDX_V(ep->l2t->idx) | L2T_IDX_V(ep->l2t->idx) |
TX_CHAN_V(ep->tx_chan) | TX_CHAN_V(ep->tx_chan) |
SMAC_SEL_V(ep->smac_idx) | SMAC_SEL_V(ep->smac_idx) |
DSCP_V(ep->tos) | DSCP_V(ep->tos >> 2) |
ULP_MODE_V(ULP_MODE_TCPDDP) | ULP_MODE_V(ULP_MODE_TCPDDP) |
RCV_BUFSIZ_V(win)); RCV_BUFSIZ_V(win));
req->tcb.opt2 = (__force __be32) (PACE_V(1) | req->tcb.opt2 = (__force __be32) (PACE_V(1) |
...@@ -1928,7 +1943,7 @@ static void set_tcp_window(struct c4iw_ep *ep, struct port_info *pi) ...@@ -1928,7 +1943,7 @@ static void set_tcp_window(struct c4iw_ep *ep, struct port_info *pi)
static int import_ep(struct c4iw_ep *ep, int iptype, __u8 *peer_ip, static int import_ep(struct c4iw_ep *ep, int iptype, __u8 *peer_ip,
struct dst_entry *dst, struct c4iw_dev *cdev, struct dst_entry *dst, struct c4iw_dev *cdev,
bool clear_mpa_v1, enum chip_type adapter_type) bool clear_mpa_v1, enum chip_type adapter_type, u8 tos)
{ {
struct neighbour *n; struct neighbour *n;
int err, step; int err, step;
...@@ -1958,7 +1973,7 @@ static int import_ep(struct c4iw_ep *ep, int iptype, __u8 *peer_ip, ...@@ -1958,7 +1973,7 @@ static int import_ep(struct c4iw_ep *ep, int iptype, __u8 *peer_ip,
goto out; goto out;
} }
ep->l2t = cxgb4_l2t_get(cdev->rdev.lldi.l2t, ep->l2t = cxgb4_l2t_get(cdev->rdev.lldi.l2t,
n, pdev, 0); n, pdev, rt_tos2priority(tos));
if (!ep->l2t) if (!ep->l2t)
goto out; goto out;
ep->mtu = pdev->mtu; ep->mtu = pdev->mtu;
...@@ -2041,7 +2056,7 @@ static int c4iw_reconnect(struct c4iw_ep *ep) ...@@ -2041,7 +2056,7 @@ static int c4iw_reconnect(struct c4iw_ep *ep)
if (ep->com.cm_id->local_addr.ss_family == AF_INET) { if (ep->com.cm_id->local_addr.ss_family == AF_INET) {
ep->dst = find_route(ep->com.dev, laddr->sin_addr.s_addr, ep->dst = find_route(ep->com.dev, laddr->sin_addr.s_addr,
raddr->sin_addr.s_addr, laddr->sin_port, raddr->sin_addr.s_addr, laddr->sin_port,
raddr->sin_port, 0); raddr->sin_port, ep->com.cm_id->tos);
iptype = 4; iptype = 4;
ra = (__u8 *)&raddr->sin_addr; ra = (__u8 *)&raddr->sin_addr;
} else { } else {
...@@ -2058,7 +2073,8 @@ static int c4iw_reconnect(struct c4iw_ep *ep) ...@@ -2058,7 +2073,8 @@ static int c4iw_reconnect(struct c4iw_ep *ep)
goto fail3; goto fail3;
} }
err = import_ep(ep, iptype, ra, ep->dst, ep->com.dev, false, err = import_ep(ep, iptype, ra, ep->dst, ep->com.dev, false,
ep->com.dev->rdev.lldi.adapter_type); ep->com.dev->rdev.lldi.adapter_type,
ep->com.cm_id->tos);
if (err) { if (err) {
pr_err("%s - cannot alloc l2e.\n", __func__); pr_err("%s - cannot alloc l2e.\n", __func__);
goto fail4; goto fail4;
...@@ -2069,7 +2085,7 @@ static int c4iw_reconnect(struct c4iw_ep *ep) ...@@ -2069,7 +2085,7 @@ static int c4iw_reconnect(struct c4iw_ep *ep)
ep->l2t->idx); ep->l2t->idx);
state_set(&ep->com, CONNECTING); state_set(&ep->com, CONNECTING);
ep->tos = 0; ep->tos = ep->com.cm_id->tos;
/* send connect request to rnic */ /* send connect request to rnic */
err = send_connect(ep); err = send_connect(ep);
...@@ -2391,6 +2407,7 @@ static int pass_accept_req(struct c4iw_dev *dev, struct sk_buff *skb) ...@@ -2391,6 +2407,7 @@ static int pass_accept_req(struct c4iw_dev *dev, struct sk_buff *skb)
u16 peer_mss = ntohs(req->tcpopt.mss); u16 peer_mss = ntohs(req->tcpopt.mss);
int iptype; int iptype;
unsigned short hdrs; unsigned short hdrs;
u8 tos = PASS_OPEN_TOS_G(ntohl(req->tos_stid));
parent_ep = lookup_stid(t, stid); parent_ep = lookup_stid(t, stid);
if (!parent_ep) { if (!parent_ep) {
...@@ -2414,7 +2431,7 @@ static int pass_accept_req(struct c4iw_dev *dev, struct sk_buff *skb) ...@@ -2414,7 +2431,7 @@ static int pass_accept_req(struct c4iw_dev *dev, struct sk_buff *skb)
ntohs(peer_port), peer_mss); ntohs(peer_port), peer_mss);
dst = find_route(dev, *(__be32 *)local_ip, *(__be32 *)peer_ip, dst = find_route(dev, *(__be32 *)local_ip, *(__be32 *)peer_ip,
local_port, peer_port, local_port, peer_port,
PASS_OPEN_TOS_G(ntohl(req->tos_stid))); tos);
} else { } else {
PDBG("%s parent ep %p hwtid %u laddr %pI6 raddr %pI6 lport %d rport %d peer_mss %d\n" PDBG("%s parent ep %p hwtid %u laddr %pI6 raddr %pI6 lport %d rport %d peer_mss %d\n"
, __func__, parent_ep, hwtid, , __func__, parent_ep, hwtid,
...@@ -2440,7 +2457,7 @@ static int pass_accept_req(struct c4iw_dev *dev, struct sk_buff *skb) ...@@ -2440,7 +2457,7 @@ static int pass_accept_req(struct c4iw_dev *dev, struct sk_buff *skb)
} }
err = import_ep(child_ep, iptype, peer_ip, dst, dev, false, err = import_ep(child_ep, iptype, peer_ip, dst, dev, false,
parent_ep->com.dev->rdev.lldi.adapter_type); parent_ep->com.dev->rdev.lldi.adapter_type, tos);
if (err) { if (err) {
printk(KERN_ERR MOD "%s - failed to allocate l2t entry!\n", printk(KERN_ERR MOD "%s - failed to allocate l2t entry!\n",
__func__); __func__);
...@@ -2508,7 +2525,7 @@ static int pass_accept_req(struct c4iw_dev *dev, struct sk_buff *skb) ...@@ -2508,7 +2525,7 @@ static int pass_accept_req(struct c4iw_dev *dev, struct sk_buff *skb)
c4iw_get_ep(&parent_ep->com); c4iw_get_ep(&parent_ep->com);
child_ep->parent_ep = parent_ep; child_ep->parent_ep = parent_ep;
child_ep->tos = PASS_OPEN_TOS_G(ntohl(req->tos_stid)); child_ep->tos = tos;
child_ep->dst = dst; child_ep->dst = dst;
child_ep->hwtid = hwtid; child_ep->hwtid = hwtid;
...@@ -3202,7 +3219,7 @@ int c4iw_connect(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param) ...@@ -3202,7 +3219,7 @@ int c4iw_connect(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param)
ra, ntohs(raddr->sin_port)); ra, ntohs(raddr->sin_port));
ep->dst = find_route(dev, laddr->sin_addr.s_addr, ep->dst = find_route(dev, laddr->sin_addr.s_addr,
raddr->sin_addr.s_addr, laddr->sin_port, raddr->sin_addr.s_addr, laddr->sin_port,
raddr->sin_port, 0); raddr->sin_port, cm_id->tos);
} else { } else {
iptype = 6; iptype = 6;
ra = (__u8 *)&raddr6->sin6_addr; ra = (__u8 *)&raddr6->sin6_addr;
...@@ -3233,7 +3250,7 @@ int c4iw_connect(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param) ...@@ -3233,7 +3250,7 @@ int c4iw_connect(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param)
} }
err = import_ep(ep, iptype, ra, ep->dst, ep->com.dev, true, err = import_ep(ep, iptype, ra, ep->dst, ep->com.dev, true,
ep->com.dev->rdev.lldi.adapter_type); ep->com.dev->rdev.lldi.adapter_type, cm_id->tos);
if (err) { if (err) {
printk(KERN_ERR MOD "%s - cannot alloc l2e.\n", __func__); printk(KERN_ERR MOD "%s - cannot alloc l2e.\n", __func__);
goto fail3; goto fail3;
...@@ -3244,7 +3261,7 @@ int c4iw_connect(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param) ...@@ -3244,7 +3261,7 @@ int c4iw_connect(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param)
ep->l2t->idx); ep->l2t->idx);
state_set(&ep->com, CONNECTING); state_set(&ep->com, CONNECTING);
ep->tos = 0; ep->tos = cm_id->tos;
/* send connect request to rnic */ /* send connect request to rnic */
err = send_connect(ep); err = send_connect(ep);
......
...@@ -1021,6 +1021,8 @@ struct cpl_l2t_write_req { ...@@ -1021,6 +1021,8 @@ struct cpl_l2t_write_req {
#define L2T_W_NOREPLY_V(x) ((x) << L2T_W_NOREPLY_S) #define L2T_W_NOREPLY_V(x) ((x) << L2T_W_NOREPLY_S)
#define L2T_W_NOREPLY_F L2T_W_NOREPLY_V(1U) #define L2T_W_NOREPLY_F L2T_W_NOREPLY_V(1U)
#define CPL_L2T_VLAN_NONE 0xfff
struct cpl_l2t_write_rpl { struct cpl_l2t_write_rpl {
union opcode_tid ot; union opcode_tid ot;
u8 status; u8 status;
......
...@@ -561,6 +561,7 @@ enum fw_flowc_mnem { ...@@ -561,6 +561,7 @@ enum fw_flowc_mnem {
FW_FLOWC_MNEM_SNDBUF, FW_FLOWC_MNEM_SNDBUF,
FW_FLOWC_MNEM_MSS, FW_FLOWC_MNEM_MSS,
FW_FLOWC_MNEM_TXDATAPLEN_MAX, FW_FLOWC_MNEM_TXDATAPLEN_MAX,
FW_FLOWC_MNEM_SCHEDCLASS = 11,
}; };
struct fw_flowc_mnemval { struct fw_flowc_mnemval {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment