diff options
author | kxie@chelsio.com <kxie@chelsio.com> | 2010-09-23 19:43:23 -0400 |
---|---|---|
committer | James Bottomley <James.Bottomley@suse.de> | 2010-10-07 18:21:11 -0400 |
commit | 0b3d8947972bfd2dd6d55c8009427ad2941ef038 (patch) | |
tree | f2e750b25a948016233b382f05cbf5e13a966d2e /drivers/scsi/cxgbi | |
parent | e3d2ad8cb2775e4201446489efd1cf26c5bbce5c (diff) |
[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>
Diffstat (limited to 'drivers/scsi/cxgbi')
-rw-r--r-- | drivers/scsi/cxgbi/cxgb3i/cxgb3i.c | 47 | ||||
-rw-r--r-- | drivers/scsi/cxgbi/libcxgbi.c | 37 | ||||
-rw-r--r-- | drivers/scsi/cxgbi/libcxgbi.h | 1 |
3 files changed, 49 insertions, 36 deletions
diff --git a/drivers/scsi/cxgbi/cxgb3i/cxgb3i.c b/drivers/scsi/cxgbi/cxgb3i/cxgb3i.c index a2c207f57d61..a129a170b47b 100644 --- a/drivers/scsi/cxgbi/cxgb3i/cxgb3i.c +++ b/drivers/scsi/cxgbi/cxgb3i/cxgb3i.c | |||
@@ -589,9 +589,10 @@ static int do_act_open_rpl(struct t3cdev *tdev, struct sk_buff *skb, void *ctx) | |||
589 | struct cxgbi_sock *csk = ctx; | 589 | struct cxgbi_sock *csk = ctx; |
590 | struct cpl_act_open_rpl *rpl = cplhdr(skb); | 590 | struct cpl_act_open_rpl *rpl = cplhdr(skb); |
591 | 591 | ||
592 | log_debug(1 << CXGBI_DBG_TOE | 1 << CXGBI_DBG_SOCK, | 592 | pr_info("csk 0x%p,%u,0x%lx,%u, status %u, %pI4:%u-%pI4:%u.\n", |
593 | "csk 0x%p,%u,0x%lx,%u, status %u.\n", | 593 | csk, csk->state, csk->flags, csk->atid, rpl->status, |
594 | 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 | if (rpl->status != CPL_ERR_TCAM_FULL && | 597 | if (rpl->status != CPL_ERR_TCAM_FULL && |
597 | rpl->status != CPL_ERR_CONN_EXIST && | 598 | rpl->status != CPL_ERR_CONN_EXIST && |
@@ -662,8 +663,7 @@ static int abort_status_to_errno(struct cxgbi_sock *csk, int abort_reason, | |||
662 | switch (abort_reason) { | 663 | switch (abort_reason) { |
663 | case CPL_ERR_BAD_SYN: /* fall through */ | 664 | case CPL_ERR_BAD_SYN: /* fall through */ |
664 | case CPL_ERR_CONN_RESET: | 665 | case CPL_ERR_CONN_RESET: |
665 | return csk->state > CTP_ESTABLISHED ? | 666 | return csk->state > CTP_ESTABLISHED ? -EPIPE : -ECONNRESET; |
666 | -EPIPE : -ECONNRESET; | ||
667 | case CPL_ERR_XMIT_TIMEDOUT: | 667 | case CPL_ERR_XMIT_TIMEDOUT: |
668 | case CPL_ERR_PERSIST_TIMEDOUT: | 668 | case CPL_ERR_PERSIST_TIMEDOUT: |
669 | case CPL_ERR_FINWAIT2_TIMEDOUT: | 669 | case CPL_ERR_FINWAIT2_TIMEDOUT: |
@@ -945,17 +945,44 @@ static void release_offload_resources(struct cxgbi_sock *csk) | |||
945 | csk->cdev = NULL; | 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 | static int init_act_open(struct cxgbi_sock *csk) | 970 | static int init_act_open(struct cxgbi_sock *csk) |
949 | { | 971 | { |
950 | struct dst_entry *dst = csk->dst; | 972 | struct dst_entry *dst = csk->dst; |
951 | struct cxgbi_device *cdev = csk->cdev; | 973 | struct cxgbi_device *cdev = csk->cdev; |
952 | struct t3cdev *t3dev = (struct t3cdev *)cdev->lldev; | 974 | struct t3cdev *t3dev = (struct t3cdev *)cdev->lldev; |
953 | struct net_device *ndev = cdev->ports[csk->port_id]; | 975 | struct net_device *ndev = cdev->ports[csk->port_id]; |
976 | struct cxgbi_hba *chba = cdev->hbas[csk->port_id]; | ||
954 | struct sk_buff *skb = NULL; | 977 | struct sk_buff *skb = NULL; |
955 | 978 | ||
956 | log_debug(1 << CXGBI_DBG_TOE | 1 << CXGBI_DBG_SOCK, | 979 | log_debug(1 << CXGBI_DBG_TOE | 1 << CXGBI_DBG_SOCK, |
957 | "csk 0x%p,%u,0x%lx.\n", csk, csk->state, csk->flags); | 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 | csk->rss_qid = 0; | 986 | csk->rss_qid = 0; |
960 | csk->l2t = t3_l2t_get(t3dev, dst->neighbour, ndev); | 987 | csk->l2t = t3_l2t_get(t3dev, dst->neighbour, ndev); |
961 | if (!csk->l2t) { | 988 | if (!csk->l2t) { |
@@ -984,6 +1011,12 @@ static int init_act_open(struct cxgbi_sock *csk) | |||
984 | cxgbi_sock_reset_wr_list(csk); | 1011 | cxgbi_sock_reset_wr_list(csk); |
985 | csk->err = 0; | 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 | cxgbi_sock_set_state(csk, CTP_ACTIVE_OPEN); | 1020 | cxgbi_sock_set_state(csk, CTP_ACTIVE_OPEN); |
988 | send_act_open_req(csk, skb, csk->l2t); | 1021 | send_act_open_req(csk, skb, csk->l2t); |
989 | return 0; | 1022 | return 0; |
@@ -1143,9 +1176,9 @@ static int ddp_alloc_gl_skb(struct cxgbi_ddp_info *ddp, int idx, | |||
1143 | for (i = 0; i < cnt; i++) { | 1176 | for (i = 0; i < cnt; i++) { |
1144 | struct sk_buff *skb = alloc_wr(sizeof(struct ulp_mem_io) + | 1177 | struct sk_buff *skb = alloc_wr(sizeof(struct ulp_mem_io) + |
1145 | PPOD_SIZE, 0, gfp); | 1178 | PPOD_SIZE, 0, gfp); |
1146 | if (skb) { | 1179 | if (skb) |
1147 | ddp->gl_skb[idx + i] = skb; | 1180 | ddp->gl_skb[idx + i] = skb; |
1148 | } else { | 1181 | else { |
1149 | ddp_free_gl_skb(ddp, idx, i); | 1182 | ddp_free_gl_skb(ddp, idx, i); |
1150 | return -ENOMEM; | 1183 | return -ENOMEM; |
1151 | } | 1184 | } |
diff --git a/drivers/scsi/cxgbi/libcxgbi.c b/drivers/scsi/cxgbi/libcxgbi.c index 6cfce2726ea3..be5661707dfa 100644 --- a/drivers/scsi/cxgbi/libcxgbi.c +++ b/drivers/scsi/cxgbi/libcxgbi.c | |||
@@ -195,16 +195,22 @@ EXPORT_SYMBOL_GPL(cxgbi_device_find_by_lldev); | |||
195 | static struct cxgbi_device *cxgbi_device_find_by_netdev(struct net_device *ndev, | 195 | static struct cxgbi_device *cxgbi_device_find_by_netdev(struct net_device *ndev, |
196 | int *port) | 196 | int *port) |
197 | { | 197 | { |
198 | struct net_device *vdev = NULL; | ||
198 | struct cxgbi_device *cdev, *tmp; | 199 | struct cxgbi_device *cdev, *tmp; |
199 | int i; | 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 | ndev = vlan_dev_real_dev(ndev); | 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 | mutex_lock(&cdev_mutex); | 209 | mutex_lock(&cdev_mutex); |
205 | list_for_each_entry_safe(cdev, tmp, &cdev_list, list_head) { | 210 | list_for_each_entry_safe(cdev, tmp, &cdev_list, list_head) { |
206 | for (i = 0; i < cdev->nports; i++) { | 211 | for (i = 0; i < cdev->nports; i++) { |
207 | if (ndev == cdev->ports[i]) { | 212 | if (ndev == cdev->ports[i]) { |
213 | cdev->hbas[i]->vdev = vdev; | ||
208 | mutex_unlock(&cdev_mutex); | 214 | mutex_unlock(&cdev_mutex); |
209 | if (port) | 215 | if (port) |
210 | *port = i; | 216 | *port = i; |
@@ -218,24 +224,6 @@ static struct cxgbi_device *cxgbi_device_find_by_netdev(struct net_device *ndev, | |||
218 | return NULL; | 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 | void cxgbi_hbas_remove(struct cxgbi_device *cdev) | 227 | void cxgbi_hbas_remove(struct cxgbi_device *cdev) |
240 | { | 228 | { |
241 | int i; | 229 | int i; |
@@ -532,12 +520,6 @@ static struct cxgbi_sock *cxgbi_check_route(struct sockaddr *dst_addr) | |||
532 | dst->neighbour->dev->name, ndev->name, mtu); | 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 | cdev = cxgbi_device_find_by_netdev(ndev, &port); | 523 | cdev = cxgbi_device_find_by_netdev(ndev, &port); |
542 | if (!cdev) { | 524 | if (!cdev) { |
543 | pr_info("dst %pI4, %s, NOT cxgbi device.\n", | 525 | pr_info("dst %pI4, %s, NOT cxgbi device.\n", |
@@ -561,10 +543,7 @@ static struct cxgbi_sock *cxgbi_check_route(struct sockaddr *dst_addr) | |||
561 | csk->dst = dst; | 543 | csk->dst = dst; |
562 | csk->daddr.sin_addr.s_addr = daddr->sin_addr.s_addr; | 544 | csk->daddr.sin_addr.s_addr = daddr->sin_addr.s_addr; |
563 | csk->daddr.sin_port = daddr->sin_port; | 545 | csk->daddr.sin_port = daddr->sin_port; |
564 | if (cdev->hbas[port]->ipv4addr) | 546 | csk->saddr.sin_addr.s_addr = rt->rt_src; |
565 | csk->saddr.sin_addr.s_addr = cdev->hbas[port]->ipv4addr; | ||
566 | else | ||
567 | csk->saddr.sin_addr.s_addr = rt->rt_src; | ||
568 | 547 | ||
569 | return csk; | 548 | return csk; |
570 | 549 | ||
diff --git a/drivers/scsi/cxgbi/libcxgbi.h b/drivers/scsi/cxgbi/libcxgbi.h index 48e6d623f76d..43025b71e295 100644 --- a/drivers/scsi/cxgbi/libcxgbi.h +++ b/drivers/scsi/cxgbi/libcxgbi.h | |||
@@ -500,6 +500,7 @@ void cxgbi_sock_free_cpl_skbs(struct cxgbi_sock *); | |||
500 | 500 | ||
501 | struct cxgbi_hba { | 501 | struct cxgbi_hba { |
502 | struct net_device *ndev; | 502 | struct net_device *ndev; |
503 | struct net_device *vdev; /* vlan dev */ | ||
503 | struct Scsi_Host *shost; | 504 | struct Scsi_Host *shost; |
504 | struct cxgbi_device *cdev; | 505 | struct cxgbi_device *cdev; |
505 | __be32 ipv4addr; | 506 | __be32 ipv4addr; |