提交 80f40c1f 编写于 作者: V Vipul Pandya 提交者: Roland Dreier

cxgb4: Add routines to create and remove listening IPv6 servers

Add cxgb4_create_server6 and cxgb4_remove_server routines to create
and remove listening IPv6 servers.

Return success (0) from cxgb4_create_server in case of ctrl queue
congestion since in case of congestion, passive open request gets
queued and gets processed later.  If a non-zero value were returned it
would be treated as an error and the ULD would free STID, which can
result in an error in passive open reply.

Add cpl structure for active open request with IPv6 address for T5.
Signed-off-by: NVipul Pandya <vipul@chelsio.com>
Signed-off-by: NRoland Dreier <roland@purestorage.com>
上级 24d44a39
......@@ -3246,6 +3246,7 @@ int cxgb4_create_server(const struct net_device *dev, unsigned int stid,
struct sk_buff *skb;
struct adapter *adap;
struct cpl_pass_open_req *req;
int ret;
skb = alloc_skb(sizeof(*req), GFP_KERNEL);
if (!skb)
......@@ -3263,10 +3264,78 @@ int cxgb4_create_server(const struct net_device *dev, unsigned int stid,
req->opt0 = cpu_to_be64(TX_CHAN(chan));
req->opt1 = cpu_to_be64(CONN_POLICY_ASK |
SYN_RSS_ENABLE | SYN_RSS_QUEUE(queue));
return t4_mgmt_tx(adap, skb);
ret = t4_mgmt_tx(adap, skb);
return net_xmit_eval(ret);
}
EXPORT_SYMBOL(cxgb4_create_server);
/* cxgb4_create_server6 - create an IPv6 server
* @dev: the device
* @stid: the server TID
* @sip: local IPv6 address to bind server to
* @sport: the server's TCP port
* @queue: queue to direct messages from this server to
*
* Create an IPv6 server for the given port and address.
* Returns <0 on error and one of the %NET_XMIT_* values on success.
*/
int cxgb4_create_server6(const struct net_device *dev, unsigned int stid,
const struct in6_addr *sip, __be16 sport,
unsigned int queue)
{
unsigned int chan;
struct sk_buff *skb;
struct adapter *adap;
struct cpl_pass_open_req6 *req;
int ret;
skb = alloc_skb(sizeof(*req), GFP_KERNEL);
if (!skb)
return -ENOMEM;
adap = netdev2adap(dev);
req = (struct cpl_pass_open_req6 *)__skb_put(skb, sizeof(*req));
INIT_TP_WR(req, 0);
OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_PASS_OPEN_REQ6, stid));
req->local_port = sport;
req->peer_port = htons(0);
req->local_ip_hi = *(__be64 *)(sip->s6_addr);
req->local_ip_lo = *(__be64 *)(sip->s6_addr + 8);
req->peer_ip_hi = cpu_to_be64(0);
req->peer_ip_lo = cpu_to_be64(0);
chan = rxq_to_chan(&adap->sge, queue);
req->opt0 = cpu_to_be64(TX_CHAN(chan));
req->opt1 = cpu_to_be64(CONN_POLICY_ASK |
SYN_RSS_ENABLE | SYN_RSS_QUEUE(queue));
ret = t4_mgmt_tx(adap, skb);
return net_xmit_eval(ret);
}
EXPORT_SYMBOL(cxgb4_create_server6);
int cxgb4_remove_server(const struct net_device *dev, unsigned int stid,
unsigned int queue, bool ipv6)
{
struct sk_buff *skb;
struct adapter *adap;
struct cpl_close_listsvr_req *req;
int ret;
adap = netdev2adap(dev);
skb = alloc_skb(sizeof(*req), GFP_KERNEL);
if (!skb)
return -ENOMEM;
req = (struct cpl_close_listsvr_req *)__skb_put(skb, sizeof(*req));
INIT_TP_WR(req, 0);
OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_CLOSE_LISTSRV_REQ, stid));
req->reply_ctrl = htons(NO_REPLY(0) | (ipv6 ? LISTSVR_IPV6(1) :
LISTSVR_IPV6(0)) | QUEUENO(queue));
ret = t4_mgmt_tx(adap, skb);
return net_xmit_eval(ret);
}
EXPORT_SYMBOL(cxgb4_remove_server);
/**
* cxgb4_best_mtu - find the entry in the MTU table closest to an MTU
* @mtus: the HW MTU table
......
......@@ -154,6 +154,11 @@ struct in6_addr;
int cxgb4_create_server(const struct net_device *dev, unsigned int stid,
__be32 sip, __be16 sport, __be16 vlan,
unsigned int queue);
int cxgb4_create_server6(const struct net_device *dev, unsigned int stid,
const struct in6_addr *sip, __be16 sport,
unsigned int queue);
int cxgb4_remove_server(const struct net_device *dev, unsigned int stid,
unsigned int queue, bool ipv6);
int cxgb4_create_server_filter(const struct net_device *dev, unsigned int stid,
__be32 sip, __be16 sport, __be16 vlan,
unsigned int queue,
......
......@@ -320,6 +320,21 @@ struct cpl_act_open_req6 {
__be32 opt2;
};
struct cpl_t5_act_open_req6 {
WR_HDR;
union opcode_tid ot;
__be16 local_port;
__be16 peer_port;
__be64 local_ip_hi;
__be64 local_ip_lo;
__be64 peer_ip_hi;
__be64 peer_ip_lo;
__be64 opt0;
__be32 rsvd;
__be32 opt2;
__be64 params;
};
struct cpl_act_open_rpl {
union opcode_tid ot;
__be32 atid_status;
......@@ -405,7 +420,7 @@ struct cpl_close_listsvr_req {
WR_HDR;
union opcode_tid ot;
__be16 reply_ctrl;
#define LISTSVR_IPV6 (1 << 14)
#define LISTSVR_IPV6(x) ((x) << 14)
__be16 rsvd;
};
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册