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 | |
| 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>
| -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; |
