Commit 0b3d8947972bfd2dd6d55c8009427ad2941ef038
Committed by
James Bottomley
1 parent
e3d2ad8cb2
Exists in
master
and in
39 other branches
[SCSI] cxgb3i: fixed connection over vlan
Signed-off-by: Karen Xie <kxie@chelsio.com> Reviewed-by: Mike Christie <michaelc@cs.wisc.edu> Signed-off-by: James Bottomley <James.Bottomley@suse.de>
Showing 3 changed files with 49 additions and 36 deletions Side-by-side Diff
drivers/scsi/cxgbi/cxgb3i/cxgb3i.c
... | ... | @@ -589,9 +589,10 @@ |
589 | 589 | struct cxgbi_sock *csk = ctx; |
590 | 590 | struct cpl_act_open_rpl *rpl = cplhdr(skb); |
591 | 591 | |
592 | - log_debug(1 << CXGBI_DBG_TOE | 1 << CXGBI_DBG_SOCK, | |
593 | - "csk 0x%p,%u,0x%lx,%u, status %u.\n", | |
594 | - csk, csk->state, csk->flags, csk->atid, rpl->status); | |
592 | + pr_info("csk 0x%p,%u,0x%lx,%u, status %u, %pI4:%u-%pI4:%u.\n", | |
593 | + csk, csk->state, csk->flags, csk->atid, rpl->status, | |
594 | + &csk->saddr.sin_addr.s_addr, ntohs(csk->saddr.sin_port), | |
595 | + &csk->daddr.sin_addr.s_addr, ntohs(csk->daddr.sin_port)); | |
595 | 596 | |
596 | 597 | if (rpl->status != CPL_ERR_TCAM_FULL && |
597 | 598 | rpl->status != CPL_ERR_CONN_EXIST && |
... | ... | @@ -662,8 +663,7 @@ |
662 | 663 | switch (abort_reason) { |
663 | 664 | case CPL_ERR_BAD_SYN: /* fall through */ |
664 | 665 | case CPL_ERR_CONN_RESET: |
665 | - return csk->state > CTP_ESTABLISHED ? | |
666 | - -EPIPE : -ECONNRESET; | |
666 | + return csk->state > CTP_ESTABLISHED ? -EPIPE : -ECONNRESET; | |
667 | 667 | case CPL_ERR_XMIT_TIMEDOUT: |
668 | 668 | case CPL_ERR_PERSIST_TIMEDOUT: |
669 | 669 | case CPL_ERR_FINWAIT2_TIMEDOUT: |
670 | 670 | |
671 | 671 | |
... | ... | @@ -945,17 +945,44 @@ |
945 | 945 | csk->cdev = NULL; |
946 | 946 | } |
947 | 947 | |
948 | +static void update_address(struct cxgbi_hba *chba) | |
949 | +{ | |
950 | + if (chba->ipv4addr) { | |
951 | + if (chba->vdev && | |
952 | + chba->ipv4addr != cxgb3i_get_private_ipv4addr(chba->vdev)) { | |
953 | + cxgb3i_set_private_ipv4addr(chba->vdev, chba->ipv4addr); | |
954 | + cxgb3i_set_private_ipv4addr(chba->ndev, 0); | |
955 | + pr_info("%s set %pI4.\n", | |
956 | + chba->vdev->name, &chba->ipv4addr); | |
957 | + } else if (chba->ipv4addr != | |
958 | + cxgb3i_get_private_ipv4addr(chba->ndev)) { | |
959 | + cxgb3i_set_private_ipv4addr(chba->ndev, chba->ipv4addr); | |
960 | + pr_info("%s set %pI4.\n", | |
961 | + chba->ndev->name, &chba->ipv4addr); | |
962 | + } | |
963 | + } else if (cxgb3i_get_private_ipv4addr(chba->ndev)) { | |
964 | + if (chba->vdev) | |
965 | + cxgb3i_set_private_ipv4addr(chba->vdev, 0); | |
966 | + cxgb3i_set_private_ipv4addr(chba->ndev, 0); | |
967 | + } | |
968 | +} | |
969 | + | |
948 | 970 | static int init_act_open(struct cxgbi_sock *csk) |
949 | 971 | { |
950 | 972 | struct dst_entry *dst = csk->dst; |
951 | 973 | struct cxgbi_device *cdev = csk->cdev; |
952 | 974 | struct t3cdev *t3dev = (struct t3cdev *)cdev->lldev; |
953 | 975 | struct net_device *ndev = cdev->ports[csk->port_id]; |
976 | + struct cxgbi_hba *chba = cdev->hbas[csk->port_id]; | |
954 | 977 | struct sk_buff *skb = NULL; |
955 | 978 | |
956 | 979 | log_debug(1 << CXGBI_DBG_TOE | 1 << CXGBI_DBG_SOCK, |
957 | 980 | "csk 0x%p,%u,0x%lx.\n", csk, csk->state, csk->flags); |
958 | 981 | |
982 | + update_address(chba); | |
983 | + if (chba->ipv4addr) | |
984 | + csk->saddr.sin_addr.s_addr = chba->ipv4addr; | |
985 | + | |
959 | 986 | csk->rss_qid = 0; |
960 | 987 | csk->l2t = t3_l2t_get(t3dev, dst->neighbour, ndev); |
961 | 988 | if (!csk->l2t) { |
... | ... | @@ -984,6 +1011,12 @@ |
984 | 1011 | cxgbi_sock_reset_wr_list(csk); |
985 | 1012 | csk->err = 0; |
986 | 1013 | |
1014 | + log_debug(1 << CXGBI_DBG_TOE | 1 << CXGBI_DBG_SOCK, | |
1015 | + "csk 0x%p,%u,0x%lx, %pI4:%u-%pI4:%u.\n", | |
1016 | + csk, csk->state, csk->flags, | |
1017 | + &csk->saddr.sin_addr.s_addr, ntohs(csk->saddr.sin_port), | |
1018 | + &csk->daddr.sin_addr.s_addr, ntohs(csk->daddr.sin_port)); | |
1019 | + | |
987 | 1020 | cxgbi_sock_set_state(csk, CTP_ACTIVE_OPEN); |
988 | 1021 | send_act_open_req(csk, skb, csk->l2t); |
989 | 1022 | return 0; |
990 | 1023 | |
... | ... | @@ -1143,9 +1176,9 @@ |
1143 | 1176 | for (i = 0; i < cnt; i++) { |
1144 | 1177 | struct sk_buff *skb = alloc_wr(sizeof(struct ulp_mem_io) + |
1145 | 1178 | PPOD_SIZE, 0, gfp); |
1146 | - if (skb) { | |
1179 | + if (skb) | |
1147 | 1180 | ddp->gl_skb[idx + i] = skb; |
1148 | - } else { | |
1181 | + else { | |
1149 | 1182 | ddp_free_gl_skb(ddp, idx, i); |
1150 | 1183 | return -ENOMEM; |
1151 | 1184 | } |
drivers/scsi/cxgbi/libcxgbi.c
... | ... | @@ -195,16 +195,22 @@ |
195 | 195 | static struct cxgbi_device *cxgbi_device_find_by_netdev(struct net_device *ndev, |
196 | 196 | int *port) |
197 | 197 | { |
198 | + struct net_device *vdev = NULL; | |
198 | 199 | struct cxgbi_device *cdev, *tmp; |
199 | 200 | int i; |
200 | 201 | |
201 | - if (ndev->priv_flags & IFF_802_1Q_VLAN) | |
202 | + if (ndev->priv_flags & IFF_802_1Q_VLAN) { | |
203 | + vdev = ndev; | |
202 | 204 | ndev = vlan_dev_real_dev(ndev); |
205 | + log_debug(1 << CXGBI_DBG_DEV, | |
206 | + "vlan dev %s -> %s.\n", vdev->name, ndev->name); | |
207 | + } | |
203 | 208 | |
204 | 209 | mutex_lock(&cdev_mutex); |
205 | 210 | list_for_each_entry_safe(cdev, tmp, &cdev_list, list_head) { |
206 | 211 | for (i = 0; i < cdev->nports; i++) { |
207 | 212 | if (ndev == cdev->ports[i]) { |
213 | + cdev->hbas[i]->vdev = vdev; | |
208 | 214 | mutex_unlock(&cdev_mutex); |
209 | 215 | if (port) |
210 | 216 | *port = i; |
... | ... | @@ -218,24 +224,6 @@ |
218 | 224 | return NULL; |
219 | 225 | } |
220 | 226 | |
221 | -struct cxgbi_hba *cxgbi_hba_find_by_netdev(struct net_device *dev, | |
222 | - struct cxgbi_device *cdev) | |
223 | -{ | |
224 | - int i; | |
225 | - | |
226 | - if (dev->priv_flags & IFF_802_1Q_VLAN) | |
227 | - dev = vlan_dev_real_dev(dev); | |
228 | - | |
229 | - for (i = 0; i < cdev->nports; i++) { | |
230 | - if (cdev->hbas[i]->ndev == dev) | |
231 | - return cdev->hbas[i]; | |
232 | - } | |
233 | - log_debug(1 << CXGBI_DBG_DEV, | |
234 | - "ndev 0x%p, %s, cdev 0x%p, NO match found.\n", | |
235 | - dev, dev->name, cdev); | |
236 | - return NULL; | |
237 | -} | |
238 | - | |
239 | 227 | void cxgbi_hbas_remove(struct cxgbi_device *cdev) |
240 | 228 | { |
241 | 229 | int i; |
... | ... | @@ -532,12 +520,6 @@ |
532 | 520 | dst->neighbour->dev->name, ndev->name, mtu); |
533 | 521 | } |
534 | 522 | |
535 | - if (ndev->priv_flags & IFF_802_1Q_VLAN) { | |
536 | - ndev = vlan_dev_real_dev(ndev); | |
537 | - pr_info("rt dev %s, vlan -> %s.\n", | |
538 | - dst->neighbour->dev->name, ndev->name); | |
539 | - } | |
540 | - | |
541 | 523 | cdev = cxgbi_device_find_by_netdev(ndev, &port); |
542 | 524 | if (!cdev) { |
543 | 525 | pr_info("dst %pI4, %s, NOT cxgbi device.\n", |
... | ... | @@ -561,10 +543,7 @@ |
561 | 543 | csk->dst = dst; |
562 | 544 | csk->daddr.sin_addr.s_addr = daddr->sin_addr.s_addr; |
563 | 545 | csk->daddr.sin_port = daddr->sin_port; |
564 | - if (cdev->hbas[port]->ipv4addr) | |
565 | - csk->saddr.sin_addr.s_addr = cdev->hbas[port]->ipv4addr; | |
566 | - else | |
567 | - csk->saddr.sin_addr.s_addr = rt->rt_src; | |
546 | + csk->saddr.sin_addr.s_addr = rt->rt_src; | |
568 | 547 | |
569 | 548 | return csk; |
570 | 549 |