Netdev List
 help / color / mirror / Atom feed
* [PATCH net-next-2.6] rps: allocate rx queues in register_netdevice only
From: Eric Dumazet @ 2010-09-24  3:26 UTC (permalink / raw)
  To: Ben Hutchings; +Cc: David Miller, netdev, linux-net-drivers, Tom Herbert
In-Reply-To: <1285296505.2380.43.camel@edumazet-laptop>


> Also, I dont understand why we need to restrict
> netif_set_real_num_rx_queues() to lower the count.
> This wastes memory.
> 
> Why dont we allocate dev->_rx once we know the real count, not in
> alloc_netdev_mq() but in register_netdevice() ?
> 
> 

Here is a patch to make this possible

I guess a similar thing could be done for tx queues.

boot tested, but please double check.

Thanks

[PATCH net-next-2.6] rps: allocate rx queues in register_netdevice()

Instead of having two places were we allocate dev->_rx, introduce
netif_alloc_rx_queues() helper and call it only from
register_netdevice(), not from alloc_netdev_mq()

Goal is to let drivers change dev->num_rx_queues after allocating netdev
and before registering it.

This also removes a lot of ifdefs in net/core/dev.c

Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
---
 net/core/dev.c |   76 +++++++++++++++++++----------------------------
 1 file changed, 32 insertions(+), 44 deletions(-)

diff --git a/net/core/dev.c b/net/core/dev.c
index 2c7934f..9110b8d 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -4964,6 +4964,34 @@ void netif_stacked_transfer_operstate(const struct net_device *rootdev,
 }
 EXPORT_SYMBOL(netif_stacked_transfer_operstate);
 
+static int netif_alloc_rx_queues(struct net_device *dev)
+{
+#ifdef CONFIG_RPS
+	unsigned int i, count = dev->num_rx_queues;
+
+	if (count) {
+		struct netdev_rx_queue *rx;
+
+		rx = kcalloc(count, sizeof(struct netdev_rx_queue), GFP_KERNEL);
+		if (!rx) {
+			pr_err("netdev: Unable to allocate %u rx queues.\n",
+			       count);
+			return -ENOMEM;
+		}
+		dev->_rx = rx;
+		atomic_set(&rx->count, count);
+
+		/*
+		 * Set a pointer to first element in the array which holds the
+		 * reference count.
+		 */
+		for (i = 0; i < count; i++)
+			rx[i].first = rx;
+	}
+#endif
+	return 0;
+}
+
 /**
  *	register_netdevice	- register a network device
  *	@dev: device to register
@@ -5001,24 +5029,10 @@ int register_netdevice(struct net_device *dev)
 
 	dev->iflink = -1;
 
-#ifdef CONFIG_RPS
-	if (!dev->num_rx_queues) {
-		/*
-		 * Allocate a single RX queue if driver never called
-		 * alloc_netdev_mq
-		 */
-
-		dev->_rx = kzalloc(sizeof(struct netdev_rx_queue), GFP_KERNEL);
-		if (!dev->_rx) {
-			ret = -ENOMEM;
-			goto out;
-		}
+	ret = netif_alloc_rx_queues(dev);
+	if (ret)
+		goto out;
 
-		dev->_rx->first = dev->_rx;
-		atomic_set(&dev->_rx->count, 1);
-		dev->num_rx_queues = 1;
-	}
-#endif
 	/* Init, if this function is available */
 	if (dev->netdev_ops->ndo_init) {
 		ret = dev->netdev_ops->ndo_init(dev);
@@ -5414,10 +5428,6 @@ struct net_device *alloc_netdev_mq(int sizeof_priv, const char *name,
 	struct net_device *dev;
 	size_t alloc_size;
 	struct net_device *p;
-#ifdef CONFIG_RPS
-	struct netdev_rx_queue *rx;
-	int i;
-#endif
 
 	BUG_ON(strlen(name) >= sizeof(dev->name));
 
@@ -5443,29 +5453,12 @@ struct net_device *alloc_netdev_mq(int sizeof_priv, const char *name,
 		goto free_p;
 	}
 
-#ifdef CONFIG_RPS
-	rx = kcalloc(queue_count, sizeof(struct netdev_rx_queue), GFP_KERNEL);
-	if (!rx) {
-		printk(KERN_ERR "alloc_netdev: Unable to allocate "
-		       "rx queues.\n");
-		goto free_tx;
-	}
-
-	atomic_set(&rx->count, queue_count);
-
-	/*
-	 * Set a pointer to first element in the array which holds the
-	 * reference count.
-	 */
-	for (i = 0; i < queue_count; i++)
-		rx[i].first = rx;
-#endif
 
 	dev = PTR_ALIGN(p, NETDEV_ALIGN);
 	dev->padded = (char *)dev - (char *)p;
 
 	if (dev_addr_init(dev))
-		goto free_rx;
+		goto free_tx;
 
 	dev_mc_init(dev);
 	dev_uc_init(dev);
@@ -5477,7 +5470,6 @@ struct net_device *alloc_netdev_mq(int sizeof_priv, const char *name,
 	dev->real_num_tx_queues = queue_count;
 
 #ifdef CONFIG_RPS
-	dev->_rx = rx;
 	dev->num_rx_queues = queue_count;
 #endif
 
@@ -5495,11 +5487,7 @@ struct net_device *alloc_netdev_mq(int sizeof_priv, const char *name,
 	strcpy(dev->name, name);
 	return dev;
 
-free_rx:
-#ifdef CONFIG_RPS
-	kfree(rx);
 free_tx:
-#endif
 	kfree(tx);
 free_p:
 	kfree(p);



^ permalink raw reply related

* Re: [PATCH net-next-2.6 1/2] net: Allow changing number of RX queues after device allocation
From: Eric Dumazet @ 2010-09-24  2:48 UTC (permalink / raw)
  To: Ben Hutchings; +Cc: David Miller, netdev, linux-net-drivers, Tom Herbert
In-Reply-To: <1285273194.7794.24.camel@achroite.uk.solarflarecom.com>

Le jeudi 23 septembre 2010 à 21:19 +0100, Ben Hutchings a écrit :
> For RPS, we create a kobject for each RX queue based on the number of
> queues passed to alloc_netdev_mq().  However, drivers generally do not
> determine the numbers of hardware queues to use until much later, so
> this usually represents the maximum number the driver may use and not
> the actual number in use.
> 
> For TX queues, drivers can update the actual number using
> netif_set_real_num_tx_queues().  Add a corresponding function for RX
> queues, netif_set_real_num_rx_queues().
> 
> Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
> ---

Seems very good to me, except a minor style issue here :

All functions in this file use a single line.

> -static int rx_queue_register_kobjects(struct net_device *net)
> +int
> +net_rx_queue_update_kobjects(struct net_device *net, int old_num, int new_num)

->

int net_rx_queue_update_kobjects(struct net_device *net, int old, int new)


Also, I dont understand why we need to restrict
netif_set_real_num_rx_queues() to lower the count.
This wastes memory.

Why dont we allocate dev->_rx once we know the real count, not in
alloc_netdev_mq() but in register_netdevice() ?




^ permalink raw reply

* Re: [PATCH] net: reset skb queue mapping when rx'ing over tunnel
From: Eric Dumazet @ 2010-09-24  2:06 UTC (permalink / raw)
  To: Tom Herbert; +Cc: netdev, davem, chavey
In-Reply-To: <alpine.DEB.1.00.1009231415290.25121@pokey.mtv.corp.google.com>

Le jeudi 23 septembre 2010 à 14:19 -0700, Tom Herbert a écrit :
> Reset queue mapping when an skb is reentering the stack via a tunnel.
> On second pass, the queue mapping from the original device is no
> longer valid.
> 
> Signed-off-by: Tom Herbert <therbert@google.com>
> ---
> diff --git a/include/net/dst.h b/include/net/dst.h
> index 81d1413..0238650 100644
> --- a/include/net/dst.h
> +++ b/include/net/dst.h
> @@ -242,6 +242,7 @@ static inline void skb_tunnel_rx(struct sk_buff *skb, struct net_device *dev)
>  	dev->stats.rx_packets++;
>  	dev->stats.rx_bytes += skb->len;
>  	skb->rxhash = 0;
> +	skb_set_queue_mapping(skb, 0);
>  	skb_dst_drop(skb);
>  	nf_reset(skb);
>  }
> --

Hmm...

This would need to be reverted later when tunnels are updated to be
multiqueue aware ? I made an attempt with GRE some days ago.

I dont understand why this patch is needed, since get_rps_cpu() has a
check anyway

        if (skb_rx_queue_recorded(skb)) {
                u16 index = skb_get_rx_queue(skb);
                if (unlikely(index >= dev->num_rx_queues)) {
                        WARN_ONCE(dev->num_rx_queues > 1, "%s received packet "
                                "on queue %u, but number of RX queues is %u\n",
                                dev->name, index, dev->num_rx_queues);
                        goto done;
                }
                rxqueue = dev->_rx + index;
        } else
                rxqueue = dev->_rx;




^ permalink raw reply

* Re: [PATCH v3] xmit_compl_seq: information to reclaim vmsplice buffers
From: Eric Dumazet @ 2010-09-24  1:48 UTC (permalink / raw)
  To: Tom Herbert; +Cc: netdev, davem, sridharr
In-Reply-To: <alpine.DEB.1.00.1009231426450.11579@pokey.mtv.corp.google.com>

Le jeudi 23 septembre 2010 à 14:35 -0700, Tom Herbert a écrit :

> diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
> index 3e8a4db..3d8d33f 100644
> --- a/net/ipv4/tcp.c
> +++ b/net/ipv4/tcp.c
> @@ -1768,6 +1768,12 @@ skip_copy:
>  
>  	TCP_CHECK_TIMER(sk);
>  	release_sock(sk);
> +
> +	/* Copy the first unacked seq into the receive msg control part. */
> +	if (sock_flag(sk, SOCK_XMIT_COMPL_SEQ))
> +		put_cmsg(msg, SOL_SOCKET, SCM_XMIT_COMPL_SEQ,
> +		    sizeof(tp->snd_una), &tp->snd_una);
> +
>  	return copied;
>  
>  out:

Tom,

I took the time to suggest : copy tp->snd_una before release_sock().

Why do you try to avoid this copy and introduce a bug ?

Hint : put_cmsg() (and copy_to_user()) makes no guarantee the copy is
atomic. 

It can be implemented by a 4 bytes copy, faut during this copy or being
interrupted, and application might get a garbled value, if tcp stack
modifies tp->snd_una during the copy.

If you want to optimize this (because release_sock() can process the
socket backlog, and update snd_una), please use :


	/* Copy the first unacked seq into the receive msg control part.
	 * As put_cmsg() might sleep, we must copy snd_una in a private var.
	 * Integer reads are atomic on all arches, so this copy can be
	 * performed while socket is unlocked.
	 */
	if (sock_flag(sk, SOCK_XMIT_COMPL_SEQ)) {
		u32 snd_una = tp->snd_una;

		put_cmsg(msg, SOL_SOCKET, SCM_XMIT_COMPL_SEQ,
			 sizeof(snd_una), &snd_una);
	}

Thanks !



^ permalink raw reply

* Re: [PATCH 1/8] posix clocks: introduce a syscall for clock tuning.
From: Benjamin Herrenschmidt @ 2010-09-24  1:20 UTC (permalink / raw)
  To: Thomas Gleixner
  Cc: Peter Zijlstra, John Stultz, Richard Cochran,
	linuxppc-dev-uLR06cmDAlY/bJ5BZ2RsiQ, LKML, David Miller,
	netdev-u79uwXL29TY76Z2rM5mHXA, linux-api-u79uwXL29TY76Z2rM5mHXA,
	Christoph Lameter, Rodolfo Giometti,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	Krzysztof Halasa
In-Reply-To: <alpine.LFD.2.00.1009240008390.2416-bi+AKbBUZKagILUCTcTcHdKyNwTtLsGr@public.gmane.org>

On Fri, 2010-09-24 at 00:12 +0200, Thomas Gleixner wrote:
> > This list is getting way too much unrelated stuff, which I find
> > annoying, it would be nice if we were all a bit more careful here
> with
> > our CC lists.
> 
> Says the guy who missed to trim the useless context of the original
> mail, which made me scroll down all the way just to find out that
> there is nothing to see. 

Heh, you can usually ignore what's after my signature :-) At least I
didn't put my reply all the way down the bottom !

Cheers,
Ben.

^ permalink raw reply

* bonding vs GSO vs checksumming.
From: Maciej Żenczykowski @ 2010-09-24  0:56 UTC (permalink / raw)
  To: Herbert Xu; +Cc: Linux NetDev

I'm seeing the following:

bonding: caps=(0x1113a3, 0x1113ab) len=18192 data_len=18120 ip_summed=0

on a 2.6.34.5 based kernel originating from v6 tcp transmit (mtu 1280)
on a bonded device of tg3 (presumably with TSO6) and forcedeth
(presumably without TSO6).

I can't quite figure out what this truly means...

Help ;-)

^ permalink raw reply

* [PATCH 3/4] cxgb3i: fixed connection over vlan
From: kxie @ 2010-09-23 23:43 UTC (permalink / raw)
  To: netdev, linux-scsi, open-iscsi
  Cc: rranjan, kxie, James.Bottomley, michaelc, davem

[PATCH 3/4] cxgb3i: fixed connection over vlan
          
From: Karen Xie <kxie@chelsio.com>
          
This patch fixed the problem of connecting over VLAN.

Signed-off-by: Karen Xie <kxie@chelsio.com>
---

 drivers/scsi/cxgbi/cxgb3i/cxgb3i.c |   47 +++++++++++++++++++++++++++++++-----
 drivers/scsi/cxgbi/libcxgbi.c      |   37 ++++++----------------------
 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 a2c207f..a129a17 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)
 	struct cxgbi_sock *csk = ctx;
 	struct cpl_act_open_rpl *rpl = cplhdr(skb);
 
-	log_debug(1 << CXGBI_DBG_TOE | 1 << CXGBI_DBG_SOCK,
-		"csk 0x%p,%u,0x%lx,%u, status %u.\n",
-		csk, csk->state, csk->flags, csk->atid, rpl->status);
+	pr_info("csk 0x%p,%u,0x%lx,%u, status %u, %pI4:%u-%pI4:%u.\n",
+		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 &&
 	    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) {
 	case CPL_ERR_BAD_SYN: /* fall through */
 	case CPL_ERR_CONN_RESET:
-		return csk->state > CTP_ESTABLISHED ?
-			-EPIPE : -ECONNRESET;
+		return csk->state > CTP_ESTABLISHED ? -EPIPE : -ECONNRESET;
 	case CPL_ERR_XMIT_TIMEDOUT:
 	case CPL_ERR_PERSIST_TIMEDOUT:
 	case CPL_ERR_FINWAIT2_TIMEDOUT:
@@ -945,17 +945,44 @@ static void release_offload_resources(struct cxgbi_sock *csk)
 	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)
 {
 	struct dst_entry *dst = csk->dst;
 	struct cxgbi_device *cdev = csk->cdev;
 	struct t3cdev *t3dev = (struct t3cdev *)cdev->lldev;
 	struct net_device *ndev = cdev->ports[csk->port_id];
+	struct cxgbi_hba *chba = cdev->hbas[csk->port_id];
 	struct sk_buff *skb = NULL;
 
 	log_debug(1 << CXGBI_DBG_TOE | 1 << CXGBI_DBG_SOCK,
 		"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->l2t = t3_l2t_get(t3dev, dst->neighbour, ndev);
 	if (!csk->l2t) {
@@ -984,6 +1011,12 @@ static int init_act_open(struct cxgbi_sock *csk)
 	cxgbi_sock_reset_wr_list(csk);
 	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);
 	send_act_open_req(csk, skb, csk->l2t);
 	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++) {
 		struct sk_buff *skb = alloc_wr(sizeof(struct ulp_mem_io) +
 						PPOD_SIZE, 0, gfp);
-		if (skb) {
+		if (skb)
 			ddp->gl_skb[idx + i] = skb;
-		} else {
+		else {
 			ddp_free_gl_skb(ddp, idx, i);
 			return -ENOMEM;
 		}
diff --git a/drivers/scsi/cxgbi/libcxgbi.c b/drivers/scsi/cxgbi/libcxgbi.c
index 7136fb2..f3fab74 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);
 static struct cxgbi_device *cxgbi_device_find_by_netdev(struct net_device *ndev,
 							int *port)
 {
+	struct net_device *vdev = NULL;
 	struct cxgbi_device *cdev, *tmp;
 	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);
+		log_debug(1 << CXGBI_DBG_DEV,
+			"vlan dev %s -> %s.\n", vdev->name, ndev->name);
+	}
 
 	mutex_lock(&cdev_mutex);
 	list_for_each_entry_safe(cdev, tmp, &cdev_list, list_head) {
 		for (i = 0; i < cdev->nports; i++) {
 			if (ndev == cdev->ports[i]) {
+				cdev->hbas[i]->vdev = vdev;
 				mutex_unlock(&cdev_mutex);
 				if (port)
 					*port = i;
@@ -218,24 +224,6 @@ static struct cxgbi_device *cxgbi_device_find_by_netdev(struct net_device *ndev,
 	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)
 {
 	int i;
@@ -532,12 +520,6 @@ static struct cxgbi_sock *cxgbi_check_route(struct sockaddr *dst_addr)
 			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);
 	if (!cdev) {
 		pr_info("dst %pI4, %s, NOT cxgbi device.\n",
@@ -561,10 +543,7 @@ static struct cxgbi_sock *cxgbi_check_route(struct sockaddr *dst_addr)
 	csk->dst = dst;
 	csk->daddr.sin_addr.s_addr = daddr->sin_addr.s_addr;
 	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;
 
diff --git a/drivers/scsi/cxgbi/libcxgbi.h b/drivers/scsi/cxgbi/libcxgbi.h
index 48e6d62..43025b7 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 *);
 
 struct cxgbi_hba {
 	struct net_device *ndev;
+	struct net_device *vdev;	/* vlan dev */
 	struct Scsi_Host *shost;
 	struct cxgbi_device *cdev;
 	__be32 ipv4addr;

^ permalink raw reply related

* [PATCH 2/4] libcxgbi: pdu read fixes
From: kxie-ut6Up61K2wZBDgjK7y7TUQ @ 2010-09-23 23:43 UTC (permalink / raw)
  To: netdev-u79uwXL29TY76Z2rM5mHXA, linux-scsi-u79uwXL29TY76Z2rM5mHXA,
	open-iscsi-/JYPxA39Uh5TLH3MbocFFw
  Cc: rranjan-ut6Up61K2wZBDgjK7y7TUQ, kxie-ut6Up61K2wZBDgjK7y7TUQ,
	James.Bottomley-d9PhHud1JfjCXq6kfMZ53/egYHeGw8Jk,
	michaelc-hcNo3dDEHLuVc3sceRu5cw, davem-fT/PcQaiUtIeIZ0/mPfg9Q

[PATCH 2/4] libcxgbi: pdu read fixes
          
From: Karen Xie <kxie-ut6Up61K2wZBDgjK7y7TUQ@public.gmane.org>
          
This patch
- fixed the locking and releasing skb in the case of error in the pdu read path, and
- added define iscsi_task_cxgbi_data to access the private data inside the iscsi_task.

Signed-off-by: Karen Xie <kxie-ut6Up61K2wZBDgjK7y7TUQ@public.gmane.org>
---

 drivers/scsi/cxgbi/libcxgbi.c |   79 ++++++++++++++++++++++++++---------------
 drivers/scsi/cxgbi/libcxgbi.h |    2 +
 2 files changed, 53 insertions(+), 28 deletions(-)


diff --git a/drivers/scsi/cxgbi/libcxgbi.c b/drivers/scsi/cxgbi/libcxgbi.c
index db9d08a..7136fb2 100644
--- a/drivers/scsi/cxgbi/libcxgbi.c
+++ b/drivers/scsi/cxgbi/libcxgbi.c
@@ -593,11 +593,11 @@ static void cxgbi_inform_iscsi_conn_closing(struct cxgbi_sock *csk)
 		csk, csk->state, csk->flags, csk->user_data);
 
 	if (csk->state != CTP_ESTABLISHED) {
-		read_lock(&csk->callback_lock);
+		read_lock_bh(&csk->callback_lock);
 		if (csk->user_data)
 			iscsi_conn_failure(csk->user_data,
 					ISCSI_ERR_CONN_FAILED);
-		read_unlock(&csk->callback_lock);
+		read_unlock_bh(&csk->callback_lock);
 	}
 }
 
@@ -1712,12 +1712,10 @@ void cxgbi_conn_pdu_ready(struct cxgbi_sock *csk)
 			"csk 0x%p, conn 0x%p, id %d, suspend_rx %lu!\n",
 			csk, conn, conn ? conn->id : 0xFF,
 			conn ? conn->suspend_rx : 0xFF);
-		read_unlock(&csk->callback_lock);
 		return;
 	}
 
 	while (!err) {
-		read_lock(&csk->callback_lock);
 		skb = skb_peek(&csk->receive_queue);
 		if (!skb ||
 		    !(cxgbi_skcb_test_flag(skb, SKCBF_RX_STATUS))) {
@@ -1725,11 +1723,9 @@ void cxgbi_conn_pdu_ready(struct cxgbi_sock *csk)
 				log_debug(1 << CXGBI_DBG_PDU_RX,
 					"skb 0x%p, NOT ready 0x%lx.\n",
 					skb, cxgbi_skcb_flags(skb));
-			read_unlock(&csk->callback_lock);
 			break;
 		}
 		__skb_unlink(skb, &csk->receive_queue);
-		read_unlock(&csk->callback_lock);
 
 		read += cxgbi_skcb_rx_pdulen(skb);
 		log_debug(1 << CXGBI_DBG_PDU_RX,
@@ -1739,37 +1735,66 @@ void cxgbi_conn_pdu_ready(struct cxgbi_sock *csk)
 
 		if (cxgbi_skcb_test_flag(skb, SKCBF_RX_COALESCED)) {
 			err = skb_read_pdu_bhs(conn, skb);
-			if (err < 0)
-				break;
+			if (err < 0) {
+				pr_err("coalesced bhs, csk 0x%p, skb 0x%p,%u, "
+					"f 0x%lx, plen %u.\n",
+					csk, skb, skb->len,
+					cxgbi_skcb_flags(skb),
+					cxgbi_skcb_rx_pdulen(skb));
+				goto skb_done;
+			}
 			err = skb_read_pdu_data(conn, skb, skb,
 						err + cdev->skb_rx_extra);
+			if (err < 0)
+				pr_err("coalesced data, csk 0x%p, skb 0x%p,%u, "
+					"f 0x%lx, plen %u.\n",
+					csk, skb, skb->len,
+					cxgbi_skcb_flags(skb),
+					cxgbi_skcb_rx_pdulen(skb));
 		} else {
 			err = skb_read_pdu_bhs(conn, skb);
-			if (err < 0)
-				break;
+			if (err < 0) {
+				pr_err("bhs, csk 0x%p, skb 0x%p,%u, "
+					"f 0x%lx, plen %u.\n",
+					csk, skb, skb->len,
+					cxgbi_skcb_flags(skb),
+					cxgbi_skcb_rx_pdulen(skb));
+				goto skb_done;
+			}
+
 			if (cxgbi_skcb_test_flag(skb, SKCBF_RX_DATA)) {
 				struct sk_buff *dskb;
 
-				read_lock(&csk->callback_lock);
 				dskb = skb_peek(&csk->receive_queue);
 				if (!dskb) {
-					read_unlock(&csk->callback_lock);
-					pr_err("csk 0x%p, NO data.\n", csk);
-					err = -EAGAIN;
-					break;
+					pr_err("csk 0x%p, skb 0x%p,%u, f 0x%lx,"
+						" plen %u, NO data.\n",
+						csk, skb, skb->len,
+						cxgbi_skcb_flags(skb),
+						cxgbi_skcb_rx_pdulen(skb));
+					err = -EIO;
+					goto skb_done;
 				}
 				__skb_unlink(dskb, &csk->receive_queue);
-				read_unlock(&csk->callback_lock);
 
 				err = skb_read_pdu_data(conn, skb, dskb, 0);
+				if (err < 0)
+					pr_err("data, csk 0x%p, skb 0x%p,%u, "
+						"f 0x%lx, plen %u, dskb 0x%p,"
+						"%u.\n",
+						csk, skb, skb->len,
+						cxgbi_skcb_flags(skb),
+						cxgbi_skcb_rx_pdulen(skb),
+						dskb, dskb->len);
 				__kfree_skb(dskb);
 			} else
 				err = skb_read_pdu_data(conn, skb, skb, 0);
 		}
+skb_done:
+		__kfree_skb(skb);
+
 		if (err < 0)
 			break;
-
-		__kfree_skb(skb);
 	}
 
 	log_debug(1 << CXGBI_DBG_PDU_RX, "csk 0x%p, read %u.\n", csk, read);
@@ -1780,7 +1805,8 @@ void cxgbi_conn_pdu_ready(struct cxgbi_sock *csk)
 	}
 
 	if (err < 0) {
-		pr_info("csk 0x%p, 0x%p, rx failed %d.\n", csk, conn, err);
+		pr_info("csk 0x%p, 0x%p, rx failed %d, read %u.\n",
+			csk, conn, err, read);
 		iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED);
 	}
 }
@@ -1861,7 +1887,7 @@ int cxgbi_conn_alloc_pdu(struct iscsi_task *task, u8 opcode)
 	struct cxgbi_device *cdev = cconn->chba->cdev;
 	struct iscsi_conn *conn = task->conn;
 	struct iscsi_tcp_task *tcp_task = task->dd_data;
-	struct cxgbi_task_data *tdata = task->dd_data + sizeof(*tcp_task);
+	struct cxgbi_task_data *tdata = iscsi_task_cxgbi_data(task);
 	struct scsi_cmnd *sc = task->sc;
 	int headroom = SKB_TX_ISCSI_PDU_HEADER_MAX;
 
@@ -1916,8 +1942,7 @@ int cxgbi_conn_init_pdu(struct iscsi_task *task, unsigned int offset,
 			      unsigned int count)
 {
 	struct iscsi_conn *conn = task->conn;
-	struct iscsi_tcp_task *tcp_task = task->dd_data;
-	struct cxgbi_task_data *tdata = tcp_task->dd_data;
+	struct cxgbi_task_data *tdata = iscsi_task_cxgbi_data(task);
 	struct sk_buff *skb = tdata->skb;
 	unsigned int datalen = count;
 	int i, padlen = iscsi_padding(count);
@@ -2019,8 +2044,7 @@ int cxgbi_conn_xmit_pdu(struct iscsi_task *task)
 {
 	struct iscsi_tcp_conn *tcp_conn = task->conn->dd_data;
 	struct cxgbi_conn *cconn = tcp_conn->dd_data;
-	struct iscsi_tcp_task *tcp_task = task->dd_data;
-	struct cxgbi_task_data *tdata = tcp_task->dd_data;
+	struct cxgbi_task_data *tdata = iscsi_task_cxgbi_data(task);
 	struct sk_buff *skb = tdata->skb;
 	unsigned int datalen;
 	int err;
@@ -2072,8 +2096,7 @@ EXPORT_SYMBOL_GPL(cxgbi_conn_xmit_pdu);
 
 void cxgbi_cleanup_task(struct iscsi_task *task)
 {
-	struct cxgbi_task_data *tdata = task->dd_data +
-				sizeof(struct iscsi_tcp_task);
+	struct cxgbi_task_data *tdata = iscsi_task_cxgbi_data(task);
 
 	log_debug(1 << CXGBI_DBG_ISCSI,
 		"task 0x%p, skb 0x%p, itt 0x%x.\n",
@@ -2290,12 +2313,12 @@ int cxgbi_bind_conn(struct iscsi_cls_session *cls_session,
 	/*  calculate the tag idx bits needed for this conn based on cmds_max */
 	cconn->task_idx_bits = (__ilog2_u32(conn->session->cmds_max - 1)) + 1;
 
-	write_lock(&csk->callback_lock);
+	write_lock_bh(&csk->callback_lock);
 	csk->user_data = conn;
 	cconn->chba = cep->chba;
 	cconn->cep = cep;
 	cep->cconn = cconn;
-	write_unlock(&csk->callback_lock);
+	write_unlock_bh(&csk->callback_lock);
 
 	cxgbi_conn_max_xmit_dlength(conn);
 	cxgbi_conn_max_recv_dlength(conn);
diff --git a/drivers/scsi/cxgbi/libcxgbi.h b/drivers/scsi/cxgbi/libcxgbi.h
index 2f2485b..48e6d62 100644
--- a/drivers/scsi/cxgbi/libcxgbi.h
+++ b/drivers/scsi/cxgbi/libcxgbi.h
@@ -592,6 +592,8 @@ struct cxgbi_task_data {
 	unsigned int count;
 	unsigned int sgoffset;
 };
+#define iscsi_task_cxgbi_data(task) \
+	((task)->dd_data + sizeof(struct iscsi_tcp_task))
 
 static inline int cxgbi_is_ddp_tag(struct cxgbi_tag_format *tformat, u32 tag)
 {

-- 
You received this message because you are subscribed to the Google Groups "open-iscsi" group.
To post to this group, send email to open-iscsi-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org
To unsubscribe from this group, send email to open-iscsi+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org
For more options, visit this group at http://groups.google.com/group/open-iscsi?hl=en.

^ permalink raw reply related

* [PATCH 4/4] cxgb4i: connection and ddp setting update
From: kxie-ut6Up61K2wZBDgjK7y7TUQ @ 2010-09-23 23:43 UTC (permalink / raw)
  To: netdev-u79uwXL29TY76Z2rM5mHXA, linux-scsi-u79uwXL29TY76Z2rM5mHXA,
	open-iscsi-/JYPxA39Uh5TLH3MbocFFw
  Cc: rranjan-ut6Up61K2wZBDgjK7y7TUQ, kxie-ut6Up61K2wZBDgjK7y7TUQ,
	James.Bottomley-d9PhHud1JfjCXq6kfMZ53/egYHeGw8Jk,
	michaelc-hcNo3dDEHLuVc3sceRu5cw, davem-fT/PcQaiUtIeIZ0/mPfg9Q

[PATCH 4/4] cxgb4i: connection and ddp setting update
          
From: Karen Xie <kxie-ut6Up61K2wZBDgjK7y7TUQ@public.gmane.org>
          
This patch updated cxgb4i connection setting and pagepod programming.

Signed-off-by: Karen Xie <kxie-ut6Up61K2wZBDgjK7y7TUQ@public.gmane.org>
---

 drivers/scsi/cxgbi/cxgb4i/cxgb4i.c |  128 +++++++++++++++++++-----------------
 drivers/scsi/cxgbi/cxgb4i/cxgb4i.h |    5 +
 drivers/scsi/cxgbi/libcxgbi.h      |   10 ---
 3 files changed, 71 insertions(+), 72 deletions(-)


diff --git a/drivers/scsi/cxgbi/cxgb4i/cxgb4i.c b/drivers/scsi/cxgbi/cxgb4i/cxgb4i.c
index 1056d97..99f2b8c 100644
--- a/drivers/scsi/cxgbi/cxgb4i/cxgb4i.c
+++ b/drivers/scsi/cxgbi/cxgb4i/cxgb4i.c
@@ -34,8 +34,8 @@ static unsigned int dbg_level;
 
 #define	DRV_MODULE_NAME		"cxgb4i"
 #define DRV_MODULE_DESC		"Chelsio T4 iSCSI Driver"
-#define	DRV_MODULE_VERSION	"0.9.0"
-#define	DRV_MODULE_RELDATE	"May 2010"
+#define	DRV_MODULE_VERSION	"0.9.1"
+#define	DRV_MODULE_RELDATE	"Aug. 2010"
 
 static char version[] =
 	DRV_MODULE_DESC " " DRV_MODULE_NAME
@@ -396,7 +396,7 @@ static inline void send_tx_flowc_wr(struct cxgbi_sock *csk)
 		htonl(FW_WR_LEN16(DIV_ROUND_UP(72, 16)) |
 				FW_WR_FLOWID(csk->tid));
 	flowc->mnemval[0].mnemonic = FW_FLOWC_MNEM_PFNVFN;
-	flowc->mnemval[0].val = htonl(0);
+	flowc->mnemval[0].val = htonl(csk->cdev->pfvf);
 	flowc->mnemval[1].mnemonic = FW_FLOWC_MNEM_CH;
 	flowc->mnemval[1].val = htonl(csk->tx_chan);
 	flowc->mnemval[2].mnemonic = FW_FLOWC_MNEM_PORT;
@@ -568,6 +568,12 @@ static void do_act_establish(struct cxgbi_device *cdev, struct sk_buff *skb)
 		goto rel_skb;
 	}
 
+	if (csk->atid != atid) {
+		pr_err("bad conn atid %u, csk 0x%p,%u,0x%lx,tid %u, atid %u.\n",
+			atid, csk, csk->state, csk->flags, csk->tid, csk->atid);
+		goto rel_skb;
+	}
+
 	log_debug(1 << CXGBI_DBG_TOE | 1 << CXGBI_DBG_SOCK,
 		"csk 0x%p,%u,0x%lx, tid %u, atid %u, rseq %u.\n",
 		csk, csk->state, csk->flags, tid, atid, rcv_isn);
@@ -681,9 +687,10 @@ static void do_act_open_rpl(struct cxgbi_device *cdev, struct sk_buff *skb)
 		goto rel_skb;
 	}
 
-	log_debug(1 << CXGBI_DBG_TOE | 1 << CXGBI_DBG_SOCK,
-		"csk 0x%p,%u,0x%lx, status %u, atid %u, tid %u.\n",
-			csk, csk->state, csk->flags, status, atid, tid);
+	pr_info("%pI4:%u-%pI4:%u, atid %u,%u, status %u, csk 0x%p,%u,0x%lx.\n",
+		&csk->saddr.sin_addr.s_addr, ntohs(csk->saddr.sin_port),
+		&csk->daddr.sin_addr.s_addr, ntohs(csk->daddr.sin_port),
+		atid, tid, status, csk, csk->state, csk->flags);
 
 	if (status && status != CPL_ERR_TCAM_FULL &&
 	    status != CPL_ERR_CONN_EXIST &&
@@ -846,7 +853,6 @@ static void do_rx_iscsi_hdr(struct cxgbi_device *cdev, struct sk_buff *skb)
 	unsigned int tid = GET_TID(cpl);
 	struct cxgb4_lld_info *lldi = cxgbi_cdev_priv(cdev);
 	struct tid_info *t = lldi->tids;
-	struct sk_buff *lskb;
 
 	csk = lookup_tid(t, tid);
 	if (unlikely(!csk)) {
@@ -872,6 +878,8 @@ static void do_rx_iscsi_hdr(struct cxgbi_device *cdev, struct sk_buff *skb)
 	}
 
 	cxgbi_skcb_tcp_seq(skb) = ntohl(cpl->seq);
+	cxgbi_skcb_flags(skb) = 0;
+
 	skb_reset_transport_header(skb);
 	__skb_pull(skb, sizeof(*cpl));
 	__pskb_trim(skb, ntohs(cpl->len));
@@ -884,17 +892,16 @@ static void do_rx_iscsi_hdr(struct cxgbi_device *cdev, struct sk_buff *skb)
 			"csk 0x%p,%u,0x%lx, tid %u, skb 0x%p header.\n",
 			csk, csk->state, csk->flags, csk->tid, skb);
 		csk->skb_ulp_lhdr = skb;
-		lskb = csk->skb_ulp_lhdr;
-		cxgbi_skcb_set_flag(lskb, SKCBF_RX_HDR);
+		cxgbi_skcb_set_flag(skb, SKCBF_RX_HDR);
 
-		if (cxgbi_skcb_tcp_seq(lskb) != csk->rcv_nxt) {
+		if (cxgbi_skcb_tcp_seq(skb) != csk->rcv_nxt) {
 			pr_info("tid %u, CPL_ISCSI_HDR, bad seq, 0x%x/0x%x.\n",
-				csk->tid, cxgbi_skcb_tcp_seq(lskb),
+				csk->tid, cxgbi_skcb_tcp_seq(skb),
 				csk->rcv_nxt);
 			goto abort_conn;
 		}
 
-		bhs = lskb->data;
+		bhs = skb->data;
 		hlen = ntohs(cpl->len);
 		dlen = ntohl(*(unsigned int *)(bhs + 4)) & 0xFFFFFF;
 
@@ -918,9 +925,9 @@ static void do_rx_iscsi_hdr(struct cxgbi_device *cdev, struct sk_buff *skb)
 			ntohl(*((unsigned int *)(bhs + 24))));
 
 	} else {
-		lskb = csk->skb_ulp_lhdr;
-		cxgbi_skcb_set_flag(lskb, SKCBF_RX_DATA);
+		struct sk_buff *lskb = csk->skb_ulp_lhdr;
 
+		cxgbi_skcb_set_flag(lskb, SKCBF_RX_DATA);
 		log_debug(1 << CXGBI_DBG_TOE | 1 << CXGBI_DBG_PDU_RX,
 			"csk 0x%p,%u,0x%lx, skb 0x%p data, 0x%p.\n",
 			csk, csk->state, csk->flags, skb, lskb);
@@ -979,7 +986,6 @@ static void do_rx_data_ddp(struct cxgbi_device *cdev,
 	lskb = csk->skb_ulp_lhdr;
 	csk->skb_ulp_lhdr = NULL;
 
-	cxgbi_skcb_set_flag(lskb, SKCBF_RX_STATUS);
 	cxgbi_skcb_rx_ddigest(lskb) = ntohl(rpl->ulp_crc);
 
 	if (ntohs(rpl->len) != cxgbi_skcb_rx_pdulen(lskb))
@@ -987,15 +993,13 @@ static void do_rx_data_ddp(struct cxgbi_device *cdev,
 			csk->tid, ntohs(rpl->len), cxgbi_skcb_rx_pdulen(lskb));
 
 	if (status & (1 << CPL_RX_DDP_STATUS_HCRC_SHIFT)) {
-		log_debug(1 << CXGBI_DBG_PDU_RX,
-			"csk 0x%p, lhdr 0x%p, status 0x%x, hcrc bad.\n",
-			csk, lskb, status);
+		pr_info("csk 0x%p, lhdr 0x%p, status 0x%x, hcrc bad 0x%lx.\n",
+			csk, lskb, status, cxgbi_skcb_flags(lskb));
 		cxgbi_skcb_set_flag(lskb, SKCBF_RX_HCRC_ERR);
 	}
 	if (status & (1 << CPL_RX_DDP_STATUS_DCRC_SHIFT)) {
-		log_debug(1 << CXGBI_DBG_PDU_RX,
-			"csk 0x%p, lhdr 0x%p, status 0x%x, dcrc bad.\n",
-			csk, lskb, status);
+		pr_info("csk 0x%p, lhdr 0x%p, status 0x%x, dcrc bad 0x%lx.\n",
+			csk, lskb, status, cxgbi_skcb_flags(lskb));
 		cxgbi_skcb_set_flag(lskb, SKCBF_RX_DCRC_ERR);
 	}
 	if (status & (1 << CPL_RX_DDP_STATUS_PAD_SHIFT)) {
@@ -1015,6 +1019,7 @@ static void do_rx_data_ddp(struct cxgbi_device *cdev,
 		"csk 0x%p, lskb 0x%p, f 0x%lx.\n",
 		csk, lskb, cxgbi_skcb_flags(lskb));
 
+	cxgbi_skcb_set_flag(lskb, SKCBF_RX_STATUS);
 	cxgbi_conn_pdu_ready(csk);
 	spin_unlock_bh(&csk->lock);
 	goto rel_skb;
@@ -1234,41 +1239,41 @@ int cxgb4i_ofld_init(struct cxgbi_device *cdev)
 /*
  * functions to program the pagepod in h/w
  */
+#define ULPMEM_IDATA_MAX_NPPODS	4 /* 256/PPOD_SIZE */
 static inline void ulp_mem_io_set_hdr(struct ulp_mem_io *req,
-				unsigned int dlen, unsigned int pm_addr)
+				unsigned int wr_len, unsigned int dlen,
+				unsigned int pm_addr)
 {
-	struct ulptx_sgl *sgl;
-	unsigned int wr_len = roundup(sizeof(struct ulp_mem_io) +
-					sizeof(struct ulptx_sgl), 16);
+	struct ulptx_idata *idata = (struct ulptx_idata *)(req + 1);
 
 	INIT_ULPTX_WR(req, wr_len, 0, 0);
-	req->cmd = htonl(ULPTX_CMD(ULP_TX_MEM_WRITE));
+	req->cmd = htonl(ULPTX_CMD(ULP_TX_MEM_WRITE) | (1 << 23));
 	req->dlen = htonl(ULP_MEMIO_DATA_LEN(dlen >> 5));
 	req->lock_addr = htonl(ULP_MEMIO_ADDR(pm_addr >> 5));
 	req->len16 = htonl(DIV_ROUND_UP(wr_len - sizeof(req->wr), 16));
-	sgl = (struct ulptx_sgl *)(req + 1);
-	sgl->cmd_nsge = htonl(ULPTX_CMD(ULP_TX_SC_DSGL) | ULPTX_NSGE(1));
-	sgl->len0 = htonl(dlen);
+
+	idata->cmd_more = htonl(ULPTX_CMD(ULP_TX_SC_IMM));
+	idata->len = htonl(dlen);
 }
 
-static int ddp_ppod_write_sgl(struct cxgbi_device *cdev, unsigned int port_id,
+static int ddp_ppod_write_idata(struct cxgbi_device *cdev, unsigned int port_id,
 				struct cxgbi_pagepod_hdr *hdr, unsigned int idx,
 				unsigned int npods,
 				struct cxgbi_gather_list *gl,
 				unsigned int gl_pidx)
 {
 	struct cxgbi_ddp_info *ddp = cdev->ddp;
-	unsigned int dlen, pm_addr;
 	struct sk_buff *skb;
 	struct ulp_mem_io *req;
-	struct ulptx_sgl *sgl;
+	struct ulptx_idata *idata;
 	struct cxgbi_pagepod *ppod;
+	unsigned int pm_addr = idx * PPOD_SIZE + ddp->llimit;
+	unsigned int dlen = PPOD_SIZE * npods;
+	unsigned int wr_len = roundup(sizeof(struct ulp_mem_io) +
+				sizeof(struct ulptx_idata) + dlen, 16);
 	unsigned int i;
 
-	dlen = PPOD_SIZE * npods;
-	pm_addr = idx * PPOD_SIZE + ddp->llimit;
-
-	skb = alloc_wr(sizeof(*req) + sizeof(*sgl), dlen, GFP_ATOMIC);
+	skb = alloc_wr(wr_len, 0, GFP_ATOMIC);
 	if (!skb) {
 		pr_err("cdev 0x%p, idx %u, npods %u, OOM.\n",
 			cdev, idx, npods);
@@ -1277,10 +1282,9 @@ static int ddp_ppod_write_sgl(struct cxgbi_device *cdev, unsigned int port_id,
 	req = (struct ulp_mem_io *)skb->head;
 	set_queue(skb, CPL_PRIORITY_CONTROL, NULL);
 
-	ulp_mem_io_set_hdr(req, dlen, pm_addr);
-	sgl = (struct ulptx_sgl *)(req + 1);
-	ppod = (struct cxgbi_pagepod *)(sgl + 1);
-	sgl->addr0 = cpu_to_be64(virt_to_phys(ppod));
+	ulp_mem_io_set_hdr(req, wr_len, dlen, pm_addr);
+	idata = (struct ulptx_idata *)(req + 1);
+	ppod = (struct cxgbi_pagepod *)(idata + 1);
 
 	for (i = 0; i < npods; i++, ppod++, gl_pidx += PPOD_PAGES_MAX) {
 		if (!hdr && !gl)
@@ -1302,9 +1306,9 @@ static int ddp_set_map(struct cxgbi_sock *csk, struct cxgbi_pagepod_hdr *hdr,
 
 	for (i = 0; i < npods; i += cnt, idx += cnt) {
 		cnt = npods - i;
-		if (cnt > ULPMEM_DSGL_MAX_NPPODS)
-			cnt = ULPMEM_DSGL_MAX_NPPODS;
-		err = ddp_ppod_write_sgl(csk->cdev, csk->port_id, hdr,
+		if (cnt > ULPMEM_IDATA_MAX_NPPODS)
+			cnt = ULPMEM_IDATA_MAX_NPPODS;
+		err = ddp_ppod_write_idata(csk->cdev, csk->port_id, hdr,
 					idx, cnt, gl, 4 * i);
 		if (err < 0)
 			break;
@@ -1320,9 +1324,9 @@ static void ddp_clear_map(struct cxgbi_hba *chba, unsigned int tag,
 
 	for (i = 0; i < npods; i += cnt, idx += cnt) {
 		cnt = npods - i;
-		if (cnt > ULPMEM_DSGL_MAX_NPPODS)
-			cnt = ULPMEM_DSGL_MAX_NPPODS;
-		err = ddp_ppod_write_sgl(chba->cdev, chba->port_id, NULL,
+		if (cnt > ULPMEM_IDATA_MAX_NPPODS)
+			cnt = ULPMEM_IDATA_MAX_NPPODS;
+		err = ddp_ppod_write_idata(chba->cdev, chba->port_id, NULL,
 					idx, cnt, NULL, 0);
 		if (err < 0)
 			break;
@@ -1334,26 +1338,22 @@ static int ddp_setup_conn_pgidx(struct cxgbi_sock *csk, unsigned int tid,
 {
 	struct sk_buff *skb;
 	struct cpl_set_tcb_field *req;
-	u64 val = pg_idx < DDP_PGIDX_MAX ? pg_idx : 0;
 
-	if (!pg_idx)
+	if (!pg_idx || pg_idx >= DDP_PGIDX_MAX)
 		return 0;
 
 	skb = alloc_wr(sizeof(*req), 0, GFP_KERNEL);
 	if (!skb)
 		return -ENOMEM;
 
-	/*  set up ulp submode and page size */
-	val = (val & 0x03) << 2;
-	val |= TCB_ULP_TYPE(ULP2_MODE_ISCSI);
-
+	/*  set up ulp page size */
 	req = (struct cpl_set_tcb_field *)skb->head;
 	INIT_TP_WR(req, csk->tid);
 	OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_SET_TCB_FIELD, csk->tid));
 	req->reply_ctrl = htons(NO_REPLY(reply) | QUEUENO(csk->rss_qid));
-	req->word_cookie = htons(TCB_WORD(W_TCB_ULP_RAW));
-	req->mask = cpu_to_be64(TCB_ULP_TYPE(TCB_ULP_TYPE_MASK));
-	req->val = cpu_to_be64(val);
+	req->word_cookie = htons(0);
+	req->mask = cpu_to_be64(0x3 << 8);
+	req->val = cpu_to_be64(pg_idx << 8);
 	set_wr_txq(skb, CPL_PRIORITY_CONTROL, csk->port_id);
 
 	log_debug(1 << CXGBI_DBG_TOE | 1 << CXGBI_DBG_SOCK,
@@ -1368,10 +1368,9 @@ static int ddp_setup_conn_digest(struct cxgbi_sock *csk, unsigned int tid,
 {
 	struct sk_buff *skb;
 	struct cpl_set_tcb_field *req;
-	u64 val = (hcrc ? ULP_CRC_HEADER : 0) | (dcrc ? ULP_CRC_DATA : 0);
 
-	val = TCB_ULP_RAW(val);
-	val |= TCB_ULP_TYPE(ULP2_MODE_ISCSI);
+	if (!hcrc && !dcrc)
+		return 0;
 
 	skb = alloc_wr(sizeof(*req), 0, GFP_KERNEL);
 	if (!skb)
@@ -1379,14 +1378,15 @@ static int ddp_setup_conn_digest(struct cxgbi_sock *csk, unsigned int tid,
 
 	csk->hcrc_len = (hcrc ? 4 : 0);
 	csk->dcrc_len = (dcrc ? 4 : 0);
-	/*  set up ulp submode and page size */
+	/*  set up ulp submode */
 	req = (struct cpl_set_tcb_field *)skb->head;
 	INIT_TP_WR(req, tid);
 	OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_SET_TCB_FIELD, tid));
 	req->reply_ctrl = htons(NO_REPLY(reply) | QUEUENO(csk->rss_qid));
-	req->word_cookie = htons(TCB_WORD(W_TCB_ULP_RAW));
-	req->mask = cpu_to_be64(TCB_ULP_RAW(TCB_ULP_RAW_MASK));
-	req->val = cpu_to_be64(val);
+	req->word_cookie = htons(0);
+	req->mask = cpu_to_be64(0x3 << 4);
+	req->val = cpu_to_be64(((hcrc ? ULP_CRC_HEADER : 0) |
+				(dcrc ? ULP_CRC_DATA : 0)) << 4);
 	set_wr_txq(skb, CPL_PRIORITY_CONTROL, csk->port_id);
 
 	log_debug(1 << CXGBI_DBG_TOE | 1 << CXGBI_DBG_SOCK,
@@ -1477,6 +1477,10 @@ static void *t4_uld_add(const struct cxgb4_lld_info *lldi)
 	cdev->skb_rx_extra = sizeof(struct cpl_iscsi_hdr);
 	cdev->itp = &cxgb4i_iscsi_transport;
 
+	cdev->pfvf = FW_VIID_PFN_GET(cxgb4_port_viid(lldi->ports[0])) << 8;
+	pr_info("cdev 0x%p,%s, pfvf %u.\n",
+		cdev, lldi->ports[0]->name, cdev->pfvf);
+
 	rc = cxgb4i_ddp_init(cdev);
 	if (rc) {
 		pr_info("t4 0x%p ddp init failed.\n", cdev);
diff --git a/drivers/scsi/cxgbi/cxgb4i/cxgb4i.h b/drivers/scsi/cxgbi/cxgb4i/cxgb4i.h
index 342263b..1096026 100644
--- a/drivers/scsi/cxgbi/cxgb4i/cxgb4i.h
+++ b/drivers/scsi/cxgbi/cxgb4i/cxgb4i.h
@@ -23,6 +23,11 @@
 #define CXGB4I_TX_HEADER_LEN \
 	(sizeof(struct fw_ofld_tx_data_wr) + sizeof(struct sge_opaque_hdr))
 
+struct ulptx_idata {
+	__be32 cmd_more;
+	__be32 len;
+};
+
 struct cpl_rx_data_ddp {
 	union opcode_tid ot;
 	__be16 urg;
diff --git a/drivers/scsi/cxgbi/libcxgbi.h b/drivers/scsi/cxgbi/libcxgbi.h
index 43025b7..c57d59d 100644
--- a/drivers/scsi/cxgbi/libcxgbi.h
+++ b/drivers/scsi/cxgbi/libcxgbi.h
@@ -162,16 +162,6 @@ struct cxgbi_ddp_info {
 #define PPOD_VALID(x)		((x) << PPOD_VALID_SHIFT)
 #define PPOD_VALID_FLAG		PPOD_VALID(1U)
 
-#define W_TCB_ULP_TYPE          0
-#define TCB_ULP_TYPE_SHIFT      0
-#define TCB_ULP_TYPE_MASK       0xfULL
-#define TCB_ULP_TYPE(x)         ((x) << TCB_ULP_TYPE_SHIFT)
-
-#define W_TCB_ULP_RAW           0
-#define TCB_ULP_RAW_SHIFT       4
-#define TCB_ULP_RAW_MASK        0xffULL
-#define TCB_ULP_RAW(x)          ((x) << TCB_ULP_RAW_SHIFT)
-
 /*
  * sge_opaque_hdr -
  * Opaque version of structure the SGE stores at skb->head of TX_DATA packets

-- 
You received this message because you are subscribed to the Google Groups "open-iscsi" group.
To post to this group, send email to open-iscsi-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org
To unsubscribe from this group, send email to open-iscsi+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org
For more options, visit this group at http://groups.google.com/group/open-iscsi?hl=en.

^ permalink raw reply related

* [PATCH 1/4] cxgbi: renamed alloc_cpl to alloc_wr
From: kxie-ut6Up61K2wZBDgjK7y7TUQ @ 2010-09-23 23:43 UTC (permalink / raw)
  To: netdev-u79uwXL29TY76Z2rM5mHXA, linux-scsi-u79uwXL29TY76Z2rM5mHXA,
	open-iscsi-/JYPxA39Uh5TLH3MbocFFw
  Cc: rranjan-ut6Up61K2wZBDgjK7y7TUQ, kxie-ut6Up61K2wZBDgjK7y7TUQ,
	James.Bottomley-d9PhHud1JfjCXq6kfMZ53/egYHeGw8Jk,
	michaelc-hcNo3dDEHLuVc3sceRu5cw, davem-fT/PcQaiUtIeIZ0/mPfg9Q

[PATCH 1/4] cxgbi: renamed alloc_cpl to alloc_wr
          
From: Karen Xie <kxie-ut6Up61K2wZBDgjK7y7TUQ@public.gmane.org>
          
This patch renamed alloc_cpl() to alloc_wr().

Signed-off-by: Karen Xie <kxie-ut6Up61K2wZBDgjK7y7TUQ@public.gmane.org>
---

 drivers/scsi/cxgbi/cxgb3i/cxgb3i.c |   18 +++++++++---------
 drivers/scsi/cxgbi/cxgb4i/cxgb4i.c |   28 ++++++++++++++--------------
 drivers/scsi/cxgbi/libcxgbi.h      |    5 ++---
 3 files changed, 25 insertions(+), 26 deletions(-)


diff --git a/drivers/scsi/cxgbi/cxgb3i/cxgb3i.c b/drivers/scsi/cxgbi/cxgb3i/cxgb3i.c
index a01c1e2..a2c207f 100644
--- a/drivers/scsi/cxgbi/cxgb3i/cxgb3i.c
+++ b/drivers/scsi/cxgbi/cxgb3i/cxgb3i.c
@@ -320,7 +320,7 @@ static u32 send_rx_credits(struct cxgbi_sock *csk, u32 credits)
 		"csk 0x%p,%u,0x%lx,%u, credit %u, dack %u.\n",
 		csk, csk->state, csk->flags, csk->tid, credits, dack);
 
-	skb = alloc_cpl(sizeof(*req), 0, GFP_ATOMIC);
+	skb = alloc_wr(sizeof(*req), 0, GFP_ATOMIC);
 	if (!skb) {
 		pr_info("csk 0x%p, credit %u, OOM.\n", csk, credits);
 		return 0;
@@ -572,7 +572,7 @@ static void act_open_retry_timer(unsigned long data)
 
 	cxgbi_sock_get(csk);
 	spin_lock_bh(&csk->lock);
-	skb = alloc_cpl(sizeof(struct cpl_act_open_req), 0, GFP_ATOMIC);
+	skb = alloc_wr(sizeof(struct cpl_act_open_req), 0, GFP_ATOMIC);
 	if (!skb)
 		cxgbi_sock_fail_act_open(csk, -ENOMEM);
 	else {
@@ -881,16 +881,16 @@ static int do_wr_ack(struct t3cdev *cdev, struct sk_buff *skb, void *ctx)
  */
 static int alloc_cpls(struct cxgbi_sock *csk)
 {
-	csk->cpl_close = alloc_cpl(sizeof(struct cpl_close_con_req), 0,
+	csk->cpl_close = alloc_wr(sizeof(struct cpl_close_con_req), 0,
 					GFP_KERNEL);
 	if (!csk->cpl_close)
 		return -ENOMEM;
-	csk->cpl_abort_req = alloc_cpl(sizeof(struct cpl_abort_req), 0,
+	csk->cpl_abort_req = alloc_wr(sizeof(struct cpl_abort_req), 0,
 					GFP_KERNEL);
 	if (!csk->cpl_abort_req)
 		goto free_cpl_skbs;
 
-	csk->cpl_abort_rpl = alloc_cpl(sizeof(struct cpl_abort_rpl), 0,
+	csk->cpl_abort_rpl = alloc_wr(sizeof(struct cpl_abort_rpl), 0,
 					GFP_KERNEL);
 	if (!csk->cpl_abort_rpl)
 		goto free_cpl_skbs;
@@ -972,7 +972,7 @@ static int init_act_open(struct cxgbi_sock *csk)
 	cxgbi_sock_set_flag(csk, CTPF_HAS_ATID);
 	cxgbi_sock_get(csk);
 
-	skb = alloc_cpl(sizeof(struct cpl_act_open_req), 0, GFP_KERNEL);
+	skb = alloc_wr(sizeof(struct cpl_act_open_req), 0, GFP_KERNEL);
 	if (!skb)
 		goto rel_resource;
 	skb->sk = (struct sock *)csk;
@@ -1141,7 +1141,7 @@ static int ddp_alloc_gl_skb(struct cxgbi_ddp_info *ddp, int idx,
 		"ddp 0x%p, idx %d, cnt %d.\n", ddp, idx, cnt);
 
 	for (i = 0; i < cnt; i++) {
-		struct sk_buff *skb = alloc_cpl(sizeof(struct ulp_mem_io) +
+		struct sk_buff *skb = alloc_wr(sizeof(struct ulp_mem_io) +
 						PPOD_SIZE, 0, gfp);
 		if (skb) {
 			ddp->gl_skb[idx + i] = skb;
@@ -1156,7 +1156,7 @@ static int ddp_alloc_gl_skb(struct cxgbi_ddp_info *ddp, int idx,
 static int ddp_setup_conn_pgidx(struct cxgbi_sock *csk,
 				       unsigned int tid, int pg_idx, bool reply)
 {
-	struct sk_buff *skb = alloc_cpl(sizeof(struct cpl_set_tcb_field), 0,
+	struct sk_buff *skb = alloc_wr(sizeof(struct cpl_set_tcb_field), 0,
 					GFP_KERNEL);
 	struct cpl_set_tcb_field *req;
 	u64 val = pg_idx < DDP_PGIDX_MAX ? pg_idx : 0;
@@ -1193,7 +1193,7 @@ static int ddp_setup_conn_pgidx(struct cxgbi_sock *csk,
 static int ddp_setup_conn_digest(struct cxgbi_sock *csk, unsigned int tid,
 			     int hcrc, int dcrc, int reply)
 {
-	struct sk_buff *skb = alloc_cpl(sizeof(struct cpl_set_tcb_field), 0,
+	struct sk_buff *skb = alloc_wr(sizeof(struct cpl_set_tcb_field), 0,
 					GFP_KERNEL);
 	struct cpl_set_tcb_field *req;
 	u64 val = (hcrc ? 1 : 0) | (dcrc ? 2 : 0);
diff --git a/drivers/scsi/cxgbi/cxgb4i/cxgb4i.c b/drivers/scsi/cxgbi/cxgb4i/cxgb4i.c
index b375a68..1056d97 100644
--- a/drivers/scsi/cxgbi/cxgb4i/cxgb4i.c
+++ b/drivers/scsi/cxgbi/cxgb4i/cxgb4i.c
@@ -332,7 +332,7 @@ static u32 send_rx_credits(struct cxgbi_sock *csk, u32 credits)
 		"csk 0x%p,%u,0x%lx,%u, credit %u.\n",
 		csk, csk->state, csk->flags, csk->tid, credits);
 
-	skb = alloc_cpl(sizeof(*req), 0, GFP_ATOMIC);
+	skb = alloc_wr(sizeof(*req), 0, GFP_ATOMIC);
 	if (!skb) {
 		pr_info("csk 0x%p, credit %u, OOM.\n", csk, credits);
 		return 0;
@@ -388,7 +388,7 @@ static inline void send_tx_flowc_wr(struct cxgbi_sock *csk)
 	int flowclen, i;
 
 	flowclen = 80;
-	skb = alloc_cpl(flowclen, 0, GFP_ATOMIC);
+	skb = alloc_wr(flowclen, 0, GFP_ATOMIC);
 	flowc = (struct fw_flowc_wr *)skb->head;
 	flowc->op_to_nparams =
 		htonl(FW_WR_OP(FW_FLOWC_WR) | FW_FLOWC_WR_NPARAMS(8));
@@ -651,7 +651,7 @@ static void csk_act_open_retry_timer(unsigned long data)
 
 	cxgbi_sock_get(csk);
 	spin_lock_bh(&csk->lock);
-	skb = alloc_cpl(sizeof(struct cpl_act_open_req), 0, GFP_ATOMIC);
+	skb = alloc_wr(sizeof(struct cpl_act_open_req), 0, GFP_ATOMIC);
 	if (!skb)
 		cxgbi_sock_fail_act_open(csk, -ENOMEM);
 	else {
@@ -1073,18 +1073,18 @@ static void do_set_tcb_rpl(struct cxgbi_device *cdev, struct sk_buff *skb)
 
 static int alloc_cpls(struct cxgbi_sock *csk)
 {
-	csk->cpl_close = alloc_cpl(sizeof(struct cpl_close_con_req),
-					0, GFP_NOIO);
+	csk->cpl_close = alloc_wr(sizeof(struct cpl_close_con_req),
+					0, GFP_KERNEL);
 	if (!csk->cpl_close)
 		return -ENOMEM;
 
-	csk->cpl_abort_req = alloc_cpl(sizeof(struct cpl_abort_req),
-					0, GFP_NOIO);
+	csk->cpl_abort_req = alloc_wr(sizeof(struct cpl_abort_req),
+					0, GFP_KERNEL);
 	if (!csk->cpl_abort_req)
 		goto free_cpls;
 
-	csk->cpl_abort_rpl = alloc_cpl(sizeof(struct cpl_abort_rpl),
-					0, GFP_NOIO);
+	csk->cpl_abort_rpl = alloc_wr(sizeof(struct cpl_abort_rpl),
+					0, GFP_KERNEL);
 	if (!csk->cpl_abort_rpl)
 		goto free_cpls;
 	return 0;
@@ -1158,7 +1158,7 @@ static int init_act_open(struct cxgbi_sock *csk)
 	}
 	cxgbi_sock_get(csk);
 
-	skb = alloc_cpl(sizeof(struct cpl_act_open_req), 0, GFP_NOIO);
+	skb = alloc_wr(sizeof(struct cpl_act_open_req), 0, GFP_KERNEL);
 	if (!skb)
 		goto rel_resource;
 	skb->sk = (struct sock *)csk;
@@ -1268,7 +1268,7 @@ static int ddp_ppod_write_sgl(struct cxgbi_device *cdev, unsigned int port_id,
 	dlen = PPOD_SIZE * npods;
 	pm_addr = idx * PPOD_SIZE + ddp->llimit;
 
-	skb = alloc_cpl(sizeof(*req) + sizeof(*sgl), dlen, GFP_ATOMIC);
+	skb = alloc_wr(sizeof(*req) + sizeof(*sgl), dlen, GFP_ATOMIC);
 	if (!skb) {
 		pr_err("cdev 0x%p, idx %u, npods %u, OOM.\n",
 			cdev, idx, npods);
@@ -1339,7 +1339,7 @@ static int ddp_setup_conn_pgidx(struct cxgbi_sock *csk, unsigned int tid,
 	if (!pg_idx)
 		return 0;
 
-	skb = alloc_cpl(sizeof(*req), 0, GFP_KERNEL);
+	skb = alloc_wr(sizeof(*req), 0, GFP_KERNEL);
 	if (!skb)
 		return -ENOMEM;
 
@@ -1373,7 +1373,7 @@ static int ddp_setup_conn_digest(struct cxgbi_sock *csk, unsigned int tid,
 	val = TCB_ULP_RAW(val);
 	val |= TCB_ULP_TYPE(ULP2_MODE_ISCSI);
 
-	skb = alloc_cpl(sizeof(*req), 0, GFP_KERNEL);
+	skb = alloc_wr(sizeof(*req), 0, GFP_KERNEL);
 	if (!skb)
 		return -ENOMEM;
 
@@ -1516,7 +1516,7 @@ static int t4_uld_rx_handler(void *handle, const __be64 *rsp,
 	if (pgl == NULL) {
 		unsigned int len = 64 - sizeof(struct rsp_ctrl) - 8;
 
-		skb = alloc_cpl(len, 0, GFP_ATOMIC);
+		skb = alloc_wr(len, 0, GFP_ATOMIC);
 		if (!skb)
 			goto nomem;
 		skb_copy_to_linear_data(skb, &rsp[1], len);
diff --git a/drivers/scsi/cxgbi/libcxgbi.h b/drivers/scsi/cxgbi/libcxgbi.h
index 40551f3..2f2485b 100644
--- a/drivers/scsi/cxgbi/libcxgbi.h
+++ b/drivers/scsi/cxgbi/libcxgbi.h
@@ -410,16 +410,15 @@ static inline unsigned int cxgbi_sock_compute_wscale(unsigned int win)
 	return wscale;
 }
 
-static inline struct sk_buff *alloc_cpl(int cpl_len, int dlen, gfp_t gfp)
+static inline struct sk_buff *alloc_wr(int wrlen, int dlen, gfp_t gfp)
 {
-	int wrlen = roundup(cpl_len, 16);
 	struct sk_buff *skb = alloc_skb(wrlen + dlen, gfp);
 
 	if (skb) {
 		__skb_put(skb, wrlen);
 		memset(skb->head, 0, wrlen + dlen);
 	} else
-		pr_info("alloc cpl skb %u+%u, OOM.\n", cpl_len, dlen);
+		pr_info("alloc cpl wr skb %u+%u, OOM.\n", wrlen, dlen);
 	return skb;
 }
 

-- 
You received this message because you are subscribed to the Google Groups "open-iscsi" group.
To post to this group, send email to open-iscsi-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org
To unsubscribe from this group, send email to open-iscsi+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org
For more options, visit this group at http://groups.google.com/group/open-iscsi?hl=en.

^ permalink raw reply related

* [PATCH 0/4] cxgbi: bug fixes and driver update
From: kxie-ut6Up61K2wZBDgjK7y7TUQ @ 2010-09-23 23:43 UTC (permalink / raw)
  To: netdev-u79uwXL29TY76Z2rM5mHXA, linux-scsi-u79uwXL29TY76Z2rM5mHXA,
	open-iscsi-/JYPxA39Uh5TLH3MbocFFw
  Cc: rranjan-ut6Up61K2wZBDgjK7y7TUQ, kxie-ut6Up61K2wZBDgjK7y7TUQ,
	James.Bottomley-d9PhHud1JfjCXq6kfMZ53/egYHeGw8Jk,
	michaelc-hcNo3dDEHLuVc3sceRu5cw, davem-fT/PcQaiUtIeIZ0/mPfg9Q

[PATCH 0/4] cxgbi: bug fixes and driver update

From: Karen Xie <kxie-ut6Up61K2wZBDgjK7y7TUQ@public.gmane.org>

This patchset includes:
- renamed alloc_cpl() to alloc_wr(),
- fixed locking in pdu read,
- fixed cxgb3i connecting over VLAN, and
- updated cxgb4i connection setting and ddp programming.

Thanks.
Karen

-- 
You received this message because you are subscribed to the Google Groups "open-iscsi" group.
To post to this group, send email to open-iscsi-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org
To unsubscribe from this group, send email to open-iscsi+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org
For more options, visit this group at http://groups.google.com/group/open-iscsi?hl=en.

^ permalink raw reply

* Re: [PATCH v4 0/2] Get and Set Feature Reports on HIDRAW (USB and   Bluetooth)
From: Alan Ott @ 2010-09-23 23:40 UTC (permalink / raw)
  To: Ville Tervo
  Cc: Jiri Kosina, Stefan Achatz, Antonio Ospite, Alexey Dobriyan,
	Tejun Heo, Alan Stern, Greg Kroah-Hartman, Marcel Holtmann,
	Stephane Chatty, Michael Poole, David S. Miller, Bastien Nocera,
	Eric Dumazet, linux-input-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	linux-usb-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	linux-bluetooth-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	netdev-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
In-Reply-To: <20100923162521.GA15641@null>

On 09/23/2010 12:25 PM, Ville Tervo wrote:
> Hi Alan,
>
> On Mon, Aug 16, 2010 at 10:20:57PM +0200, ext Alan Ott wrote:
>    
>> This is version 4. Built against 2.6.35+ revision 320b2b8de12698 .
>>      
>
> I gave a try to to this patch using your test tool [1] and very old BT
> keyboard. I don't have anything else ATM to test with. Is there some BT hid
> devices which support setting and getting features?
>    

A keyboard is the only BT device I've used which has feature reports.

> Shouldn't HIDIOCSFEATURE's bt version have similar wait as HIDIOCGFEATURE to
> get report status back from the device? or is there even any status coming back
> in successful case? Sorry I'm a newbie with HID and trying to understand how
> this should work.
>
> Now it just returns num of send bytes even if the remote device returned some
> error. Which one is the expected behavior?
>    

I made it function the same as the existing hidp_output_raw_report(). 
Nothing in net/bluetooth/hidp/core.c is acked at all. I'm not sure of 
the reasons.

Jiri, Marcel, any ideas?

> Other problem is that Get report is getting now handshake from set report.
>
>
>    

Yeah, that makes sense. I hadn't considered the set_report failing. In 
that case, I guess it means we _must_ wait for an ack for sent packets.

Anyone else agree or disagree?

Alan.


--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* [net-next-2.6 PATCH] ixgbevf: Refactor ring parameter re-size
From: Jeff Kirsher @ 2010-09-23 22:46 UTC (permalink / raw)
  To: davem; +Cc: netdev, gospo, bphilips, Greg Rose, Jeff Kirsher

From: Greg Rose <gregory.v.rose@intel.com>

The function to resize the Tx/Rx rings had the potential to
dereference a NULL pointer and the code would attempt to resize
the Tx ring even if the Rx ring allocation had failed.  This
would cause some confusion in the return code semantics.  Fixed
up to just unwind the allocations if any of them fail and return
an error.

Signed-off-by: Greg Rose <gregory.v.rose@intel.com>
Tested-by: Emil Tantilov <emil.s.tantilov@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---

 drivers/net/ixgbevf/ethtool.c |  153 +++++++++++++++++++++--------------------
 1 files changed, 79 insertions(+), 74 deletions(-)

diff --git a/drivers/net/ixgbevf/ethtool.c b/drivers/net/ixgbevf/ethtool.c
index 4680b06..4cc817a 100644
--- a/drivers/net/ixgbevf/ethtool.c
+++ b/drivers/net/ixgbevf/ethtool.c
@@ -330,10 +330,8 @@ static int ixgbevf_set_ringparam(struct net_device *netdev,
 {
 	struct ixgbevf_adapter *adapter = netdev_priv(netdev);
 	struct ixgbevf_ring *tx_ring = NULL, *rx_ring = NULL;
-	int i, err;
+	int i, err = 0;
 	u32 new_rx_count, new_tx_count;
-	bool need_tx_update = false;
-	bool need_rx_update = false;
 
 	if ((ring->rx_mini_pending) || (ring->rx_jumbo_pending))
 		return -EINVAL;
@@ -355,89 +353,96 @@ static int ixgbevf_set_ringparam(struct net_device *netdev,
 	while (test_and_set_bit(__IXGBEVF_RESETTING, &adapter->state))
 		msleep(1);
 
-	if (new_tx_count != adapter->tx_ring_count) {
-		tx_ring = kcalloc(adapter->num_tx_queues,
-				  sizeof(struct ixgbevf_ring), GFP_KERNEL);
-		if (!tx_ring) {
-			err = -ENOMEM;
-			goto err_setup;
-		}
-		memcpy(tx_ring, adapter->tx_ring,
-		       adapter->num_tx_queues * sizeof(struct ixgbevf_ring));
-		for (i = 0; i < adapter->num_tx_queues; i++) {
-			tx_ring[i].count = new_tx_count;
-			err = ixgbevf_setup_tx_resources(adapter,
-							 &tx_ring[i]);
-			if (err) {
-				while (i) {
-					i--;
-					ixgbevf_free_tx_resources(adapter,
-								  &tx_ring[i]);
-				}
-				kfree(tx_ring);
-				goto err_setup;
-			}
-			tx_ring[i].v_idx = adapter->tx_ring[i].v_idx;
-		}
-		need_tx_update = true;
+	/*
+	 * If the adapter isn't up and running then just set the
+	 * new parameters and scurry for the exits.
+	 */
+	if (!netif_running(adapter->netdev)) {
+		for (i = 0; i < adapter->num_tx_queues; i++)
+			adapter->tx_ring[i].count = new_tx_count;
+		for (i = 0; i < adapter->num_rx_queues; i++)
+			adapter->rx_ring[i].count = new_rx_count;
+		adapter->tx_ring_count = new_tx_count;
+		adapter->rx_ring_count = new_rx_count;
+		goto clear_reset;
 	}
 
-	if (new_rx_count != adapter->rx_ring_count) {
-		rx_ring = kcalloc(adapter->num_rx_queues,
-				  sizeof(struct ixgbevf_ring), GFP_KERNEL);
-		if ((!rx_ring) && (need_tx_update)) {
-			err = -ENOMEM;
-			goto err_rx_setup;
-		}
-		memcpy(rx_ring, adapter->rx_ring,
-		       adapter->num_rx_queues * sizeof(struct ixgbevf_ring));
-		for (i = 0; i < adapter->num_rx_queues; i++) {
-			rx_ring[i].count = new_rx_count;
-			err = ixgbevf_setup_rx_resources(adapter,
-							 &rx_ring[i]);
-			if (err) {
-				while (i) {
-					i--;
-					ixgbevf_free_rx_resources(adapter,
-								  &rx_ring[i]);
-				}
-				kfree(rx_ring);
-				goto err_rx_setup;
-			}
-			rx_ring[i].v_idx = adapter->rx_ring[i].v_idx;
-		}
-		need_rx_update = true;
+	tx_ring = kcalloc(adapter->num_tx_queues,
+			  sizeof(struct ixgbevf_ring), GFP_KERNEL);
+	if (!tx_ring) {
+		err = -ENOMEM;
+		goto clear_reset;
 	}
 
-err_rx_setup:
-	/* if rings need to be updated, here's the place to do it in one shot */
-	if (need_tx_update || need_rx_update) {
-		if (netif_running(netdev))
-			ixgbevf_down(adapter);
+	rx_ring = kcalloc(adapter->num_rx_queues,
+			  sizeof(struct ixgbevf_ring), GFP_KERNEL);
+	if (!rx_ring) {
+		err = -ENOMEM;
+		goto err_rx_setup;
 	}
 
-	/* tx */
-	if (need_tx_update) {
-		kfree(adapter->tx_ring);
-		adapter->tx_ring = tx_ring;
-		tx_ring = NULL;
-		adapter->tx_ring_count = new_tx_count;
+	ixgbevf_down(adapter);
+
+	memcpy(tx_ring, adapter->tx_ring,
+	       adapter->num_tx_queues * sizeof(struct ixgbevf_ring));
+	for (i = 0; i < adapter->num_tx_queues; i++) {
+		tx_ring[i].count = new_tx_count;
+		err = ixgbevf_setup_tx_resources(adapter, &tx_ring[i]);
+		if (err) {
+			while (i) {
+				i--;
+				ixgbevf_free_tx_resources(adapter,
+							  &tx_ring[i]);
+			}
+			goto err_tx_ring_setup;
+		}
+		tx_ring[i].v_idx = adapter->tx_ring[i].v_idx;
 	}
 
-	/* rx */
-	if (need_rx_update) {
-		kfree(adapter->rx_ring);
-		adapter->rx_ring = rx_ring;
-		rx_ring = NULL;
-		adapter->rx_ring_count = new_rx_count;
+	memcpy(rx_ring, adapter->rx_ring,
+	       adapter->num_rx_queues * sizeof(struct ixgbevf_ring));
+	for (i = 0; i < adapter->num_rx_queues; i++) {
+		rx_ring[i].count = new_rx_count;
+		err = ixgbevf_setup_rx_resources(adapter, &rx_ring[i]);
+		if (err) {
+			while (i) {
+				i--;
+				ixgbevf_free_rx_resources(adapter,
+							  &rx_ring[i]);
+			}
+				goto err_rx_ring_setup;
+		}
+		rx_ring[i].v_idx = adapter->rx_ring[i].v_idx;
 	}
 
+	/*
+	 * Only switch to new rings if all the prior allocations
+	 * and ring setups have succeeded.
+	 */
+	kfree(adapter->tx_ring);
+	adapter->tx_ring = tx_ring;
+	adapter->tx_ring_count = new_tx_count;
+
+	kfree(adapter->rx_ring);
+	adapter->rx_ring = rx_ring;
+	adapter->rx_ring_count = new_rx_count;
+
 	/* success! */
-	err = 0;
-	if (netif_running(netdev))
-		ixgbevf_up(adapter);
+	ixgbevf_up(adapter);
+
+	goto clear_reset;
+
+err_rx_ring_setup:
+	for(i = 0; i < adapter->num_tx_queues; i++)
+		ixgbevf_free_tx_resources(adapter, &tx_ring[i]);
+
+err_tx_ring_setup:
+	kfree(rx_ring);
+
+err_rx_setup:
+	kfree(tx_ring);
 
-err_setup:
+clear_reset:
 	clear_bit(__IXGBEVF_RESETTING, &adapter->state);
 	return err;
 }


^ permalink raw reply related

* Re: [PATCH 1/8] posix clocks: introduce a syscall for clock tuning.
From: Thomas Gleixner @ 2010-09-23 22:12 UTC (permalink / raw)
  To: Benjamin Herrenschmidt
  Cc: Richard Cochran, LKML, John Stultz, Rodolfo Giometti,
	Peter Zijlstra, linux-api-u79uwXL29TY76Z2rM5mHXA,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	netdev-u79uwXL29TY76Z2rM5mHXA, Christoph Lameter,
	linuxppc-dev-uLR06cmDAlY/bJ5BZ2RsiQ, David Miller,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	Krzysztof Halasa
In-Reply-To: <1285279423.5158.20.camel@pasglop>

On Fri, 24 Sep 2010, Benjamin Herrenschmidt wrote:
> On Thu, 2010-09-23 at 19:31 +0200, Richard Cochran wrote:
> > The new syscall, clock_adjtime, takes two parameters, the clock ID,
> > and a pointer to a struct timex. The semantics of the timex struct
> > have been expanded by one additional mode flag, which allows an
> > absolute offset correction. When specificied, the clock offset is
> > immediately corrected by adding the given time value to the current
> > time value.
> 
> Any reason why you CC'ed device-tree discuss ?
> 
> This list is getting way too much unrelated stuff, which I find
> annoying, it would be nice if we were all a bit more careful here with
> our CC lists.

Says the guy who missed to trim the useless context of the original
mail, which made me scroll down all the way just to find out that
there is nothing to see.

Thanks,

	tglx

^ permalink raw reply

* [PATCH] smsc911x: Add MODULE_ALIAS()
From: Vincent @ 2010-09-23 22:08 UTC (permalink / raw)
  To: netdev

[-- Attachment #1: Type: text/plain, Size: 189 bytes --]


Hi,

The smsc911x ethernet driver is lacking a module alias. This does
prevent auto-loading of the driver.

The attached patch fixes this. Please apply.

Best regards,

-- 
Vincent Stehlé

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-smsc911x-Add-MODULE_ALIAS.patch --]
[-- Type: text/x-patch; name="0001-smsc911x-Add-MODULE_ALIAS.patch", Size: 847 bytes --]

>From 54d0c88812d9707fc721ab4b6a2f669a44f873d7 Mon Sep 17 00:00:00 2001
From: =?utf-8?q?Vincent=20Stehl=C3=A9?= <vincent.stehle@laposte.net>
Date: Thu, 23 Sep 2010 23:19:14 +0200
Subject: [PATCH] smsc911x: Add MODULE_ALIAS()
MIME-Version: 1.0
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: 8bit

This enables auto loading for the smsc911x ethernet driver.

Signed-off-by: Vincent Stehlé <vincent.stehle@laposte.net>
---
 drivers/net/smsc911x.c |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/drivers/net/smsc911x.c b/drivers/net/smsc911x.c
index 7a7b01a..1cf5b8a 100644
--- a/drivers/net/smsc911x.c
+++ b/drivers/net/smsc911x.c
@@ -58,6 +58,7 @@
 
 MODULE_LICENSE("GPL");
 MODULE_VERSION(SMSC_DRV_VERSION);
+MODULE_ALIAS("platform:smsc911x");
 
 #if USE_DEBUG > 0
 static int debug = 16;
-- 
1.5.6.5


^ permalink raw reply related

* Re: [PATCH 1/8] posix clocks: introduce a syscall for clock tuning.
From: Benjamin Herrenschmidt @ 2010-09-23 22:03 UTC (permalink / raw)
  To: Richard Cochran
  Cc: Peter Zijlstra, John Stultz,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	linuxppc-dev-uLR06cmDAlY/bJ5BZ2RsiQ,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, David Miller,
	netdev-u79uwXL29TY76Z2rM5mHXA, linux-api-u79uwXL29TY76Z2rM5mHXA,
	Thomas Gleixner, Rodolfo Giometti, Christoph Lameter,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	Krzysztof Halasa
In-Reply-To: <b94ef1cd9c04ef3ad5964408bd0af7251add78de.1285261534.git.richard.cochran-3mrvs1K0uXizZXS1Dc/lvw@public.gmane.org>

On Thu, 2010-09-23 at 19:31 +0200, Richard Cochran wrote:
> A new syscall is introduced that allows tuning of a POSIX clock. The
> syscall is implemented for four architectures: arm, blackfin, powerpc,
> and x86.
> 
> The new syscall, clock_adjtime, takes two parameters, the clock ID,
> and a pointer to a struct timex. The semantics of the timex struct
> have been expanded by one additional mode flag, which allows an
> absolute offset correction. When specificied, the clock offset is
> immediately corrected by adding the given time value to the current
> time value.

Any reason why you CC'ed device-tree discuss ?

This list is getting way too much unrelated stuff, which I find
annoying, it would be nice if we were all a bit more careful here with
our CC lists.

Cheers,
Ben.

> Signed-off-by: Richard Cochran <richard.cochran-3mrvs1K0uXizZXS1Dc/lvw@public.gmane.org>
> ---
>  arch/arm/include/asm/unistd.h      |    1 +
>  arch/arm/kernel/calls.S            |    1 +
>  arch/blackfin/include/asm/unistd.h |    3 +-
>  arch/blackfin/mach-common/entry.S  |    1 +
>  arch/powerpc/include/asm/systbl.h  |    1 +
>  arch/powerpc/include/asm/unistd.h  |    3 +-
>  arch/x86/ia32/ia32entry.S          |    1 +
>  arch/x86/include/asm/unistd_32.h   |    3 +-
>  arch/x86/include/asm/unistd_64.h   |    2 +
>  arch/x86/kernel/syscall_table_32.S |    1 +
>  include/linux/posix-timers.h       |    3 +
>  include/linux/syscalls.h           |    2 +
>  include/linux/timex.h              |    3 +-
>  kernel/compat.c                    |  136 +++++++++++++++++++++++-------------
>  kernel/posix-cpu-timers.c          |    4 +
>  kernel/posix-timers.c              |   17 +++++
>  16 files changed, 130 insertions(+), 52 deletions(-)
> 
> diff --git a/arch/arm/include/asm/unistd.h b/arch/arm/include/asm/unistd.h
> index c891eb7..f58d881 100644
> --- a/arch/arm/include/asm/unistd.h
> +++ b/arch/arm/include/asm/unistd.h
> @@ -396,6 +396,7 @@
>  #define __NR_fanotify_init		(__NR_SYSCALL_BASE+367)
>  #define __NR_fanotify_mark		(__NR_SYSCALL_BASE+368)
>  #define __NR_prlimit64			(__NR_SYSCALL_BASE+369)
> +#define __NR_clock_adjtime		(__NR_SYSCALL_BASE+370)
>  
>  /*
>   * The following SWIs are ARM private.
> diff --git a/arch/arm/kernel/calls.S b/arch/arm/kernel/calls.S
> index 5c26ecc..430de4c 100644
> --- a/arch/arm/kernel/calls.S
> +++ b/arch/arm/kernel/calls.S
> @@ -379,6 +379,7 @@
>  		CALL(sys_fanotify_init)
>  		CALL(sys_fanotify_mark)
>  		CALL(sys_prlimit64)
> +/* 370 */	CALL(sys_clock_adjtime)
>  #ifndef syscalls_counted
>  .equ syscalls_padding, ((NR_syscalls + 3) & ~3) - NR_syscalls
>  #define syscalls_counted
> diff --git a/arch/blackfin/include/asm/unistd.h b/arch/blackfin/include/asm/unistd.h
> index 14fcd25..79ad99b 100644
> --- a/arch/blackfin/include/asm/unistd.h
> +++ b/arch/blackfin/include/asm/unistd.h
> @@ -392,8 +392,9 @@
>  #define __NR_fanotify_init	371
>  #define __NR_fanotify_mark	372
>  #define __NR_prlimit64		373
> +#define __NR_clock_adjtime	374
>  
> -#define __NR_syscall		374
> +#define __NR_syscall		375
>  #define NR_syscalls		__NR_syscall
>  
>  /* Old optional stuff no one actually uses */
> diff --git a/arch/blackfin/mach-common/entry.S b/arch/blackfin/mach-common/entry.S
> index af1bffa..ee68730 100644
> --- a/arch/blackfin/mach-common/entry.S
> +++ b/arch/blackfin/mach-common/entry.S
> @@ -1631,6 +1631,7 @@ ENTRY(_sys_call_table)
>  	.long _sys_fanotify_init
>  	.long _sys_fanotify_mark
>  	.long _sys_prlimit64
> +	.long _sys_clock_adjtime
>  
>  	.rept NR_syscalls-(.-_sys_call_table)/4
>  	.long _sys_ni_syscall
> diff --git a/arch/powerpc/include/asm/systbl.h b/arch/powerpc/include/asm/systbl.h
> index 3d21266..2485d8f 100644
> --- a/arch/powerpc/include/asm/systbl.h
> +++ b/arch/powerpc/include/asm/systbl.h
> @@ -329,3 +329,4 @@ COMPAT_SYS(rt_tgsigqueueinfo)
>  SYSCALL(fanotify_init)
>  COMPAT_SYS(fanotify_mark)
>  SYSCALL_SPU(prlimit64)
> +COMPAT_SYS_SPU(clock_adjtime)
> diff --git a/arch/powerpc/include/asm/unistd.h b/arch/powerpc/include/asm/unistd.h
> index 597e6f9..85d5067 100644
> --- a/arch/powerpc/include/asm/unistd.h
> +++ b/arch/powerpc/include/asm/unistd.h
> @@ -348,10 +348,11 @@
>  #define __NR_fanotify_init	323
>  #define __NR_fanotify_mark	324
>  #define __NR_prlimit64		325
> +#define __NR_clock_adjtime	326
>  
>  #ifdef __KERNEL__
>  
> -#define __NR_syscalls		326
> +#define __NR_syscalls		327
>  
>  #define __NR__exit __NR_exit
>  #define NR_syscalls	__NR_syscalls
> diff --git a/arch/x86/ia32/ia32entry.S b/arch/x86/ia32/ia32entry.S
> index 518bb99..0ed7896 100644
> --- a/arch/x86/ia32/ia32entry.S
> +++ b/arch/x86/ia32/ia32entry.S
> @@ -851,4 +851,5 @@ ia32_sys_call_table:
>  	.quad sys_fanotify_init
>  	.quad sys32_fanotify_mark
>  	.quad sys_prlimit64		/* 340 */
> +	.quad compat_sys_clock_adjtime
>  ia32_syscall_end:
> diff --git a/arch/x86/include/asm/unistd_32.h b/arch/x86/include/asm/unistd_32.h
> index b766a5e..b6f73f1 100644
> --- a/arch/x86/include/asm/unistd_32.h
> +++ b/arch/x86/include/asm/unistd_32.h
> @@ -346,10 +346,11 @@
>  #define __NR_fanotify_init	338
>  #define __NR_fanotify_mark	339
>  #define __NR_prlimit64		340
> +#define __NR_clock_adjtime	341
>  
>  #ifdef __KERNEL__
>  
> -#define NR_syscalls 341
> +#define NR_syscalls 342
>  
>  #define __ARCH_WANT_IPC_PARSE_VERSION
>  #define __ARCH_WANT_OLD_READDIR
> diff --git a/arch/x86/include/asm/unistd_64.h b/arch/x86/include/asm/unistd_64.h
> index 363e9b8..5ee3085 100644
> --- a/arch/x86/include/asm/unistd_64.h
> +++ b/arch/x86/include/asm/unistd_64.h
> @@ -669,6 +669,8 @@ __SYSCALL(__NR_fanotify_init, sys_fanotify_init)
>  __SYSCALL(__NR_fanotify_mark, sys_fanotify_mark)
>  #define __NR_prlimit64				302
>  __SYSCALL(__NR_prlimit64, sys_prlimit64)
> +#define __NR_clock_adjtime			303
> +__SYSCALL(__NR_clock_adjtime, sys_clock_adjtime)
>  
>  #ifndef __NO_STUBS
>  #define __ARCH_WANT_OLD_READDIR
> diff --git a/arch/x86/kernel/syscall_table_32.S b/arch/x86/kernel/syscall_table_32.S
> index b35786d..68c7b9a 100644
> --- a/arch/x86/kernel/syscall_table_32.S
> +++ b/arch/x86/kernel/syscall_table_32.S
> @@ -340,3 +340,4 @@ ENTRY(sys_call_table)
>  	.long sys_fanotify_init
>  	.long sys_fanotify_mark
>  	.long sys_prlimit64		/* 340 */
> +	.long sys_clock_adjtime
> diff --git a/include/linux/posix-timers.h b/include/linux/posix-timers.h
> index 3e23844..abf61cc 100644
> --- a/include/linux/posix-timers.h
> +++ b/include/linux/posix-timers.h
> @@ -4,6 +4,7 @@
>  #include <linux/spinlock.h>
>  #include <linux/list.h>
>  #include <linux/sched.h>
> +#include <linux/timex.h>
>  
>  union cpu_time_count {
>  	cputime_t cpu;
> @@ -71,6 +72,7 @@ struct k_clock {
>  	int (*clock_getres) (const clockid_t which_clock, struct timespec *tp);
>  	int (*clock_set) (const clockid_t which_clock, struct timespec * tp);
>  	int (*clock_get) (const clockid_t which_clock, struct timespec * tp);
> +	int (*clock_adj) (const clockid_t which_clock, struct timex *tx);
>  	int (*timer_create) (struct k_itimer *timer);
>  	int (*nsleep) (const clockid_t which_clock, int flags,
>  		       struct timespec *, struct timespec __user *);
> @@ -97,6 +99,7 @@ int posix_timer_event(struct k_itimer *timr, int si_private);
>  int posix_cpu_clock_getres(const clockid_t which_clock, struct timespec *ts);
>  int posix_cpu_clock_get(const clockid_t which_clock, struct timespec *ts);
>  int posix_cpu_clock_set(const clockid_t which_clock, const struct timespec *ts);
> +int posix_cpu_clock_adj(const clockid_t which_clock, struct timex *tx);
>  int posix_cpu_timer_create(struct k_itimer *timer);
>  int posix_cpu_nsleep(const clockid_t which_clock, int flags,
>  		     struct timespec *rqtp, struct timespec __user *rmtp);
> diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h
> index e6319d1..0b24775 100644
> --- a/include/linux/syscalls.h
> +++ b/include/linux/syscalls.h
> @@ -313,6 +313,8 @@ asmlinkage long sys_clock_settime(clockid_t which_clock,
>  				const struct timespec __user *tp);
>  asmlinkage long sys_clock_gettime(clockid_t which_clock,
>  				struct timespec __user *tp);
> +asmlinkage long sys_clock_adjtime(clockid_t which_clock,
> +				struct timex __user *tx);
>  asmlinkage long sys_clock_getres(clockid_t which_clock,
>  				struct timespec __user *tp);
>  asmlinkage long sys_clock_nanosleep(clockid_t which_clock, int flags,
> diff --git a/include/linux/timex.h b/include/linux/timex.h
> index 32d852f..82d4b24 100644
> --- a/include/linux/timex.h
> +++ b/include/linux/timex.h
> @@ -73,7 +73,7 @@ struct timex {
>  	long tolerance;		/* clock frequency tolerance (ppm)
>  				 * (read only)
>  				 */
> -	struct timeval time;	/* (read only) */
> +	struct timeval time;	/* (read only, except for ADJ_SETOFFSET) */
>  	long tick;		/* (modified) usecs between clock ticks */
>  
>  	long ppsfreq;           /* pps frequency (scaled ppm) (ro) */
> @@ -101,6 +101,7 @@ struct timex {
>  #define ADJ_ESTERROR		0x0008	/* estimated time error */
>  #define ADJ_STATUS		0x0010	/* clock status */
>  #define ADJ_TIMECONST		0x0020	/* pll time constant */
> +#define ADJ_SETOFFSET		0x0040  /* add 'time' to current time */
>  #define ADJ_TAI			0x0080	/* set TAI offset */
>  #define ADJ_MICRO		0x1000	/* select microsecond resolution */
>  #define ADJ_NANO		0x2000	/* select nanosecond resolution */
> diff --git a/kernel/compat.c b/kernel/compat.c
> index c9e2ec0..38b1d2c 100644
> --- a/kernel/compat.c
> +++ b/kernel/compat.c
> @@ -52,6 +52,64 @@ static int compat_put_timeval(struct compat_timeval __user *o,
>  		put_user(i->tv_usec, &o->tv_usec)) ? -EFAULT : 0;
>  }
>  
> +static int compat_get_timex(struct timex *txc, struct compat_timex __user *utp)
> +{
> +	memset(txc, 0, sizeof(struct timex));
> +
> +	if (!access_ok(VERIFY_READ, utp, sizeof(struct compat_timex)) ||
> +			__get_user(txc->modes, &utp->modes) ||
> +			__get_user(txc->offset, &utp->offset) ||
> +			__get_user(txc->freq, &utp->freq) ||
> +			__get_user(txc->maxerror, &utp->maxerror) ||
> +			__get_user(txc->esterror, &utp->esterror) ||
> +			__get_user(txc->status, &utp->status) ||
> +			__get_user(txc->constant, &utp->constant) ||
> +			__get_user(txc->precision, &utp->precision) ||
> +			__get_user(txc->tolerance, &utp->tolerance) ||
> +			__get_user(txc->time.tv_sec, &utp->time.tv_sec) ||
> +			__get_user(txc->time.tv_usec, &utp->time.tv_usec) ||
> +			__get_user(txc->tick, &utp->tick) ||
> +			__get_user(txc->ppsfreq, &utp->ppsfreq) ||
> +			__get_user(txc->jitter, &utp->jitter) ||
> +			__get_user(txc->shift, &utp->shift) ||
> +			__get_user(txc->stabil, &utp->stabil) ||
> +			__get_user(txc->jitcnt, &utp->jitcnt) ||
> +			__get_user(txc->calcnt, &utp->calcnt) ||
> +			__get_user(txc->errcnt, &utp->errcnt) ||
> +			__get_user(txc->stbcnt, &utp->stbcnt))
> +		return -EFAULT;
> +
> +	return 0;
> +}
> +
> +static int compat_put_timex(struct compat_timex __user *utp, struct timex *txc)
> +{
> +	if (!access_ok(VERIFY_WRITE, utp, sizeof(struct compat_timex)) ||
> +			__put_user(txc->modes, &utp->modes) ||
> +			__put_user(txc->offset, &utp->offset) ||
> +			__put_user(txc->freq, &utp->freq) ||
> +			__put_user(txc->maxerror, &utp->maxerror) ||
> +			__put_user(txc->esterror, &utp->esterror) ||
> +			__put_user(txc->status, &utp->status) ||
> +			__put_user(txc->constant, &utp->constant) ||
> +			__put_user(txc->precision, &utp->precision) ||
> +			__put_user(txc->tolerance, &utp->tolerance) ||
> +			__put_user(txc->time.tv_sec, &utp->time.tv_sec) ||
> +			__put_user(txc->time.tv_usec, &utp->time.tv_usec) ||
> +			__put_user(txc->tick, &utp->tick) ||
> +			__put_user(txc->ppsfreq, &utp->ppsfreq) ||
> +			__put_user(txc->jitter, &utp->jitter) ||
> +			__put_user(txc->shift, &utp->shift) ||
> +			__put_user(txc->stabil, &utp->stabil) ||
> +			__put_user(txc->jitcnt, &utp->jitcnt) ||
> +			__put_user(txc->calcnt, &utp->calcnt) ||
> +			__put_user(txc->errcnt, &utp->errcnt) ||
> +			__put_user(txc->stbcnt, &utp->stbcnt) ||
> +			__put_user(txc->tai, &utp->tai))
> +		return -EFAULT;
> +	return 0;
> +}
> +
>  asmlinkage long compat_sys_gettimeofday(struct compat_timeval __user *tv,
>  		struct timezone __user *tz)
>  {
> @@ -617,6 +675,29 @@ long compat_sys_clock_gettime(clockid_t which_clock,
>  	return err;
>  }
>  
> +long compat_sys_clock_adjtime(clockid_t which_clock,
> +		struct compat_timex __user *utp)
> +{
> +	struct timex txc;
> +	mm_segment_t oldfs;
> +	int err, ret;
> +
> +	err = compat_get_timex(&txc, utp);
> +	if (err)
> +		return err;
> +
> +	oldfs = get_fs();
> +	set_fs(KERNEL_DS);
> +	ret = sys_clock_adjtime(which_clock, (struct timex __user *) &txc);
> +	set_fs(oldfs);
> +
> +	err = compat_put_timex(utp, &txc);
> +	if (err)
> +		return err;
> +
> +	return ret;
> +}
> +
>  long compat_sys_clock_getres(clockid_t which_clock,
>  		struct compat_timespec __user *tp)
>  {
> @@ -951,58 +1032,17 @@ asmlinkage long compat_sys_rt_sigsuspend(compat_sigset_t __user *unewset, compat
>  asmlinkage long compat_sys_adjtimex(struct compat_timex __user *utp)
>  {
>  	struct timex txc;
> -	int ret;
> -
> -	memset(&txc, 0, sizeof(struct timex));
> +	int err, ret;
>  
> -	if (!access_ok(VERIFY_READ, utp, sizeof(struct compat_timex)) ||
> -			__get_user(txc.modes, &utp->modes) ||
> -			__get_user(txc.offset, &utp->offset) ||
> -			__get_user(txc.freq, &utp->freq) ||
> -			__get_user(txc.maxerror, &utp->maxerror) ||
> -			__get_user(txc.esterror, &utp->esterror) ||
> -			__get_user(txc.status, &utp->status) ||
> -			__get_user(txc.constant, &utp->constant) ||
> -			__get_user(txc.precision, &utp->precision) ||
> -			__get_user(txc.tolerance, &utp->tolerance) ||
> -			__get_user(txc.time.tv_sec, &utp->time.tv_sec) ||
> -			__get_user(txc.time.tv_usec, &utp->time.tv_usec) ||
> -			__get_user(txc.tick, &utp->tick) ||
> -			__get_user(txc.ppsfreq, &utp->ppsfreq) ||
> -			__get_user(txc.jitter, &utp->jitter) ||
> -			__get_user(txc.shift, &utp->shift) ||
> -			__get_user(txc.stabil, &utp->stabil) ||
> -			__get_user(txc.jitcnt, &utp->jitcnt) ||
> -			__get_user(txc.calcnt, &utp->calcnt) ||
> -			__get_user(txc.errcnt, &utp->errcnt) ||
> -			__get_user(txc.stbcnt, &utp->stbcnt))
> -		return -EFAULT;
> +	err = compat_get_timex(&txc, utp);
> +	if (err)
> +		return err;
>  
>  	ret = do_adjtimex(&txc);
>  
> -	if (!access_ok(VERIFY_WRITE, utp, sizeof(struct compat_timex)) ||
> -			__put_user(txc.modes, &utp->modes) ||
> -			__put_user(txc.offset, &utp->offset) ||
> -			__put_user(txc.freq, &utp->freq) ||
> -			__put_user(txc.maxerror, &utp->maxerror) ||
> -			__put_user(txc.esterror, &utp->esterror) ||
> -			__put_user(txc.status, &utp->status) ||
> -			__put_user(txc.constant, &utp->constant) ||
> -			__put_user(txc.precision, &utp->precision) ||
> -			__put_user(txc.tolerance, &utp->tolerance) ||
> -			__put_user(txc.time.tv_sec, &utp->time.tv_sec) ||
> -			__put_user(txc.time.tv_usec, &utp->time.tv_usec) ||
> -			__put_user(txc.tick, &utp->tick) ||
> -			__put_user(txc.ppsfreq, &utp->ppsfreq) ||
> -			__put_user(txc.jitter, &utp->jitter) ||
> -			__put_user(txc.shift, &utp->shift) ||
> -			__put_user(txc.stabil, &utp->stabil) ||
> -			__put_user(txc.jitcnt, &utp->jitcnt) ||
> -			__put_user(txc.calcnt, &utp->calcnt) ||
> -			__put_user(txc.errcnt, &utp->errcnt) ||
> -			__put_user(txc.stbcnt, &utp->stbcnt) ||
> -			__put_user(txc.tai, &utp->tai))
> -		ret = -EFAULT;
> +	err = compat_put_timex(utp, &txc);
> +	if (err)
> +		return err;
>  
>  	return ret;
>  }
> diff --git a/kernel/posix-cpu-timers.c b/kernel/posix-cpu-timers.c
> index 6842eeb..e1c2e7b 100644
> --- a/kernel/posix-cpu-timers.c
> +++ b/kernel/posix-cpu-timers.c
> @@ -207,6 +207,10 @@ int posix_cpu_clock_set(const clockid_t which_clock, const struct timespec *tp)
>  	return error;
>  }
>  
> +int posix_cpu_clock_adj(const clockid_t which_clock, struct timex *tx)
> +{
> +	return -EOPNOTSUPP;
> +}
>  
>  /*
>   * Sample a per-thread clock for the given task.
> diff --git a/kernel/posix-timers.c b/kernel/posix-timers.c
> index 9ca4973..446b566 100644
> --- a/kernel/posix-timers.c
> +++ b/kernel/posix-timers.c
> @@ -197,6 +197,14 @@ static int common_timer_create(struct k_itimer *new_timer)
>  	return 0;
>  }
>  
> +static inline int common_clock_adj(const clockid_t which_clock, struct timex *t)
> +{
> +	if (CLOCK_REALTIME == which_clock)
> +		return do_adjtimex(t);
> +	else
> +		return -EOPNOTSUPP;
> +}
> +
>  static int no_timer_create(struct k_itimer *new_timer)
>  {
>  	return -EOPNOTSUPP;
> @@ -969,6 +977,15 @@ SYSCALL_DEFINE2(clock_gettime, const clockid_t, which_clock,
>  
>  }
>  
> +SYSCALL_DEFINE2(clock_adjtime, const clockid_t, which_clock,
> +		struct timex __user *, tx)
> +{
> +	if (invalid_clockid(which_clock))
> +		return -EINVAL;
> +
> +	return CLOCK_DISPATCH(which_clock, clock_adj, (which_clock, tx));
> +}
> +
>  SYSCALL_DEFINE2(clock_getres, const clockid_t, which_clock,
>  		struct timespec __user *, tp)
>  {

^ permalink raw reply

* Re: [PATCH v6 0/8] ptp: IEEE 1588 hardware clock support
From: john stultz @ 2010-09-23 22:03 UTC (permalink / raw)
  To: Alan Cox
  Cc: Richard Cochran, linux-kernel, devicetree-discuss, linux-api,
	linux-arm-kernel, linuxppc-dev, netdev, Arnd Bergmann,
	Christoph Lameter, David Miller, Krzysztof Halasa, Peter Zijlstra,
	Rodolfo Giometti, Thomas Gleixner
In-Reply-To: <20100923223025.2877cce2@lxorguk.ukuu.org.uk>

On Thu, 2010-09-23 at 22:30 +0100, Alan Cox wrote:
> O> I don't see how this is a problem, as it exposes the multiple hardware
> > clocks via different posix clock ids. So in the boundary clock case, you
> > can configure which side is the client and which side is the master in a
> > config file and the PTPd will appropriately steer them individually.
> 
> They may all be slaves - that means you can't treat them as part of
> system time.

Sure, and that's something one would configure. So I'm not sure I see
how exposing the different hardware bits via a clock_id is problematic.
They're just clocks that are being exposed. The steering of system time
to PTP or PTP to system time  (or just PTP to other PTP clocks).


> > on module unload, but I don't think we need a use-count to prevent the
> > module from being unloaded.
> > 
> > My question would be: How do we handle a USB network device ($14.99 now
> > with PTP!) being unplugged? We can't say "Sorry! That's in use!". So we
> > note the hardware is gone, and return the proper error code.
> > 
> > Or am I missing something else?
> 
> Open list
> Oh number 31 appears to be the device I want
> Close list
> 
> 	USB unplugged
> 	Random other device plugged
> 
> clock_op(31, ....)
> 
> Oh bugger I've just reprogrammed the wrong time source.

Ok. So its just the issue of clock_id reuse. I was confusing it with
some sort of module use counting issue.  And yea, I can see how it might
be  easier to re-use the file descriptor then re-implementing the reuse
logic in the posix-clock registration.


> We don't have stop the device being removed, instead of a disaster you get
> 
> 	clock_op(fd, blah)
> 	-ENODEV
> 
> which btw is how just about everything else USB works when you pull the
> hardware.

Right, which was what I was thinking as well, but assuming we didn't
re-use clockids quickly.
 
> > So, I don't really see how that's so different from what is being
> > proposed. The clock_id is dynamically assigned per registered clock, and
> > exposed via the sysfs interface from ptp hardware entry.
> > 
> > The only difference is the open/close reference counting, which I don't
> > think is necessary here (since we can't always keep the hardware from
> > going away).
> 
> It is absolutely neccessary in order that you can be sure that two calls
> actually relate to the *same* device. It's as fundamental as the
> difference betweeh chmod and fchmod although with the added ugliness of
> some random numeric identifier stuck in the middle.
> 
> It also btw makes it much easier to fix up the existing random collection
> of /dev/rtc devices - because you can open them and issue fclock_adjtime
> if we are careful how we do it and it makes sense.

Wait, you're suggesting we add new fclock_* calls that duplicate the
posix interface? That doesn't sound great to me.

What did you think of Kyle Moffett's suggestion of utilizing the fd to
map to the clock_id which could then be used by the posix clocks
interface?

Although I'm still not sure if it wouldn't be so hard to just simply
increment the id on each registration and index to a clock through a
reasonably small hash table. I suspect that would solve the
enumeration/reuse issue without much trouble (but again, I'm open to
being corrected if I'm missing something larger).

But yes, in summary, this is an issue to be addressed one way or
another.

thanks
-john

^ permalink raw reply

* [PATCH ethtool 7/7] ethtool: Add my authorship and Solarflare copyright notice
From: Ben Hutchings @ 2010-09-23 21:50 UTC (permalink / raw)
  To: Jeff Garzik; +Cc: netdev, linux-net-drivers
In-Reply-To: <1285278428.7794.27.camel@achroite.uk.solarflarecom.com>

Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
---
 AUTHORS   |    1 +
 ethtool.c |    2 ++
 2 files changed, 3 insertions(+), 0 deletions(-)

diff --git a/AUTHORS b/AUTHORS
index 77500ce..aed04fa 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -6,3 +6,4 @@ Eli Kupermann <eli.kupermann@intel.com>
 Chris Leech <christopher.leech@intel.com>
 Scott Feldman <scott.feldman@intel.com>
 Andi Kleen
+Ben Hutchings <bhutchings@solarflare.com>
diff --git a/ethtool.c b/ethtool.c
index 31158f8..7612b14 100644
--- a/ethtool.c
+++ b/ethtool.c
@@ -14,6 +14,8 @@
  * amd8111e support by Reeja John <reeja.john@amd.com>
  * long arguments by Andi Kleen.
  * SMSC LAN911x support by Steve Glendinning <steve.glendinning@smsc.com>
+ * Various features by Ben Hutchings <bhutchings@solarflare.com>;
+ *	Copyright 2009, 2010 Solarflare Communications
  *
  * TODO:
  *   * no-args => summary of each device (mii-tool style)
-- 
1.7.2.1


-- 
Ben Hutchings, Senior Software Engineer, Solarflare Communications
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.


^ permalink raw reply related

* [PATCH ethtool 6/7] ethtool: Update sfc register dump
From: Ben Hutchings @ 2010-09-23 21:50 UTC (permalink / raw)
  To: Jeff Garzik; +Cc: netdev, linux-net-drivers
In-Reply-To: <1285278428.7794.27.camel@achroite.uk.solarflarecom.com>

Add length checks to allow for extensions to the register dump without
changing the version number.

Show the RX IP filter table if present.

Fix address field definitions for the MAC filter tables.

Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
---
 sfc.c |   25 ++++++++++++++-----------
 1 files changed, 14 insertions(+), 11 deletions(-)

diff --git a/sfc.c b/sfc.c
index 2e4735f..c8ca74a 100644
--- a/sfc.c
+++ b/sfc.c
@@ -2420,8 +2420,8 @@
 #define	FRF_CZ_RMFT_RXQ_ID_WIDTH 12
 #define	FRF_CZ_RMFT_WILDCARD_MATCH_LBN 60
 #define	FRF_CZ_RMFT_WILDCARD_MATCH_WIDTH 1
-#define	FRF_CZ_RMFT_DEST_MAC_LBN 16
-#define	FRF_CZ_RMFT_DEST_MAC_WIDTH 44
+#define	FRF_CZ_RMFT_DEST_MAC_LBN 12
+#define	FRF_CZ_RMFT_DEST_MAC_WIDTH 48
 #define	FRF_CZ_RMFT_VLAN_ID_LBN 0
 #define	FRF_CZ_RMFT_VLAN_ID_WIDTH 12
 
@@ -2497,8 +2497,8 @@
 #define	FRF_CZ_TMFT_TXQ_ID_WIDTH 12
 #define	FRF_CZ_TMFT_WILDCARD_MATCH_LBN 60
 #define	FRF_CZ_TMFT_WILDCARD_MATCH_WIDTH 1
-#define	FRF_CZ_TMFT_SRC_MAC_LBN 16
-#define	FRF_CZ_TMFT_SRC_MAC_WIDTH 44
+#define	FRF_CZ_TMFT_SRC_MAC_LBN 12
+#define	FRF_CZ_TMFT_SRC_MAC_WIDTH 48
 #define	FRF_CZ_TMFT_VLAN_ID_LBN 0
 #define	FRF_CZ_TMFT_VLAN_ID_WIDTH 12
 
@@ -3445,9 +3445,11 @@ static const struct efx_nic_reg_field efx_nic_reg_fields_BUF_FULL_TBL[] = {
 };
 #define efx_nic_reg_fields_BUF_FULL_TBL_KER efx_nic_reg_fields_BUF_FULL_TBL
 static const struct efx_nic_reg_field efx_nic_reg_fields_RX_FILTER_TBL0[] = {
-	REGISTER_FIELD_BZ(SRC_TCP_DEST_UDP),
+	/* Source port for full match; destination port for UDP wild match */
+	REGISTER_FIELD_BZ_RENAME(SRC_TCP_DEST_UDP, "SRC_PORT"),
 	REGISTER_FIELD_BZ(SRC_IP),
-	REGISTER_FIELD_BZ(DEST_PORT_TCP),
+	/* Destination port for full match or TCP wild match */
+	REGISTER_FIELD_BZ_RENAME(DEST_PORT_TCP, "DEST_PORT"),
 	REGISTER_FIELD_BZ(DEST_IP),
 	REGISTER_FIELD_BZ(RXQ_ID),
 	REGISTER_FIELD_BZ(TCP_UDP),
@@ -3663,8 +3665,7 @@ static const struct efx_nic_reg_table efx_nic_reg_tables[] = {
 	REGISTER_TABLE_BB_CZ(TX_DESC_PTR_TBL),
 	REGISTER_TABLE_AA(EVQ_PTR_TBL_KER),
 	REGISTER_TABLE_BB_CZ(EVQ_PTR_TBL),
-	/* The register buffer is allocated with slab, so we can't
-	 * reasonably read all of the buffer table (up to 8MB!).
+	/* We can't reasonably read all of the buffer table (up to 8MB!).
 	 * However this driver will only use a few entries.  Reading
 	 * 1K entries allows for some expansion of queue count and
 	 * size before we need to change the version. */
@@ -3672,7 +3673,6 @@ static const struct efx_nic_reg_table efx_nic_reg_tables[] = {
 				  A, A, 8, 1024),
 	REGISTER_TABLE_DIMENSIONS(BUF_FULL_TBL, FR_BZ_BUF_FULL_TBL,
 				  B, Z, 8, 1024),
-	/* RX_FILTER_TBL{0,1} is huge and not used by this driver */
 	REGISTER_TABLE_CZ(RX_MAC_FILTER_TBL0),
 	REGISTER_TABLE_BB_CZ(TIMER_TBL),
 	REGISTER_TABLE_BB_CZ(TX_PACE_TBL),
@@ -3682,6 +3682,7 @@ static const struct efx_nic_reg_table efx_nic_reg_tables[] = {
 	REGISTER_TABLE_CZ(MC_TREG_SMEM),
 	/* MSIX_PBA_TABLE is not mapped */
 	/* SRM_DBG is not mapped (and is redundant with BUF_FLL_TBL) */
+	REGISTER_TABLE_BZ(RX_FILTER_TBL0),
 };
 
 static size_t column_width(const struct efx_nic_reg_field *field)
@@ -3830,12 +3831,13 @@ sfc_dump_regs(struct ethtool_drvinfo *info, struct ethtool_regs *regs)
 	const struct efx_nic_reg_table *table;
 	unsigned revision = regs->version;
 	const void *buf = regs->data;
+	const void *end = regs->data + regs->len;
 
 	if (revision > REGISTER_REVISION_Z)
 		return -1;
 
 	for (reg = efx_nic_regs;	
-	     reg < efx_nic_regs + ARRAY_SIZE(efx_nic_regs);
+	     reg < efx_nic_regs + ARRAY_SIZE(efx_nic_regs) && buf < end;
 	     reg++) {
 		if (revision >= reg->min_revision &&
 		    revision <= reg->max_revision)
@@ -3843,7 +3845,8 @@ sfc_dump_regs(struct ethtool_drvinfo *info, struct ethtool_regs *regs)
 	}
 
 	for (table = efx_nic_reg_tables;
-	     table < efx_nic_reg_tables + ARRAY_SIZE(efx_nic_reg_tables);
+	     table < efx_nic_reg_tables + ARRAY_SIZE(efx_nic_reg_tables) &&
+		     buf < end;
 	     table++) {
 		if (revision >= table->min_revision &&
 		    revision <= table->max_revision) {
-- 
1.7.2.1



-- 
Ben Hutchings, Senior Software Engineer, Solarflare Communications
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.


^ permalink raw reply related

* [PATCH ethtool 5/7] ethtool: Add Ethernet-level RX n-tuple filtering and 'clear' action
From: Ben Hutchings @ 2010-09-23 21:49 UTC (permalink / raw)
  To: Jeff Garzik; +Cc: netdev, linux-net-drivers
In-Reply-To: <1285278428.7794.27.camel@achroite.uk.solarflarecom.com>

Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
---
 ethtool.8 |   48 ++++++++++++++++++++++++++++++++++++++----
 ethtool.c |   68 +++++++++++++++++++++++++++++++++++++++++++++++++++++-------
 2 files changed, 103 insertions(+), 13 deletions(-)

diff --git a/ethtool.8 b/ethtool.8
index 295caab..2c54cb4 100644
--- a/ethtool.8
+++ b/ethtool.8
@@ -233,8 +233,9 @@ ethtool \- Display or change ethernet card settings
 .B ethtool \-u|\-\-show\-ntuple
 .I ethX
 
-.B ethtool \-U|\-\-config\-ntuple
-.I ethX
+.TP
+.BI ethtool\ \-U|\-\-config\-ntuple \ ethX
+.RB {
 .A3 flow-type tcp4 udp4 sctp4
 .RB [ src-ip
 .IR addr
@@ -252,6 +253,21 @@ ethtool \- Display or change ethernet card settings
 .IR port
 .RB [ dst-port-mask
 .IR mask ]]
+.br
+.RB | \ flow-type\ ether
+.RB [ src
+.IR mac-addr
+.RB [ src-mask
+.IR mask ]]
+.RB [ dst
+.IR mac-addr
+.RB [ dst-mask
+.IR mask ]]
+.RB [ proto
+.IR N
+.RB [ proto-mask
+.IR mask ]]\ }
+.br
 .RB [ vlan
 .IR VLAN-tag
 .RB [ vlan-mask
@@ -649,7 +665,7 @@ Get Rx ntuple filters and actions, then display them to the user.
 .B \-U \-\-config-ntuple
 Configure Rx ntuple filters and actions
 .TP
-.B flow-type tcp4|udp4|sctp4
+.B flow-type tcp4|udp4|sctp4|ether
 .RS
 .PD 0
 .TP 3
@@ -658,6 +674,8 @@ Configure Rx ntuple filters and actions
 .BR "udp4" "    UDP over IPv4"
 .TP 3
 .BR "sctp4" "   SCTP over IPv4"
+.TP 3
+.BR "ether" "   Ethernet"
 .PD
 .RE
 .TP
@@ -686,6 +704,25 @@ Includes the destination port.
 .BI dst-port-mask \ mask
 Specify a mask for the destination port.
 .TP
+.BI src \ mac-addr
+Includes the source MAC address, specified as 6 bytes in hexadecimal
+separated by colons.
+.TP
+.BI src-mask \ mask
+Specify a mask for the source MAC address.
+.TP
+.BI dst \ mac-addr
+Includes the destination MAC address.
+.TP
+.BI dst-mask \ mask
+Specify a mask for the destination MAC address.
+.TP
+.BI proto \ N
+Includes the Ethernet protocol number (ethertype).
+.TP
+.BI proto-mask \ mask
+Specify a mask for the Ethernet protocol number.
+.TP
 .BI vlan \ VLAN-tag
 Includes the VLAN tag.
 .TP
@@ -699,11 +736,12 @@ Includes 64-bits of user-specific data.
 Specify a mask for the user-specific data.
 .TP
 .BI action \ N
-Specifies either the Rx queue to send packets to, or to drop
-the matched flow.
+Specifies the Rx queue to send packets to, or some other action.
 .RS
 .PD 0
 .TP 3
+.BR "-2" "             Clear the filter"
+.TP 3
 .BR "-1" "             Drop the matched flow"
 .TP 3
 .BR "0 or higher" "    Rx queue to route the flow"
diff --git a/ethtool.c b/ethtool.c
index ea6a26f..31158f8 100644
--- a/ethtool.c
+++ b/ethtool.c
@@ -240,11 +240,15 @@ static struct option {
 		"		equal N | weight W0 W1 ...\n" },
     { "-U", "--config-ntuple", MODE_SNTUPLE, "Configure Rx ntuple filters "
 		"and actions",
-		"		flow-type tcp4|udp4|sctp4\n"
-		"		[ src-ip ADDR [src-ip-mask MASK] ]\n"
-		"		[ dst-ip ADDR [dst-ip-mask MASK] ]\n"
-		"		[ src-port PORT [src-port-mask MASK] ]\n"
-		"		[ dst-port PORT [dst-port-mask MASK] ]\n"
+		"		{ flow-type tcp4|udp4|sctp4\n"
+		"		  [ src-ip ADDR [src-ip-mask MASK] ]\n"
+		"		  [ dst-ip ADDR [dst-ip-mask MASK] ]\n"
+		"		  [ src-port PORT [src-port-mask MASK] ]\n"
+		"		  [ dst-port PORT [dst-port-mask MASK] ]\n"
+		"		| flow-type ether\n"
+		"		  [ src MAC-ADDR [src-mask MASK] ]\n"
+		"		  [ dst MAC-ADDR [dst-mask MASK] ]\n"
+		"		  [ proto N [proto-mask MASK] ] }\n"
 		"		[ vlan VLAN-TAG [vlan-mask MASK] ]\n"
 		"		[ user-def DATA [user-def-mask MASK] ]\n"
 		"		action N\n" },
@@ -377,6 +381,12 @@ static int ntuple_psrc_seen = 0;
 static int ntuple_psrc_mask_seen = 0;
 static int ntuple_pdst_seen = 0;
 static int ntuple_pdst_mask_seen = 0;
+static int ntuple_ether_dst_seen = 0;
+static int ntuple_ether_dst_mask_seen = 0;
+static int ntuple_ether_src_seen = 0;
+static int ntuple_ether_src_mask_seen = 0;
+static int ntuple_ether_proto_seen = 0;
+static int ntuple_ether_proto_mask_seen = 0;
 static int ntuple_vlan_tag_seen = 0;
 static int ntuple_vlan_tag_mask_seen = 0;
 static int ntuple_user_def_seen = 0;
@@ -497,7 +507,7 @@ static struct cmdline_info cmdline_coalesce[] = {
 	{ "tx-frames-high", CMDL_S32, &coal_tx_frames_high_wanted, &ecoal.tx_max_coalesced_frames_high },
 };
 
-static struct cmdline_info cmdline_ntuple[] = {
+static struct cmdline_info cmdline_ntuple_tcp_ip4[] = {
 	{ "src-ip", CMDL_IP4, &ntuple_fs.h_u.tcp_ip4_spec.ip4src, NULL,
 	  0, &ntuple_ip4src_seen },
 	{ "src-ip-mask", CMDL_IP4, &ntuple_fs.m_u.tcp_ip4_spec.ip4src, NULL,
@@ -525,6 +535,30 @@ static struct cmdline_info cmdline_ntuple[] = {
 	{ "action", CMDL_S32, &ntuple_fs.action, NULL },
 };
 
+static struct cmdline_info cmdline_ntuple_ether[] = {
+	{ "dst", CMDL_MAC, ntuple_fs.h_u.ether_spec.h_dest, NULL,
+	  0, &ntuple_ether_dst_seen },
+	{ "dst-mask", CMDL_MAC, ntuple_fs.m_u.ether_spec.h_dest, NULL,
+	  0, &ntuple_ether_dst_mask_seen },
+	{ "src", CMDL_MAC, ntuple_fs.h_u.ether_spec.h_source, NULL,
+	  0, &ntuple_ether_src_seen },
+	{ "src-mask", CMDL_MAC, ntuple_fs.m_u.ether_spec.h_source, NULL,
+	  0, &ntuple_ether_src_mask_seen },
+	{ "proto", CMDL_BE16, &ntuple_fs.h_u.ether_spec.h_proto, NULL,
+	  0, &ntuple_ether_proto_seen },
+	{ "proto-mask", CMDL_BE16, &ntuple_fs.m_u.ether_spec.h_proto, NULL,
+	  0, &ntuple_ether_proto_mask_seen },
+	{ "vlan", CMDL_U16, &ntuple_fs.vlan_tag, NULL,
+	  0, &ntuple_vlan_tag_seen },
+	{ "vlan-mask", CMDL_U16, &ntuple_fs.vlan_tag_mask, NULL,
+	  0, &ntuple_vlan_tag_mask_seen },
+	{ "user-def", CMDL_U64, &ntuple_fs.data, NULL,
+	  0, &ntuple_user_def_seen },
+	{ "user-def-mask", CMDL_U64, &ntuple_fs.data_mask, NULL,
+	  0, &ntuple_user_def_mask_seen },
+	{ "action", CMDL_S32, &ntuple_fs.action, NULL },
+};
+
 static struct cmdline_info cmdline_msglvl[] = {
 	{ "drv", CMDL_FLAG, &msglvl_wanted, NULL,
 	  NETIF_MSG_DRV, &msglvl_mask },
@@ -741,6 +775,8 @@ static int rxflow_str_to_type(const char *str)
 		flow_type = AH_ESP_V6_FLOW;
 	else if (!strcmp(str, "sctp6"))
 		flow_type = SCTP_V6_FLOW;
+	else if (!strcmp(str, "ether"))
+		flow_type = ETHER_FLOW;
 
 	return flow_type;
 }
@@ -1551,8 +1587,8 @@ static void parse_rxntupleopts(int argc, char **argp, int i)
 	case SCTP_V4_FLOW:
 		parse_generic_cmdline(argc, argp, i + 1,
 				      &sntuple_changed,
-				      cmdline_ntuple,
-				      ARRAY_SIZE(cmdline_ntuple));
+				      cmdline_ntuple_tcp_ip4,
+				      ARRAY_SIZE(cmdline_ntuple_tcp_ip4));
 		if (!ntuple_ip4src_seen)
 			ntuple_fs.m_u.tcp_ip4_spec.ip4src = 0xffffffff;
 		if (!ntuple_ip4dst_seen)
@@ -1563,6 +1599,19 @@ static void parse_rxntupleopts(int argc, char **argp, int i)
 			ntuple_fs.m_u.tcp_ip4_spec.pdst = 0xffff;
 		ntuple_fs.m_u.tcp_ip4_spec.tos = 0xff;
 		break;
+	case ETHER_FLOW:
+		parse_generic_cmdline(argc, argp, i + 1,
+				      &sntuple_changed,
+				      cmdline_ntuple_ether,
+				      ARRAY_SIZE(cmdline_ntuple_ether));
+		if (!ntuple_ether_dst_seen)
+			memset(ntuple_fs.m_u.ether_spec.h_dest, 0xff, ETH_ALEN);
+		if (!ntuple_ether_src_seen)
+			memset(ntuple_fs.m_u.ether_spec.h_source, 0xff,
+			       ETH_ALEN);
+		if (!ntuple_ether_proto_seen)
+			ntuple_fs.m_u.ether_spec.h_proto = 0xffff;
+		break;
 	default:
 		fprintf(stderr, "Unsupported flow type \"%s\"\n", argp[i]);
 		exit(106);
@@ -1578,6 +1627,9 @@ static void parse_rxntupleopts(int argc, char **argp, int i)
 	    (ntuple_ip4dst_mask_seen && !ntuple_ip4dst_seen) ||
 	    (ntuple_psrc_mask_seen && !ntuple_psrc_seen) ||
 	    (ntuple_pdst_mask_seen && !ntuple_pdst_seen) ||
+	    (ntuple_ether_dst_mask_seen && !ntuple_ether_dst_seen) ||
+	    (ntuple_ether_src_mask_seen && !ntuple_ether_src_seen) ||
+	    (ntuple_ether_proto_mask_seen && !ntuple_ether_proto_seen) ||
 	    (ntuple_vlan_tag_mask_seen && !ntuple_vlan_tag_seen) ||
 	    (ntuple_user_def_mask_seen && !ntuple_user_def_seen)) {
 		fprintf(stderr, "Cannot specify mask without value\n");
-- 
1.7.2.1



-- 
Ben Hutchings, Senior Software Engineer, Solarflare Communications
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.


^ permalink raw reply related

* [PATCH ethtool 4/7] ethtool: Add MAC parameter type based on the parse_sopass() function
From: Ben Hutchings @ 2010-09-23 21:49 UTC (permalink / raw)
  To: Jeff Garzik; +Cc: netdev, linux-net-drivers
In-Reply-To: <1285278428.7794.27.camel@achroite.uk.solarflarecom.com>

Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
---
 ethtool.c |   26 ++++++++++++++------------
 1 files changed, 14 insertions(+), 12 deletions(-)

diff --git a/ethtool.c b/ethtool.c
index 6ec1cac..ea6a26f 100644
--- a/ethtool.c
+++ b/ethtool.c
@@ -77,7 +77,7 @@ enum {
 
 static int parse_wolopts(char *optstr, u32 *data);
 static char *unparse_wolopts(int wolopts);
-static int parse_sopass(char *src, unsigned char *dest);
+static void get_mac_addr(char *src, unsigned char *dest);
 static int do_gdrv(int fd, struct ifreq *ifr);
 static int do_gset(int fd, struct ifreq *ifr);
 static int do_sset(int fd, struct ifreq *ifr);
@@ -405,14 +405,15 @@ typedef enum {
 	CMDL_IP4,
 	CMDL_STR,
 	CMDL_FLAG,
+	CMDL_MAC,
 } cmdline_type_t;
 
 struct cmdline_info {
 	const char *name;
 	cmdline_type_t type;
-	/* Points to int (BOOL), s32, u16, u32 (U32/FLAG/IP4), u64 or
-	 * char * (STR).  For FLAG, the value accumulates all flags
-	 * to be set. */
+	/* Points to int (BOOL), s32, u16, u32 (U32/FLAG/IP4), u64,
+	 * char * (STR) or u8[6] (MAC).  For FLAG, the value accumulates
+	 * all flags to be set. */
 	void *wanted_val;
 	void *ioctl_val;
 	/* For FLAG, the flag value to be set/cleared */
@@ -668,6 +669,10 @@ static void parse_generic_cmdline(int argc, char **argp,
 					*p = in.s_addr;
 					break;
 				}
+				case CMDL_MAC:
+					get_mac_addr(argp[i],
+						     info[idx].wanted_val);
+					break;
 				case CMDL_FLAG: {
 					u32 *p;
 					p = info[idx].seen_val;
@@ -1044,8 +1049,7 @@ static void parse_cmdline(int argc, char **argp)
 				i++;
 				if (i >= argc)
 					show_usage(1);
-				if (parse_sopass(argp[i], sopass_wanted) < 0)
-					show_usage(1);
+				get_mac_addr(argp[i], sopass_wanted);
 				sopass_change = 1;
 				break;
 			} else if (!strcmp(argp[i], "msglvl")) {
@@ -1449,22 +1453,20 @@ static char *unparse_wolopts(int wolopts)
 	return buf;
 }
 
-static int parse_sopass(char *src, unsigned char *dest)
+static void get_mac_addr(char *src, unsigned char *dest)
 {
 	int count;
 	int i;
-	int buf[SOPASS_MAX];
+	int buf[ETH_ALEN];
 
 	count = sscanf(src, "%2x:%2x:%2x:%2x:%2x:%2x",
 		&buf[0], &buf[1], &buf[2], &buf[3], &buf[4], &buf[5]);
-	if (count != SOPASS_MAX) {
-		return -1;
-	}
+	if (count != ETH_ALEN)
+		show_usage(1);
 
 	for (i = 0; i < count; i++) {
 		dest[i] = buf[i];
 	}
-	return 0;
 }
 
 static int parse_rxfhashopts(char *optstr, u32 *data)
-- 
1.7.2.1



-- 
Ben Hutchings, Senior Software Engineer, Solarflare Communications
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.


^ permalink raw reply related

* [PATCH ethtool 3/7] ethtool: Fix RX n-tuple masks and documentation
From: Ben Hutchings @ 2010-09-23 21:48 UTC (permalink / raw)
  To: Jeff Garzik; +Cc: netdev, linux-net-drivers, Peter Waskiewicz
In-Reply-To: <1285278428.7794.27.camel@achroite.uk.solarflarecom.com>

For fields with unspecified values, explicitly mask all bits.  Do not
allow specifying a mask without a value.

Change usage information to clarify which parameters are optional or
required.

Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
---
 ethtool.8 |   31 ++++++++--------
 ethtool.c |  115 +++++++++++++++++++++++++++++++++++++++++++++++-------------
 2 files changed, 105 insertions(+), 41 deletions(-)

diff --git a/ethtool.8 b/ethtool.8
index 3ca403c..295caab 100644
--- a/ethtool.8
+++ b/ethtool.8
@@ -235,34 +235,33 @@ ethtool \- Display or change ethernet card settings
 
 .B ethtool \-U|\-\-config\-ntuple
 .I ethX
-.RB [ flow-type
-.RB tcp4|udp4|sctp4 ]
+.A3 flow-type tcp4 udp4 sctp4
 .RB [ src-ip
-.IR addr ]
+.IR addr
 .RB [ src-ip-mask
-.IR mask ]
+.IR mask ]]
 .RB [ dst-ip
-.IR addr ]
+.IR addr
 .RB [ dst-ip-mask
-.IR mask ]
+.IR mask ]]
 .RB [ src-port
-.IR port ]
+.IR port
 .RB [ src-port-mask
-.IR mask ]
+.IR mask ]]
 .RB [ dst-port
-.IR port ]
+.IR port
 .RB [ dst-port-mask
-.IR mask ]
+.IR mask ]]
 .RB [ vlan
-.IR VLAN-tag ]
+.IR VLAN-tag
 .RB [ vlan-mask
-.IR mask ]
+.IR mask ]]
 .RB [ user-def
-.IR data ]
+.IR data
 .RB [ user-def-mask
-.IR mask ]
-.RB [ action
-.IR queue\ or\ drop ]
+.IR mask ]]
+.RI action \ N
+
 .SH DESCRIPTION
 .BI ethtool
 is used for querying settings of an ethernet device and changing them.
diff --git a/ethtool.c b/ethtool.c
index 8c5d595..6ec1cac 100644
--- a/ethtool.c
+++ b/ethtool.c
@@ -99,6 +99,7 @@ static int do_gstats(int fd, struct ifreq *ifr);
 static int rxflow_str_to_type(const char *str);
 static int parse_rxfhashopts(char *optstr, u32 *data);
 static char *unparse_rxfhashopts(u64 opts);
+static void parse_rxntupleopts(int argc, char **argp, int first_arg);
 static int dump_rxfhash(int fhash, u64 val);
 static int do_srxclass(int fd, struct ifreq *ifr);
 static int do_grxclass(int fd, struct ifreq *ifr);
@@ -239,12 +240,14 @@ static struct option {
 		"		equal N | weight W0 W1 ...\n" },
     { "-U", "--config-ntuple", MODE_SNTUPLE, "Configure Rx ntuple filters "
 		"and actions",
-		"               [ flow-type tcp4|udp4|sctp4 src-ip <addr> "
-		"src-ip-mask <mask> dst-ip <addr> dst-ip-mask <mask> "
-		"src-port <port> src-port-mask <mask> dst-port <port> "
-		"dst-port-mask <mask> vlan <VLAN tag> vlan-mask <mask> "
-		"user-def <data> user-def-mask <mask> "
-		"action <queue or drop>\n" },
+		"		flow-type tcp4|udp4|sctp4\n"
+		"		[ src-ip ADDR [src-ip-mask MASK] ]\n"
+		"		[ dst-ip ADDR [dst-ip-mask MASK] ]\n"
+		"		[ src-port PORT [src-port-mask MASK] ]\n"
+		"		[ dst-port PORT [dst-port-mask MASK] ]\n"
+		"		[ vlan VLAN-TAG [vlan-mask MASK] ]\n"
+		"		[ user-def DATA [user-def-mask MASK] ]\n"
+		"		action N\n" },
     { "-u", "--show-ntuple", MODE_GNTUPLE,
 		"Get Rx ntuple filters and actions\n" },
     { "-h", "--help", MODE_HELP, "Show this help" },
@@ -366,6 +369,18 @@ static int rxfhindir_equal = 0;
 static char **rxfhindir_weight = NULL;
 static int sntuple_changed = 0;
 static struct ethtool_rx_ntuple_flow_spec ntuple_fs;
+static int ntuple_ip4src_seen = 0;
+static int ntuple_ip4src_mask_seen = 0;
+static int ntuple_ip4dst_seen = 0;
+static int ntuple_ip4dst_mask_seen = 0;
+static int ntuple_psrc_seen = 0;
+static int ntuple_psrc_mask_seen = 0;
+static int ntuple_pdst_seen = 0;
+static int ntuple_pdst_mask_seen = 0;
+static int ntuple_vlan_tag_seen = 0;
+static int ntuple_vlan_tag_mask_seen = 0;
+static int ntuple_user_def_seen = 0;
+static int ntuple_user_def_mask_seen = 0;
 static char *flash_file = NULL;
 static int flash = -1;
 static int flash_region = -1;
@@ -482,18 +497,30 @@ static struct cmdline_info cmdline_coalesce[] = {
 };
 
 static struct cmdline_info cmdline_ntuple[] = {
-	{ "src-ip", CMDL_IP4, &ntuple_fs.h_u.tcp_ip4_spec.ip4src, NULL },
-	{ "src-ip-mask", CMDL_IP4, &ntuple_fs.m_u.tcp_ip4_spec.ip4src, NULL },
-	{ "dst-ip", CMDL_IP4, &ntuple_fs.h_u.tcp_ip4_spec.ip4dst, NULL },
-	{ "dst-ip-mask", CMDL_IP4, &ntuple_fs.m_u.tcp_ip4_spec.ip4dst, NULL },
-	{ "src-port", CMDL_BE16, &ntuple_fs.h_u.tcp_ip4_spec.psrc, NULL },
-	{ "src-port-mask", CMDL_BE16, &ntuple_fs.m_u.tcp_ip4_spec.psrc, NULL },
-	{ "dst-port", CMDL_BE16, &ntuple_fs.h_u.tcp_ip4_spec.pdst, NULL },
-	{ "dst-port-mask", CMDL_BE16, &ntuple_fs.m_u.tcp_ip4_spec.pdst, NULL },
-	{ "vlan", CMDL_U16, &ntuple_fs.vlan_tag, NULL },
-	{ "vlan-mask", CMDL_U16, &ntuple_fs.vlan_tag_mask, NULL },
-	{ "user-def", CMDL_U64, &ntuple_fs.data, NULL },
-	{ "user-def-mask", CMDL_U64, &ntuple_fs.data_mask, NULL },
+	{ "src-ip", CMDL_IP4, &ntuple_fs.h_u.tcp_ip4_spec.ip4src, NULL,
+	  0, &ntuple_ip4src_seen },
+	{ "src-ip-mask", CMDL_IP4, &ntuple_fs.m_u.tcp_ip4_spec.ip4src, NULL,
+	  0, &ntuple_ip4src_mask_seen },
+	{ "dst-ip", CMDL_IP4, &ntuple_fs.h_u.tcp_ip4_spec.ip4dst, NULL,
+	  0, &ntuple_ip4dst_seen },
+	{ "dst-ip-mask", CMDL_IP4, &ntuple_fs.m_u.tcp_ip4_spec.ip4dst, NULL,
+	  0, &ntuple_ip4dst_mask_seen },
+	{ "src-port", CMDL_BE16, &ntuple_fs.h_u.tcp_ip4_spec.psrc, NULL,
+	  0, &ntuple_psrc_seen },
+	{ "src-port-mask", CMDL_BE16, &ntuple_fs.m_u.tcp_ip4_spec.psrc, NULL,
+	  0, &ntuple_psrc_mask_seen },
+	{ "dst-port", CMDL_BE16, &ntuple_fs.h_u.tcp_ip4_spec.pdst, NULL,
+	  0, &ntuple_pdst_seen },
+	{ "dst-port-mask", CMDL_BE16, &ntuple_fs.m_u.tcp_ip4_spec.pdst, NULL,
+	  0, &ntuple_pdst_mask_seen },
+	{ "vlan", CMDL_U16, &ntuple_fs.vlan_tag, NULL,
+	  0, &ntuple_vlan_tag_seen },
+	{ "vlan-mask", CMDL_U16, &ntuple_fs.vlan_tag_mask, NULL,
+	  0, &ntuple_vlan_tag_mask_seen },
+	{ "user-def", CMDL_U64, &ntuple_fs.data, NULL,
+	  0, &ntuple_user_def_seen },
+	{ "user-def-mask", CMDL_U64, &ntuple_fs.data_mask, NULL,
+	  0, &ntuple_user_def_mask_seen },
 	{ "action", CMDL_S32, &ntuple_fs.action, NULL },
 };
 
@@ -844,13 +871,7 @@ static void parse_cmdline(int argc, char **argp)
 						show_usage(1);
 						break;
 					}
-					ntuple_fs.flow_type =
-					            rxflow_str_to_type(argp[i]);
-					i += 1;
-					parse_generic_cmdline(argc, argp, i,
-						&sntuple_changed,
-						cmdline_ntuple,
-						ARRAY_SIZE(cmdline_ntuple));
+					parse_rxntupleopts(argc, argp, i);
 					i = argc;
 					break;
 				} else {
@@ -1518,6 +1539,50 @@ static char *unparse_rxfhashopts(u64 opts)
 	return buf;
 }
 
+static void parse_rxntupleopts(int argc, char **argp, int i)
+{
+	ntuple_fs.flow_type = rxflow_str_to_type(argp[i]);
+
+	switch (ntuple_fs.flow_type) {
+	case TCP_V4_FLOW:
+	case UDP_V4_FLOW:
+	case SCTP_V4_FLOW:
+		parse_generic_cmdline(argc, argp, i + 1,
+				      &sntuple_changed,
+				      cmdline_ntuple,
+				      ARRAY_SIZE(cmdline_ntuple));
+		if (!ntuple_ip4src_seen)
+			ntuple_fs.m_u.tcp_ip4_spec.ip4src = 0xffffffff;
+		if (!ntuple_ip4dst_seen)
+			ntuple_fs.m_u.tcp_ip4_spec.ip4dst = 0xffffffff;
+		if (!ntuple_psrc_seen)
+			ntuple_fs.m_u.tcp_ip4_spec.psrc = 0xffff;
+		if (!ntuple_pdst_seen)
+			ntuple_fs.m_u.tcp_ip4_spec.pdst = 0xffff;
+		ntuple_fs.m_u.tcp_ip4_spec.tos = 0xff;
+		break;
+	default:
+		fprintf(stderr, "Unsupported flow type \"%s\"\n", argp[i]);
+		exit(106);
+		break;
+	}
+
+	if (!ntuple_vlan_tag_seen)
+		ntuple_fs.vlan_tag_mask = 0xffff;
+	if (!ntuple_user_def_seen)
+		ntuple_fs.data_mask = 0xffffffffffffffffULL;
+
+	if ((ntuple_ip4src_mask_seen && !ntuple_ip4src_seen) ||
+	    (ntuple_ip4dst_mask_seen && !ntuple_ip4dst_seen) ||
+	    (ntuple_psrc_mask_seen && !ntuple_psrc_seen) ||
+	    (ntuple_pdst_mask_seen && !ntuple_pdst_seen) ||
+	    (ntuple_vlan_tag_mask_seen && !ntuple_vlan_tag_seen) ||
+	    (ntuple_user_def_mask_seen && !ntuple_user_def_seen)) {
+		fprintf(stderr, "Cannot specify mask without value\n");
+		exit(107);
+	}
+}
+
 static struct {
 	const char *name;
 	int (*func)(struct ethtool_drvinfo *info, struct ethtool_regs *regs);
-- 
1.7.2.1



-- 
Ben Hutchings, Senior Software Engineer, Solarflare Communications
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.


^ permalink raw reply related

* [PATCH ethtool 2/7] ethtool: Generalise cmdline_info::unwanted_val to a "seen" flag or bitmask
From: Ben Hutchings @ 2010-09-23 21:48 UTC (permalink / raw)
  To: Jeff Garzik; +Cc: netdev, linux-net-drivers
In-Reply-To: <1285278428.7794.27.camel@achroite.uk.solarflarecom.com>

Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
---
 ethtool.c |   68 +++++++++++++++++++++++++++++++++---------------------------
 1 files changed, 37 insertions(+), 31 deletions(-)

diff --git a/ethtool.c b/ethtool.c
index 6b2b7c8..8c5d595 100644
--- a/ethtool.c
+++ b/ethtool.c
@@ -290,7 +290,7 @@ static int off_tso_wanted = -1;
 static int off_ufo_wanted = -1;
 static int off_gso_wanted = -1;
 static u32 off_flags_wanted = 0;
-static u32 off_flags_unwanted = 0;
+static u32 off_flags_mask = 0;
 static int off_gro_wanted = -1;
 
 static struct ethtool_pauseparam epause;
@@ -372,7 +372,7 @@ static int flash_region = -1;
 
 static int msglvl_changed;
 static u32 msglvl_wanted = 0;
-static u32 msglvl_unwanted =0;
+static u32 msglvl_mask = 0;
 
 static enum {
 	ONLINE=0,
@@ -402,8 +402,10 @@ struct cmdline_info {
 	void *ioctl_val;
 	/* For FLAG, the flag value to be set/cleared */
 	u32 flag_val;
-	/* For FLAG, accumulates all flags to be cleared */
-	u32 *unwanted_val;
+	/* For FLAG, points to u32 and accumulates all flags seen.
+	 * For anything else, points to int and is set if the option is
+	 * seen. */
+	void *seen_val;
 };
 
 static struct cmdline_info cmdline_gregs[] = {
@@ -433,12 +435,12 @@ static struct cmdline_info cmdline_offload[] = {
 	{ "ufo", CMDL_BOOL, &off_ufo_wanted, NULL },
 	{ "gso", CMDL_BOOL, &off_gso_wanted, NULL },
 	{ "lro", CMDL_FLAG, &off_flags_wanted, NULL,
-	  ETH_FLAG_LRO, &off_flags_unwanted },
+	  ETH_FLAG_LRO, &off_flags_mask },
 	{ "gro", CMDL_BOOL, &off_gro_wanted, NULL },
 	{ "ntuple", CMDL_FLAG, &off_flags_wanted, NULL,
-	  ETH_FLAG_NTUPLE, &off_flags_unwanted },
+	  ETH_FLAG_NTUPLE, &off_flags_mask },
 	{ "rxhash", CMDL_FLAG, &off_flags_wanted, NULL,
-	  ETH_FLAG_RXHASH, &off_flags_unwanted },
+	  ETH_FLAG_RXHASH, &off_flags_mask },
 };
 
 static struct cmdline_info cmdline_pause[] = {
@@ -497,35 +499,35 @@ static struct cmdline_info cmdline_ntuple[] = {
 
 static struct cmdline_info cmdline_msglvl[] = {
 	{ "drv", CMDL_FLAG, &msglvl_wanted, NULL,
-	  NETIF_MSG_DRV, &msglvl_unwanted },
+	  NETIF_MSG_DRV, &msglvl_mask },
 	{ "probe", CMDL_FLAG, &msglvl_wanted, NULL,
-	  NETIF_MSG_PROBE, &msglvl_unwanted },
+	  NETIF_MSG_PROBE, &msglvl_mask },
 	{ "link", CMDL_FLAG, &msglvl_wanted, NULL,
-	  NETIF_MSG_LINK, &msglvl_unwanted },
+	  NETIF_MSG_LINK, &msglvl_mask },
 	{ "timer", CMDL_FLAG, &msglvl_wanted, NULL,
-	  NETIF_MSG_TIMER, &msglvl_unwanted },
+	  NETIF_MSG_TIMER, &msglvl_mask },
 	{ "ifdown", CMDL_FLAG, &msglvl_wanted, NULL,
-	  NETIF_MSG_IFDOWN, &msglvl_unwanted },
+	  NETIF_MSG_IFDOWN, &msglvl_mask },
 	{ "ifup", CMDL_FLAG, &msglvl_wanted, NULL,
-	  NETIF_MSG_IFUP, &msglvl_unwanted },
+	  NETIF_MSG_IFUP, &msglvl_mask },
 	{ "rx_err", CMDL_FLAG, &msglvl_wanted, NULL,
-	  NETIF_MSG_RX_ERR, &msglvl_unwanted },
+	  NETIF_MSG_RX_ERR, &msglvl_mask },
 	{ "tx_err", CMDL_FLAG, &msglvl_wanted, NULL,
-	  NETIF_MSG_TX_ERR, &msglvl_unwanted },
+	  NETIF_MSG_TX_ERR, &msglvl_mask },
 	{ "tx_queued", CMDL_FLAG, &msglvl_wanted, NULL,
-	  NETIF_MSG_TX_QUEUED, &msglvl_unwanted },
+	  NETIF_MSG_TX_QUEUED, &msglvl_mask },
 	{ "intr", CMDL_FLAG, &msglvl_wanted, NULL,
-	  NETIF_MSG_INTR, &msglvl_unwanted },
+	  NETIF_MSG_INTR, &msglvl_mask },
 	{ "tx_done", CMDL_FLAG, &msglvl_wanted, NULL,
-	  NETIF_MSG_TX_DONE, &msglvl_unwanted },
+	  NETIF_MSG_TX_DONE, &msglvl_mask },
 	{ "rx_status", CMDL_FLAG, &msglvl_wanted, NULL,
-	  NETIF_MSG_RX_STATUS, &msglvl_unwanted },
+	  NETIF_MSG_RX_STATUS, &msglvl_mask },
 	{ "pktdata", CMDL_FLAG, &msglvl_wanted, NULL,
-	  NETIF_MSG_PKTDATA, &msglvl_unwanted },
+	  NETIF_MSG_PKTDATA, &msglvl_mask },
 	{ "hw", CMDL_FLAG, &msglvl_wanted, NULL,
-	  NETIF_MSG_HW, &msglvl_unwanted },
+	  NETIF_MSG_HW, &msglvl_mask },
 	{ "wol", CMDL_FLAG, &msglvl_wanted, NULL,
-	  NETIF_MSG_WOL, &msglvl_unwanted },
+	  NETIF_MSG_WOL, &msglvl_mask },
 };
 
 static long long
@@ -582,6 +584,9 @@ static void parse_generic_cmdline(int argc, char **argp,
 			if (!strcmp(info[idx].name, argp[i])) {
 				found = 1;
 				*changed = 1;
+				if (info[idx].type != CMDL_FLAG &&
+				    info[idx].seen_val)
+					*(int *)info[idx].seen_val = 1;
 				i += 1;
 				if (i >= argc)
 					show_usage(1);
@@ -638,13 +643,14 @@ static void parse_generic_cmdline(int argc, char **argp,
 				}
 				case CMDL_FLAG: {
 					u32 *p;
-					if (!strcmp(argp[i], "on"))
+					p = info[idx].seen_val;
+					*p |= info[idx].flag_val;
+					if (!strcmp(argp[i], "on")) {
 						p = info[idx].wanted_val;
-					else if (!strcmp(argp[i], "off"))
-						p = info[idx].unwanted_val;
-					else
+						*p |= info[idx].flag_val;
+					} else if (strcmp(argp[i], "off")) {
 						show_usage(1);
-					*p |= info[idx].flag_val;
+					}
 					break;
 				}
 				case CMDL_STR: {
@@ -1027,7 +1033,7 @@ static void parse_cmdline(int argc, char **argp)
 					show_usage(1);
 				if (isdigit((unsigned char)argp[i][0])) {
 					msglvl_changed = 1;
-					msglvl_unwanted = ~0;
+					msglvl_mask = ~0;
 					msglvl_wanted =
 						get_uint_range(argp[i], 0,
 							       0xffffffff);
@@ -2243,7 +2249,7 @@ static int do_soffload(int fd, struct ifreq *ifr)
 			return 90;
 		}
 	}
-	if (off_flags_wanted || off_flags_unwanted) {
+	if (off_flags_mask) {
 		changed = 1;
 		eval.cmd = ETHTOOL_GFLAGS;
 		eval.data = 0;
@@ -2255,7 +2261,7 @@ static int do_soffload(int fd, struct ifreq *ifr)
 		}
 
 		eval.cmd = ETHTOOL_SFLAGS;
-		eval.data = ((eval.data & ~off_flags_unwanted) |
+		eval.data = ((eval.data & ~off_flags_mask) |
 			     off_flags_wanted);
 
 		err = ioctl(fd, SIOCETHTOOL, ifr);
@@ -2459,7 +2465,7 @@ static int do_sset(int fd, struct ifreq *ifr)
 			perror("Cannot get msglvl");
 		} else {
 			edata.cmd = ETHTOOL_SMSGLVL;
-			edata.data = ((edata.data & ~msglvl_unwanted) |
+			edata.data = ((edata.data & ~msglvl_mask) |
 				      msglvl_wanted);
 			ifr->ifr_data = (caddr_t)&edata;
 			err = send_ioctl(fd, ifr);
-- 
1.7.2.1



-- 
Ben Hutchings, Senior Software Engineer, Solarflare Communications
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.


^ permalink raw reply related

* [PATCH ethtool 1/7] ethtool-copy.h: sync with net-next-2.6
From: Ben Hutchings @ 2010-09-23 21:48 UTC (permalink / raw)
  To: Jeff Garzik; +Cc: netdev, linux-net-drivers
In-Reply-To: <1285278428.7794.27.camel@achroite.uk.solarflarecom.com>

Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
---
 ethtool-copy.h |  228 ++++++++++++++++++++++++++++++++++++++-----------------
 1 files changed, 157 insertions(+), 71 deletions(-)

diff --git a/ethtool-copy.h b/ethtool-copy.h
index 894f1da..1be08cf 100644
--- a/ethtool-copy.h
+++ b/ethtool-copy.h
@@ -14,6 +14,7 @@
 #define _LINUX_ETHTOOL_H
 
 #include <linux/types.h>
+#include <linux/if_ether.h>
 
 /* This should work for both 32 and 64 bit userland. */
 struct ethtool_cmd {
@@ -314,9 +315,20 @@ enum ethtool_flags {
 };
 
 /* The following structures are for supporting RX network flow
- * classification configuration. Note, all multibyte fields, e.g.,
- * ip4src, ip4dst, psrc, pdst, spi, etc. are expected to be in network
- * byte order.
+ * classification and RX n-tuple configuration. Note, all multibyte
+ * fields, e.g., ip4src, ip4dst, psrc, pdst, spi, etc. are expected to
+ * be in network byte order.
+ */
+
+/**
+ * struct ethtool_tcpip4_spec - flow specification for TCP/IPv4 etc.
+ * @ip4src: Source host
+ * @ip4dst: Destination host
+ * @psrc: Source port
+ * @pdst: Destination port
+ * @tos: Type-of-service
+ *
+ * This can be used to specify a TCP/IPv4, UDP/IPv4 or SCTP/IPv4 flow.
  */
 struct ethtool_tcpip4_spec {
 	__be32	ip4src;
@@ -326,6 +338,15 @@ struct ethtool_tcpip4_spec {
 	__u8    tos;
 };
 
+/**
+ * struct ethtool_ah_espip4_spec - flow specification for IPsec/IPv4
+ * @ip4src: Source host
+ * @ip4dst: Destination host
+ * @spi: Security parameters index
+ * @tos: Type-of-service
+ *
+ * This can be used to specify an IPsec transport or tunnel over IPv4.
+ */
 struct ethtool_ah_espip4_spec {
 	__be32	ip4src;
 	__be32	ip4dst;
@@ -333,21 +354,17 @@ struct ethtool_ah_espip4_spec {
 	__u8    tos;
 };
 
-struct ethtool_rawip4_spec {
-	__be32	ip4src;
-	__be32	ip4dst;
-	__u8	hdata[64];
-};
-
-struct ethtool_ether_spec {
-	__be16	ether_type;
-	__u8	frame_size;
-	__u8	eframe[16];
-};
-
 #define	ETH_RX_NFC_IP4	1
-#define	ETH_RX_NFC_IP6	2
 
+/**
+ * struct ethtool_usrip4_spec - general flow specification for IPv4
+ * @ip4src: Source host
+ * @ip4dst: Destination host
+ * @l4_4_bytes: First 4 bytes of transport (layer 4) header
+ * @tos: Type-of-service
+ * @ip_ver: Value must be %ETH_RX_NFC_IP4; mask must be 0
+ * @proto: Transport protocol number; mask must be 0
+ */
 struct ethtool_usrip4_spec {
 	__be32	ip4src;
 	__be32	ip4dst;
@@ -357,6 +374,15 @@ struct ethtool_usrip4_spec {
 	__u8    proto;
 };
 
+/**
+ * struct ethtool_rx_flow_spec - specification for RX flow filter
+ * @flow_type: Type of match to perform, e.g. %TCP_V4_FLOW
+ * @h_u: Flow fields to match (dependent on @flow_type)
+ * @m_u: Masks for flow field bits to be ignored
+ * @ring_cookie: RX ring/queue index to deliver to, or %RX_CLS_FLOW_DISC
+ *	if packets should be discarded
+ * @location: Index of filter in hardware table
+ */
 struct ethtool_rx_flow_spec {
 	__u32		flow_type;
 	union {
@@ -365,36 +391,91 @@ struct ethtool_rx_flow_spec {
 		struct ethtool_tcpip4_spec		sctp_ip4_spec;
 		struct ethtool_ah_espip4_spec		ah_ip4_spec;
 		struct ethtool_ah_espip4_spec		esp_ip4_spec;
-		struct ethtool_rawip4_spec		raw_ip4_spec;
-		struct ethtool_ether_spec		ether_spec;
 		struct ethtool_usrip4_spec		usr_ip4_spec;
-		__u8					hdata[64];
-	} h_u, m_u; /* entry, mask */
+		struct ethhdr				ether_spec;
+		__u8					hdata[72];
+	} h_u, m_u;
 	__u64		ring_cookie;
 	__u32		location;
 };
 
+/**
+ * struct ethtool_rxnfc - command to get or set RX flow classification rules
+ * @cmd: Specific command number - %ETHTOOL_GRXFH, %ETHTOOL_SRXFH,
+ *	%ETHTOOL_GRXRINGS, %ETHTOOL_GRXCLSRLCNT, %ETHTOOL_GRXCLSRULE,
+ *	%ETHTOOL_GRXCLSRLALL, %ETHTOOL_SRXCLSRLDEL or %ETHTOOL_SRXCLSRLINS
+ * @flow_type: Type of flow to be affected, e.g. %TCP_V4_FLOW
+ * @data: Command-dependent value
+ * @fs: Flow filter specification
+ * @rule_cnt: Number of rules to be affected
+ * @rule_locs: Array of valid rule indices
+ *
+ * For %ETHTOOL_GRXFH and %ETHTOOL_SRXFH, @data is a bitmask indicating
+ * the fields included in the flow hash, e.g. %RXH_IP_SRC.  The following
+ * structure fields must not be used.
+ *
+ * For %ETHTOOL_GRXRINGS, @data is set to the number of RX rings/queues
+ * on return.
+ *
+ * For %ETHTOOL_GRXCLSRLCNT, @rule_cnt is set to the number of defined
+ * rules on return.
+ *
+ * For %ETHTOOL_GRXCLSRULE, @fs.@location specifies the index of an
+ * existing filter rule on entry and @fs contains the rule on return.
+ *
+ * For %ETHTOOL_GRXCLSRLALL, @rule_cnt specifies the array size of the
+ * user buffer for @rule_locs on entry.  On return, @data is the size
+ * of the filter table and @rule_locs contains the indices of the
+ * defined rules.
+ *
+ * For %ETHTOOL_SRXCLSRLINS, @fs specifies the filter rule to add or
+ * update.  @fs.@location specifies the index to use and must not be
+ * ignored.
+ *
+ * For %ETHTOOL_SRXCLSRLDEL, @fs.@location specifies the index of an
+ * existing filter rule on entry.
+ *
+ * Implementation of indexed classification rules generally requires a
+ * TCAM.
+ */
 struct ethtool_rxnfc {
 	__u32				cmd;
 	__u32				flow_type;
-	/* The rx flow hash value or the rule DB size */
 	__u64				data;
-	/* The following fields are not valid and must not be used for
-	 * the ETHTOOL_{G,X}RXFH commands. */
 	struct ethtool_rx_flow_spec	fs;
 	__u32				rule_cnt;
 	__u32				rule_locs[0];
 };
 
+/**
+ * struct ethtool_rxfh_indir - command to get or set RX flow hash indirection
+ * @cmd: Specific command number - %ETHTOOL_GRXFHINDIR or %ETHTOOL_SRXFHINDIR
+ * @size: On entry, the array size of the user buffer.  On return from
+ *	%ETHTOOL_GRXFHINDIR, the array size of the hardware indirection table.
+ * @ring_index: RX ring/queue index for each hash value
+ */
 struct ethtool_rxfh_indir {
 	__u32	cmd;
-	/* On entry, this is the array size of the user buffer.  On
-	 * return from ETHTOOL_GRXFHINDIR, this is the array size of
-	 * the hardware indirection table. */
 	__u32	size;
-	__u32	ring_index[0];	/* ring/queue index for each hash value */
+	__u32	ring_index[0];
 };
 
+/**
+ * struct ethtool_rx_ntuple_flow_spec - specification for RX flow filter
+ * @flow_type: Type of match to perform, e.g. %TCP_V4_FLOW
+ * @h_u: Flow field values to match (dependent on @flow_type)
+ * @m_u: Masks for flow field value bits to be ignored
+ * @vlan_tag: VLAN tag to match
+ * @vlan_tag_mask: Mask for VLAN tag bits to be ignored
+ * @data: Driver-dependent data to match
+ * @data_mask: Mask for driver-dependent data bits to be ignored
+ * @action: RX ring/queue index to deliver to (non-negative) or other action
+ *	(negative, e.g. %ETHTOOL_RXNTUPLE_ACTION_DROP)
+ *
+ * For flow types %TCP_V4_FLOW, %UDP_V4_FLOW and %SCTP_V4_FLOW, where
+ * a field value and mask are both zero this is treated as if all mask
+ * bits are set i.e. the field is ignored.
+ */
 struct ethtool_rx_ntuple_flow_spec {
 	__u32		 flow_type;
 	union {
@@ -403,22 +484,26 @@ struct ethtool_rx_ntuple_flow_spec {
 		struct ethtool_tcpip4_spec		sctp_ip4_spec;
 		struct ethtool_ah_espip4_spec		ah_ip4_spec;
 		struct ethtool_ah_espip4_spec		esp_ip4_spec;
-		struct ethtool_rawip4_spec		raw_ip4_spec;
-		struct ethtool_ether_spec		ether_spec;
 		struct ethtool_usrip4_spec		usr_ip4_spec;
-		__u8					hdata[64];
-	} h_u, m_u; /* entry, mask */
+		struct ethhdr				ether_spec;
+		__u8					hdata[72];
+	} h_u, m_u;
 
 	__u16	        vlan_tag;
 	__u16	        vlan_tag_mask;
-	__u64		data;      /* user-defined flow spec data */
-	__u64		data_mask; /* user-defined flow spec mask */
+	__u64		data;
+	__u64		data_mask;
 
-	/* signed to distinguish between queue and actions (DROP) */
 	__s32		action;
-#define ETHTOOL_RXNTUPLE_ACTION_DROP -1
+#define ETHTOOL_RXNTUPLE_ACTION_DROP	(-1)	/* drop packet */
+#define ETHTOOL_RXNTUPLE_ACTION_CLEAR	(-2)	/* clear filter */
 };
 
+/**
+ * struct ethtool_rx_ntuple - command to set or clear RX flow filter
+ * @cmd: Command number - %ETHTOOL_SRXNTUPLE
+ * @fs: Flow filter specification
+ */
 struct ethtool_rx_ntuple {
 	__u32					cmd;
 	struct ethtool_rx_ntuple_flow_spec	fs;
@@ -444,29 +529,29 @@ struct ethtool_flash {
 #define ETHTOOL_GREGS		0x00000004 /* Get NIC registers. */
 #define ETHTOOL_GWOL		0x00000005 /* Get wake-on-lan options. */
 #define ETHTOOL_SWOL		0x00000006 /* Set wake-on-lan options. */
-#define ETHTOOL_GMSGLVL	0x00000007 /* Get driver message level */
-#define ETHTOOL_SMSGLVL	0x00000008 /* Set driver msg level. */
+#define ETHTOOL_GMSGLVL		0x00000007 /* Get driver message level */
+#define ETHTOOL_SMSGLVL		0x00000008 /* Set driver msg level. */
 #define ETHTOOL_NWAY_RST	0x00000009 /* Restart autonegotiation. */
 #define ETHTOOL_GLINK		0x0000000a /* Get link status (ethtool_value) */
-#define ETHTOOL_GEEPROM	0x0000000b /* Get EEPROM data */
-#define ETHTOOL_SEEPROM	0x0000000c /* Set EEPROM data. */
+#define ETHTOOL_GEEPROM		0x0000000b /* Get EEPROM data */
+#define ETHTOOL_SEEPROM		0x0000000c /* Set EEPROM data. */
 #define ETHTOOL_GCOALESCE	0x0000000e /* Get coalesce config */
 #define ETHTOOL_SCOALESCE	0x0000000f /* Set coalesce config. */
 #define ETHTOOL_GRINGPARAM	0x00000010 /* Get ring parameters */
 #define ETHTOOL_SRINGPARAM	0x00000011 /* Set ring parameters. */
 #define ETHTOOL_GPAUSEPARAM	0x00000012 /* Get pause parameters */
 #define ETHTOOL_SPAUSEPARAM	0x00000013 /* Set pause parameters. */
-#define ETHTOOL_GRXCSUM	0x00000014 /* Get RX hw csum enable (ethtool_value) */
-#define ETHTOOL_SRXCSUM	0x00000015 /* Set RX hw csum enable (ethtool_value) */
-#define ETHTOOL_GTXCSUM	0x00000016 /* Get TX hw csum enable (ethtool_value) */
-#define ETHTOOL_STXCSUM	0x00000017 /* Set TX hw csum enable (ethtool_value) */
+#define ETHTOOL_GRXCSUM		0x00000014 /* Get RX hw csum enable (ethtool_value) */
+#define ETHTOOL_SRXCSUM		0x00000015 /* Set RX hw csum enable (ethtool_value) */
+#define ETHTOOL_GTXCSUM		0x00000016 /* Get TX hw csum enable (ethtool_value) */
+#define ETHTOOL_STXCSUM		0x00000017 /* Set TX hw csum enable (ethtool_value) */
 #define ETHTOOL_GSG		0x00000018 /* Get scatter-gather enable
 					    * (ethtool_value) */
 #define ETHTOOL_SSG		0x00000019 /* Set scatter-gather enable
 					    * (ethtool_value). */
 #define ETHTOOL_TEST		0x0000001a /* execute NIC self-test. */
 #define ETHTOOL_GSTRINGS	0x0000001b /* get specified string set */
-#define ETHTOOL_PHYS_ID	0x0000001c /* identify the NIC */
+#define ETHTOOL_PHYS_ID		0x0000001c /* identify the NIC */
 #define ETHTOOL_GSTATS		0x0000001d /* get NIC-specific statistics */
 #define ETHTOOL_GTSO		0x0000001e /* Get TSO enable (ethtool_value) */
 #define ETHTOOL_STSO		0x0000001f /* Set TSO enable (ethtool_value) */
@@ -477,8 +562,8 @@ struct ethtool_flash {
 #define ETHTOOL_SGSO		0x00000024 /* Set GSO enable (ethtool_value) */
 #define ETHTOOL_GFLAGS		0x00000025 /* Get flags bitmap(ethtool_value) */
 #define ETHTOOL_SFLAGS		0x00000026 /* Set flags bitmap(ethtool_value) */
-#define ETHTOOL_GPFLAGS	0x00000027 /* Get driver-private flags bitmap */
-#define ETHTOOL_SPFLAGS	0x00000028 /* Set driver-private flags bitmap */
+#define ETHTOOL_GPFLAGS		0x00000027 /* Get driver-private flags bitmap */
+#define ETHTOOL_SPFLAGS		0x00000028 /* Set driver-private flags bitmap */
 
 #define ETHTOOL_GRXFH		0x00000029 /* Get RX flow hash configuration */
 #define ETHTOOL_SRXFH		0x0000002a /* Set RX flow hash configuration */
@@ -505,18 +590,18 @@ struct ethtool_flash {
 /* Indicates what features are supported by the interface. */
 #define SUPPORTED_10baseT_Half		(1 << 0)
 #define SUPPORTED_10baseT_Full		(1 << 1)
-#define SUPPORTED_100baseT_Half	(1 << 2)
-#define SUPPORTED_100baseT_Full	(1 << 3)
+#define SUPPORTED_100baseT_Half		(1 << 2)
+#define SUPPORTED_100baseT_Full		(1 << 3)
 #define SUPPORTED_1000baseT_Half	(1 << 4)
 #define SUPPORTED_1000baseT_Full	(1 << 5)
 #define SUPPORTED_Autoneg		(1 << 6)
 #define SUPPORTED_TP			(1 << 7)
 #define SUPPORTED_AUI			(1 << 8)
 #define SUPPORTED_MII			(1 << 9)
-#define SUPPORTED_FIBRE		(1 << 10)
+#define SUPPORTED_FIBRE			(1 << 10)
 #define SUPPORTED_BNC			(1 << 11)
 #define SUPPORTED_10000baseT_Full	(1 << 12)
-#define SUPPORTED_Pause		(1 << 13)
+#define SUPPORTED_Pause			(1 << 13)
 #define SUPPORTED_Asym_Pause		(1 << 14)
 #define SUPPORTED_2500baseX_Full	(1 << 15)
 #define SUPPORTED_Backplane		(1 << 16)
@@ -526,8 +611,8 @@ struct ethtool_flash {
 #define SUPPORTED_10000baseR_FEC	(1 << 20)
 
 /* Indicates what features are advertised by the interface. */
-#define ADVERTISED_10baseT_Half	(1 << 0)
-#define ADVERTISED_10baseT_Full	(1 << 1)
+#define ADVERTISED_10baseT_Half		(1 << 0)
+#define ADVERTISED_10baseT_Full		(1 << 1)
 #define ADVERTISED_100baseT_Half	(1 << 2)
 #define ADVERTISED_100baseT_Full	(1 << 3)
 #define ADVERTISED_1000baseT_Half	(1 << 4)
@@ -566,12 +651,12 @@ struct ethtool_flash {
 #define DUPLEX_FULL		0x01
 
 /* Which connector port. */
-#define PORT_TP		0x00
+#define PORT_TP			0x00
 #define PORT_AUI		0x01
 #define PORT_MII		0x02
 #define PORT_FIBRE		0x03
 #define PORT_BNC		0x04
-#define PORT_DA		0x05
+#define PORT_DA			0x05
 #define PORT_NONE		0xef
 #define PORT_OTHER		0xff
 
@@ -585,7 +670,7 @@ struct ethtool_flash {
 /* Enable or disable autonegotiation.  If this is set to enable,
  * the forced link modes above are completely ignored.
  */
-#define AUTONEG_DISABLE	0x00
+#define AUTONEG_DISABLE		0x00
 #define AUTONEG_ENABLE		0x01
 
 /* Mode MDI or MDI-X */
@@ -602,22 +687,23 @@ struct ethtool_flash {
 #define WAKE_MAGIC		(1 << 5)
 #define WAKE_MAGICSECURE	(1 << 6) /* only meaningful if WAKE_MAGIC */
 
-/* L3-L4 network traffic flow types */
-#define	TCP_V4_FLOW	0x01
-#define	UDP_V4_FLOW	0x02
-#define	SCTP_V4_FLOW	0x03
-#define	AH_ESP_V4_FLOW	0x04
-#define	TCP_V6_FLOW	0x05
-#define	UDP_V6_FLOW	0x06
-#define	SCTP_V6_FLOW	0x07
-#define	AH_ESP_V6_FLOW	0x08
-#define	AH_V4_FLOW	0x09
-#define	ESP_V4_FLOW	0x0a
-#define	AH_V6_FLOW	0x0b
-#define	ESP_V6_FLOW	0x0c
-#define	IP_USER_FLOW	0x0d
-#define	IPV4_FLOW	0x10
-#define	IPV6_FLOW	0x11
+/* L2-L4 network traffic flow types */
+#define	TCP_V4_FLOW	0x01	/* hash or spec (tcp_ip4_spec) */
+#define	UDP_V4_FLOW	0x02	/* hash or spec (udp_ip4_spec) */
+#define	SCTP_V4_FLOW	0x03	/* hash or spec (sctp_ip4_spec) */
+#define	AH_ESP_V4_FLOW	0x04	/* hash only */
+#define	TCP_V6_FLOW	0x05	/* hash only */
+#define	UDP_V6_FLOW	0x06	/* hash only */
+#define	SCTP_V6_FLOW	0x07	/* hash only */
+#define	AH_ESP_V6_FLOW	0x08	/* hash only */
+#define	AH_V4_FLOW	0x09	/* hash or spec (ah_ip4_spec) */
+#define	ESP_V4_FLOW	0x0a	/* hash or spec (esp_ip4_spec) */
+#define	AH_V6_FLOW	0x0b	/* hash only */
+#define	ESP_V6_FLOW	0x0c	/* hash only */
+#define	IP_USER_FLOW	0x0d	/* spec only (usr_ip4_spec) */
+#define	IPV4_FLOW	0x10	/* hash only */
+#define	IPV6_FLOW	0x11	/* hash only */
+#define	ETHER_FLOW	0x12	/* spec only (ether_spec) */
 
 /* L3-L4 network traffic flow hash options */
 #define	RXH_L2DA	(1 << 1)
-- 
1.7.2.1



-- 
Ben Hutchings, Senior Software Engineer, Solarflare Communications
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.


^ permalink raw reply related

* [PATCH ethtool 0/7] Update RX n-tuple filtering
From: Ben Hutchings @ 2010-09-23 21:47 UTC (permalink / raw)
  To: Jeff Garzik; +Cc: netdev, linux-net-drivers

This patch series brings ethtool up to date with my recent changes to RX
n-tuple filtering in the kernel.

Ben.

Ben Hutchings (7):
  ethtool-copy.h: sync with net-next
  ethtool: Generalise cmdline_info::unwanted_val to a "seen" flag or
    bitmask
  ethtool: Fix RX n-tuple masks and documentation
  ethtool: Add MAC parameter type based on the parse_sopass() function
  ethtool: Add Ethernet-level RX n-tuple filtering and 'clear' action
  ethtool: Update sfc register dump
  ethtool: Add my authorship and Solarflare copyright notice

 AUTHORS        |    1 +
 ethtool-copy.h |  228 +++++++++++++++++++++++++++++++++---------------
 ethtool.8      |   79 ++++++++++++-----
 ethtool.c      |  265 +++++++++++++++++++++++++++++++++++++++++---------------
 sfc.c          |   25 +++---
 5 files changed, 426 insertions(+), 172 deletions(-)

-- 
1.7.2.1


-- 
Ben Hutchings, Senior Software Engineer, Solarflare Communications
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.


^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox