|
@@ -232,12 +232,16 @@ static void release_tid(struct c4iw_rdev *rdev, u32 hwtid, struct sk_buff *skb)
|
|
|
|
|
|
static void set_emss(struct c4iw_ep *ep, u16 opt)
|
|
static void set_emss(struct c4iw_ep *ep, u16 opt)
|
|
{
|
|
{
|
|
- ep->emss = ep->com.dev->rdev.lldi.mtus[GET_TCPOPT_MSS(opt)] - 40;
|
|
|
|
|
|
+ ep->emss = ep->com.dev->rdev.lldi.mtus[GET_TCPOPT_MSS(opt)] -
|
|
|
|
+ sizeof(struct iphdr) - sizeof(struct tcphdr);
|
|
ep->mss = ep->emss;
|
|
ep->mss = ep->emss;
|
|
if (GET_TCPOPT_TSTAMP(opt))
|
|
if (GET_TCPOPT_TSTAMP(opt))
|
|
ep->emss -= 12;
|
|
ep->emss -= 12;
|
|
if (ep->emss < 128)
|
|
if (ep->emss < 128)
|
|
ep->emss = 128;
|
|
ep->emss = 128;
|
|
|
|
+ if (ep->emss & 7)
|
|
|
|
+ PDBG("Warning: misaligned mtu idx %u mss %u emss=%u\n",
|
|
|
|
+ GET_TCPOPT_MSS(opt), ep->mss, ep->emss);
|
|
PDBG("%s mss_idx %u mss %u emss=%u\n", __func__, GET_TCPOPT_MSS(opt),
|
|
PDBG("%s mss_idx %u mss %u emss=%u\n", __func__, GET_TCPOPT_MSS(opt),
|
|
ep->mss, ep->emss);
|
|
ep->mss, ep->emss);
|
|
}
|
|
}
|
|
@@ -528,6 +532,17 @@ 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);
|
|
return c4iw_l2t_send(&ep->com.dev->rdev, skb, ep->l2t);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+static void best_mtu(const unsigned short *mtus, unsigned short mtu,
|
|
|
|
+ unsigned int *idx, int use_ts)
|
|
|
|
+{
|
|
|
|
+ unsigned short hdr_size = sizeof(struct iphdr) +
|
|
|
|
+ sizeof(struct tcphdr) +
|
|
|
|
+ (use_ts ? 12 : 0);
|
|
|
|
+ unsigned short data_size = mtu - hdr_size;
|
|
|
|
+
|
|
|
|
+ cxgb4_best_aligned_mtu(mtus, hdr_size, data_size, 8, idx);
|
|
|
|
+}
|
|
|
|
+
|
|
static int send_connect(struct c4iw_ep *ep)
|
|
static int send_connect(struct c4iw_ep *ep)
|
|
{
|
|
{
|
|
struct cpl_act_open_req *req;
|
|
struct cpl_act_open_req *req;
|
|
@@ -565,7 +580,8 @@ static int send_connect(struct c4iw_ep *ep)
|
|
}
|
|
}
|
|
set_wr_txq(skb, CPL_PRIORITY_SETUP, ep->ctrlq_idx);
|
|
set_wr_txq(skb, CPL_PRIORITY_SETUP, ep->ctrlq_idx);
|
|
|
|
|
|
- cxgb4_best_mtu(ep->com.dev->rdev.lldi.mtus, ep->mtu, &mtu_idx);
|
|
|
|
|
|
+ best_mtu(ep->com.dev->rdev.lldi.mtus, ep->mtu, &mtu_idx,
|
|
|
|
+ enable_tcp_timestamps);
|
|
wscale = compute_wscale(rcv_win);
|
|
wscale = compute_wscale(rcv_win);
|
|
opt0 = (nocong ? NO_CONG(1) : 0) |
|
|
opt0 = (nocong ? NO_CONG(1) : 0) |
|
|
KEEP_ALIVE(1) |
|
|
KEEP_ALIVE(1) |
|
|
@@ -633,6 +649,13 @@ static int send_connect(struct c4iw_ep *ep)
|
|
req6->opt2 = cpu_to_be32(opt2);
|
|
req6->opt2 = cpu_to_be32(opt2);
|
|
}
|
|
}
|
|
} else {
|
|
} else {
|
|
|
|
+ u32 isn = (prandom_u32() & ~7UL) - 1;
|
|
|
|
+
|
|
|
|
+ opt2 |= T5_OPT_2_VALID;
|
|
|
|
+ opt2 |= CONG_CNTRL_VALID; /* OPT_2_ISS for T5 */
|
|
|
|
+ if (peer2peer)
|
|
|
|
+ isn += 4;
|
|
|
|
+
|
|
if (ep->com.remote_addr.ss_family == AF_INET) {
|
|
if (ep->com.remote_addr.ss_family == AF_INET) {
|
|
t5_req = (struct cpl_t5_act_open_req *)
|
|
t5_req = (struct cpl_t5_act_open_req *)
|
|
skb_put(skb, wrlen);
|
|
skb_put(skb, wrlen);
|
|
@@ -649,6 +672,9 @@ static int send_connect(struct c4iw_ep *ep)
|
|
cxgb4_select_ntuple(
|
|
cxgb4_select_ntuple(
|
|
ep->com.dev->rdev.lldi.ports[0],
|
|
ep->com.dev->rdev.lldi.ports[0],
|
|
ep->l2t)));
|
|
ep->l2t)));
|
|
|
|
+ t5_req->rsvd = cpu_to_be32(isn);
|
|
|
|
+ PDBG("%s snd_isn %u\n", __func__,
|
|
|
|
+ be32_to_cpu(t5_req->rsvd));
|
|
t5_req->opt2 = cpu_to_be32(opt2);
|
|
t5_req->opt2 = cpu_to_be32(opt2);
|
|
} else {
|
|
} else {
|
|
t5_req6 = (struct cpl_t5_act_open_req6 *)
|
|
t5_req6 = (struct cpl_t5_act_open_req6 *)
|
|
@@ -672,6 +698,9 @@ static int send_connect(struct c4iw_ep *ep)
|
|
cxgb4_select_ntuple(
|
|
cxgb4_select_ntuple(
|
|
ep->com.dev->rdev.lldi.ports[0],
|
|
ep->com.dev->rdev.lldi.ports[0],
|
|
ep->l2t));
|
|
ep->l2t));
|
|
|
|
+ t5_req6->rsvd = cpu_to_be32(isn);
|
|
|
|
+ PDBG("%s snd_isn %u\n", __func__,
|
|
|
|
+ be32_to_cpu(t5_req6->rsvd));
|
|
t5_req6->opt2 = cpu_to_be32(opt2);
|
|
t5_req6->opt2 = cpu_to_be32(opt2);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -1640,7 +1669,8 @@ static void send_fw_act_open_req(struct c4iw_ep *ep, unsigned int atid)
|
|
htons(F_FW_OFLD_CONNECTION_WR_CPLRXDATAACK);
|
|
htons(F_FW_OFLD_CONNECTION_WR_CPLRXDATAACK);
|
|
req->tcb.tx_max = (__force __be32) jiffies;
|
|
req->tcb.tx_max = (__force __be32) jiffies;
|
|
req->tcb.rcv_adv = htons(1);
|
|
req->tcb.rcv_adv = htons(1);
|
|
- cxgb4_best_mtu(ep->com.dev->rdev.lldi.mtus, ep->mtu, &mtu_idx);
|
|
|
|
|
|
+ best_mtu(ep->com.dev->rdev.lldi.mtus, ep->mtu, &mtu_idx,
|
|
|
|
+ enable_tcp_timestamps);
|
|
wscale = compute_wscale(rcv_win);
|
|
wscale = compute_wscale(rcv_win);
|
|
req->tcb.opt0 = (__force __be64) (TCAM_BYPASS(1) |
|
|
req->tcb.opt0 = (__force __be64) (TCAM_BYPASS(1) |
|
|
(nocong ? NO_CONG(1) : 0) |
|
|
(nocong ? NO_CONG(1) : 0) |
|
|
@@ -1986,12 +2016,26 @@ static void accept_cr(struct c4iw_ep *ep, struct sk_buff *skb,
|
|
u64 opt0;
|
|
u64 opt0;
|
|
u32 opt2;
|
|
u32 opt2;
|
|
int wscale;
|
|
int wscale;
|
|
|
|
+ struct cpl_t5_pass_accept_rpl *rpl5 = NULL;
|
|
|
|
|
|
PDBG("%s ep %p tid %u\n", __func__, ep, ep->hwtid);
|
|
PDBG("%s ep %p tid %u\n", __func__, ep, ep->hwtid);
|
|
BUG_ON(skb_cloned(skb));
|
|
BUG_ON(skb_cloned(skb));
|
|
- skb_trim(skb, sizeof(*rpl));
|
|
|
|
|
|
+
|
|
skb_get(skb);
|
|
skb_get(skb);
|
|
- cxgb4_best_mtu(ep->com.dev->rdev.lldi.mtus, ep->mtu, &mtu_idx);
|
|
|
|
|
|
+ rpl = cplhdr(skb);
|
|
|
|
+ if (is_t5(ep->com.dev->rdev.lldi.adapter_type)) {
|
|
|
|
+ skb_trim(skb, roundup(sizeof(*rpl5), 16));
|
|
|
|
+ rpl5 = (void *)rpl;
|
|
|
|
+ INIT_TP_WR(rpl5, ep->hwtid);
|
|
|
|
+ } else {
|
|
|
|
+ skb_trim(skb, sizeof(*rpl));
|
|
|
|
+ INIT_TP_WR(rpl, ep->hwtid);
|
|
|
|
+ }
|
|
|
|
+ OPCODE_TID(rpl) = cpu_to_be32(MK_OPCODE_TID(CPL_PASS_ACCEPT_RPL,
|
|
|
|
+ ep->hwtid));
|
|
|
|
+
|
|
|
|
+ best_mtu(ep->com.dev->rdev.lldi.mtus, ep->mtu, &mtu_idx,
|
|
|
|
+ enable_tcp_timestamps && req->tcpopt.tstamp);
|
|
wscale = compute_wscale(rcv_win);
|
|
wscale = compute_wscale(rcv_win);
|
|
opt0 = (nocong ? NO_CONG(1) : 0) |
|
|
opt0 = (nocong ? NO_CONG(1) : 0) |
|
|
KEEP_ALIVE(1) |
|
|
KEEP_ALIVE(1) |
|
|
@@ -2023,14 +2067,18 @@ static void accept_cr(struct c4iw_ep *ep, struct sk_buff *skb,
|
|
opt2 |= CCTRL_ECN(1);
|
|
opt2 |= CCTRL_ECN(1);
|
|
}
|
|
}
|
|
if (is_t5(ep->com.dev->rdev.lldi.adapter_type)) {
|
|
if (is_t5(ep->com.dev->rdev.lldi.adapter_type)) {
|
|
|
|
+ u32 isn = (prandom_u32() & ~7UL) - 1;
|
|
opt2 |= T5_OPT_2_VALID;
|
|
opt2 |= T5_OPT_2_VALID;
|
|
opt2 |= V_CONG_CNTRL(CONG_ALG_TAHOE);
|
|
opt2 |= V_CONG_CNTRL(CONG_ALG_TAHOE);
|
|
|
|
+ opt2 |= CONG_CNTRL_VALID; /* OPT_2_ISS for T5 */
|
|
|
|
+ rpl5 = (void *)rpl;
|
|
|
|
+ memset(&rpl5->iss, 0, roundup(sizeof(*rpl5)-sizeof(*rpl), 16));
|
|
|
|
+ if (peer2peer)
|
|
|
|
+ isn += 4;
|
|
|
|
+ rpl5->iss = cpu_to_be32(isn);
|
|
|
|
+ PDBG("%s iss %u\n", __func__, be32_to_cpu(rpl5->iss));
|
|
}
|
|
}
|
|
|
|
|
|
- rpl = cplhdr(skb);
|
|
|
|
- INIT_TP_WR(rpl, ep->hwtid);
|
|
|
|
- OPCODE_TID(rpl) = cpu_to_be32(MK_OPCODE_TID(CPL_PASS_ACCEPT_RPL,
|
|
|
|
- ep->hwtid));
|
|
|
|
rpl->opt0 = cpu_to_be64(opt0);
|
|
rpl->opt0 = cpu_to_be64(opt0);
|
|
rpl->opt2 = cpu_to_be32(opt2);
|
|
rpl->opt2 = cpu_to_be32(opt2);
|
|
set_wr_txq(skb, CPL_PRIORITY_SETUP, ep->ctrlq_idx);
|
|
set_wr_txq(skb, CPL_PRIORITY_SETUP, ep->ctrlq_idx);
|
|
@@ -2095,6 +2143,7 @@ static int pass_accept_req(struct c4iw_dev *dev, struct sk_buff *skb)
|
|
int err;
|
|
int err;
|
|
u16 peer_mss = ntohs(req->tcpopt.mss);
|
|
u16 peer_mss = ntohs(req->tcpopt.mss);
|
|
int iptype;
|
|
int iptype;
|
|
|
|
+ unsigned short hdrs;
|
|
|
|
|
|
parent_ep = lookup_stid(t, stid);
|
|
parent_ep = lookup_stid(t, stid);
|
|
if (!parent_ep) {
|
|
if (!parent_ep) {
|
|
@@ -2152,8 +2201,10 @@ static int pass_accept_req(struct c4iw_dev *dev, struct sk_buff *skb)
|
|
goto reject;
|
|
goto reject;
|
|
}
|
|
}
|
|
|
|
|
|
- if (peer_mss && child_ep->mtu > (peer_mss + 40))
|
|
|
|
- child_ep->mtu = peer_mss + 40;
|
|
|
|
|
|
+ hdrs = sizeof(struct iphdr) + sizeof(struct tcphdr) +
|
|
|
|
+ ((enable_tcp_timestamps && req->tcpopt.tstamp) ? 12 : 0);
|
|
|
|
+ if (peer_mss && child_ep->mtu > (peer_mss + hdrs))
|
|
|
|
+ child_ep->mtu = peer_mss + hdrs;
|
|
|
|
|
|
state_set(&child_ep->com, CONNECTING);
|
|
state_set(&child_ep->com, CONNECTING);
|
|
child_ep->com.dev = dev;
|
|
child_ep->com.dev = dev;
|