Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0b3d8947 authored by kxie@chelsio.com's avatar kxie@chelsio.com Committed by James Bottomley
Browse files

[SCSI] cxgb3i: fixed connection over vlan

parent e3d2ad8c
Loading
Loading
Loading
Loading
+40 −7
Original line number Original line Diff line number Diff line
@@ -589,9 +589,10 @@ static int do_act_open_rpl(struct t3cdev *tdev, struct sk_buff *skb, void *ctx)
	struct cxgbi_sock *csk = ctx;
	struct cxgbi_sock *csk = ctx;
	struct cpl_act_open_rpl *rpl = cplhdr(skb);
	struct cpl_act_open_rpl *rpl = cplhdr(skb);


	log_debug(1 << CXGBI_DBG_TOE | 1 << CXGBI_DBG_SOCK,
	pr_info("csk 0x%p,%u,0x%lx,%u, status %u, %pI4:%u-%pI4:%u.\n",
		"csk 0x%p,%u,0x%lx,%u, status %u.\n",
		csk, csk->state, csk->flags, csk->atid, rpl->status,
		csk, csk->state, csk->flags, csk->atid, rpl->status);
		&csk->saddr.sin_addr.s_addr, ntohs(csk->saddr.sin_port),
		&csk->daddr.sin_addr.s_addr, ntohs(csk->daddr.sin_port));


	if (rpl->status != CPL_ERR_TCAM_FULL &&
	if (rpl->status != CPL_ERR_TCAM_FULL &&
	    rpl->status != CPL_ERR_CONN_EXIST &&
	    rpl->status != CPL_ERR_CONN_EXIST &&
@@ -662,8 +663,7 @@ static int abort_status_to_errno(struct cxgbi_sock *csk, int abort_reason,
	switch (abort_reason) {
	switch (abort_reason) {
	case CPL_ERR_BAD_SYN: /* fall through */
	case CPL_ERR_BAD_SYN: /* fall through */
	case CPL_ERR_CONN_RESET:
	case CPL_ERR_CONN_RESET:
		return csk->state > CTP_ESTABLISHED ?
		return csk->state > CTP_ESTABLISHED ? -EPIPE : -ECONNRESET;
			-EPIPE : -ECONNRESET;
	case CPL_ERR_XMIT_TIMEDOUT:
	case CPL_ERR_XMIT_TIMEDOUT:
	case CPL_ERR_PERSIST_TIMEDOUT:
	case CPL_ERR_PERSIST_TIMEDOUT:
	case CPL_ERR_FINWAIT2_TIMEDOUT:
	case CPL_ERR_FINWAIT2_TIMEDOUT:
@@ -945,17 +945,44 @@ static void release_offload_resources(struct cxgbi_sock *csk)
	csk->cdev = NULL;
	csk->cdev = NULL;
}
}


static void update_address(struct cxgbi_hba *chba)
{
	if (chba->ipv4addr) {
		if (chba->vdev &&
		    chba->ipv4addr != cxgb3i_get_private_ipv4addr(chba->vdev)) {
			cxgb3i_set_private_ipv4addr(chba->vdev, chba->ipv4addr);
			cxgb3i_set_private_ipv4addr(chba->ndev, 0);
			pr_info("%s set %pI4.\n",
				chba->vdev->name, &chba->ipv4addr);
		} else if (chba->ipv4addr !=
				cxgb3i_get_private_ipv4addr(chba->ndev)) {
			cxgb3i_set_private_ipv4addr(chba->ndev, chba->ipv4addr);
			pr_info("%s set %pI4.\n",
				chba->ndev->name, &chba->ipv4addr);
		}
	} else if (cxgb3i_get_private_ipv4addr(chba->ndev)) {
		if (chba->vdev)
			cxgb3i_set_private_ipv4addr(chba->vdev, 0);
		cxgb3i_set_private_ipv4addr(chba->ndev, 0);
	}
}

static int init_act_open(struct cxgbi_sock *csk)
static int init_act_open(struct cxgbi_sock *csk)
{
{
	struct dst_entry *dst = csk->dst;
	struct dst_entry *dst = csk->dst;
	struct cxgbi_device *cdev = csk->cdev;
	struct cxgbi_device *cdev = csk->cdev;
	struct t3cdev *t3dev = (struct t3cdev *)cdev->lldev;
	struct t3cdev *t3dev = (struct t3cdev *)cdev->lldev;
	struct net_device *ndev = cdev->ports[csk->port_id];
	struct net_device *ndev = cdev->ports[csk->port_id];
	struct cxgbi_hba *chba = cdev->hbas[csk->port_id];
	struct sk_buff *skb = NULL;
	struct sk_buff *skb = NULL;


	log_debug(1 << CXGBI_DBG_TOE | 1 << CXGBI_DBG_SOCK,
	log_debug(1 << CXGBI_DBG_TOE | 1 << CXGBI_DBG_SOCK,
		"csk 0x%p,%u,0x%lx.\n", csk, csk->state, csk->flags);
		"csk 0x%p,%u,0x%lx.\n", csk, csk->state, csk->flags);


	update_address(chba);
	if (chba->ipv4addr)
		csk->saddr.sin_addr.s_addr = chba->ipv4addr;

	csk->rss_qid = 0;
	csk->rss_qid = 0;
	csk->l2t = t3_l2t_get(t3dev, dst->neighbour, ndev);
	csk->l2t = t3_l2t_get(t3dev, dst->neighbour, ndev);
	if (!csk->l2t) {
	if (!csk->l2t) {
@@ -984,6 +1011,12 @@ static int init_act_open(struct cxgbi_sock *csk)
	cxgbi_sock_reset_wr_list(csk);
	cxgbi_sock_reset_wr_list(csk);
	csk->err = 0;
	csk->err = 0;


	log_debug(1 << CXGBI_DBG_TOE | 1 << CXGBI_DBG_SOCK,
		"csk 0x%p,%u,0x%lx, %pI4:%u-%pI4:%u.\n",
		csk, csk->state, csk->flags,
		&csk->saddr.sin_addr.s_addr, ntohs(csk->saddr.sin_port),
		&csk->daddr.sin_addr.s_addr, ntohs(csk->daddr.sin_port));

	cxgbi_sock_set_state(csk, CTP_ACTIVE_OPEN);
	cxgbi_sock_set_state(csk, CTP_ACTIVE_OPEN);
	send_act_open_req(csk, skb, csk->l2t);
	send_act_open_req(csk, skb, csk->l2t);
	return 0;
	return 0;
@@ -1143,9 +1176,9 @@ static int ddp_alloc_gl_skb(struct cxgbi_ddp_info *ddp, int idx,
	for (i = 0; i < cnt; i++) {
	for (i = 0; i < cnt; i++) {
		struct sk_buff *skb = alloc_wr(sizeof(struct ulp_mem_io) +
		struct sk_buff *skb = alloc_wr(sizeof(struct ulp_mem_io) +
						PPOD_SIZE, 0, gfp);
						PPOD_SIZE, 0, gfp);
		if (skb) {
		if (skb)
			ddp->gl_skb[idx + i] = skb;
			ddp->gl_skb[idx + i] = skb;
		} else {
		else {
			ddp_free_gl_skb(ddp, idx, i);
			ddp_free_gl_skb(ddp, idx, i);
			return -ENOMEM;
			return -ENOMEM;
		}
		}
+8 −29
Original line number Original line Diff line number Diff line
@@ -195,16 +195,22 @@ EXPORT_SYMBOL_GPL(cxgbi_device_find_by_lldev);
static struct cxgbi_device *cxgbi_device_find_by_netdev(struct net_device *ndev,
static struct cxgbi_device *cxgbi_device_find_by_netdev(struct net_device *ndev,
							int *port)
							int *port)
{
{
	struct net_device *vdev = NULL;
	struct cxgbi_device *cdev, *tmp;
	struct cxgbi_device *cdev, *tmp;
	int i;
	int i;


	if (ndev->priv_flags & IFF_802_1Q_VLAN)
	if (ndev->priv_flags & IFF_802_1Q_VLAN) {
		vdev = ndev;
		ndev = vlan_dev_real_dev(ndev);
		ndev = vlan_dev_real_dev(ndev);
		log_debug(1 << CXGBI_DBG_DEV,
			"vlan dev %s -> %s.\n", vdev->name, ndev->name);
	}


	mutex_lock(&cdev_mutex);
	mutex_lock(&cdev_mutex);
	list_for_each_entry_safe(cdev, tmp, &cdev_list, list_head) {
	list_for_each_entry_safe(cdev, tmp, &cdev_list, list_head) {
		for (i = 0; i < cdev->nports; i++) {
		for (i = 0; i < cdev->nports; i++) {
			if (ndev == cdev->ports[i]) {
			if (ndev == cdev->ports[i]) {
				cdev->hbas[i]->vdev = vdev;
				mutex_unlock(&cdev_mutex);
				mutex_unlock(&cdev_mutex);
				if (port)
				if (port)
					*port = i;
					*port = i;
@@ -218,24 +224,6 @@ static struct cxgbi_device *cxgbi_device_find_by_netdev(struct net_device *ndev,
	return NULL;
	return NULL;
}
}


struct cxgbi_hba *cxgbi_hba_find_by_netdev(struct net_device *dev,
					struct cxgbi_device *cdev)
{
	int i;

	if (dev->priv_flags & IFF_802_1Q_VLAN)
		dev = vlan_dev_real_dev(dev);

	for (i = 0; i < cdev->nports; i++) {
		if (cdev->hbas[i]->ndev == dev)
			return cdev->hbas[i];
	}
	log_debug(1 << CXGBI_DBG_DEV,
		"ndev 0x%p, %s, cdev 0x%p, NO match found.\n",
		dev, dev->name, cdev);
	return NULL;
}

void cxgbi_hbas_remove(struct cxgbi_device *cdev)
void cxgbi_hbas_remove(struct cxgbi_device *cdev)
{
{
	int i;
	int i;
@@ -532,12 +520,6 @@ static struct cxgbi_sock *cxgbi_check_route(struct sockaddr *dst_addr)
			dst->neighbour->dev->name, ndev->name, mtu);
			dst->neighbour->dev->name, ndev->name, mtu);
	}
	}


	if (ndev->priv_flags & IFF_802_1Q_VLAN) {
		ndev = vlan_dev_real_dev(ndev);
		pr_info("rt dev %s, vlan -> %s.\n",
			dst->neighbour->dev->name, ndev->name);
	}

	cdev = cxgbi_device_find_by_netdev(ndev, &port);
	cdev = cxgbi_device_find_by_netdev(ndev, &port);
	if (!cdev) {
	if (!cdev) {
		pr_info("dst %pI4, %s, NOT cxgbi device.\n",
		pr_info("dst %pI4, %s, NOT cxgbi device.\n",
@@ -561,9 +543,6 @@ static struct cxgbi_sock *cxgbi_check_route(struct sockaddr *dst_addr)
	csk->dst = dst;
	csk->dst = dst;
	csk->daddr.sin_addr.s_addr = daddr->sin_addr.s_addr;
	csk->daddr.sin_addr.s_addr = daddr->sin_addr.s_addr;
	csk->daddr.sin_port = daddr->sin_port;
	csk->daddr.sin_port = daddr->sin_port;
	if (cdev->hbas[port]->ipv4addr)
		csk->saddr.sin_addr.s_addr = cdev->hbas[port]->ipv4addr;
	else
	csk->saddr.sin_addr.s_addr = rt->rt_src;
	csk->saddr.sin_addr.s_addr = rt->rt_src;


	return csk;
	return csk;
+1 −0
Original line number Original line Diff line number Diff line
@@ -500,6 +500,7 @@ void cxgbi_sock_free_cpl_skbs(struct cxgbi_sock *);


struct cxgbi_hba {
struct cxgbi_hba {
	struct net_device *ndev;
	struct net_device *ndev;
	struct net_device *vdev;	/* vlan dev */
	struct Scsi_Host *shost;
	struct Scsi_Host *shost;
	struct cxgbi_device *cdev;
	struct cxgbi_device *cdev;
	__be32 ipv4addr;
	__be32 ipv4addr;