aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/chelsio/cxgb4
diff options
context:
space:
mode:
authorVipul Pandya <vipul@chelsio.com>2013-07-04 06:40:45 -0400
committerRoland Dreier <roland@purestorage.com>2013-08-12 15:33:36 -0400
commit80f40c1f7a722d754a73027931a80746420c7c89 (patch)
treec5683c85a5912a0bb5cdc678b28afc0c8acc0cb0 /drivers/net/ethernet/chelsio/cxgb4
parent24d44a391f1b5d56e9c7a4fc1edd085687864ff9 (diff)
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: Vipul Pandya <vipul@chelsio.com> Signed-off-by: Roland Dreier <roland@purestorage.com>
Diffstat (limited to 'drivers/net/ethernet/chelsio/cxgb4')
-rw-r--r--drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c71
-rw-r--r--drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.h5
-rw-r--r--drivers/net/ethernet/chelsio/cxgb4/t4_msg.h17
3 files changed, 91 insertions, 2 deletions
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
index 5a3256b083f2..d1d6ff722dc9 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
@@ -3246,6 +3246,7 @@ int cxgb4_create_server(const struct net_device *dev, unsigned int stid,
3246 struct sk_buff *skb; 3246 struct sk_buff *skb;
3247 struct adapter *adap; 3247 struct adapter *adap;
3248 struct cpl_pass_open_req *req; 3248 struct cpl_pass_open_req *req;
3249 int ret;
3249 3250
3250 skb = alloc_skb(sizeof(*req), GFP_KERNEL); 3251 skb = alloc_skb(sizeof(*req), GFP_KERNEL);
3251 if (!skb) 3252 if (!skb)
@@ -3263,10 +3264,78 @@ int cxgb4_create_server(const struct net_device *dev, unsigned int stid,
3263 req->opt0 = cpu_to_be64(TX_CHAN(chan)); 3264 req->opt0 = cpu_to_be64(TX_CHAN(chan));
3264 req->opt1 = cpu_to_be64(CONN_POLICY_ASK | 3265 req->opt1 = cpu_to_be64(CONN_POLICY_ASK |
3265 SYN_RSS_ENABLE | SYN_RSS_QUEUE(queue)); 3266 SYN_RSS_ENABLE | SYN_RSS_QUEUE(queue));
3266 return t4_mgmt_tx(adap, skb); 3267 ret = t4_mgmt_tx(adap, skb);
3268 return net_xmit_eval(ret);
3267} 3269}
3268EXPORT_SYMBOL(cxgb4_create_server); 3270EXPORT_SYMBOL(cxgb4_create_server);
3269 3271
3272/* cxgb4_create_server6 - create an IPv6 server
3273 * @dev: the device
3274 * @stid: the server TID
3275 * @sip: local IPv6 address to bind server to
3276 * @sport: the server's TCP port
3277 * @queue: queue to direct messages from this server to
3278 *
3279 * Create an IPv6 server for the given port and address.
3280 * Returns <0 on error and one of the %NET_XMIT_* values on success.
3281 */
3282int cxgb4_create_server6(const struct net_device *dev, unsigned int stid,
3283 const struct in6_addr *sip, __be16 sport,
3284 unsigned int queue)
3285{
3286 unsigned int chan;
3287 struct sk_buff *skb;
3288 struct adapter *adap;
3289 struct cpl_pass_open_req6 *req;
3290 int ret;
3291
3292 skb = alloc_skb(sizeof(*req), GFP_KERNEL);
3293 if (!skb)
3294 return -ENOMEM;
3295
3296 adap = netdev2adap(dev);
3297 req = (struct cpl_pass_open_req6 *)__skb_put(skb, sizeof(*req));
3298 INIT_TP_WR(req, 0);
3299 OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_PASS_OPEN_REQ6, stid));
3300 req->local_port = sport;
3301 req->peer_port = htons(0);
3302 req->local_ip_hi = *(__be64 *)(sip->s6_addr);
3303 req->local_ip_lo = *(__be64 *)(sip->s6_addr + 8);
3304 req->peer_ip_hi = cpu_to_be64(0);
3305 req->peer_ip_lo = cpu_to_be64(0);
3306 chan = rxq_to_chan(&adap->sge, queue);
3307 req->opt0 = cpu_to_be64(TX_CHAN(chan));
3308 req->opt1 = cpu_to_be64(CONN_POLICY_ASK |
3309 SYN_RSS_ENABLE | SYN_RSS_QUEUE(queue));
3310 ret = t4_mgmt_tx(adap, skb);
3311 return net_xmit_eval(ret);
3312}
3313EXPORT_SYMBOL(cxgb4_create_server6);
3314
3315int cxgb4_remove_server(const struct net_device *dev, unsigned int stid,
3316 unsigned int queue, bool ipv6)
3317{
3318 struct sk_buff *skb;
3319 struct adapter *adap;
3320 struct cpl_close_listsvr_req *req;
3321 int ret;
3322
3323 adap = netdev2adap(dev);
3324
3325 skb = alloc_skb(sizeof(*req), GFP_KERNEL);
3326 if (!skb)
3327 return -ENOMEM;
3328
3329 req = (struct cpl_close_listsvr_req *)__skb_put(skb, sizeof(*req));
3330 INIT_TP_WR(req, 0);
3331 OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_CLOSE_LISTSRV_REQ, stid));
3332 req->reply_ctrl = htons(NO_REPLY(0) | (ipv6 ? LISTSVR_IPV6(1) :
3333 LISTSVR_IPV6(0)) | QUEUENO(queue));
3334 ret = t4_mgmt_tx(adap, skb);
3335 return net_xmit_eval(ret);
3336}
3337EXPORT_SYMBOL(cxgb4_remove_server);
3338
3270/** 3339/**
3271 * cxgb4_best_mtu - find the entry in the MTU table closest to an MTU 3340 * cxgb4_best_mtu - find the entry in the MTU table closest to an MTU
3272 * @mtus: the HW MTU table 3341 * @mtus: the HW MTU table
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.h b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.h
index 4faf4d067ee7..6f21f2451c30 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.h
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.h
@@ -154,6 +154,11 @@ struct in6_addr;
154int cxgb4_create_server(const struct net_device *dev, unsigned int stid, 154int cxgb4_create_server(const struct net_device *dev, unsigned int stid,
155 __be32 sip, __be16 sport, __be16 vlan, 155 __be32 sip, __be16 sport, __be16 vlan,
156 unsigned int queue); 156 unsigned int queue);
157int cxgb4_create_server6(const struct net_device *dev, unsigned int stid,
158 const struct in6_addr *sip, __be16 sport,
159 unsigned int queue);
160int cxgb4_remove_server(const struct net_device *dev, unsigned int stid,
161 unsigned int queue, bool ipv6);
157int cxgb4_create_server_filter(const struct net_device *dev, unsigned int stid, 162int cxgb4_create_server_filter(const struct net_device *dev, unsigned int stid,
158 __be32 sip, __be16 sport, __be16 vlan, 163 __be32 sip, __be16 sport, __be16 vlan,
159 unsigned int queue, 164 unsigned int queue,
diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_msg.h b/drivers/net/ethernet/chelsio/cxgb4/t4_msg.h
index 01d484441200..cd6874b571ee 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/t4_msg.h
+++ b/drivers/net/ethernet/chelsio/cxgb4/t4_msg.h
@@ -320,6 +320,21 @@ struct cpl_act_open_req6 {
320 __be32 opt2; 320 __be32 opt2;
321}; 321};
322 322
323struct cpl_t5_act_open_req6 {
324 WR_HDR;
325 union opcode_tid ot;
326 __be16 local_port;
327 __be16 peer_port;
328 __be64 local_ip_hi;
329 __be64 local_ip_lo;
330 __be64 peer_ip_hi;
331 __be64 peer_ip_lo;
332 __be64 opt0;
333 __be32 rsvd;
334 __be32 opt2;
335 __be64 params;
336};
337
323struct cpl_act_open_rpl { 338struct cpl_act_open_rpl {
324 union opcode_tid ot; 339 union opcode_tid ot;
325 __be32 atid_status; 340 __be32 atid_status;
@@ -405,7 +420,7 @@ struct cpl_close_listsvr_req {
405 WR_HDR; 420 WR_HDR;
406 union opcode_tid ot; 421 union opcode_tid ot;
407 __be16 reply_ctrl; 422 __be16 reply_ctrl;
408#define LISTSVR_IPV6 (1 << 14) 423#define LISTSVR_IPV6(x) ((x) << 14)
409 __be16 rsvd; 424 __be16 rsvd;
410}; 425};
411 426