Netdev List
 help / color / mirror / Atom feed
* Re: [PATCH] Add MSG_WAITFORONE flag to recvmmsg
From: Brandon Black @ 2010-03-26 22:55 UTC (permalink / raw)
  To: Eric Dumazet
  Cc: netdev, David S. Miller, Arnaldo Carvalho de Melo, Ulrich Drepper,
	linux-kernel
In-Reply-To: <1269643470.2256.17.camel@edumazet-laptop>

On Fri, Mar 26, 2010 at 5:44 PM, Eric Dumazet <eric.dumazet@gmail.com> wrote:
> Hmmm, no need to test !datagram, just do :
>
>        ++datagrams;
>
>        if (flags & MSG_WAITFORONE)
>                flags |= MSG_DONTWAIT;
>

Ok.  I've never been through this process before.  Do I resubmit a new
subject/thread with the changed patch and [PATCH v2] at this point?
Any other nits about how the patch was sent before I do?

Thanks,
-- Brandon

^ permalink raw reply

* Re: ICMP echo reply fails
From: Andy Fleming @ 2010-03-27  0:56 UTC (permalink / raw)
  To: netdev
In-Reply-To: <1269643575.2256.19.camel@edumazet-laptop>

On Fri, Mar 26, 2010 at 5:46 PM, Eric Dumazet <eric.dumazet@gmail.com> wrote:
> Le vendredi 26 mars 2010 à 23:06 +0100, Eric Dumazet a écrit :
>> Le vendredi 26 mars 2010 à 16:48 -0500, Andy Fleming a écrit :
>> > For various reasons, we have been running a stress test on one of our
>> > boards.  The test consists of initiating 2-3 flood pings from a
>> > Windows box running Cygwin, plus one additional ping we use as a
>> > "heartbeat".  The ping flood is overwhelming our board (we're dropping
>> > packets at a prodigious rate), but the board continues to respond for
>> > a while.  In addition, we are running a script on the  board which
>> > alternates bringing up and bringing down the interface every ten
>> > seconds.  After a highly variable amount of time, the board stops
>> > replying to the pings.  We suspected a driver issue, however, on
>> > closer inspection, we are still able to send and receive packets (I
>> > can ping *from* the board to the PC, and I can *telnet* from the PC to
>> > the board).  We tried pinging the board from another PC, and it also
>> > failed.  Essentially, ICMP echo requests are being ignored (A glance
>> > at memory indicates that packets are arriving, but no packets are
>> > being enqueued to the ethernet controller).  We still have a lot more
>> > debugging to do, but I was wondering if anyone had ever seen something
>> > like this, or might be quicker to realize the obvious mistake we're
>> > making.
>> >
>> > Thanks,
>> > Andy Fleming
>>
>>
>> kernel version ?
>>
>> NIC driver ?
>>
>> Are ICMP echo request received ? (grep Icmp /proc/net/snmp)
>>
>
> vi +1166 net/ipv4/icmp.c
>
>        /* Enough space for 2 64K ICMP packets, including
>         * sk_buff struct overhead.
>         */
>        sk->sk_sndbuf =
>                (2 * ((64 * 1024) + sizeof(struct sk_buff)));
>
>
> If many ICMP replies are lost/leaked by your driver when doing up/down
> things, ICMP socket can consume all its sndbuf reserve and no more icmp
> replies can be sent (a reboot is needed)
>
> You could try changing sk->sk_sndbuf to 0x7FFFFFFF  to see if the icmp
> replies survive longer to your tests. If this is the case, then find the
> leaks in your driver (tx path, maybe you forgot to free skbs in some
> reset cases ?)
>

Ah, that makes a bunch of sense.  I had a feeling the socket was
involved.  Thank you so much for your help.  I will test this as soon
as I have access to the board again!

^ permalink raw reply

* [ANNOUNCEMENT] NET: usb: sierra_net.c driver
From: Elina Pasheva @ 2010-03-27  1:21 UTC (permalink / raw)
  To: David Brownell
  Cc: Rory Filer, epasheva-ywE8TTl5eJHWpu6QEFMNjNBPR1lH4CV8,
	netdev-u79uwXL29TY76Z2rM5mHXA, linux-usb

Subject: [ANNOUNCEMENT] NET: usb: sierra_net.c driver
From: Elina Pasheva <epasheva-ywE8TTl5eJHWpu6QEFMNjNBPR1lH4CV8@public.gmane.org>

The following is a new Linux driver which exposes certain models of Sierra
Wireless modems to the operating system as Network Interface Cards (NICs).

This driver requires a version of the sierra.c driver which supports
blacklisting to work properly. The blacklist in sierra.c rejects the interfaces
claimed by sierra_net.c. Likewise, the sierra_net.c driver only accepts
(i.e. whitelists) the interface(s) used for Direct IP traffic.
The term "Direct IP" is used within Sierra Wireless to refer to these alternate
data interfaces. The version of sierra.c which supports blacklisting is
available from the sierra wireless knowledge base page for older kernels. It is
also available in Linux kernel starting from version 2.6.31.

This driver works with all Sierra Wireless devices configured with PID=68A3
like USB305, USB306 provided the corresponding firmware version is I2.0
(for USB305) or M3.0 (for USB306) and later.
This driver will not work with earlier firmware versions than the ones shown
above. In this case the driver will issue an error message indicating 
incompatibility and will not serve the device's DirectIP interface.

Sierra_net.c sits atop a pre-existing Linux driver called usbnet.c.
A series of hook functions are provided in sierra_net.c which are called by
usbnet.c in response to a particular condition such as receipt or transmission
of a data packet. As such, usbnet.c does most of the work of making
a modem appear to the system as a network device and for properly exchanging
traffic between the USB subsystem and the Network card interface.
Sierra_net.c is concerned with managing the data exchanged between the
so-called Direct-IP interface and the upper layers of the operating system.

The version number of sierra_net.c driver is set to 2.0.
This patch has been tested on the latest stable kernel-2.6.33.1.
Signed-off-by: Elina Pasheva <epasheva-ywE8TTl5eJHWpu6QEFMNjNBPR1lH4CV8@public.gmane.org>
Signed-off-by: Rory Filer <epasheva-ywE8TTl5eJHWpu6QEFMNjNBPR1lH4CV8@public.gmane.org>
---

 drivers/net/usb/Kconfig |   10 ++++++++++
 1 file changed, 10 insertions(+)

--- a/drivers/net/usb/Kconfig	2010-03-25 12:46:33.000000000 -0700
+++ b/drivers/net/usb/Kconfig	2010-03-25 15:56:29.000000000 -0700
@@ -377,4 +377,14 @@ config USB_CDC_PHONET
 	  cellular modem, as found on most Nokia handsets with the
 	  "PC suite" USB profile.
 
+config USB_SIERRA_NET
+	tristate "DirectIP Driver for Sierra Wireless modems"
+	depends on USB_USBNET
+
+	help
+	  Choose this option if you have a Sierra Wireless DirectIP device.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called sierra_net.
+
 endmenu


 drivers/net/usb/Makefile |    2 ++
 1 file changed, 2 insertions(+)

--- a/drivers/net/usb/Makefile	2010-03-25 12:46:56.000000000 -0700
+++ b/drivers/net/usb/Makefile	2010-03-25 12:48:27.000000000 -0700
@@ -22,4 +22,6 @@ obj-$(CONFIG_USB_NET_MCS7830)	+= mcs7830
 obj-$(CONFIG_USB_USBNET)	+= usbnet.o
 obj-$(CONFIG_USB_NET_INT51X1)	+= int51x1.o
 obj-$(CONFIG_USB_CDC_PHONET)	+= cdc-phonet.o
+obj-$(CONFIG_USB_SIERRA_NET)	+= sierra_net.o
+
 

 drivers/net/usb/sierra_net.c |  968 +++++++++++++++++++++++++++++++++
 1 file changed, 968 insertions(+)

--- a/drivers/net/usb/sierra_net.c	2010-03-23 00:33:20.000000000 -0700
+++ b/drivers/net/usb/sierra_net.c	2010-03-25 15:54:47.000000000 -0700
@@ -1 +1,969 @@
+/*
+ * DirectIP Driver for Sierra Wireless modems
+ *
+ * Copyright (C) 2008, 2009, 2010 Paxton Smith, Matthew Safar, Rory Filer
+ *                          <linux-ywE8TTl5eJHWpu6QEFMNjNBPR1lH4CV8@public.gmane.org>
+ *
+ * Portions of this based on the cdc_ether driver by David Brownell (2003-2005)
+ * and Ole Andre Vadla Ravnas (ActiveSync) (2006).
+ *
+ * IMPORTANT DISCLAIMER: This driver is not commercially supported by
+ * Sierra Wireless. Use at your own risk.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#define DRIVER_VERSION "v.2.0"
+#define DRIVER_AUTHOR "Paxton Smith, Matthew Safar, Rory Filer"
+#define DRIVER_DESC "DirectIP Driver for Sierra Wireless modems"
+static const char driver_name[] = "sierra_net";
+
+/* if defined debug messages enabled */
+/*#define	DEBUG*/
+/* more debug messages */
+/*#define	VERBOSE*/
+
+#include <linux/module.h>
+#include <linux/etherdevice.h>
+#include <linux/ethtool.h>
+#include <linux/mii.h>
+#include <linux/sched.h>
+#include <linux/timer.h>
+#include <linux/usb.h>
+#include <linux/usb/cdc.h>
+#include <net/ip.h>
+#include <net/udp.h>
+#include <asm/unaligned.h>
+#include <linux/usb/usbnet.h>
+
+#define SWI_USB_REQUEST_GET_FW_ATTR	0x06
+#define SWI_GET_FW_ATTR_MASK		0x08
+
+/* atomic counter partially included in MAC address to make sure 2 devices
+ * do not end up with the same MAC - concept breaks in case of > 255 ifaces
+ */
+static	atomic_t iface_counter = ATOMIC_INIT(0);
+
+/*
+ * SYNC Timer Delay definition used to set the expiry time
+ */
+#define SIERRA_NET_SYNCDELAY (2*HZ)
+
+/* Max. MTU supported. The modem buffers are limited to 1500 */
+#define SIERRA_NET_MAX_SUPPORTED_MTU	1500
+
+/* The SIERRA_NET_USBCTL_BUF_LEN defines a buffer size allocated for control
+ * message reception ... and thus the max. received packet.
+ * (May be the cause for parse_hip returning -3)
+ */
+#define SIERRA_NET_USBCTL_BUF_LEN	1024
+
+/* list of interface numbers - used for constructing interface lists */
+struct sierra_net_iface_info {
+	const u32 infolen;	/* number of interface numbers on list */
+	const u8  *ifaceinfo;	/* pointer to the array holding the numbers */
+};
+
+struct sierra_net_info_data {
+	u16 rx_urb_size;
+	struct sierra_net_iface_info whitelist;
+};
+
+/* Private data structure */
+struct sierra_net_data {
+
+	u8 ethr_hdr_tmpl[ETH_HLEN]; /* ethernet header template for rx'd pkts */
+
+	u16 link_up; 		/* air link up or down */
+	u8 tx_hdr_template[4];	/* part of HIP hdr for tx'd packets */
+
+	u8 sync_msg[4];		/* SYNC message */
+	u8 shdwn_msg[4];	/* Shutdown message */
+
+	/* Backpointer to the container */
+	struct usbnet *usbnet;
+
+	u8 ifnum;	/* interface number */
+
+/* Bit masks, must be a power of 2 */
+#define SIERRA_NET_EVENT_RESP_AVAIL    0x01
+#define SIERRA_NET_TIMER_EXPIRY        0x02
+	unsigned long kevent_flags;
+	struct work_struct sierra_net_kevent;
+	struct timer_list sync_timer; /* For retrying SYNC sequence */
+};
+
+struct param {
+	int is_present;
+	union {
+		void  *ptr;
+		u32    dword;
+		u16    word;
+		u8     byte;
+	};
+};
+
+/* HIP message type */
+#define SIERRA_NET_HIP_EXTENDEDID	0x7F
+#define SIERRA_NET_HIP_HSYNC_ID 	0x60	/* Modem -> host */
+#define SIERRA_NET_HIP_RESTART_ID	0x62	/* Modem -> host */
+#define SIERRA_NET_HIP_MSYNC_ID 	0x20	/* Host -> modem */
+#define SIERRA_NET_HIP_SHUTD_ID 	0x26	/* Host -> modem */
+
+#define SIERRA_NET_HIP_EXT_IP_IN_ID   0x0202
+#define SIERRA_NET_HIP_EXT_IP_OUT_ID  0x0002
+
+/* 3G UMTS Link Sense Indication definitions */
+#define SIERRA_NET_HIP_LSI_UMTSID	0x78
+
+/* Reverse Channel Grant Indication HIP message */
+#define SIERRA_NET_HIP_RCGI		0x64
+
+/* LSI Protocol types */
+#define SIERRA_NET_PROTOCOL_UMTS      0x01
+/* LSI Coverage */
+#define SIERRA_NET_COVERAGE_NONE      0x00
+#define SIERRA_NET_COVERAGE_NOPACKET  0x01
+
+/* LSI Session */
+#define SIERRA_NET_SESSION_IDLE       0x00
+/* LSI Link types */
+#define SIERRA_NET_AS_LINK_TYPE_IPv4  0x00
+
+typedef struct s_lsi_umts {
+	u8 protocol;
+	u8 unused1;
+	__be16 length;
+	/* eventually use a union for the rest - assume umts for now */
+	u8 coverage;
+	u8 unused2[41];
+	u8 session_state;
+	u8 unused3[33];
+	u8 link_type;
+	u8 pdp_addr_len; /* NW-supplied PDP address len */
+	u8 pdp_addr[16]; /* NW-supplied PDP address (bigendian)) */
+	u8 unused4[23];
+	u8 dns1_addr_len; /* NW-supplied 1st DNS address len (bigendian) */
+	u8 dns1_addr[16]; /* NW-supplied 1st DNS address */
+	u8 dns2_addr_len; /* NW-supplied 2nd DNS address len */
+	u8 dns2_addr[16]; /* NW-supplied 2nd DNS address (bigendian)*/
+	u8 wins1_addr_len; /* NW-supplied 1st Wins address len */
+	u8 wins1_addr[16]; /* NW-supplied 1st Wins address (bigendian)*/
+	u8 wins2_addr_len; /* NW-supplied 2nd Wins address len */
+	u8 wins2_addr[16]; /* NW-supplied 2nd Wins address (bigendian) */
+	u8 unused5[4];
+	u8 gw_addr_len; /* NW-supplied GW address len */
+	u8 gw_addr[16]; /* NW-supplied GW address (bigendian) */
+	u8 reserved[8];
+} __attribute__ ((packed)) lsi_umts_t;
+
+#define SIERRA_NET_LSI_COMMON_LEN      4
+#define SIERRA_NET_LSI_UMTS_LEN        (sizeof(lsi_umts_t))
+#define SIERRA_NET_LSI_UMTS_STATUS_LEN \
+	(SIERRA_NET_LSI_UMTS_LEN - SIERRA_NET_LSI_COMMON_LEN)
+
+/* Forward definitions */
+extern void sierra_sync_timer(unsigned long syncdata);
+static int sierra_net_change_mtu(struct net_device *net, int new_mtu);
+
+/* Our own net device operations structure */
+static const struct net_device_ops sierra_net_device_ops = {
+	.ndo_open               = usbnet_open,
+	.ndo_stop               = usbnet_stop,
+	.ndo_start_xmit         = usbnet_start_xmit,
+	.ndo_tx_timeout         = usbnet_tx_timeout,
+	.ndo_change_mtu         = sierra_net_change_mtu,
+	.ndo_set_mac_address    = eth_mac_addr,
+	.ndo_validate_addr      = eth_validate_addr,
+};
+
+/* get private data associated with passed in usbnet device */
+static inline struct sierra_net_data *sierra_net_get_private(struct usbnet *dev)
+{
+	return (struct sierra_net_data *)dev->data[0];
+}
+
+/* set private data associated with passed in usbnet device */
+static inline void sierra_net_set_private(struct usbnet *dev,
+			struct sierra_net_data *priv)
+{
+	dev->data[0] = (unsigned long)priv;
+}
+
+/* is packet IPv4 */
+static inline int is_ip(struct sk_buff *skb)
+{
+	return (skb->protocol == cpu_to_be16(ETH_P_IP));
+}
+
+/*
+ * check passed in packet and make sure that:
+ *  - it is linear (no scatter/gather)
+ *  - it is ethernet (mac_header properly set)
+ */
+static int check_ethip_packet(struct sk_buff *skb, struct usbnet *dev)
+{
+	skb_reset_mac_header(skb); /* ethernet header */
+
+	if (skb_is_nonlinear(skb)) {
+		deverr(dev, "Non linear buffer-dropping");
+		return 0;
+	}
+
+	if (!pskb_may_pull(skb, ETH_HLEN))
+		return 0;
+	skb->protocol = eth_hdr(skb)->h_proto;
+
+	return 1;
+}
+
+static const u8 *save16bit(struct param *p, const u8 *datap)
+{
+	p->is_present = 1;
+	p->word = get_unaligned_be16(datap);
+	return datap + sizeof(p->word);
+}
+
+static const u8 *save8bit(struct param *p, const u8 *datap)
+{
+	p->is_present = 1;
+	p->byte = *datap;
+	return datap + sizeof(p->byte);
+}
+
+/*----------------------------------------------------------------------------*
+ *                              BEGIN HIP                                     *
+ *----------------------------------------------------------------------------*/
+/* HIP header */
+#define SIERRA_NET_HIP_HDR_LEN 4
+/* Extended HIP header */
+#define SIERRA_NET_HIP_EXT_HDR_LEN 6
+
+struct hip_hdr {
+	int    hdrlen;
+	struct param payload_len;
+	struct param msgid;
+	struct param msgspecific;
+	struct param extmsgid;
+};
+
+static int parse_hip(const u8 *buf, const u32 buflen, struct hip_hdr *hh)
+{
+	const u8 *curp = buf;
+	int    padded;
+
+	if (buflen < SIERRA_NET_HIP_HDR_LEN)
+		return -1;
+
+	curp = save16bit(&hh->payload_len, curp);
+	curp = save8bit(&hh->msgid, curp);
+	curp = save8bit(&hh->msgspecific, curp);
+
+	padded = hh->msgid.byte & 0x80;
+	hh->msgid.byte &= 0x7F;			/* 7 bits */
+
+	hh->extmsgid.is_present = (hh->msgid.byte == SIERRA_NET_HIP_EXTENDEDID);
+	if (hh->extmsgid.is_present) {
+		if (buflen < SIERRA_NET_HIP_EXT_HDR_LEN)
+			return -2;
+
+		hh->payload_len.word &= 0x3FFF; /* 14 bits */
+
+		curp = save16bit(&hh->extmsgid, curp);
+		hh->extmsgid.word &= 0x03FF;	/* 10 bits */
+
+		hh->hdrlen = SIERRA_NET_HIP_EXT_HDR_LEN;
+	} else {
+		hh->payload_len.word &= 0x07FF;	/* 11 bits */
+		hh->hdrlen = SIERRA_NET_HIP_HDR_LEN;
+	}
+
+	if (padded) {
+		hh->hdrlen++;
+		hh->payload_len.word--;
+	}
+
+	/* if real packet shorter than the claimed length */
+	if (buflen < (hh->hdrlen + hh->payload_len.word))
+		return -3;
+
+	return 0;
+}
+
+static void build_hip(u8 *buf, const u16 payloadlen,
+		struct sierra_net_data *priv)
+{
+	/* the following doesn't have the full functionality. We
+	 * currently build only one kind of header, so it is faster this way
+	 */
+	put_unaligned_be16(payloadlen, buf);
+	memcpy(buf+2, priv->tx_hdr_template, sizeof(priv->tx_hdr_template));
+}
+/*----------------------------------------------------------------------------*
+ *                              END HIP                                       *
+ *----------------------------------------------------------------------------*/
+
+static void sierra_net_send_cmd(struct usbnet *dev,
+		u8 *cmd, int cmdlen, const char * cmd_name)
+{
+	struct sierra_net_data *priv = sierra_net_get_private(dev);
+	int  status;
+
+	status = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0),
+			USB_CDC_SEND_ENCAPSULATED_COMMAND,
+			USB_DIR_OUT|USB_TYPE_CLASS|USB_RECIP_INTERFACE,	0,
+			priv->ifnum, cmd, cmdlen, 0);
+
+	if (status != cmdlen && status != -ENODEV)
+		deverr(dev, "Submit %s failed %d", cmd_name, status);
+}
+
+static void sierra_net_send_sync(struct usbnet *dev)
+{
+	struct sierra_net_data *priv = sierra_net_get_private(dev);
+
+	dev_dbg(&dev->udev->dev, "%s", __func__);
+
+	sierra_net_send_cmd(dev, priv->sync_msg,
+			sizeof(priv->sync_msg), "SYNC");
+}
+
+static void sierra_net_send_shutdown(struct usbnet *dev)
+{
+	struct sierra_net_data *priv = sierra_net_get_private(dev);
+
+	dev_dbg(&dev->udev->dev, "%s", __func__);
+
+	sierra_net_send_cmd(dev, priv->shdwn_msg,
+			sizeof(priv->shdwn_msg), "Shutdown");
+}
+
+static void sierra_net_set_ctx_index(struct sierra_net_data *priv, u8 ctx_ix)
+{
+	dev_dbg(&(priv->usbnet->udev->dev), "%s %d", __func__, ctx_ix);
+	priv->tx_hdr_template[0] = 0x3F;
+	priv->tx_hdr_template[1] = ctx_ix;
+	*((u16 *)&priv->tx_hdr_template[2]) =
+		cpu_to_be16(SIERRA_NET_HIP_EXT_IP_OUT_ID);
+}
+
+static inline int sierra_net_is_valid_addrlen(u8 len)
+{
+	return (len == sizeof(struct in_addr));
+}
+
+static int sierra_net_parse_lsi(struct usbnet *dev, char *data, int datalen)
+{
+	lsi_umts_t *lsi = (lsi_umts_t *)data;
+
+	if (lsi->length != cpu_to_be16(SIERRA_NET_LSI_UMTS_STATUS_LEN)) {
+		deverr(dev, "%s: LSI_UMTS_STATUS_LEN %d, expected %u",
+				__func__, be16_to_cpu(lsi->length),
+				(u32)SIERRA_NET_LSI_UMTS_STATUS_LEN);
+		return -1;
+	}
+
+	/* Validate the protocol  - only support UMTS for now */
+	if (lsi->protocol != SIERRA_NET_PROTOCOL_UMTS) {
+		deverr(dev, "Protocol unsupported, 0x%02x", lsi->protocol);
+		return -1;
+	}
+
+	/* Validate the link type */
+	if (lsi->link_type != SIERRA_NET_AS_LINK_TYPE_IPv4) {
+		deverr(dev, "Link type unsupported: 0x%02x", lsi->link_type);
+		return -1;
+	}
+
+	/* Validate the coverage */
+	if (lsi->coverage == SIERRA_NET_COVERAGE_NONE
+	   || lsi->coverage == SIERRA_NET_COVERAGE_NOPACKET) {
+		deverr(dev, "No coverage, 0x%02x", lsi->coverage);
+		return 0;
+	}
+
+	/* Validate the session state */
+	if (lsi->session_state == SIERRA_NET_SESSION_IDLE) {
+		deverr(dev, "Session idle, 0x%02x", lsi->session_state);
+		return 0;
+	}
+
+	/* Set link_sense true */
+	return 1;
+}
+
+static void sierra_net_handle_lsi(struct usbnet *dev, char *data,
+		struct hip_hdr	*hh)
+{
+	struct sierra_net_data *priv = sierra_net_get_private(dev);
+	int link_up;
+
+	link_up = sierra_net_parse_lsi(dev, data + hh->hdrlen,
+					hh->payload_len.word);
+	if (link_up < 0) {
+		deverr(dev, "Invalid LSI");
+		return;
+	}
+	if (link_up) {
+		sierra_net_set_ctx_index(priv, hh->msgspecific.byte);
+		priv->link_up = 1;
+		netif_carrier_on(dev->net);
+	} else {
+		priv->link_up = 0;
+		netif_carrier_off(dev->net);
+	}
+}
+
+static void sierra_net_dosync(struct usbnet *dev)
+{
+	struct sierra_net_data *priv = sierra_net_get_private(dev);
+
+	dev_dbg(&dev->udev->dev, "%s", __func__);
+
+	/* tell modem we are ready */
+	sierra_net_send_sync(dev);
+	sierra_net_send_sync(dev);
+
+	/* Now, start a timer and make sure we get the Restart Indication */
+	priv->sync_timer.function = sierra_sync_timer;
+	priv->sync_timer.data = (unsigned long) dev;
+	priv->sync_timer.expires = jiffies + SIERRA_NET_SYNCDELAY;
+	add_timer(&priv->sync_timer);
+}
+
+static void sierra_net_kevent(struct work_struct *work)
+{
+	struct sierra_net_data *priv =
+		container_of(work, struct sierra_net_data, sierra_net_kevent);
+	struct usbnet *dev = priv->usbnet;
+	int  len;
+	int  err;
+	u8  *buf;
+	u8   ifnum;
+
+	if (test_bit(SIERRA_NET_EVENT_RESP_AVAIL, &priv->kevent_flags)) {
+		clear_bit(SIERRA_NET_EVENT_RESP_AVAIL, &priv->kevent_flags);
+
+		/* Query the modem for the LSI message */
+		buf = kzalloc(SIERRA_NET_USBCTL_BUF_LEN, GFP_KERNEL);
+		if (!buf) {
+			deverr(dev, "failed to allocate buf for LS msg");
+			return;
+		}
+		ifnum = priv->ifnum;
+		len = usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0),
+				USB_CDC_GET_ENCAPSULATED_RESPONSE,
+				USB_DIR_IN|USB_TYPE_CLASS|USB_RECIP_INTERFACE,
+				0, ifnum, buf, SIERRA_NET_USBCTL_BUF_LEN, 0);
+
+		if (unlikely(len < 0)) {
+			deverr(dev,
+				"usb_control_msg failed, status %d", len);
+		} else {
+			struct hip_hdr	hh;
+
+			dev_dbg(&dev->udev->dev, "%s: Received status message,"
+				" %04x bytes", __func__, len);
+
+			err = parse_hip(buf, len, &hh);
+			if (err) {
+				deverr(dev, "%s: Bad packet, parse result %d",
+					__func__, err);
+				kfree(buf);
+				return;
+			}
+
+			/* Validate packet length */
+			if (len != hh.hdrlen + hh.payload_len.word) {
+				deverr(dev, "%s: Bad packet, received %d,"
+					" expected %d",	__func__, len,
+					hh.hdrlen + hh.payload_len.word);
+				kfree(buf);
+				return;
+			}
+
+			/* Switch on received message types */
+			switch (hh.msgid.byte) {
+			case SIERRA_NET_HIP_LSI_UMTSID:
+				dev_dbg(&dev->udev->dev, "LSI for ctx:%d",
+					hh.msgspecific.byte);
+				sierra_net_handle_lsi(dev, buf, &hh);
+				break;
+			case SIERRA_NET_HIP_RESTART_ID:
+				dev_dbg(&dev->udev->dev, "Restart reported: %d,"
+						" stopping sync timer",
+						hh.msgspecific.byte);
+				/* Got sync resp - stop timer & clear mask */
+				del_timer_sync(&priv->sync_timer);
+				clear_bit(SIERRA_NET_TIMER_EXPIRY,
+					  &priv->kevent_flags);
+				break;
+			case SIERRA_NET_HIP_HSYNC_ID:
+				dev_dbg(&dev->udev->dev, "SYNC received");
+				sierra_net_send_sync(dev);
+				break;
+			case SIERRA_NET_HIP_EXTENDEDID:
+				deverr(dev, "Unrecognized HIP msg, "
+					"extmsgid 0x%04x", hh.extmsgid.word);
+				break;
+			case SIERRA_NET_HIP_RCGI:
+				/* Ignored */
+				break;
+			default:
+				deverr(dev, "Unrecognized HIP msg, "
+					"msgid 0x%02x", hh.msgid.byte);
+				break;
+			}
+		}
+		kfree(buf);
+	}
+	/* The sync timer bit might be set */
+	if (test_bit(SIERRA_NET_TIMER_EXPIRY, &priv->kevent_flags)) {
+		clear_bit(SIERRA_NET_TIMER_EXPIRY, &priv->kevent_flags);
+		dev_dbg(&dev->udev->dev, "Deferred sync timer expiry");
+		sierra_net_dosync(priv->usbnet);
+	}
+
+	if (priv->kevent_flags)
+		dev_dbg(&dev->udev->dev, "sierra_net_kevent done, "
+			"kevent_flags = 0x%lx", priv->kevent_flags);
+}
+
+static void sierra_net_defer_kevent(struct usbnet *dev, int work)
+{
+	struct sierra_net_data *priv = sierra_net_get_private(dev);
+
+	set_bit(work, &priv->kevent_flags);
+	schedule_work(&priv->sierra_net_kevent);
+}
+
+/*
+ * Sync Retransmit Timer Handler. On expiry, kick the work queue
+ */
+void sierra_sync_timer(unsigned long syncdata)
+{
+	struct usbnet *dev = (struct usbnet *)syncdata;
+
+	dev_dbg(&dev->udev->dev, "%s", __func__);
+	/* Kick the tasklet */
+	sierra_net_defer_kevent(dev, SIERRA_NET_TIMER_EXPIRY);
+}
+
+static void sierra_net_status(struct usbnet *dev, struct urb *urb)
+{
+	struct usb_cdc_notification *event;
+
+	dev_dbg(&dev->udev->dev, "%s", __func__);
+
+	if (urb->actual_length < sizeof *event)
+		return;
+
+	/* Add cases to handle other standard notifications. */
+	event = urb->transfer_buffer;
+	switch (event->bNotificationType) {
+	case USB_CDC_NOTIFY_NETWORK_CONNECTION:
+	case USB_CDC_NOTIFY_SPEED_CHANGE:
+		/* USB 305 sends those */
+		break;
+	case USB_CDC_NOTIFY_RESPONSE_AVAILABLE:
+		sierra_net_defer_kevent(dev, SIERRA_NET_EVENT_RESP_AVAIL);
+		break;
+	default:
+		deverr(dev, ": unexpected notification %02x!",
+				event->bNotificationType);
+		break;
+	}
+}
+
+static void sierra_net_get_drvinfo(struct net_device *net,
+		struct ethtool_drvinfo *info)
+{
+	/* Inherit standard device info */
+	usbnet_get_drvinfo(net, info);
+	strncpy(info->driver, driver_name, sizeof info->driver);
+	strncpy(info->version, DRIVER_VERSION, sizeof info->version);
+}
+
+static u32 sierra_net_get_link(struct net_device *net)
+{
+	struct usbnet *dev = netdev_priv(net);
+	/* Report link is down whenever the interface is down */
+	return sierra_net_get_private(dev)->link_up && netif_running(net);
+}
+
+static struct ethtool_ops sierra_net_ethtool_ops = {
+	.get_drvinfo = sierra_net_get_drvinfo,
+	.get_link = sierra_net_get_link,
+	.get_msglevel = usbnet_get_msglevel,
+	.set_msglevel = usbnet_set_msglevel,
+	.get_settings = usbnet_get_settings,
+	.set_settings = usbnet_set_settings,
+	.nway_reset = usbnet_nway_reset,
+};
+
+/* MTU can not be more than 1500 bytes, enforce it. */
+static int sierra_net_change_mtu(struct net_device *net, int new_mtu)
+{
+	if (new_mtu > SIERRA_NET_MAX_SUPPORTED_MTU)
+		return -EINVAL;
+
+	return usbnet_change_mtu(net, new_mtu);
+}
+
+static int is_whitelisted(const u8 ifnum,
+			const struct sierra_net_iface_info *whitelist)
+{
+	if (whitelist) {
+		const u8 *list = whitelist->ifaceinfo;
+		int i;
+
+		for (i = 0; i < whitelist->infolen; i++) {
+			if (list[i] == ifnum)
+				return 1;
+		}
+	}
+	return 0;
+}
+
+static int sierra_net_get_fw_attr(struct usbnet *dev, u16 *datap)
+{
+	int result = 0;
+	u16 *attrdata;
+
+	attrdata = kmalloc(sizeof(*attrdata), GFP_KERNEL);
+	if (!attrdata)
+		return -ENOMEM;
+
+	result = usb_control_msg(
+			dev->udev,
+			usb_rcvctrlpipe(dev->udev, 0),
+			/* _u8 vendor specific request */
+			SWI_USB_REQUEST_GET_FW_ATTR,
+			USB_DIR_IN | USB_TYPE_VENDOR,	/* __u8 request type */
+			0x0000,		/* __u16 value not used */
+			0x0000,		/* __u16 index  not used */
+			attrdata,	/* char *data */
+			sizeof(*attrdata),		/* __u16 size */
+			USB_CTRL_SET_TIMEOUT);	/* int timeout */
+
+	if (result < 0) {
+		kfree(attrdata);
+		return -EIO;
+	}
+
+	*datap = *attrdata;
+
+	kfree(attrdata);
+	return result;
+}
+
+/*
+ * collects the bulk endpoints, the status endpoint.
+ */
+static int sierra_net_bind(struct usbnet *dev, struct usb_interface *intf)
+{
+	u8	ifacenum;
+	u8	numendpoints;
+	u16	fwattr = 0;
+	int	status;
+	struct ethhdr *eth;
+	struct sierra_net_data *priv;
+	static const u8 sync_tmplate[sizeof(priv->sync_msg)] = {
+		0x00, 0x00, SIERRA_NET_HIP_MSYNC_ID, 0x00};
+	static const u8 shdwn_tmplate[sizeof(priv->shdwn_msg)] = {
+		0x00, 0x00, SIERRA_NET_HIP_SHUTD_ID, 0x00};
+
+	struct sierra_net_info_data *data =
+			(struct sierra_net_info_data *)dev->driver_info->data;
+
+	dev_dbg(&dev->udev->dev, "%s", __func__);
+
+	ifacenum = intf->cur_altsetting->desc.bInterfaceNumber;
+	/* We only accept certain interfaces */
+	if (!is_whitelisted(ifacenum, &data->whitelist)) {
+		dev_dbg(&dev->udev->dev, "Ignoring interface: %d", ifacenum);
+		return -ENODEV;
+	}
+
+	numendpoints = intf->cur_altsetting->desc.bNumEndpoints;
+	/* We have three endpoints, bulk in and out, and a status */
+	if (numendpoints != 3) {
+		deverr(dev, "Expected 3 endpoints, found: %d", numendpoints);
+		return -ENODEV;
+	}
+
+	/* Status endpoint set in usbnet_get_endpoints() */
+	dev->status = NULL;
+	status = usbnet_get_endpoints(dev, intf);
+	if (status < 0) {
+		deverr(dev, "Error in usbnet_get_endpoints (%d)",
+			status);
+		return -ENODEV;
+	}
+
+	/* Initialize sierra private data */
+	priv = kzalloc(sizeof *priv, GFP_KERNEL);
+	if (!priv) {
+		deverr(dev, "No memory");
+		return -ENOMEM;
+	}
+
+	priv->usbnet = dev;
+	priv->ifnum = ifacenum;
+	dev->net->netdev_ops = &sierra_net_device_ops;
+
+	/* change MAC addr to include, ifacenum, and to be unique */
+	dev->net->dev_addr[ETH_ALEN-2] = atomic_inc_return(&iface_counter);
+	dev->net->dev_addr[ETH_ALEN-1] = ifacenum;
+
+	/* we will have to manufacture ethernet headers, prepare template */
+	eth = (struct ethhdr *)priv->ethr_hdr_tmpl;
+	memcpy(&eth->h_dest, dev->net->dev_addr, ETH_ALEN);
+	eth->h_proto = cpu_to_be16(ETH_P_IP);
+
+	/* prepare shutdown message template */
+	memcpy(priv->shdwn_msg, shdwn_tmplate, sizeof(priv->shdwn_msg));
+	/* set context index initially to 0 - prepares tx hdr template */
+	sierra_net_set_ctx_index(priv, 0);
+
+	/* decrease the rx_urb_size and max_tx_size to 4k on USB 1.1 */
+	dev->rx_urb_size  = data->rx_urb_size;
+	if (dev->udev->speed != USB_SPEED_HIGH)
+		dev->rx_urb_size  = min_t(size_t, 4096, data->rx_urb_size);
+
+	dev->net->hard_header_len += SIERRA_NET_HIP_EXT_HDR_LEN;
+	dev->hard_mtu = dev->net->mtu + dev->net->hard_header_len;
+
+	/* Set up the netdev */
+	dev->net->flags |= IFF_NOARP;
+	dev->net->ethtool_ops = &sierra_net_ethtool_ops;
+	netif_carrier_off(dev->net);
+
+	sierra_net_set_private(dev, priv);
+
+	priv->kevent_flags = 0;
+
+	/* Use the shared workqueue */
+	INIT_WORK(&priv->sierra_net_kevent, sierra_net_kevent);
+
+	/* Only need to do this once */
+	init_timer(&priv->sync_timer);
+
+	/* verify fw attributes */
+	status = sierra_net_get_fw_attr(dev, &fwattr);
+	dev_dbg(&dev->udev->dev, "Fw attr: %x\n", fwattr);
+
+	/* test whether firmware supports DHCP */
+	if (!(status == sizeof(fwattr) && (fwattr & SWI_GET_FW_ATTR_MASK))) {
+		/* found incompatible firmware version */
+		deverr(dev, "Incompatible driver and firmware"
+			" versions\n");
+		return -ENODEV;
+	}
+	/* prepare sync message from template */
+	memcpy(priv->sync_msg, sync_tmplate, sizeof(priv->sync_msg));
+
+	/* initiate the sync sequence */
+	sierra_net_dosync(dev);
+
+	return 0;
+}
+
+static void sierra_net_unbind(struct usbnet *dev, struct usb_interface *intf)
+{
+	struct sierra_net_data *priv = sierra_net_get_private(dev);
+
+	dev_dbg(&dev->udev->dev, "%s", __func__);
+
+	/* Kill the timer then flush the work queue */
+	del_timer_sync(&priv->sync_timer);
+
+	flush_scheduled_work();
+
+	/* tell modem we are going away */
+	sierra_net_send_shutdown(dev);
+
+	sierra_net_set_private(dev, NULL);
+
+	kfree(priv);
+}
+
+static struct sk_buff *sierra_net_skb_clone(struct usbnet *dev,
+		struct sk_buff *skb, int len)
+{
+	struct sk_buff *new_skb;
+
+	/* clone skb */
+	new_skb = skb_clone(skb, GFP_ATOMIC);
+
+	/* remove len bytes from original */
+	skb_pull(skb, len);
+
+	/* trim next packet to it's length */
+	if (new_skb) {
+		skb_trim(new_skb, len);
+	} else {
+		if (netif_msg_rx_err(dev))
+			deverr(dev, "failed to get skb");
+		dev->net->stats.rx_dropped++;
+	}
+
+	return new_skb;
+}
+
+/* ---------------------------- Receive data path ----------------------*/
+static int sierra_net_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
+{
+	int err;
+	struct hip_hdr  hh;
+	struct sk_buff *new_skb;
+
+	dev_dbg(&dev->udev->dev, "%s", __func__);
+
+	/* could contain multiple packets */
+	while (likely(skb->len)) {
+		err = parse_hip(skb->data, skb->len, &hh);
+		if (err) {
+			if (netif_msg_rx_err(dev))
+				deverr(dev, "Invalid HIP header %d", err);
+			/* dev->net->stats.rx_errors incremented by caller */
+			dev->net->stats.rx_length_errors++;
+			return 0;
+		}
+
+		/* Validate Extended HIP header */
+		if (!hh.extmsgid.is_present
+		    || hh.extmsgid.word != SIERRA_NET_HIP_EXT_IP_IN_ID) {
+			if (netif_msg_rx_err(dev))
+				deverr(dev, "HIP/ETH: Invalid packet");
+
+			dev->net->stats.rx_frame_errors++;
+			/* dev->net->stats.rx_errors incremented by caller */;
+			return 0;
+		}
+
+		skb_pull(skb, hh.hdrlen);
+
+		/* We are going to accept this packet, prepare it */
+		memcpy(skb->data, sierra_net_get_private(dev)->ethr_hdr_tmpl,
+			ETH_HLEN);
+
+		/* Last packet in batch handled by usbnet */
+		if (hh.payload_len.word == skb->len)
+			return 1;
+
+		new_skb = sierra_net_skb_clone(dev, skb, hh.payload_len.word);
+		if (new_skb)
+			usbnet_skb_return(dev, new_skb);
+
+	} /* while */
+
+	return 0;
+}
+
+/* ---------------------------- Transmit data path ----------------------*/
+struct sk_buff *sierra_net_tx_fixup(struct usbnet *dev, struct sk_buff *skb,
+		gfp_t flags)
+{
+	struct sierra_net_data *priv = sierra_net_get_private(dev);
+	u16 len;
+
+	dev_dbg(&dev->udev->dev, "%s", __func__);
+	if (priv->link_up && check_ethip_packet(skb, dev) && is_ip(skb)) {
+		/* enough head room as is? */
+		if (SIERRA_NET_HIP_EXT_HDR_LEN <= skb_headroom(skb)) {
+			/* Save the Eth/IP length and set up HIP hdr */
+			len = skb->len;
+			skb_push(skb, SIERRA_NET_HIP_EXT_HDR_LEN);
+			build_hip(skb->data, len, priv);
+			return skb;
+		} else {
+			/*
+			 * compensate in the future if necessary
+			 */
+			deverr(dev, "tx_fixup: no room for HIP");
+		} /* headroom */
+	}
+
+	if (!priv->link_up)
+		dev->net->stats.tx_carrier_errors++;
+
+	/* tx_dropped incremented by usbnet */
+
+	/* filter the packet out, release it  */
+	dev_kfree_skb_any(skb);
+	return NULL;
+}
+
+static const u8 sierra_net_ifnum_list[] = { 7, 10, 11 };
+static const struct sierra_net_info_data sierra_net_info_data_68A3 = {
+	.rx_urb_size = 8 * 1024,
+	.whitelist = {
+		.infolen = ARRAY_SIZE(sierra_net_ifnum_list),
+		.ifaceinfo = sierra_net_ifnum_list
+	}
+};
+
+static const struct driver_info sierra_net_info_68A3 = {
+	.description = "Sierra Wireless USB-Ethernet Modem",
+	.flags = FLAG_ETHER | FLAG_SEND_ZLP,
+	.bind = sierra_net_bind,
+	.unbind = sierra_net_unbind,
+	.status = sierra_net_status,
+	.rx_fixup = sierra_net_rx_fixup,
+	.tx_fixup = sierra_net_tx_fixup,
+	.data = (unsigned long)&sierra_net_info_data_68A3,
+};
+
+static const struct usb_device_id products[] = {
+	{USB_DEVICE(0x1199, 0x68A3), /* Sierra Wireless Direct IP modem */
+	.driver_info = (unsigned long) &sierra_net_info_68A3},
+
+	{}, /* last item */
+};
+MODULE_DEVICE_TABLE(usb, products);
+
+/* We are based on usbnet, so let it handle the USB driver specifics */
+static struct usb_driver sierra_net_driver = {
+	.name = "sierra_net",
+	.id_table = products,
+	.probe = usbnet_probe,
+	.disconnect = usbnet_disconnect,
+	.suspend = usbnet_suspend,
+	.resume = usbnet_resume,
+	.no_dynamic_id = 1,
+};
+
+static int __init sierra_net_init(void)
+{
+	BUILD_BUG_ON(FIELD_SIZEOF(struct usbnet, data)
+				< sizeof(struct cdc_state));
+
+	return usb_register(&sierra_net_driver);
+}
+
+static void __exit sierra_net_exit(void)
+{
+	usb_deregister(&sierra_net_driver);
+}
+
+module_exit(sierra_net_exit);
+module_init(sierra_net_init);
+
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_VERSION(DRIVER_VERSION);
+MODULE_LICENSE("GPL");


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

* Re: [Regression] r8169: enable 64-bit DMA by default for PCI Express devices (v2)
From: Robert Hancock @ 2010-03-27  1:55 UTC (permalink / raw)
  To: � Engel; +Cc: David Miller, torvalds, linux-kernel, netdev, romieu
In-Reply-To: <20100326091234.GA11959@Dublin.logfs.org>

On 03/26/2010 03:12 AM, � Engel wrote:
> On Thu, 25 March 2010 18:56:03 -0600, Robert Hancock wrote:
>>
>> Francois, ping? Is there anyone else that has access to this kind of
>> information about these chips?
>>
>> It's kind of interesting that there's only been one report of this
>> though. Either the affected chips are rare among people testing
>> 2.6.34-rc or there's something more to this. Maybe something
>> wierd/unusual about Jörn's system?
>>
>> Jörn, are any other devices on your system working with 64-bit
>> addressing? Try doing this:
>>
>> find /sys -name "*dma_mask_bits*" | xargs cat
>>
>> Does anything show more than 32?
>
> I've slightly changed the command:
> # for i in `find /sys -name "*dma_mask_bits*"`; do echo -n "$i: "; cat $i; done
> /sys/devices/pci0000:00/0000:00:00.0/dma_mask_bits: 32
> /sys/devices/pci0000:00/0000:00:00.0/consistent_dma_mask_bits: 32
> /sys/devices/pci0000:00/0000:00:02.0/dma_mask_bits: 36
> /sys/devices/pci0000:00/0000:00:02.0/consistent_dma_mask_bits: 36
> /sys/devices/pci0000:00/0000:00:1c.0/dma_mask_bits: 32
> /sys/devices/pci0000:00/0000:00:1c.0/consistent_dma_mask_bits: 32
> /sys/devices/pci0000:00/0000:00:1c.1/dma_mask_bits: 32
> /sys/devices/pci0000:00/0000:00:1c.1/consistent_dma_mask_bits: 32
> /sys/devices/pci0000:00/0000:00:1c.1/0000:01:00.0/dma_mask_bits: 32
> /sys/devices/pci0000:00/0000:00:1c.1/0000:01:00.0/consistent_dma_mask_bits: 32
> /sys/devices/pci0000:00/0000:00:1d.0/dma_mask_bits: 32
> /sys/devices/pci0000:00/0000:00:1d.0/consistent_dma_mask_bits: 32
> /sys/devices/pci0000:00/0000:00:1d.1/dma_mask_bits: 32
> /sys/devices/pci0000:00/0000:00:1d.1/consistent_dma_mask_bits: 32
> /sys/devices/pci0000:00/0000:00:1d.2/dma_mask_bits: 32
> /sys/devices/pci0000:00/0000:00:1d.2/consistent_dma_mask_bits: 32
> /sys/devices/pci0000:00/0000:00:1d.3/dma_mask_bits: 32
> /sys/devices/pci0000:00/0000:00:1d.3/consistent_dma_mask_bits: 32
> /sys/devices/pci0000:00/0000:00:1d.7/dma_mask_bits: 32
> /sys/devices/pci0000:00/0000:00:1d.7/consistent_dma_mask_bits: 32
> /sys/devices/pci0000:00/0000:00:1e.0/dma_mask_bits: 32
> /sys/devices/pci0000:00/0000:00:1e.0/consistent_dma_mask_bits: 32
> /sys/devices/pci0000:00/0000:00:1f.0/dma_mask_bits: 32
> /sys/devices/pci0000:00/0000:00:1f.0/consistent_dma_mask_bits: 32
> /sys/devices/pci0000:00/0000:00:1f.1/dma_mask_bits: 32
> /sys/devices/pci0000:00/0000:00:1f.1/consistent_dma_mask_bits: 32
> /sys/devices/pci0000:00/0000:00:1f.2/dma_mask_bits: 32
> /sys/devices/pci0000:00/0000:00:1f.2/consistent_dma_mask_bits: 32
> /sys/devices/pci0000:00/0000:00:1f.3/dma_mask_bits: 32
> /sys/devices/pci0000:00/0000:00:1f.3/consistent_dma_mask_bits: 32
>
> One device, which should be this one:
> 00:02.0 VGA compatible controller: Intel Corporation 82G33/G31 Express Integrated Graphics Controller (rev 10)

Well, that one's 36 bits, but it's unclear whether that driver would 
actually be likely to access anything over 4GB. It's possible that 
there's just some general problem with 64-bit DMA on that machine.

The fact that even stuff like lspci and MII is breaking seems odd, 
though. It could be that model of card doesn't like the PCIDAC register 
bit being set (maybe it means something different on that model, or 
something).

I suppose a publicly accessible datasheet for these chips is too much to 
hope for?

^ permalink raw reply

* Re: [PATCH] Add MSG_WAITFORONE flag to recvmmsg
From: Ulrich Drepper @ 2010-03-27  2:07 UTC (permalink / raw)
  To: Brandon Black
  Cc: Eric Dumazet, netdev, David S. Miller, Arnaldo Carvalho de Melo,
	linux-kernel
In-Reply-To: <84621a61003261555q2c78f6a8o5b438113bed6bd2@mail.gmail.com>

On Fri, Mar 26, 2010 at 15:55, Brandon Black <blblack@gmail.com> wrote:
> Ok.  I've never been through this process before.  Do I resubmit a new
> subject/thread with the changed patch and [PATCH v2] at this point?

The patch is small enough for this to be OK.

^ permalink raw reply

* [PATCH v2] Add MSG_WAITFORONE flag to recvmmsg
From: Brandon L Black @ 2010-03-27  2:18 UTC (permalink / raw)
  To: netdev
  Cc: David S. Miller, Arnaldo Carvalho de Melo, Ulrich Drepper,
	linux-kernel
In-Reply-To: <a36005b51003261907x7ebe057bt2d541f63f20f632b@mail.gmail.com>


From: Brandon L Black <blblack@gmail.com>

Add new flag MSG_WAITFORONE for the recvmmsg() syscall.
When this flag is specified for a blocking socket, recvmmsg()
will only block until at least 1 packet is available.  The
default behavior is to block until all vlen packets are
available.  This flag has no effect on non-blocking sockets
or when used in combination with MSG_DONTWAIT.

Signed-off-by: Brandon L Black <blblack@gmail.com>

---
diff --git a/include/linux/socket.h b/include/linux/socket.h
index 7b3aae2..354cc56 100644
--- a/include/linux/socket.h
+++ b/include/linux/socket.h
@@ -255,6 +255,7 @@ struct ucred {
 #define MSG_ERRQUEUE	0x2000	/* Fetch message from error queue */
 #define MSG_NOSIGNAL	0x4000	/* Do not generate SIGPIPE */
 #define MSG_MORE	0x8000	/* Sender will send more */
+#define MSG_WAITFORONE	0x10000	/* recvmmsg(): block until 1+ packets avail */
 
 #define MSG_EOF         MSG_FIN
 
diff --git a/net/socket.c b/net/socket.c
index 769c386..f55ffe9 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -2135,6 +2135,10 @@ int __sys_recvmmsg(int fd, struct mmsghdr __user *mmsg, unsigned int vlen,
 			break;
 		++datagrams;
 
+		/* MSG_WAITFORONE turns on MSG_DONTWAIT after one packet */
+		if (flags & MSG_WAITFORONE)
+			flags |= MSG_DONTWAIT;
+
 		if (timeout) {
 			ktime_get_ts(timeout);
 			*timeout = timespec_sub(end_time, *timeout);

^ permalink raw reply related

* [PATCH 6/9] drivers/net: Fix continuation lines
From: Joe Perches @ 2010-03-27  2:27 UTC (permalink / raw)
  To: linux-kernel; +Cc: Jay Cliburn, Chris Snook, Jie Yang, atl1-devel, netdev
In-Reply-To: <cover.1269655208.git.joe@perches.com>

Signed-off-by: Joe Perches <joe@perches.com>
---
 drivers/net/atlx/atl1.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/net/atlx/atl1.c b/drivers/net/atlx/atl1.c
index 9ba5470..0ebd820 100644
--- a/drivers/net/atlx/atl1.c
+++ b/drivers/net/atlx/atl1.c
@@ -84,7 +84,7 @@
 
 #define ATLX_DRIVER_VERSION "2.1.3"
 MODULE_AUTHOR("Xiong Huang <xiong.huang@atheros.com>, \
-	Chris Snook <csnook@redhat.com>, Jay Cliburn <jcliburn@gmail.com>");
+Chris Snook <csnook@redhat.com>, Jay Cliburn <jcliburn@gmail.com>");
 MODULE_LICENSE("GPL");
 MODULE_VERSION(ATLX_DRIVER_VERSION);
 
-- 
1.7.0.14.g7e948

^ permalink raw reply related

* Re: [PATCH 1/2] ixgbe: convert to use netdev_for_each_mc_addr
From: David Miller @ 2010-03-27  3:10 UTC (permalink / raw)
  To: jeffrey.t.kirsher; +Cc: netdev, gospo, jpirko
In-Reply-To: <20100324085733.32706.70587.stgit@localhost.localdomain>

From: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Date: Wed, 24 Mar 2010 01:58:01 -0700

> From: Jiri Pirko <jpirko@redhat.com>
> 
> Signed-off-by: Jiri Pirko <jpirko@redhat.com>
> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>

Applied.

^ permalink raw reply

* Re: [PATCH 2/2] ixgbevf: convert to use netdev_for_each_mc_addr
From: David Miller @ 2010-03-27  3:10 UTC (permalink / raw)
  To: jeffrey.t.kirsher; +Cc: netdev, gospo, jpirko
In-Reply-To: <20100324085819.32706.384.stgit@localhost.localdomain>

From: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Date: Wed, 24 Mar 2010 01:58:20 -0700

> From: Jiri Pirko <jpirko@redhat.com>
> 
> Signed-off-by: Jiri Pirko <jpirko@redhat.com>
> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>

Applied.

^ permalink raw reply

* Re: [PATCH] netlink: use the appropriate namespace pid
From: David Miller @ 2010-03-27  3:14 UTC (permalink / raw)
  To: adobriyan; +Cc: thomas.goff, netdev, adobriyan
In-Reply-To: <b6fcc0a1003240119h7c26d649taa1f947c2aeb6064@mail.gmail.com>

From: Alexey Dobriyan <adobriyan@gmail.com>
Date: Wed, 24 Mar 2010 10:19:37 +0200

>>> Alexey, can you review Tom's namespace patches in this
>>> set?
> 
> re netns sched patch:
> 
> * in psched_open() PDE(inode)->data isn't needed because
>   it isn't used -- just pass NULL.
> * drop useless trailing return; in psched_net_exit() :^)
> * sch_mirred.c still won't work in netns

Tom, please send a patch to fixup these issues.

Thanks.

^ permalink raw reply

* Re: [PATCH] netlink: use the appropriate namespace pid
From: David Miller @ 2010-03-27  3:15 UTC (permalink / raw)
  To: Thomas.Goff; +Cc: adobriyan, netdev, adobriyan
In-Reply-To: <6AFD35BEDB60334C9A31FD694E13EF0D226771E62E@XCH-NW-18V.nw.nos.boeing.com>

From: "Goff, Thomas" <Thomas.Goff@boeing.com>
Date: Wed, 24 Mar 2010 07:18:12 -0700

> On Wed March 24, 2010 12:59 AM, Alexey Dobriyan <adobriyan@gmail.com> wrote:
>> ACK tgid patch, should have sent it myself long ago.
> 
> Thanks for reviewing this.
> 
> David is correct that pid is arbitrary here anyway so it really
> shouldn't matter.  The patch just lets applications that make an
> incorrect assumption that happens to usually be right for the
> initial namespace work similarly in other namespaces.  So
> including the patch seems more of a policy question.

I ended up applying this to net-next-2.6, it's not critical
so it's not net-2.6 material, but it's harmless so we can
still queue it up for the next merge window.

^ permalink raw reply

* Re: [RFC PATCH] gianfar: fix undo of reserve()
From: David Miller @ 2010-03-27  3:16 UTC (permalink / raw)
  To: ben; +Cc: netdev
In-Reply-To: <A6A1774AFD79E346AE6D49A33CB294530DC19FC4@EX-BE-017-SFO.shared.themessagecenter.com>

From: "Ben Menchaca (ben@bigfootnetworks.com)" <ben@bigfootnetworks.com>
Date: Wed, 24 Mar 2010 08:05:02 -0700

> From: Ben Menchaca <ben@bigfootnetworks.com>
> 
> Fix undo of reserve() before RX recycle
> 
> gfar_new_skb reserve()s space in the SKB to align it.  If an error occurs,
> and the skb needs to be returned to the RX recycle queue, the current code
> attempts to reset head, but did not reset tail.  This patch remembers the
> alignment amount, and reverses the reserve() when needed.
> 
> Signed-off-by: Ben Menchaca <ben@bigfootnetworks.com>

Applied, thanks.

^ permalink raw reply

* Re: Null dereference in uli526x_rx_packet()
From: David Miller @ 2010-03-27  3:21 UTC (permalink / raw)
  To: grundler; +Cc: kyle, netdev, error27
In-Reply-To: <20100207071540.GA9908@lackof.org>

From: Grant Grundler <grundler@parisc-linux.org>
Date: Sun, 7 Feb 2010 00:15:40 -0700

> On Sat, Mar 28, 2009 at 11:59:31PM -0700, David Miller wrote:
> ...
>> > Patch below looks right to me. Clobbering the skb is certainly wrong.
>> > 
>> > Acked-by: Grant Grundler <grundler@parisc-linux.org>
>> 
>> It looks correct to me, can we get a proper submission with
>> signoffs etc.?
> 
> Dave,
> Looks like this patch was never resubmitted.
> 
> Kyle, can you look at http://lists.openwall.net/netdev/2009/03/27/117
> and resubmit the code you had then with my "Acked-by" added please?
> 
> Or if you don't want to touch it, let me know and I'll resurrect it.

I got tired of waiting for this resubmission (a month and a half) and
just applied the most recent version of the patch to net-2.6.

It looked correct to me too.

^ permalink raw reply

* Re: [PATCH] net: fix netlink address dumping in IPv4/IPv6
From: David Miller @ 2010-03-27  3:28 UTC (permalink / raw)
  To: kaber; +Cc: netdev
In-Reply-To: <4BACEB4F.9060900@trash.net>


Applied, thanks.




^ permalink raw reply

* Re: [PATCH] net: fix netlink address dumping in IPv4/IPv6
From: David Miller @ 2010-03-27  3:36 UTC (permalink / raw)
  To: kaber; +Cc: netdev
In-Reply-To: <20100326.202828.165365437.davem@davemloft.net>

From: David Miller <davem@davemloft.net>
Date: Fri, 26 Mar 2010 20:28:28 -0700 (PDT)

> 
> Applied, thanks.

BTW, you encoded this patch in such a way that:

1) patchwork didn't even notice it

2) it made more work for me to apply it

Putting just the commit message and the patch itself
as an attachment isn't going to work.

It ought to be quite simple:

Mail headers:

1) If you wrote the patch the normal "From: " in your
   email takes care of everything.  Else add a new
   one at the top of the mail message body for the
   actual author.

2) Make "Subject: " be the commit message header line.
   Anything in leading "[]" brackets will be removed by
   the git tools so you can say things like "[PATCH]" and
   "[PATCH net-2.6]" there.

3) After any optional "From: " override for the patch author, the
   content of your email body should start with the commit message.

4) If you want to make more comments that don't end up into the commit
   message (like: "Dave this should go to -stable for 2.6.33 only")
   add a line with "---" three dashes then on the following lines say
   what you want to say

5) Then comes the patch.

This really should be trivial.

Don't use attachments, just:

--------------------------------------------------
From: Patrick McHardy <kaber@trash.net>
Subject: [PATCH whatever] Commit header line

Commit message

---

Any extra side notes.

 net/ipv4/devinet.c  |    2 +-
 net/ipv6/addrconf.c |    2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c
index 51ca946..3feb2b3 100644
--- a/net/ipv4/devinet.c
+++ b/net/ipv4/devinet.c
@@ -1194,7 +1194,7 @@ static int inet_dump_ifaddr(struct sk_buff *skb, struct n
...
--------------------------------------------------

I really should be able to take your email and feed it
to "git am" and it should "just work".  I can't do that
with what you're giving me.

^ permalink raw reply related

* Re: [PATCH] e1000e: Use pr_<level> and netdev_<level>
From: David Miller @ 2010-03-27  3:52 UTC (permalink / raw)
  To: joe; +Cc: bruce.w.allan, jeffrey.t.kirsher, netdev, gospo
In-Reply-To: <1269475474.1541.20.camel@Joe-Laptop.home>

From: Joe Perches <joe@perches.com>
Date: Wed, 24 Mar 2010 17:04:34 -0700

> hw and adapter are locally scoped in each function here,
> but are not local to the macro.  That can make conversions
> of macros to functions difficult.

This is pretty common practice in drivers though.

Especially for register accessors and whatnot, and I see no problem
doing it here.

All specifying these args explicitly will do is make the fingers move
one step closer to carpel tunnel. :-)


^ permalink raw reply

* Re: [PATCH v2] Add MSG_WAITFORONE flag to recvmmsg
From: David Miller @ 2010-03-27  3:54 UTC (permalink / raw)
  To: blblack; +Cc: netdev, acme, drepper, linux-kernel
In-Reply-To: <20100327021803.GA10866@xpc.home>

From: Brandon L Black <blblack@gmail.com>
Date: Fri, 26 Mar 2010 21:18:03 -0500

> 
> From: Brandon L Black <blblack@gmail.com>
> 
> Add new flag MSG_WAITFORONE for the recvmmsg() syscall.
> When this flag is specified for a blocking socket, recvmmsg()
> will only block until at least 1 packet is available.  The
> default behavior is to block until all vlen packets are
> available.  This flag has no effect on non-blocking sockets
> or when used in combination with MSG_DONTWAIT.
> 
> Signed-off-by: Brandon L Black <blblack@gmail.com>

Arnaldo, please review this, thanks.

^ permalink raw reply

* Re: [PATCH 1/2] ipv4: Cleanup struct net dereference in rt_intern_hash
From: David Miller @ 2010-03-27  3:58 UTC (permalink / raw)
  To: xemul; +Cc: dada1, nhorman, netdev
In-Reply-To: <4BAA4F35.3000903@openvz.org>

From: Pavel Emelyanov <xemul@openvz.org>
Date: Wed, 24 Mar 2010 20:43:17 +0300

> There's no need in getting it 3 times and gcc isn't smart enough
> to understand this himself.
> 
> This is just a cleanup before the fix (next patch).
> 
> Signed-off-by: Pavel Emelyanov <xemul@openvz.org>

Applied.

^ permalink raw reply

* Re: [PATCH 2/2] ipv4: Restart rt_intern_hash after emergency rebuild (v2)
From: David Miller @ 2010-03-27  3:58 UTC (permalink / raw)
  To: nhorman; +Cc: xemul, dada1, netdev
In-Reply-To: <20100325131721.GA17675@shamino.rdu.redhat.com>

From: Neil Horman <nhorman@tuxdriver.com>
Date: Thu, 25 Mar 2010 09:17:21 -0400

> On Thu, Mar 25, 2010 at 10:51:22AM +0300, Pavel Emelyanov wrote:
>> The the rebuild changes the genid which in turn is used at
>> the hash calculation. Thus if we don't restart and go on with
>> inserting the rt will happen in wrong chain.
>> 
>> (Fixed Neil's comment about the index passed into the rt_intern_hash)
>> 
>> Signed-off-by: Pavel Emelyanov <xemul@openvz.org>
> Thanks!  I think this is pretty reasonable.
> Reviewed-by: Neil Horman <nhorman@tuxdriver.com>

Applied, thanks.

^ permalink raw reply

* Re: [net-2.6 PATCH] ixgbe: fix bug with vlan strip in promsic mode
From: David Miller @ 2010-03-27  4:00 UTC (permalink / raw)
  To: jeffrey.t.kirsher; +Cc: netdev, gospo, jesse.brandeburg
In-Reply-To: <20100325213428.8089.1879.stgit@localhost.localdomain>


Doesn't apply.

It depends upon the mc_list traversal conversions which are
absolutely not appropriate for net-2.6, and thus I only
applied to net-next-2.6

^ permalink raw reply

* Re: [net-2.6 PATCH] igbvf: do not modify tx_queue_len on link speed change
From: David Miller @ 2010-03-27  4:01 UTC (permalink / raw)
  To: jeffrey.t.kirsher; +Cc: netdev, gospo, franco, emil.s.tantilov
In-Reply-To: <20100325221120.8756.51559.stgit@localhost.localdomain>

From: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Date: Thu, 25 Mar 2010 15:11:48 -0700

> From: Emil Tantilov <emil.s.tantilov@intel.com>
> 
> Previously the driver tweaked txqueuelen to avoid false Tx hang reports seen at half duplex.
> This had the effect of overriding user set values on link change/reset. Testing shows that
> adjusting only the timeout factor is sufficient to prevent Tx hang reports at half duplex.
> 
> Based on e1000e patch by Franco Fichtner <franco@lastsummer.de>
> 
> CC: Franco Fichtner <franco@lastsummer.de>
> Signed-off-by: Emil Tantilov <emil.s.tantilov@intel.com>
> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>

Applied.

^ permalink raw reply

* Re: [PATCH] e1000e: do not modify tx_queue_len on link speed change
From: David Miller @ 2010-03-27  4:05 UTC (permalink / raw)
  To: jeffrey.t.kirsher; +Cc: netdev, gospo, franco, emil.s.tantilov
In-Reply-To: <20100324225501.7104.28849.stgit@localhost.localdomain>

From: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Date: Wed, 24 Mar 2010 15:55:02 -0700

> From: Emil Tantilov <emil.s.tantilov@intel.com>
> 
> Previously the driver tweaked txqueuelen to avoid false Tx hang reports seen at half duplex.
> This had the effect of overriding user set values on link change/reset. Testing shows that
> adjusting only the timeout factor is sufficient to prevent Tx hang reports at half duplex.
> 
> This patch removes all instances of tx_queue_len in the driver.
> 
> Originally reported and patched by Franco Fichtner
> CC: Franco Fichtner <franco@lastsummer.de>
> Signed-off-by: Emil Tantilov <emil.s.tantilov@intel.com>
> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>

Applied to net-2.6

^ permalink raw reply

* Re: [PATCH] e1000e: Use pr_<level> and netdev_<level>
From: David Miller @ 2010-03-27  4:05 UTC (permalink / raw)
  To: jeffrey.t.kirsher; +Cc: netdev, gospo, joe, bruce.w.allan
In-Reply-To: <20100324225529.7104.17189.stgit@localhost.localdomain>

From: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Date: Wed, 24 Mar 2010 15:55:30 -0700

> From: Bruce Allan <bruce.w.allan@intel.com>
> 
> As an alternative to a quite large patch previously submitted by Joe
> Perches to make use of kernel logging API, this patch is much less
> intrusive.
> 
> Convert e_<level> to netdev_<level>
> Use #define pr_fmt
> Convert a few printks to pr_<level>
> 
> Cc: Joe Perches <joe@perches.com>
> Signed-off-by: Bruce Allan <bruce.w.allan@intel.com>
> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>

Applied to net-next-2.6

^ permalink raw reply

* Re: [PATCH v2] Add MSG_WAITFORONE flag to recvmmsg
From: Ulrich Drepper @ 2010-03-27  4:58 UTC (permalink / raw)
  To: Brandon L Black
  Cc: netdev, David S. Miller, Arnaldo Carvalho de Melo, linux-kernel
In-Reply-To: <20100327021803.GA10866@xpc.home>

On Fri, Mar 26, 2010 at 19:18, Brandon L Black <blblack@gmail.com> wrote:
> Add new flag MSG_WAITFORONE for the recvmmsg() syscall.
> When this flag is specified for a blocking socket, recvmmsg()
> will only block until at least 1 packet is available.  The
> default behavior is to block until all vlen packets are
> available.  This flag has no effect on non-blocking sockets
> or when used in combination with MSG_DONTWAIT.
>
> Signed-off-by: Brandon L Black <blblack@gmail.com>

This is useful and looks OK to me.

Acked-by: Ulrich Drepper <drepper@redhat.com>

^ permalink raw reply

* Re: [PATCH v2] Add MSG_WAITFORONE flag to recvmmsg
From: Eric Dumazet @ 2010-03-27  6:00 UTC (permalink / raw)
  To: Brandon L Black
  Cc: netdev, David S. Miller, Arnaldo Carvalho de Melo, Ulrich Drepper,
	linux-kernel
In-Reply-To: <20100327021803.GA10866@xpc.home>

Le vendredi 26 mars 2010 à 21:18 -0500, Brandon L Black a écrit :
> From: Brandon L Black <blblack@gmail.com>
> 
> Add new flag MSG_WAITFORONE for the recvmmsg() syscall.
> When this flag is specified for a blocking socket, recvmmsg()
> will only block until at least 1 packet is available.  The
> default behavior is to block until all vlen packets are
> available.  This flag has no effect on non-blocking sockets
> or when used in combination with MSG_DONTWAIT.
> 
> Signed-off-by: Brandon L Black <blblack@gmail.com>
> 

Acked-by: Eric Dumazet <eric.dumazet@gmail.com>

> ---
> diff --git a/include/linux/socket.h b/include/linux/socket.h
> index 7b3aae2..354cc56 100644
> --- a/include/linux/socket.h
> +++ b/include/linux/socket.h
> @@ -255,6 +255,7 @@ struct ucred {
>  #define MSG_ERRQUEUE	0x2000	/* Fetch message from error queue */
>  #define MSG_NOSIGNAL	0x4000	/* Do not generate SIGPIPE */
>  #define MSG_MORE	0x8000	/* Sender will send more */
> +#define MSG_WAITFORONE	0x10000	/* recvmmsg(): block until 1+ packets avail */
>  
>  #define MSG_EOF         MSG_FIN
>  
> diff --git a/net/socket.c b/net/socket.c
> index 769c386..f55ffe9 100644
> --- a/net/socket.c
> +++ b/net/socket.c
> @@ -2135,6 +2135,10 @@ int __sys_recvmmsg(int fd, struct mmsghdr __user *mmsg, unsigned int vlen,
>  			break;
>  		++datagrams;
>  
> +		/* MSG_WAITFORONE turns on MSG_DONTWAIT after one packet */
> +		if (flags & MSG_WAITFORONE)
> +			flags |= MSG_DONTWAIT;
> +
>  		if (timeout) {
>  			ktime_get_ts(timeout);
>  			*timeout = timespec_sub(end_time, *timeout);
> --

^ 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