aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkxie@chelsio.com <kxie@chelsio.com>2010-09-23 19:43:23 -0400
committerJames Bottomley <James.Bottomley@suse.de>2010-10-07 18:21:11 -0400
commit0b3d8947972bfd2dd6d55c8009427ad2941ef038 (patch)
treef2e750b25a948016233b382f05cbf5e13a966d2e
parente3d2ad8cb2775e4201446489efd1cf26c5bbce5c (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.c47
-rw-r--r--drivers/scsi/cxgbi/libcxgbi.c37
-rw-r--r--drivers/scsi/cxgbi/libcxgbi.h1
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
948static 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
948static int init_act_open(struct cxgbi_sock *csk) 970static 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);
195static struct cxgbi_device *cxgbi_device_find_by_netdev(struct net_device *ndev, 195static 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
221struct 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
239void cxgbi_hbas_remove(struct cxgbi_device *cdev) 227void 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
501struct cxgbi_hba { 501struct 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;