diff options
Diffstat (limited to 'drivers/scsi/cxgbi')
-rw-r--r-- | drivers/scsi/cxgbi/cxgb4i/cxgb4i.c | 363 | ||||
-rw-r--r-- | drivers/scsi/cxgbi/libcxgbi.c | 241 | ||||
-rw-r--r-- | drivers/scsi/cxgbi/libcxgbi.h | 21 |
3 files changed, 563 insertions, 62 deletions
diff --git a/drivers/scsi/cxgbi/cxgb4i/cxgb4i.c b/drivers/scsi/cxgbi/cxgb4i/cxgb4i.c index e8ee5e5fe0ef..79788a12712d 100644 --- a/drivers/scsi/cxgbi/cxgb4i/cxgb4i.c +++ b/drivers/scsi/cxgbi/cxgb4i/cxgb4i.c | |||
@@ -19,6 +19,7 @@ | |||
19 | #include <net/tcp.h> | 19 | #include <net/tcp.h> |
20 | #include <net/dst.h> | 20 | #include <net/dst.h> |
21 | #include <linux/netdevice.h> | 21 | #include <linux/netdevice.h> |
22 | #include <net/addrconf.h> | ||
22 | 23 | ||
23 | #include "t4_regs.h" | 24 | #include "t4_regs.h" |
24 | #include "t4_msg.h" | 25 | #include "t4_msg.h" |
@@ -150,6 +151,7 @@ static struct scsi_transport_template *cxgb4i_stt; | |||
150 | * The section below implments CPLs that related to iscsi tcp connection | 151 | * The section below implments CPLs that related to iscsi tcp connection |
151 | * open/close/abort and data send/receive. | 152 | * open/close/abort and data send/receive. |
152 | */ | 153 | */ |
154 | |||
153 | #define DIV_ROUND_UP(n, d) (((n) + (d) - 1) / (d)) | 155 | #define DIV_ROUND_UP(n, d) (((n) + (d) - 1) / (d)) |
154 | #define RCV_BUFSIZ_MASK 0x3FFU | 156 | #define RCV_BUFSIZ_MASK 0x3FFU |
155 | #define MAX_IMM_TX_PKT_LEN 128 | 157 | #define MAX_IMM_TX_PKT_LEN 128 |
@@ -179,6 +181,7 @@ static void send_act_open_req(struct cxgbi_sock *csk, struct sk_buff *skb, | |||
179 | struct l2t_entry *e) | 181 | struct l2t_entry *e) |
180 | { | 182 | { |
181 | struct cxgb4_lld_info *lldi = cxgbi_cdev_priv(csk->cdev); | 183 | struct cxgb4_lld_info *lldi = cxgbi_cdev_priv(csk->cdev); |
184 | int t4 = is_t4(lldi->adapter_type); | ||
182 | int wscale = cxgbi_sock_compute_wscale(csk->mss_idx); | 185 | int wscale = cxgbi_sock_compute_wscale(csk->mss_idx); |
183 | unsigned long long opt0; | 186 | unsigned long long opt0; |
184 | unsigned int opt2; | 187 | unsigned int opt2; |
@@ -248,6 +251,97 @@ static void send_act_open_req(struct cxgbi_sock *csk, struct sk_buff *skb, | |||
248 | } | 251 | } |
249 | 252 | ||
250 | set_wr_txq(skb, CPL_PRIORITY_SETUP, csk->port_id); | 253 | set_wr_txq(skb, CPL_PRIORITY_SETUP, csk->port_id); |
254 | |||
255 | pr_info_ipaddr("t%d csk 0x%p,%u,0x%lx,%u, rss_qid %u.\n", | ||
256 | (&csk->saddr), (&csk->daddr), t4 ? 4 : 5, csk, | ||
257 | csk->state, csk->flags, csk->atid, csk->rss_qid); | ||
258 | |||
259 | cxgb4_l2t_send(csk->cdev->ports[csk->port_id], skb, csk->l2t); | ||
260 | } | ||
261 | |||
262 | static void send_act_open_req6(struct cxgbi_sock *csk, struct sk_buff *skb, | ||
263 | struct l2t_entry *e) | ||
264 | { | ||
265 | struct cxgb4_lld_info *lldi = cxgbi_cdev_priv(csk->cdev); | ||
266 | int t4 = is_t4(lldi->adapter_type); | ||
267 | int wscale = cxgbi_sock_compute_wscale(csk->mss_idx); | ||
268 | unsigned long long opt0; | ||
269 | unsigned int opt2; | ||
270 | unsigned int qid_atid = ((unsigned int)csk->atid) | | ||
271 | (((unsigned int)csk->rss_qid) << 14); | ||
272 | |||
273 | opt0 = KEEP_ALIVE(1) | | ||
274 | WND_SCALE(wscale) | | ||
275 | MSS_IDX(csk->mss_idx) | | ||
276 | L2T_IDX(((struct l2t_entry *)csk->l2t)->idx) | | ||
277 | TX_CHAN(csk->tx_chan) | | ||
278 | SMAC_SEL(csk->smac_idx) | | ||
279 | ULP_MODE(ULP_MODE_ISCSI) | | ||
280 | RCV_BUFSIZ(cxgb4i_rcv_win >> 10); | ||
281 | |||
282 | opt2 = RX_CHANNEL(0) | | ||
283 | RSS_QUEUE_VALID | | ||
284 | RX_FC_DISABLE | | ||
285 | RSS_QUEUE(csk->rss_qid); | ||
286 | |||
287 | if (t4) { | ||
288 | struct cpl_act_open_req6 *req = | ||
289 | (struct cpl_act_open_req6 *)skb->head; | ||
290 | |||
291 | INIT_TP_WR(req, 0); | ||
292 | OPCODE_TID(req) = cpu_to_be32(MK_OPCODE_TID(CPL_ACT_OPEN_REQ6, | ||
293 | qid_atid)); | ||
294 | req->local_port = csk->saddr6.sin6_port; | ||
295 | req->peer_port = csk->daddr6.sin6_port; | ||
296 | |||
297 | req->local_ip_hi = *(__be64 *)(csk->saddr6.sin6_addr.s6_addr); | ||
298 | req->local_ip_lo = *(__be64 *)(csk->saddr6.sin6_addr.s6_addr + | ||
299 | 8); | ||
300 | req->peer_ip_hi = *(__be64 *)(csk->daddr6.sin6_addr.s6_addr); | ||
301 | req->peer_ip_lo = *(__be64 *)(csk->daddr6.sin6_addr.s6_addr + | ||
302 | 8); | ||
303 | |||
304 | req->opt0 = cpu_to_be64(opt0); | ||
305 | |||
306 | opt2 |= RX_FC_VALID; | ||
307 | req->opt2 = cpu_to_be32(opt2); | ||
308 | |||
309 | req->params = cpu_to_be32(cxgb4_select_ntuple( | ||
310 | csk->cdev->ports[csk->port_id], | ||
311 | csk->l2t)); | ||
312 | } else { | ||
313 | struct cpl_t5_act_open_req6 *req = | ||
314 | (struct cpl_t5_act_open_req6 *)skb->head; | ||
315 | |||
316 | INIT_TP_WR(req, 0); | ||
317 | OPCODE_TID(req) = cpu_to_be32(MK_OPCODE_TID(CPL_ACT_OPEN_REQ6, | ||
318 | qid_atid)); | ||
319 | req->local_port = csk->saddr6.sin6_port; | ||
320 | req->peer_port = csk->daddr6.sin6_port; | ||
321 | req->local_ip_hi = *(__be64 *)(csk->saddr6.sin6_addr.s6_addr); | ||
322 | req->local_ip_lo = *(__be64 *)(csk->saddr6.sin6_addr.s6_addr + | ||
323 | 8); | ||
324 | req->peer_ip_hi = *(__be64 *)(csk->daddr6.sin6_addr.s6_addr); | ||
325 | req->peer_ip_lo = *(__be64 *)(csk->daddr6.sin6_addr.s6_addr + | ||
326 | 8); | ||
327 | req->opt0 = cpu_to_be64(opt0); | ||
328 | |||
329 | opt2 |= T5_OPT_2_VALID; | ||
330 | req->opt2 = cpu_to_be32(opt2); | ||
331 | |||
332 | req->params = cpu_to_be64(V_FILTER_TUPLE(cxgb4_select_ntuple( | ||
333 | csk->cdev->ports[csk->port_id], | ||
334 | csk->l2t))); | ||
335 | } | ||
336 | |||
337 | set_wr_txq(skb, CPL_PRIORITY_SETUP, csk->port_id); | ||
338 | |||
339 | pr_info("t%d csk 0x%p,%u,0x%lx,%u, [%pI6]:%u-[%pI6]:%u, rss_qid %u.\n", | ||
340 | t4 ? 4 : 5, csk, csk->state, csk->flags, csk->atid, | ||
341 | &csk->saddr6.sin6_addr, ntohs(csk->saddr.sin_port), | ||
342 | &csk->daddr6.sin6_addr, ntohs(csk->daddr.sin_port), | ||
343 | csk->rss_qid); | ||
344 | |||
251 | cxgb4_l2t_send(csk->cdev->ports[csk->port_id], skb, csk->l2t); | 345 | cxgb4_l2t_send(csk->cdev->ports[csk->port_id], skb, csk->l2t); |
252 | } | 346 | } |
253 | 347 | ||
@@ -586,9 +680,11 @@ static void do_act_establish(struct cxgbi_device *cdev, struct sk_buff *skb) | |||
586 | goto rel_skb; | 680 | goto rel_skb; |
587 | } | 681 | } |
588 | 682 | ||
589 | log_debug(1 << CXGBI_DBG_TOE | 1 << CXGBI_DBG_SOCK, | 683 | pr_info_ipaddr("atid 0x%x, tid 0x%x, csk 0x%p,%u,0x%lx, isn %u.\n", |
590 | "csk 0x%p,%u,0x%lx, tid %u, atid %u, rseq %u.\n", | 684 | (&csk->saddr), (&csk->daddr), |
591 | csk, csk->state, csk->flags, tid, atid, rcv_isn); | 685 | atid, tid, csk, csk->state, csk->flags, rcv_isn); |
686 | |||
687 | module_put(THIS_MODULE); | ||
592 | 688 | ||
593 | cxgbi_sock_get(csk); | 689 | cxgbi_sock_get(csk); |
594 | csk->tid = tid; | 690 | csk->tid = tid; |
@@ -663,6 +759,9 @@ static void csk_act_open_retry_timer(unsigned long data) | |||
663 | struct sk_buff *skb; | 759 | struct sk_buff *skb; |
664 | struct cxgbi_sock *csk = (struct cxgbi_sock *)data; | 760 | struct cxgbi_sock *csk = (struct cxgbi_sock *)data; |
665 | struct cxgb4_lld_info *lldi = cxgbi_cdev_priv(csk->cdev); | 761 | struct cxgb4_lld_info *lldi = cxgbi_cdev_priv(csk->cdev); |
762 | void (*send_act_open_func)(struct cxgbi_sock *, struct sk_buff *, | ||
763 | struct l2t_entry *); | ||
764 | int t4 = is_t4(lldi->adapter_type), size, size6; | ||
666 | 765 | ||
667 | log_debug(1 << CXGBI_DBG_TOE | 1 << CXGBI_DBG_SOCK, | 766 | log_debug(1 << CXGBI_DBG_TOE | 1 << CXGBI_DBG_SOCK, |
668 | "csk 0x%p,%u,0x%lx,%u.\n", | 767 | "csk 0x%p,%u,0x%lx,%u.\n", |
@@ -670,20 +769,35 @@ static void csk_act_open_retry_timer(unsigned long data) | |||
670 | 769 | ||
671 | cxgbi_sock_get(csk); | 770 | cxgbi_sock_get(csk); |
672 | spin_lock_bh(&csk->lock); | 771 | spin_lock_bh(&csk->lock); |
673 | skb = alloc_wr(is_t4(lldi->adapter_type) ? | 772 | |
674 | sizeof(struct cpl_act_open_req) : | 773 | if (t4) { |
675 | sizeof(struct cpl_t5_act_open_req), | 774 | size = sizeof(struct cpl_act_open_req); |
676 | 0, GFP_ATOMIC); | 775 | size6 = sizeof(struct cpl_act_open_req6); |
776 | } else { | ||
777 | size = sizeof(struct cpl_t5_act_open_req); | ||
778 | size6 = sizeof(struct cpl_t5_act_open_req6); | ||
779 | } | ||
780 | |||
781 | if (csk->csk_family == AF_INET) { | ||
782 | send_act_open_func = send_act_open_req; | ||
783 | skb = alloc_wr(size, 0, GFP_ATOMIC); | ||
784 | } else { | ||
785 | send_act_open_func = send_act_open_req6; | ||
786 | skb = alloc_wr(size6, 0, GFP_ATOMIC); | ||
787 | } | ||
788 | |||
677 | if (!skb) | 789 | if (!skb) |
678 | cxgbi_sock_fail_act_open(csk, -ENOMEM); | 790 | cxgbi_sock_fail_act_open(csk, -ENOMEM); |
679 | else { | 791 | else { |
680 | skb->sk = (struct sock *)csk; | 792 | skb->sk = (struct sock *)csk; |
681 | t4_set_arp_err_handler(skb, csk, | 793 | t4_set_arp_err_handler(skb, csk, |
682 | cxgbi_sock_act_open_req_arp_failure); | 794 | cxgbi_sock_act_open_req_arp_failure); |
683 | send_act_open_req(csk, skb, csk->l2t); | 795 | send_act_open_func(csk, skb, csk->l2t); |
684 | } | 796 | } |
797 | |||
685 | spin_unlock_bh(&csk->lock); | 798 | spin_unlock_bh(&csk->lock); |
686 | cxgbi_sock_put(csk); | 799 | cxgbi_sock_put(csk); |
800 | |||
687 | } | 801 | } |
688 | 802 | ||
689 | static void do_act_open_rpl(struct cxgbi_device *cdev, struct sk_buff *skb) | 803 | static void do_act_open_rpl(struct cxgbi_device *cdev, struct sk_buff *skb) |
@@ -703,10 +817,9 @@ static void do_act_open_rpl(struct cxgbi_device *cdev, struct sk_buff *skb) | |||
703 | goto rel_skb; | 817 | goto rel_skb; |
704 | } | 818 | } |
705 | 819 | ||
706 | pr_info("%pI4:%u-%pI4:%u, atid %u,%u, status %u, csk 0x%p,%u,0x%lx.\n", | 820 | pr_info_ipaddr("tid %u/%u, status %u.\n" |
707 | &csk->saddr.sin_addr.s_addr, ntohs(csk->saddr.sin_port), | 821 | "csk 0x%p,%u,0x%lx. ", (&csk->saddr), (&csk->daddr), |
708 | &csk->daddr.sin_addr.s_addr, ntohs(csk->daddr.sin_port), | 822 | atid, tid, status, csk, csk->state, csk->flags); |
709 | atid, tid, status, csk, csk->state, csk->flags); | ||
710 | 823 | ||
711 | if (status == CPL_ERR_RTX_NEG_ADVICE) | 824 | if (status == CPL_ERR_RTX_NEG_ADVICE) |
712 | goto rel_skb; | 825 | goto rel_skb; |
@@ -746,9 +859,9 @@ static void do_peer_close(struct cxgbi_device *cdev, struct sk_buff *skb) | |||
746 | pr_err("can't find connection for tid %u.\n", tid); | 859 | pr_err("can't find connection for tid %u.\n", tid); |
747 | goto rel_skb; | 860 | goto rel_skb; |
748 | } | 861 | } |
749 | log_debug(1 << CXGBI_DBG_TOE | 1 << CXGBI_DBG_SOCK, | 862 | pr_info_ipaddr("csk 0x%p,%u,0x%lx,%u.\n", |
750 | "csk 0x%p,%u,0x%lx,%u.\n", | 863 | (&csk->saddr), (&csk->daddr), |
751 | csk, csk->state, csk->flags, csk->tid); | 864 | csk, csk->state, csk->flags, csk->tid); |
752 | cxgbi_sock_rcv_peer_close(csk); | 865 | cxgbi_sock_rcv_peer_close(csk); |
753 | rel_skb: | 866 | rel_skb: |
754 | __kfree_skb(skb); | 867 | __kfree_skb(skb); |
@@ -767,9 +880,9 @@ static void do_close_con_rpl(struct cxgbi_device *cdev, struct sk_buff *skb) | |||
767 | pr_err("can't find connection for tid %u.\n", tid); | 880 | pr_err("can't find connection for tid %u.\n", tid); |
768 | goto rel_skb; | 881 | goto rel_skb; |
769 | } | 882 | } |
770 | log_debug(1 << CXGBI_DBG_TOE | 1 << CXGBI_DBG_SOCK, | 883 | pr_info_ipaddr("csk 0x%p,%u,0x%lx,%u.\n", |
771 | "csk 0x%p,%u,0x%lx,%u.\n", | 884 | (&csk->saddr), (&csk->daddr), |
772 | csk, csk->state, csk->flags, csk->tid); | 885 | csk, csk->state, csk->flags, csk->tid); |
773 | cxgbi_sock_rcv_close_conn_rpl(csk, ntohl(rpl->snd_nxt)); | 886 | cxgbi_sock_rcv_close_conn_rpl(csk, ntohl(rpl->snd_nxt)); |
774 | rel_skb: | 887 | rel_skb: |
775 | __kfree_skb(skb); | 888 | __kfree_skb(skb); |
@@ -808,9 +921,9 @@ static void do_abort_req_rss(struct cxgbi_device *cdev, struct sk_buff *skb) | |||
808 | goto rel_skb; | 921 | goto rel_skb; |
809 | } | 922 | } |
810 | 923 | ||
811 | log_debug(1 << CXGBI_DBG_TOE | 1 << CXGBI_DBG_SOCK, | 924 | pr_info_ipaddr("csk 0x%p,%u,0x%lx,%u, status %u.\n", |
812 | "csk 0x%p,%u,0x%lx, tid %u, status 0x%x.\n", | 925 | (&csk->saddr), (&csk->daddr), |
813 | csk, csk->state, csk->flags, csk->tid, req->status); | 926 | csk, csk->state, csk->flags, csk->tid, req->status); |
814 | 927 | ||
815 | if (req->status == CPL_ERR_RTX_NEG_ADVICE || | 928 | if (req->status == CPL_ERR_RTX_NEG_ADVICE || |
816 | req->status == CPL_ERR_PERSIST_NEG_ADVICE) | 929 | req->status == CPL_ERR_PERSIST_NEG_ADVICE) |
@@ -851,10 +964,10 @@ static void do_abort_rpl_rss(struct cxgbi_device *cdev, struct sk_buff *skb) | |||
851 | if (!csk) | 964 | if (!csk) |
852 | goto rel_skb; | 965 | goto rel_skb; |
853 | 966 | ||
854 | log_debug(1 << CXGBI_DBG_TOE | 1 << CXGBI_DBG_SOCK, | 967 | if (csk) |
855 | "status 0x%x, csk 0x%p, s %u, 0x%lx.\n", | 968 | pr_info_ipaddr("csk 0x%p,%u,0x%lx,%u, status %u.\n", |
856 | rpl->status, csk, csk ? csk->state : 0, | 969 | (&csk->saddr), (&csk->daddr), csk, |
857 | csk ? csk->flags : 0UL); | 970 | csk->state, csk->flags, csk->tid, rpl->status); |
858 | 971 | ||
859 | if (rpl->status == CPL_ERR_ABORT_FAILED) | 972 | if (rpl->status == CPL_ERR_ABORT_FAILED) |
860 | goto rel_skb; | 973 | goto rel_skb; |
@@ -1163,15 +1276,35 @@ static int init_act_open(struct cxgbi_sock *csk) | |||
1163 | struct cxgbi_device *cdev = csk->cdev; | 1276 | struct cxgbi_device *cdev = csk->cdev; |
1164 | struct cxgb4_lld_info *lldi = cxgbi_cdev_priv(cdev); | 1277 | struct cxgb4_lld_info *lldi = cxgbi_cdev_priv(cdev); |
1165 | struct net_device *ndev = cdev->ports[csk->port_id]; | 1278 | struct net_device *ndev = cdev->ports[csk->port_id]; |
1166 | struct port_info *pi = netdev_priv(ndev); | ||
1167 | struct sk_buff *skb = NULL; | 1279 | struct sk_buff *skb = NULL; |
1168 | struct neighbour *n; | 1280 | struct neighbour *n = NULL; |
1281 | void *daddr; | ||
1169 | unsigned int step; | 1282 | unsigned int step; |
1283 | unsigned int size, size6; | ||
1284 | int t4 = is_t4(lldi->adapter_type); | ||
1170 | 1285 | ||
1171 | log_debug(1 << CXGBI_DBG_TOE | 1 << CXGBI_DBG_SOCK, | 1286 | log_debug(1 << CXGBI_DBG_TOE | 1 << CXGBI_DBG_SOCK, |
1172 | "csk 0x%p,%u,0x%lx,%u.\n", | 1287 | "csk 0x%p,%u,0x%lx,%u.\n", |
1173 | csk, csk->state, csk->flags, csk->tid); | 1288 | csk, csk->state, csk->flags, csk->tid); |
1174 | 1289 | ||
1290 | if (csk->csk_family == AF_INET) | ||
1291 | daddr = &csk->daddr.sin_addr.s_addr; | ||
1292 | #if IS_ENABLED(CONFIG_IPV6) | ||
1293 | else if (csk->csk_family == AF_INET6) | ||
1294 | daddr = &csk->daddr6.sin6_addr; | ||
1295 | #endif | ||
1296 | else { | ||
1297 | pr_err("address family 0x%x not supported\n", csk->csk_family); | ||
1298 | goto rel_resource; | ||
1299 | } | ||
1300 | |||
1301 | n = dst_neigh_lookup(csk->dst, daddr); | ||
1302 | |||
1303 | if (!n) { | ||
1304 | pr_err("%s, can't get neighbour of csk->dst.\n", ndev->name); | ||
1305 | goto rel_resource; | ||
1306 | } | ||
1307 | |||
1175 | csk->atid = cxgb4_alloc_atid(lldi->tids, csk); | 1308 | csk->atid = cxgb4_alloc_atid(lldi->tids, csk); |
1176 | if (csk->atid < 0) { | 1309 | if (csk->atid < 0) { |
1177 | pr_err("%s, NO atid available.\n", ndev->name); | 1310 | pr_err("%s, NO atid available.\n", ndev->name); |
@@ -1192,10 +1325,19 @@ static int init_act_open(struct cxgbi_sock *csk) | |||
1192 | } | 1325 | } |
1193 | cxgbi_sock_get(csk); | 1326 | cxgbi_sock_get(csk); |
1194 | 1327 | ||
1195 | skb = alloc_wr(is_t4(lldi->adapter_type) ? | 1328 | if (t4) { |
1196 | sizeof(struct cpl_act_open_req) : | 1329 | size = sizeof(struct cpl_act_open_req); |
1197 | sizeof(struct cpl_t5_act_open_req), | 1330 | size6 = sizeof(struct cpl_act_open_req6); |
1198 | 0, GFP_ATOMIC); | 1331 | } else { |
1332 | size = sizeof(struct cpl_t5_act_open_req); | ||
1333 | size6 = sizeof(struct cpl_t5_act_open_req6); | ||
1334 | } | ||
1335 | |||
1336 | if (csk->csk_family == AF_INET) | ||
1337 | skb = alloc_wr(size, 0, GFP_NOIO); | ||
1338 | else | ||
1339 | skb = alloc_wr(size6, 0, GFP_NOIO); | ||
1340 | |||
1199 | if (!skb) | 1341 | if (!skb) |
1200 | goto rel_resource; | 1342 | goto rel_resource; |
1201 | skb->sk = (struct sock *)csk; | 1343 | skb->sk = (struct sock *)csk; |
@@ -1211,19 +1353,27 @@ static int init_act_open(struct cxgbi_sock *csk) | |||
1211 | csk->txq_idx = cxgb4_port_idx(ndev) * step; | 1353 | csk->txq_idx = cxgb4_port_idx(ndev) * step; |
1212 | step = lldi->nrxq / lldi->nchan; | 1354 | step = lldi->nrxq / lldi->nchan; |
1213 | csk->rss_qid = lldi->rxq_ids[cxgb4_port_idx(ndev) * step]; | 1355 | csk->rss_qid = lldi->rxq_ids[cxgb4_port_idx(ndev) * step]; |
1214 | csk->wr_max_cred = csk->wr_cred = lldi->wr_cred; | 1356 | csk->wr_cred = lldi->wr_cred - |
1357 | DIV_ROUND_UP(sizeof(struct cpl_abort_req), 16); | ||
1358 | csk->wr_max_cred = csk->wr_cred; | ||
1215 | csk->wr_una_cred = 0; | 1359 | csk->wr_una_cred = 0; |
1216 | cxgbi_sock_reset_wr_list(csk); | 1360 | cxgbi_sock_reset_wr_list(csk); |
1217 | csk->err = 0; | 1361 | csk->err = 0; |
1218 | log_debug(1 << CXGBI_DBG_TOE | 1 << CXGBI_DBG_SOCK, | ||
1219 | "csk 0x%p,p%d,%s, %u,%u,%u, mss %u,%u, smac %u.\n", | ||
1220 | csk, pi->port_id, ndev->name, csk->tx_chan, | ||
1221 | csk->txq_idx, csk->rss_qid, csk->mtu, csk->mss_idx, | ||
1222 | csk->smac_idx); | ||
1223 | 1362 | ||
1363 | pr_info_ipaddr("csk 0x%p,%u,0x%lx,%u,%u,%u, mtu %u,%u, smac %u.\n", | ||
1364 | (&csk->saddr), (&csk->daddr), csk, csk->state, | ||
1365 | csk->flags, csk->tx_chan, csk->txq_idx, csk->rss_qid, | ||
1366 | csk->mtu, csk->mss_idx, csk->smac_idx); | ||
1367 | |||
1368 | /* must wait for either a act_open_rpl or act_open_establish */ | ||
1369 | try_module_get(THIS_MODULE); | ||
1224 | cxgbi_sock_set_state(csk, CTP_ACTIVE_OPEN); | 1370 | cxgbi_sock_set_state(csk, CTP_ACTIVE_OPEN); |
1225 | send_act_open_req(csk, skb, csk->l2t); | 1371 | if (csk->csk_family == AF_INET) |
1372 | send_act_open_req(csk, skb, csk->l2t); | ||
1373 | else | ||
1374 | send_act_open_req6(csk, skb, csk->l2t); | ||
1226 | neigh_release(n); | 1375 | neigh_release(n); |
1376 | |||
1227 | return 0; | 1377 | return 0; |
1228 | 1378 | ||
1229 | rel_resource: | 1379 | rel_resource: |
@@ -1234,8 +1384,6 @@ rel_resource: | |||
1234 | return -EINVAL; | 1384 | return -EINVAL; |
1235 | } | 1385 | } |
1236 | 1386 | ||
1237 | #define CPL_ISCSI_DATA 0xB2 | ||
1238 | #define CPL_RX_ISCSI_DDP 0x49 | ||
1239 | cxgb4i_cplhandler_func cxgb4i_cplhandlers[NUM_CPL_CMDS] = { | 1387 | cxgb4i_cplhandler_func cxgb4i_cplhandlers[NUM_CPL_CMDS] = { |
1240 | [CPL_ACT_ESTABLISH] = do_act_establish, | 1388 | [CPL_ACT_ESTABLISH] = do_act_establish, |
1241 | [CPL_ACT_OPEN_RPL] = do_act_open_rpl, | 1389 | [CPL_ACT_OPEN_RPL] = do_act_open_rpl, |
@@ -1487,6 +1635,129 @@ static int cxgb4i_ddp_init(struct cxgbi_device *cdev) | |||
1487 | return 0; | 1635 | return 0; |
1488 | } | 1636 | } |
1489 | 1637 | ||
1638 | #if IS_ENABLED(CONFIG_IPV6) | ||
1639 | static int cxgbi_inet6addr_handler(struct notifier_block *this, | ||
1640 | unsigned long event, void *data) | ||
1641 | { | ||
1642 | struct inet6_ifaddr *ifa = data; | ||
1643 | struct net_device *event_dev = ifa->idev->dev; | ||
1644 | struct cxgbi_device *cdev; | ||
1645 | int ret = NOTIFY_DONE; | ||
1646 | |||
1647 | if (event_dev->priv_flags & IFF_802_1Q_VLAN) | ||
1648 | event_dev = vlan_dev_real_dev(event_dev); | ||
1649 | |||
1650 | cdev = cxgbi_device_find_by_netdev(event_dev, NULL); | ||
1651 | |||
1652 | if (!cdev) | ||
1653 | return ret; | ||
1654 | |||
1655 | switch (event) { | ||
1656 | case NETDEV_UP: | ||
1657 | ret = cxgb4_clip_get(event_dev, | ||
1658 | (const struct in6_addr *) | ||
1659 | ((ifa)->addr.s6_addr)); | ||
1660 | if (ret < 0) | ||
1661 | return ret; | ||
1662 | |||
1663 | ret = NOTIFY_OK; | ||
1664 | break; | ||
1665 | |||
1666 | case NETDEV_DOWN: | ||
1667 | cxgb4_clip_release(event_dev, | ||
1668 | (const struct in6_addr *) | ||
1669 | ((ifa)->addr.s6_addr)); | ||
1670 | ret = NOTIFY_OK; | ||
1671 | break; | ||
1672 | |||
1673 | default: | ||
1674 | break; | ||
1675 | } | ||
1676 | |||
1677 | return ret; | ||
1678 | } | ||
1679 | |||
1680 | static struct notifier_block cxgbi_inet6addr_notifier = { | ||
1681 | .notifier_call = cxgbi_inet6addr_handler | ||
1682 | }; | ||
1683 | |||
1684 | /* Retrieve IPv6 addresses from a root device (bond, vlan) associated with | ||
1685 | * a physical device. | ||
1686 | * The physical device reference is needed to send the actual CLIP command. | ||
1687 | */ | ||
1688 | static int update_dev_clip(struct net_device *root_dev, struct net_device *dev) | ||
1689 | { | ||
1690 | struct inet6_dev *idev = NULL; | ||
1691 | struct inet6_ifaddr *ifa; | ||
1692 | int ret = 0; | ||
1693 | |||
1694 | idev = __in6_dev_get(root_dev); | ||
1695 | if (!idev) | ||
1696 | return ret; | ||
1697 | |||
1698 | read_lock_bh(&idev->lock); | ||
1699 | list_for_each_entry(ifa, &idev->addr_list, if_list) { | ||
1700 | pr_info("updating the clip for addr %pI6\n", | ||
1701 | ifa->addr.s6_addr); | ||
1702 | ret = cxgb4_clip_get(dev, (const struct in6_addr *) | ||
1703 | ifa->addr.s6_addr); | ||
1704 | if (ret < 0) | ||
1705 | break; | ||
1706 | } | ||
1707 | |||
1708 | read_unlock_bh(&idev->lock); | ||
1709 | return ret; | ||
1710 | } | ||
1711 | |||
1712 | static int update_root_dev_clip(struct net_device *dev) | ||
1713 | { | ||
1714 | struct net_device *root_dev = NULL; | ||
1715 | int i, ret = 0; | ||
1716 | |||
1717 | /* First populate the real net device's IPv6 address */ | ||
1718 | ret = update_dev_clip(dev, dev); | ||
1719 | if (ret) | ||
1720 | return ret; | ||
1721 | |||
1722 | /* Parse all bond and vlan devices layered on top of the physical dev */ | ||
1723 | root_dev = netdev_master_upper_dev_get(dev); | ||
1724 | if (root_dev) { | ||
1725 | ret = update_dev_clip(root_dev, dev); | ||
1726 | if (ret) | ||
1727 | return ret; | ||
1728 | } | ||
1729 | |||
1730 | for (i = 0; i < VLAN_N_VID; i++) { | ||
1731 | root_dev = __vlan_find_dev_deep_rcu(dev, htons(ETH_P_8021Q), i); | ||
1732 | if (!root_dev) | ||
1733 | continue; | ||
1734 | |||
1735 | ret = update_dev_clip(root_dev, dev); | ||
1736 | if (ret) | ||
1737 | break; | ||
1738 | } | ||
1739 | return ret; | ||
1740 | } | ||
1741 | |||
1742 | static void cxgbi_update_clip(struct cxgbi_device *cdev) | ||
1743 | { | ||
1744 | int i; | ||
1745 | |||
1746 | rcu_read_lock(); | ||
1747 | |||
1748 | for (i = 0; i < cdev->nports; i++) { | ||
1749 | struct net_device *dev = cdev->ports[i]; | ||
1750 | int ret = 0; | ||
1751 | |||
1752 | if (dev) | ||
1753 | ret = update_root_dev_clip(dev); | ||
1754 | if (ret < 0) | ||
1755 | break; | ||
1756 | } | ||
1757 | rcu_read_unlock(); | ||
1758 | } | ||
1759 | #endif /* IS_ENABLED(CONFIG_IPV6) */ | ||
1760 | |||
1490 | static void *t4_uld_add(const struct cxgb4_lld_info *lldi) | 1761 | static void *t4_uld_add(const struct cxgb4_lld_info *lldi) |
1491 | { | 1762 | { |
1492 | struct cxgbi_device *cdev; | 1763 | struct cxgbi_device *cdev; |
@@ -1605,6 +1876,9 @@ static int t4_uld_state_change(void *handle, enum cxgb4_state state) | |||
1605 | switch (state) { | 1876 | switch (state) { |
1606 | case CXGB4_STATE_UP: | 1877 | case CXGB4_STATE_UP: |
1607 | pr_info("cdev 0x%p, UP.\n", cdev); | 1878 | pr_info("cdev 0x%p, UP.\n", cdev); |
1879 | #if IS_ENABLED(CONFIG_IPV6) | ||
1880 | cxgbi_update_clip(cdev); | ||
1881 | #endif | ||
1608 | /* re-initialize */ | 1882 | /* re-initialize */ |
1609 | break; | 1883 | break; |
1610 | case CXGB4_STATE_START_RECOVERY: | 1884 | case CXGB4_STATE_START_RECOVERY: |
@@ -1635,11 +1909,18 @@ static int __init cxgb4i_init_module(void) | |||
1635 | if (rc < 0) | 1909 | if (rc < 0) |
1636 | return rc; | 1910 | return rc; |
1637 | cxgb4_register_uld(CXGB4_ULD_ISCSI, &cxgb4i_uld_info); | 1911 | cxgb4_register_uld(CXGB4_ULD_ISCSI, &cxgb4i_uld_info); |
1912 | |||
1913 | #if IS_ENABLED(CONFIG_IPV6) | ||
1914 | register_inet6addr_notifier(&cxgbi_inet6addr_notifier); | ||
1915 | #endif | ||
1638 | return 0; | 1916 | return 0; |
1639 | } | 1917 | } |
1640 | 1918 | ||
1641 | static void __exit cxgb4i_exit_module(void) | 1919 | static void __exit cxgb4i_exit_module(void) |
1642 | { | 1920 | { |
1921 | #if IS_ENABLED(CONFIG_IPV6) | ||
1922 | unregister_inet6addr_notifier(&cxgbi_inet6addr_notifier); | ||
1923 | #endif | ||
1643 | cxgb4_unregister_uld(CXGB4_ULD_ISCSI); | 1924 | cxgb4_unregister_uld(CXGB4_ULD_ISCSI); |
1644 | cxgbi_device_unregister_all(CXGBI_FLAG_DEV_T4); | 1925 | cxgbi_device_unregister_all(CXGBI_FLAG_DEV_T4); |
1645 | cxgbi_iscsi_cleanup(&cxgb4i_iscsi_transport, &cxgb4i_stt); | 1926 | cxgbi_iscsi_cleanup(&cxgb4i_iscsi_transport, &cxgb4i_stt); |
diff --git a/drivers/scsi/cxgbi/libcxgbi.c b/drivers/scsi/cxgbi/libcxgbi.c index dc812069046c..d65df6dc106f 100644 --- a/drivers/scsi/cxgbi/libcxgbi.c +++ b/drivers/scsi/cxgbi/libcxgbi.c | |||
@@ -24,6 +24,10 @@ | |||
24 | #include <linux/inet.h> | 24 | #include <linux/inet.h> |
25 | #include <net/dst.h> | 25 | #include <net/dst.h> |
26 | #include <net/route.h> | 26 | #include <net/route.h> |
27 | #include <net/ipv6.h> | ||
28 | #include <net/ip6_route.h> | ||
29 | #include <net/addrconf.h> | ||
30 | |||
27 | #include <linux/inetdevice.h> /* ip_dev_find */ | 31 | #include <linux/inetdevice.h> /* ip_dev_find */ |
28 | #include <linux/module.h> | 32 | #include <linux/module.h> |
29 | #include <net/tcp.h> | 33 | #include <net/tcp.h> |
@@ -193,8 +197,8 @@ struct cxgbi_device *cxgbi_device_find_by_lldev(void *lldev) | |||
193 | } | 197 | } |
194 | EXPORT_SYMBOL_GPL(cxgbi_device_find_by_lldev); | 198 | EXPORT_SYMBOL_GPL(cxgbi_device_find_by_lldev); |
195 | 199 | ||
196 | static struct cxgbi_device *cxgbi_device_find_by_netdev(struct net_device *ndev, | 200 | struct cxgbi_device *cxgbi_device_find_by_netdev(struct net_device *ndev, |
197 | int *port) | 201 | int *port) |
198 | { | 202 | { |
199 | struct net_device *vdev = NULL; | 203 | struct net_device *vdev = NULL; |
200 | struct cxgbi_device *cdev, *tmp; | 204 | struct cxgbi_device *cdev, *tmp; |
@@ -224,6 +228,40 @@ static struct cxgbi_device *cxgbi_device_find_by_netdev(struct net_device *ndev, | |||
224 | "ndev 0x%p, %s, NO match found.\n", ndev, ndev->name); | 228 | "ndev 0x%p, %s, NO match found.\n", ndev, ndev->name); |
225 | return NULL; | 229 | return NULL; |
226 | } | 230 | } |
231 | EXPORT_SYMBOL_GPL(cxgbi_device_find_by_netdev); | ||
232 | |||
233 | static struct cxgbi_device *cxgbi_device_find_by_mac(struct net_device *ndev, | ||
234 | int *port) | ||
235 | { | ||
236 | struct net_device *vdev = NULL; | ||
237 | struct cxgbi_device *cdev, *tmp; | ||
238 | int i; | ||
239 | |||
240 | if (ndev->priv_flags & IFF_802_1Q_VLAN) { | ||
241 | vdev = ndev; | ||
242 | ndev = vlan_dev_real_dev(ndev); | ||
243 | pr_info("vlan dev %s -> %s.\n", vdev->name, ndev->name); | ||
244 | } | ||
245 | |||
246 | mutex_lock(&cdev_mutex); | ||
247 | list_for_each_entry_safe(cdev, tmp, &cdev_list, list_head) { | ||
248 | for (i = 0; i < cdev->nports; i++) { | ||
249 | if (!memcmp(ndev->dev_addr, cdev->ports[i]->dev_addr, | ||
250 | MAX_ADDR_LEN)) { | ||
251 | cdev->hbas[i]->vdev = vdev; | ||
252 | mutex_unlock(&cdev_mutex); | ||
253 | if (port) | ||
254 | *port = i; | ||
255 | return cdev; | ||
256 | } | ||
257 | } | ||
258 | } | ||
259 | mutex_unlock(&cdev_mutex); | ||
260 | log_debug(1 << CXGBI_DBG_DEV, | ||
261 | "ndev 0x%p, %s, NO match mac found.\n", | ||
262 | ndev, ndev->name); | ||
263 | return NULL; | ||
264 | } | ||
227 | 265 | ||
228 | void cxgbi_hbas_remove(struct cxgbi_device *cdev) | 266 | void cxgbi_hbas_remove(struct cxgbi_device *cdev) |
229 | { | 267 | { |
@@ -320,6 +358,7 @@ static int sock_get_port(struct cxgbi_sock *csk) | |||
320 | struct cxgbi_ports_map *pmap = &cdev->pmap; | 358 | struct cxgbi_ports_map *pmap = &cdev->pmap; |
321 | unsigned int start; | 359 | unsigned int start; |
322 | int idx; | 360 | int idx; |
361 | __be16 *port; | ||
323 | 362 | ||
324 | if (!pmap->max_connect) { | 363 | if (!pmap->max_connect) { |
325 | pr_err("cdev 0x%p, p#%u %s, NO port map.\n", | 364 | pr_err("cdev 0x%p, p#%u %s, NO port map.\n", |
@@ -327,9 +366,14 @@ static int sock_get_port(struct cxgbi_sock *csk) | |||
327 | return -EADDRNOTAVAIL; | 366 | return -EADDRNOTAVAIL; |
328 | } | 367 | } |
329 | 368 | ||
330 | if (csk->saddr.sin_port) { | 369 | if (csk->csk_family == AF_INET) |
370 | port = &csk->saddr.sin_port; | ||
371 | else /* ipv6 */ | ||
372 | port = &csk->saddr6.sin6_port; | ||
373 | |||
374 | if (*port) { | ||
331 | pr_err("source port NON-ZERO %u.\n", | 375 | pr_err("source port NON-ZERO %u.\n", |
332 | ntohs(csk->saddr.sin_port)); | 376 | ntohs(*port)); |
333 | return -EADDRINUSE; | 377 | return -EADDRINUSE; |
334 | } | 378 | } |
335 | 379 | ||
@@ -347,8 +391,7 @@ static int sock_get_port(struct cxgbi_sock *csk) | |||
347 | idx = 0; | 391 | idx = 0; |
348 | if (!pmap->port_csk[idx]) { | 392 | if (!pmap->port_csk[idx]) { |
349 | pmap->used++; | 393 | pmap->used++; |
350 | csk->saddr.sin_port = | 394 | *port = htons(pmap->sport_base + idx); |
351 | htons(pmap->sport_base + idx); | ||
352 | pmap->next = idx; | 395 | pmap->next = idx; |
353 | pmap->port_csk[idx] = csk; | 396 | pmap->port_csk[idx] = csk; |
354 | spin_unlock_bh(&pmap->lock); | 397 | spin_unlock_bh(&pmap->lock); |
@@ -374,16 +417,22 @@ static void sock_put_port(struct cxgbi_sock *csk) | |||
374 | { | 417 | { |
375 | struct cxgbi_device *cdev = csk->cdev; | 418 | struct cxgbi_device *cdev = csk->cdev; |
376 | struct cxgbi_ports_map *pmap = &cdev->pmap; | 419 | struct cxgbi_ports_map *pmap = &cdev->pmap; |
420 | __be16 *port; | ||
377 | 421 | ||
378 | if (csk->saddr.sin_port) { | 422 | if (csk->csk_family == AF_INET) |
379 | int idx = ntohs(csk->saddr.sin_port) - pmap->sport_base; | 423 | port = &csk->saddr.sin_port; |
424 | else /* ipv6 */ | ||
425 | port = &csk->saddr6.sin6_port; | ||
380 | 426 | ||
381 | csk->saddr.sin_port = 0; | 427 | if (*port) { |
428 | int idx = ntohs(*port) - pmap->sport_base; | ||
429 | |||
430 | *port = 0; | ||
382 | if (idx < 0 || idx >= pmap->max_connect) { | 431 | if (idx < 0 || idx >= pmap->max_connect) { |
383 | pr_err("cdev 0x%p, p#%u %s, port %u OOR.\n", | 432 | pr_err("cdev 0x%p, p#%u %s, port %u OOR.\n", |
384 | cdev, csk->port_id, | 433 | cdev, csk->port_id, |
385 | cdev->ports[csk->port_id]->name, | 434 | cdev->ports[csk->port_id]->name, |
386 | ntohs(csk->saddr.sin_port)); | 435 | ntohs(*port)); |
387 | return; | 436 | return; |
388 | } | 437 | } |
389 | 438 | ||
@@ -479,17 +528,11 @@ static struct cxgbi_sock *cxgbi_check_route(struct sockaddr *dst_addr) | |||
479 | int port = 0xFFFF; | 528 | int port = 0xFFFF; |
480 | int err = 0; | 529 | int err = 0; |
481 | 530 | ||
482 | if (daddr->sin_family != AF_INET) { | ||
483 | pr_info("address family 0x%x NOT supported.\n", | ||
484 | daddr->sin_family); | ||
485 | err = -EAFNOSUPPORT; | ||
486 | goto err_out; | ||
487 | } | ||
488 | |||
489 | rt = find_route_ipv4(&fl4, 0, daddr->sin_addr.s_addr, 0, daddr->sin_port, 0); | 531 | rt = find_route_ipv4(&fl4, 0, daddr->sin_addr.s_addr, 0, daddr->sin_port, 0); |
490 | if (!rt) { | 532 | if (!rt) { |
491 | pr_info("no route to ipv4 0x%x, port %u.\n", | 533 | pr_info("no route to ipv4 0x%x, port %u.\n", |
492 | daddr->sin_addr.s_addr, daddr->sin_port); | 534 | be32_to_cpu(daddr->sin_addr.s_addr), |
535 | be16_to_cpu(daddr->sin_port)); | ||
493 | err = -ENETUNREACH; | 536 | err = -ENETUNREACH; |
494 | goto err_out; | 537 | goto err_out; |
495 | } | 538 | } |
@@ -537,9 +580,12 @@ static struct cxgbi_sock *cxgbi_check_route(struct sockaddr *dst_addr) | |||
537 | csk->port_id = port; | 580 | csk->port_id = port; |
538 | csk->mtu = mtu; | 581 | csk->mtu = mtu; |
539 | csk->dst = dst; | 582 | csk->dst = dst; |
583 | |||
584 | csk->csk_family = AF_INET; | ||
540 | csk->daddr.sin_addr.s_addr = daddr->sin_addr.s_addr; | 585 | csk->daddr.sin_addr.s_addr = daddr->sin_addr.s_addr; |
541 | csk->daddr.sin_port = daddr->sin_port; | 586 | csk->daddr.sin_port = daddr->sin_port; |
542 | csk->daddr.sin_family = daddr->sin_family; | 587 | csk->daddr.sin_family = daddr->sin_family; |
588 | csk->saddr.sin_family = daddr->sin_family; | ||
543 | csk->saddr.sin_addr.s_addr = fl4.saddr; | 589 | csk->saddr.sin_addr.s_addr = fl4.saddr; |
544 | neigh_release(n); | 590 | neigh_release(n); |
545 | 591 | ||
@@ -556,6 +602,123 @@ err_out: | |||
556 | return ERR_PTR(err); | 602 | return ERR_PTR(err); |
557 | } | 603 | } |
558 | 604 | ||
605 | #if IS_ENABLED(CONFIG_IPV6) | ||
606 | static struct rt6_info *find_route_ipv6(const struct in6_addr *saddr, | ||
607 | const struct in6_addr *daddr) | ||
608 | { | ||
609 | struct flowi6 fl; | ||
610 | |||
611 | if (saddr) | ||
612 | memcpy(&fl.saddr, saddr, sizeof(struct in6_addr)); | ||
613 | if (daddr) | ||
614 | memcpy(&fl.daddr, daddr, sizeof(struct in6_addr)); | ||
615 | return (struct rt6_info *)ip6_route_output(&init_net, NULL, &fl); | ||
616 | } | ||
617 | |||
618 | static struct cxgbi_sock *cxgbi_check_route6(struct sockaddr *dst_addr) | ||
619 | { | ||
620 | struct sockaddr_in6 *daddr6 = (struct sockaddr_in6 *)dst_addr; | ||
621 | struct dst_entry *dst; | ||
622 | struct net_device *ndev; | ||
623 | struct cxgbi_device *cdev; | ||
624 | struct rt6_info *rt = NULL; | ||
625 | struct neighbour *n; | ||
626 | struct in6_addr pref_saddr; | ||
627 | struct cxgbi_sock *csk = NULL; | ||
628 | unsigned int mtu = 0; | ||
629 | int port = 0xFFFF; | ||
630 | int err = 0; | ||
631 | |||
632 | rt = find_route_ipv6(NULL, &daddr6->sin6_addr); | ||
633 | |||
634 | if (!rt) { | ||
635 | pr_info("no route to ipv6 %pI6 port %u\n", | ||
636 | daddr6->sin6_addr.s6_addr, | ||
637 | be16_to_cpu(daddr6->sin6_port)); | ||
638 | err = -ENETUNREACH; | ||
639 | goto err_out; | ||
640 | } | ||
641 | |||
642 | dst = &rt->dst; | ||
643 | |||
644 | n = dst_neigh_lookup(dst, &daddr6->sin6_addr); | ||
645 | |||
646 | if (!n) { | ||
647 | pr_info("%pI6, port %u, dst no neighbour.\n", | ||
648 | daddr6->sin6_addr.s6_addr, | ||
649 | be16_to_cpu(daddr6->sin6_port)); | ||
650 | err = -ENETUNREACH; | ||
651 | goto rel_rt; | ||
652 | } | ||
653 | ndev = n->dev; | ||
654 | |||
655 | if (ipv6_addr_is_multicast(&rt->rt6i_dst.addr)) { | ||
656 | pr_info("multi-cast route %pI6 port %u, dev %s.\n", | ||
657 | daddr6->sin6_addr.s6_addr, | ||
658 | ntohs(daddr6->sin6_port), ndev->name); | ||
659 | err = -ENETUNREACH; | ||
660 | goto rel_rt; | ||
661 | } | ||
662 | |||
663 | cdev = cxgbi_device_find_by_netdev(ndev, &port); | ||
664 | if (!cdev) | ||
665 | cdev = cxgbi_device_find_by_mac(ndev, &port); | ||
666 | if (!cdev) { | ||
667 | pr_info("dst %pI6 %s, NOT cxgbi device.\n", | ||
668 | daddr6->sin6_addr.s6_addr, ndev->name); | ||
669 | err = -ENETUNREACH; | ||
670 | goto rel_rt; | ||
671 | } | ||
672 | log_debug(1 << CXGBI_DBG_SOCK, | ||
673 | "route to %pI6 :%u, ndev p#%d,%s, cdev 0x%p.\n", | ||
674 | daddr6->sin6_addr.s6_addr, ntohs(daddr6->sin6_port), port, | ||
675 | ndev->name, cdev); | ||
676 | |||
677 | csk = cxgbi_sock_create(cdev); | ||
678 | if (!csk) { | ||
679 | err = -ENOMEM; | ||
680 | goto rel_rt; | ||
681 | } | ||
682 | csk->cdev = cdev; | ||
683 | csk->port_id = port; | ||
684 | csk->mtu = mtu; | ||
685 | csk->dst = dst; | ||
686 | |||
687 | if (ipv6_addr_any(&rt->rt6i_prefsrc.addr)) { | ||
688 | struct inet6_dev *idev = ip6_dst_idev((struct dst_entry *)rt); | ||
689 | |||
690 | err = ipv6_dev_get_saddr(&init_net, idev ? idev->dev : NULL, | ||
691 | &daddr6->sin6_addr, 0, &pref_saddr); | ||
692 | if (err) { | ||
693 | pr_info("failed to get source address to reach %pI6\n", | ||
694 | &daddr6->sin6_addr); | ||
695 | goto rel_rt; | ||
696 | } | ||
697 | } else { | ||
698 | pref_saddr = rt->rt6i_prefsrc.addr; | ||
699 | } | ||
700 | |||
701 | csk->csk_family = AF_INET6; | ||
702 | csk->daddr6.sin6_addr = daddr6->sin6_addr; | ||
703 | csk->daddr6.sin6_port = daddr6->sin6_port; | ||
704 | csk->daddr6.sin6_family = daddr6->sin6_family; | ||
705 | csk->saddr6.sin6_addr = pref_saddr; | ||
706 | |||
707 | neigh_release(n); | ||
708 | return csk; | ||
709 | |||
710 | rel_rt: | ||
711 | if (n) | ||
712 | neigh_release(n); | ||
713 | |||
714 | ip6_rt_put(rt); | ||
715 | if (csk) | ||
716 | cxgbi_sock_closed(csk); | ||
717 | err_out: | ||
718 | return ERR_PTR(err); | ||
719 | } | ||
720 | #endif /* IS_ENABLED(CONFIG_IPV6) */ | ||
721 | |||
559 | void cxgbi_sock_established(struct cxgbi_sock *csk, unsigned int snd_isn, | 722 | void cxgbi_sock_established(struct cxgbi_sock *csk, unsigned int snd_isn, |
560 | unsigned int opt) | 723 | unsigned int opt) |
561 | { | 724 | { |
@@ -2194,6 +2357,34 @@ int cxgbi_set_conn_param(struct iscsi_cls_conn *cls_conn, | |||
2194 | } | 2357 | } |
2195 | EXPORT_SYMBOL_GPL(cxgbi_set_conn_param); | 2358 | EXPORT_SYMBOL_GPL(cxgbi_set_conn_param); |
2196 | 2359 | ||
2360 | static inline int csk_print_port(struct cxgbi_sock *csk, char *buf) | ||
2361 | { | ||
2362 | int len; | ||
2363 | |||
2364 | cxgbi_sock_get(csk); | ||
2365 | len = sprintf(buf, "%hu\n", ntohs(csk->daddr.sin_port)); | ||
2366 | cxgbi_sock_put(csk); | ||
2367 | |||
2368 | return len; | ||
2369 | } | ||
2370 | |||
2371 | static inline int csk_print_ip(struct cxgbi_sock *csk, char *buf) | ||
2372 | { | ||
2373 | int len; | ||
2374 | |||
2375 | cxgbi_sock_get(csk); | ||
2376 | if (csk->csk_family == AF_INET) | ||
2377 | len = sprintf(buf, "%pI4", | ||
2378 | &csk->daddr.sin_addr.s_addr); | ||
2379 | else | ||
2380 | len = sprintf(buf, "%pI6", | ||
2381 | &csk->daddr6.sin6_addr); | ||
2382 | |||
2383 | cxgbi_sock_put(csk); | ||
2384 | |||
2385 | return len; | ||
2386 | } | ||
2387 | |||
2197 | int cxgbi_get_ep_param(struct iscsi_endpoint *ep, enum iscsi_param param, | 2388 | int cxgbi_get_ep_param(struct iscsi_endpoint *ep, enum iscsi_param param, |
2198 | char *buf) | 2389 | char *buf) |
2199 | { | 2390 | { |
@@ -2447,7 +2638,19 @@ struct iscsi_endpoint *cxgbi_ep_connect(struct Scsi_Host *shost, | |||
2447 | } | 2638 | } |
2448 | } | 2639 | } |
2449 | 2640 | ||
2450 | csk = cxgbi_check_route(dst_addr); | 2641 | if (dst_addr->sa_family == AF_INET) { |
2642 | csk = cxgbi_check_route(dst_addr); | ||
2643 | #if IS_ENABLED(CONFIG_IPV6) | ||
2644 | } else if (dst_addr->sa_family == AF_INET6) { | ||
2645 | csk = cxgbi_check_route6(dst_addr); | ||
2646 | #endif | ||
2647 | } else { | ||
2648 | pr_info("address family 0x%x NOT supported.\n", | ||
2649 | dst_addr->sa_family); | ||
2650 | err = -EAFNOSUPPORT; | ||
2651 | return (struct iscsi_endpoint *)ERR_PTR(err); | ||
2652 | } | ||
2653 | |||
2451 | if (IS_ERR(csk)) | 2654 | if (IS_ERR(csk)) |
2452 | return (struct iscsi_endpoint *)csk; | 2655 | return (struct iscsi_endpoint *)csk; |
2453 | cxgbi_sock_get(csk); | 2656 | cxgbi_sock_get(csk); |
diff --git a/drivers/scsi/cxgbi/libcxgbi.h b/drivers/scsi/cxgbi/libcxgbi.h index 538d7a64e138..b3e6e7541cc5 100644 --- a/drivers/scsi/cxgbi/libcxgbi.h +++ b/drivers/scsi/cxgbi/libcxgbi.h | |||
@@ -44,6 +44,15 @@ enum cxgbi_dbg_flag { | |||
44 | pr_info(fmt, ##__VA_ARGS__); \ | 44 | pr_info(fmt, ##__VA_ARGS__); \ |
45 | } while (0) | 45 | } while (0) |
46 | 46 | ||
47 | #define pr_info_ipaddr(fmt_trail, \ | ||
48 | addr1, addr2, args_trail...) \ | ||
49 | do { \ | ||
50 | if (!((1 << CXGBI_DBG_SOCK) & dbg_level)) \ | ||
51 | break; \ | ||
52 | pr_info("%pISpc - %pISpc, " fmt_trail, \ | ||
53 | addr1, addr2, args_trail); \ | ||
54 | } while (0) | ||
55 | |||
47 | /* max. connections per adapter */ | 56 | /* max. connections per adapter */ |
48 | #define CXGBI_MAX_CONN 16384 | 57 | #define CXGBI_MAX_CONN 16384 |
49 | 58 | ||
@@ -202,8 +211,15 @@ struct cxgbi_sock { | |||
202 | spinlock_t lock; | 211 | spinlock_t lock; |
203 | struct kref refcnt; | 212 | struct kref refcnt; |
204 | unsigned int state; | 213 | unsigned int state; |
205 | struct sockaddr_in saddr; | 214 | unsigned int csk_family; |
206 | struct sockaddr_in daddr; | 215 | union { |
216 | struct sockaddr_in saddr; | ||
217 | struct sockaddr_in6 saddr6; | ||
218 | }; | ||
219 | union { | ||
220 | struct sockaddr_in daddr; | ||
221 | struct sockaddr_in6 daddr6; | ||
222 | }; | ||
207 | struct dst_entry *dst; | 223 | struct dst_entry *dst; |
208 | struct sk_buff_head receive_queue; | 224 | struct sk_buff_head receive_queue; |
209 | struct sk_buff_head write_queue; | 225 | struct sk_buff_head write_queue; |
@@ -692,6 +708,7 @@ struct cxgbi_device *cxgbi_device_register(unsigned int, unsigned int); | |||
692 | void cxgbi_device_unregister(struct cxgbi_device *); | 708 | void cxgbi_device_unregister(struct cxgbi_device *); |
693 | void cxgbi_device_unregister_all(unsigned int flag); | 709 | void cxgbi_device_unregister_all(unsigned int flag); |
694 | struct cxgbi_device *cxgbi_device_find_by_lldev(void *); | 710 | struct cxgbi_device *cxgbi_device_find_by_lldev(void *); |
711 | struct cxgbi_device *cxgbi_device_find_by_netdev(struct net_device *, int *); | ||
695 | int cxgbi_hbas_add(struct cxgbi_device *, u64, unsigned int, | 712 | int cxgbi_hbas_add(struct cxgbi_device *, u64, unsigned int, |
696 | struct scsi_host_template *, | 713 | struct scsi_host_template *, |
697 | struct scsi_transport_template *); | 714 | struct scsi_transport_template *); |