Netdev List
 help / color / mirror / Atom feed
* [PATCH] pegasus: fix USB device ID for ETX-US2
From: Tadashi Abe @ 2010-05-17  8:19 UTC (permalink / raw)
  To: davem; +Cc: netdev

USB device ID definition for I-O Data ETX-US2 is wrong.
Correct ID is 0x093a. Here's snippet from /proc/bus/usb/devices;

T:  Bus=01 Lev=01 Prnt=01 Port=01 Cnt=01 Dev#=  2 Spd=480 MxCh= 0
D:  Ver= 2.00 Cls=ff(vend.) Sub=ff Prot=00 MxPS=64 #Cfgs=  1
P:  Vendor=04bb ProdID=093a Rev= 1.01
S:  Manufacturer=I-O DATA DEVICE,INC.
S:  Product=I-O DATA ETX2-US2
S:  SerialNumber=A26427
C:* #Ifs= 1 Cfg#= 1 Atr=80 MxPwr=224mA
I:* If#= 0 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=00 Driver=pegasus
E:  Ad=81(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=83(I) Atr=03(Int.) MxPS=   8 Ivl=125us

This patch enables pegasus driver to work fine with ETX-US2.

Signed-off-by: Tadashi Abe <tabe@mvista.com>
---
diff --git a/drivers/net/usb/pegasus.h b/drivers/net/usb/pegasus.h
index b90d876..29f5211 100644
--- a/drivers/net/usb/pegasus.h
+++ b/drivers/net/usb/pegasus.h
@@ -256,7 +256,7 @@ PEGASUS_DEV( "IO DATA USB ET/TX", VENDOR_IODATA, 0x0904,
 		DEFAULT_GPIO_RESET )
 PEGASUS_DEV( "IO DATA USB ET/TX-S", VENDOR_IODATA, 0x0913,
 		DEFAULT_GPIO_RESET | PEGASUS_II )
-PEGASUS_DEV( "IO DATA USB ETX-US2", VENDOR_IODATA, 0x092a,
+PEGASUS_DEV( "IO DATA USB ETX-US2", VENDOR_IODATA, 0x093a,
 		DEFAULT_GPIO_RESET | PEGASUS_II )
 PEGASUS_DEV( "Kingston KNU101TX Ethernet", VENDOR_KINGSTON, 0x000a,
 		DEFAULT_GPIO_RESET)

^ permalink raw reply related

* Re: [PATCH v3 3/3] ptp: Added a clock that uses the eTSEC found on the MPC85xx.
From: Richard Cochran @ 2010-05-17  8:27 UTC (permalink / raw)
  To: Scott Wood
  Cc: netdev-u79uwXL29TY76Z2rM5mHXA,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	linuxppc-dev-uLR06cmDAlY/bJ5BZ2RsiQ
In-Reply-To: <4BED8C91.8020107-KZfg59tc24xl57MIdRCFDg@public.gmane.org>

On Fri, May 14, 2010 at 12:46:57PM -0500, Scott Wood wrote:
> On 05/14/2010 11:46 AM, Richard Cochran wrote:
> >diff --git a/Documentation/powerpc/dts-bindings/fsl/tsec.txt b/Documentation/powerpc/dts-bindings/fsl/tsec.txt
> 
> Get rid of both device_type and model, and specify a compatible
> string instead (e.g. "fsl,etsec-ptp").

Okay, will do. I really am at a loss at understanding all the rules in
the whole device tree world. I just tried to follow
Documentation/powerpc and what is already present in the kernel.

> Or perhaps this should just be some additional properties on the
> existing gianfar nodes, rather than presenting it as a separate
> device?  How do you associate a given ptp block with the
> corresponding gianfar node?

There only one PTP clock. Its registers repeat in each port's memory
space, but you are only supposed to touch the first set of PTP
registers. If you consider how PTP works, there can never be per port
clocks, since this would make it impossible to make a boundary clock,
for example.

The whole idea of this PTP clock framework is to keep the clock
drivers separate from the MAC drivers, even when they use the same
hardware. The functionality is logically divided into two parts. The
MAC provides time stamps, and the clock provides a way to control its
offset and frequency.

Up until this point, people have simply hacked new private ioctls into
the driver for each MAC that supports PTP. That is not a good long
term solution for PTP support in Linux.

In general, I think it will not be hard to keep the MAC and the clock
drivers from stepping on each other's toes. The eTSEC hardware is
certainly able to be used in this way.

> If there are differences in ptp implementation between different
> versions of etsec, can the ptp driver see the etsec version
> register?

There are no differences (that I know of) in how the PTP clocks
work. I have in house the mpc8313, the mpc8572, and the p2020. The
mpc8572 appears to lack some of the TMR_CTRL bits, but this is
probably a documentation bug. I will check it.

> >+  - tclk_period  Timer reference clock period in nanoseconds.
> >+  - tmr_prsc     Prescaler, divides the output clock.
> >+  - tmr_add      Frequency compensation value.
> >+  - cksel        0= external clock, 1= eTSEC system clock, 3= RTC clock input.
> >+                 Currently the driver only supports choice "1".
> >+  - tmr_fiper1   Fixed interval period pulse generator.
> >+  - tmr_fiper2   Fixed interval period pulse generator.
> 
> Dashes are more typical in OF names than underscores, and it's
> generally better to be a little more verbose -- these aren't local
> loop iterators.

The names come from the register mnemonics from the documentation. I
prefer to use the same names as is found in the manuals. That way, a
person working with docu in hand will have an easier job.

> They should probably have an "fsl,ptp-" prefix as well.

Okay, but must I then change the following code in order to find them?
Does adding the prefix just mean that I also add it to my search
strings, or is it preprocessed (stripped) somehow?

static int get_of_u32(struct device_node *node, char *str, u32 *val)
{
	int plen;
	const u32 *prop = of_get_property(node, str, &plen);

	if (!prop || plen != sizeof(*prop))
	   return -1;
	   *val = *prop;
	   return 0;
}
...
	if (get_of_u32(node, "tclk_period",&etsects->tclk_period) ||
	    get_of_u32(node, "tmr_prsc",&etsects->tmr_prsc) ||
	    get_of_u32(node, "tmr_add",&etsects->tmr_add) ||
	    get_of_u32(node, "cksel",&etsects->cksel) ||
	    get_of_u32(node, "tmr_fiper1",&etsects->tmr_fiper1) ||
	    get_of_u32(node, "tmr_fiper2",&etsects->tmr_fiper2))
		return -ENODEV;

> >+  These properties set the operational parameters for the PTP
> >+  clock. You must choose these carefully for the clock to work right.
> 
> Do these values describe the way the hardware is, or how it's been
> configured by firmware, or a set of values that are clearly optimal
> for this particular board?  If it's just configuration for the Linux
> driver, that could reasonably differ based on what a given user or
> OS will want, the device tree probably isn't the right place for it.

The values are related to the board. One important parameter is the
input clock, and the rest reflect some engineering decisions/tradeoffs
related to the signals to and from the PTP clock. There is not just
one "optimal" choice, so I wanted to let the designer set the
values. In any case, the parameters are definitely related to the
board (not to the cpu or to linux), so I think the device tree is the
right place for them.

> This one has 3 interrupts?  The driver supports only two.

The documentation does not specify the IRQ line that each event
belongs to. After some trial and error, it appears that all of the
ancillary clock interrupts arrive on the first interrupt. The other
lines (one per port) must be for the Tx/Rx packet time stamp
indication, but we don't need these for the clock or for the MAC.

I'll just reduce the driver to one interrupt.

> >+/* Private globals */
> >+static struct ptp_clock *gianfar_clock;
> 
> Do you not support more than one of these?
> 
> >+static struct etsects the_clock;
> 
> "The" clock?  As oppsed to the "other" clock one line above? :-)

The 'gianfar_clock' variable holds the returned instance from the
class driver, while 'the_clock' is the driver's private data (and
there can only be one driver).

I'll combine these into one struct to make it more clear and less
funny sounding.

> >+	return IRQ_HANDLED;
> 
> Should only return IRQ_HANDLED if you found an event.

Okay.

> >+	if (get_of_u32(node, "tclk_period",&etsects->tclk_period) ||
> >+	    get_of_u32(node, "tmr_prsc",&etsects->tmr_prsc) ||
> >+	    get_of_u32(node, "tmr_add",&etsects->tmr_add) ||
> >+	    get_of_u32(node, "cksel",&etsects->cksel) ||
> >+	    get_of_u32(node, "tmr_fiper1",&etsects->tmr_fiper1) ||
> >+	    get_of_u32(node, "tmr_fiper2",&etsects->tmr_fiper2))
> >+		return -ENODEV;
> 
> Might want to print an error so the user knows what's missing.

Okay.

> You've got two IRQs, with the same handler, and the same dev_id?
> From the manual it looks like there's one PTP interrupt per eTSEC
> (which would explain 3 interrupts on p2020).

Will reduce to just one IRQ.

> >+static struct of_device_id match_table[] = {
> >+	{ .type = "ptp_clock" },
> >+	{},
> >+};
> 
> This driver controls every possible PTP implementation?

No, I only want to match with the eTSEC clock device. Given the
compatible string above ("fsl,etsec-ptp"), what is the correct way to
do this? (pointer to an existing driver to emulate would be enough)

Thanks for your help,

Richard

^ permalink raw reply

* [PATCH 1/4] X25: Move qbit flag to bitfield
From: Andrew Hendry @ 2010-05-17  8:59 UTC (permalink / raw)
  To: netdev

Moves the X25 q bit flag from char into a bitfield to allow BKL cleanup.

Signed-off-by: Andrew Hendry <andrew.hendry@gmail.com>

---
 include/net/x25.h |    6 +++++-
 net/x25/af_x25.c  |   17 ++++++++++-------
 2 files changed, 15 insertions(+), 8 deletions(-)

diff --git a/include/net/x25.h b/include/net/x25.h
index 468551e..7b5795e 100644
--- a/include/net/x25.h
+++ b/include/net/x25.h
@@ -113,6 +113,9 @@ enum {
 #define X25_MAX_AE_LEN 		40			/* Max num of semi-octets in AE - OSI Nw */
 #define X25_MAX_DTE_FACIL_LEN	21			/* Max length of DTE facility params */
 
+/* Bitset in x25_sock->flags for misc flags */
+#define X25_Q_BIT_FLAG		0
+
 /**
  *	struct x25_route - x25 routing entry
  *	@node - entry in x25_list_lock
@@ -146,10 +149,11 @@ struct x25_sock {
 	struct x25_address	source_addr, dest_addr;
 	struct x25_neigh	*neighbour;
 	unsigned int		lci, cudmatchlength;
-	unsigned char		state, condition, qbitincl, intflag, accptapprv;
+	unsigned char		state, condition, intflag, accptapprv;
 	unsigned short		vs, vr, va, vl;
 	unsigned long		t2, t21, t22, t23;
 	unsigned short		fraglen;
+	unsigned long		flags;
 	struct sk_buff_head	ack_queue;
 	struct sk_buff_head	fragment_queue;
 	struct sk_buff_head	interrupt_in_queue;
diff --git a/net/x25/af_x25.c b/net/x25/af_x25.c
index 296e65e..720534c 100644
--- a/net/x25/af_x25.c
+++ b/net/x25/af_x25.c
@@ -465,7 +465,10 @@ static int x25_setsockopt(struct socket *sock, int level, int optname,
 	if (get_user(opt, (int __user *)optval))
 		goto out;
 
-	x25_sk(sk)->qbitincl = !!opt;
+	if (opt)
+		set_bit(X25_Q_BIT_FLAG, &x25_sk(sk)->flags);
+	else
+		clear_bit(X25_Q_BIT_FLAG, &x25_sk(sk)->flags);
 	rc = 0;
 out:
 	unlock_kernel();
@@ -496,7 +499,7 @@ static int x25_getsockopt(struct socket *sock, int level, int optname,
 	if (put_user(len, optlen))
 		goto out;
 
-	val = x25_sk(sk)->qbitincl;
+	val = test_bit(X25_Q_BIT_FLAG, &x25_sk(sk)->flags);
 	rc = copy_to_user(optval, &val, len) ? -EFAULT : 0;
 out:
 	unlock_kernel();
@@ -632,8 +635,8 @@ static struct sock *x25_make_new(struct sock *osk)
 	x25->t22        = ox25->t22;
 	x25->t23        = ox25->t23;
 	x25->t2         = ox25->t2;
+	x25->flags	= ox25->flags;
 	x25->facilities = ox25->facilities;
-	x25->qbitincl   = ox25->qbitincl;
 	x25->dte_facilities = ox25->dte_facilities;
 	x25->cudmatchlength = ox25->cudmatchlength;
 	x25->accptapprv = ox25->accptapprv;
@@ -1186,7 +1189,7 @@ static int x25_sendmsg(struct kiocb *iocb, struct socket *sock,
 	 *	If the Q BIT Include socket option is in force, the first
 	 *	byte of the user data is the logical value of the Q Bit.
 	 */
-	if (x25->qbitincl) {
+	if (test_bit(X25_Q_BIT_FLAG, &x25->flags)) {
 		qbit = skb->data[0];
 		skb_pull(skb, 1);
 	}
@@ -1242,7 +1245,7 @@ static int x25_sendmsg(struct kiocb *iocb, struct socket *sock,
 		len = rc;
 		if (rc < 0)
 			kfree_skb(skb);
-		else if (x25->qbitincl)
+		else if (test_bit(X25_Q_BIT_FLAG, &x25->flags))
 			len++;
 	}
 
@@ -1307,7 +1310,7 @@ static int x25_recvmsg(struct kiocb *iocb, struct socket *sock,
 		/*
 		 *	No Q bit information on Interrupt data.
 		 */
-		if (x25->qbitincl) {
+		if (test_bit(X25_Q_BIT_FLAG, &x25->flags)) {
 			asmptr  = skb_push(skb, 1);
 			*asmptr = 0x00;
 		}
@@ -1325,7 +1328,7 @@ static int x25_recvmsg(struct kiocb *iocb, struct socket *sock,
 		skb_pull(skb, x25->neighbour->extended ?
 				X25_EXT_MIN_LEN : X25_STD_MIN_LEN);
 
-		if (x25->qbitincl) {
+		if (test_bit(X25_Q_BIT_FLAG, &x25->flags)) {
 			asmptr  = skb_push(skb, 1);
 			*asmptr = qbit;
 		}
-- 
1.5.6.5



^ permalink raw reply related

* [PATCH 2/4] X25: Move interrupt flag to bitfield
From: Andrew Hendry @ 2010-05-17  9:00 UTC (permalink / raw)
  To: netdev

Moves the x25 interrupt flag from char into bitfield.

Signed-off-by: Andrew Hendry <andrew.hendry@gmail.com>

---
 include/net/x25.h |    3 ++-
 net/x25/af_x25.c  |    1 +
 net/x25/x25_in.c  |    2 +-
 net/x25/x25_out.c |    5 +++--
 4 files changed, 7 insertions(+), 4 deletions(-)

diff --git a/include/net/x25.h b/include/net/x25.h
index 7b5795e..1576e92 100644
--- a/include/net/x25.h
+++ b/include/net/x25.h
@@ -115,6 +115,7 @@ enum {
 
 /* Bitset in x25_sock->flags for misc flags */
 #define X25_Q_BIT_FLAG		0
+#define X25_INTERRUPT_FLAG	1
 
 /**
  *	struct x25_route - x25 routing entry
@@ -149,7 +150,7 @@ struct x25_sock {
 	struct x25_address	source_addr, dest_addr;
 	struct x25_neigh	*neighbour;
 	unsigned int		lci, cudmatchlength;
-	unsigned char		state, condition, intflag, accptapprv;
+	unsigned char		state, condition, accptapprv;
 	unsigned short		vs, vr, va, vl;
 	unsigned long		t2, t21, t22, t23;
 	unsigned short		fraglen;
diff --git a/net/x25/af_x25.c b/net/x25/af_x25.c
index 720534c..3d97b8c 100644
--- a/net/x25/af_x25.c
+++ b/net/x25/af_x25.c
@@ -641,6 +641,7 @@ static struct sock *x25_make_new(struct sock *osk)
 	x25->cudmatchlength = ox25->cudmatchlength;
 	x25->accptapprv = ox25->accptapprv;
 
+	clear_bit(X25_INTERRUPT_FLAG, &x25->flags);
 	x25_init_timers(sk);
 out:
 	return sk;
diff --git a/net/x25/x25_in.c b/net/x25/x25_in.c
index 372ac22..6317896 100644
--- a/net/x25/x25_in.c
+++ b/net/x25/x25_in.c
@@ -273,7 +273,7 @@ static int x25_state3_machine(struct sock *sk, struct sk_buff *skb, int frametyp
 			break;
 
 		case X25_INTERRUPT_CONFIRMATION:
-			x25->intflag = 0;
+			clear_bit(X25_INTERRUPT_FLAG, &x25->flags);
 			break;
 
 		case X25_INTERRUPT:
diff --git a/net/x25/x25_out.c b/net/x25/x25_out.c
index 52351a2..d00649f 100644
--- a/net/x25/x25_out.c
+++ b/net/x25/x25_out.c
@@ -148,8 +148,9 @@ void x25_kick(struct sock *sk)
 	/*
 	 *	Transmit interrupt data.
 	 */
-	if (!x25->intflag && skb_peek(&x25->interrupt_out_queue) != NULL) {
-		x25->intflag = 1;
+	if (skb_peek(&x25->interrupt_out_queue) != NULL &&
+		!test_and_set_bit(X25_INTERRUPT_FLAG, &x25->flags)) {
+
 		skb = skb_dequeue(&x25->interrupt_out_queue);
 		x25_transmit_link(skb, x25->neighbour);
 	}
-- 
1.5.6.5



^ permalink raw reply related

* [PATCH 3/4] X25: Move accept approve flag to bitfield
From: Andrew Hendry @ 2010-05-17  9:00 UTC (permalink / raw)
  To: netdev


Moves the x25 accept approve flag from char into bitfield.

Signed-off-by: Andrew Hendry <andrew.hendry@gmail.com>

---
 include/net/x25.h |    5 ++---
 net/x25/af_x25.c  |   12 ++++++------
 2 files changed, 8 insertions(+), 9 deletions(-)

diff --git a/include/net/x25.h b/include/net/x25.h
index 1576e92..1479cb4 100644
--- a/include/net/x25.h
+++ b/include/net/x25.h
@@ -80,8 +80,6 @@ enum {
 #define	X25_DEFAULT_PACKET_SIZE	X25_PS128		/* Default Packet Size */
 #define	X25_DEFAULT_THROUGHPUT	0x0A			/* Deafult Throughput */
 #define	X25_DEFAULT_REVERSE	0x00			/* Default Reverse Charging */
-#define X25_DENY_ACCPT_APPRV   0x01			/* Default value */
-#define X25_ALLOW_ACCPT_APPRV  0x00			/* Control enabled */
 
 #define X25_SMODULUS 		8
 #define	X25_EMODULUS		128
@@ -116,6 +114,7 @@ enum {
 /* Bitset in x25_sock->flags for misc flags */
 #define X25_Q_BIT_FLAG		0
 #define X25_INTERRUPT_FLAG	1
+#define X25_ACCPT_APPRV_FLAG	2
 
 /**
  *	struct x25_route - x25 routing entry
@@ -150,7 +149,7 @@ struct x25_sock {
 	struct x25_address	source_addr, dest_addr;
 	struct x25_neigh	*neighbour;
 	unsigned int		lci, cudmatchlength;
-	unsigned char		state, condition, accptapprv;
+	unsigned char		state, condition;
 	unsigned short		vs, vr, va, vl;
 	unsigned long		t2, t21, t22, t23;
 	unsigned short		fraglen;
diff --git a/net/x25/af_x25.c b/net/x25/af_x25.c
index 3d97b8c..e5c1e32 100644
--- a/net/x25/af_x25.c
+++ b/net/x25/af_x25.c
@@ -586,7 +586,7 @@ static int x25_create(struct net *net, struct socket *sock, int protocol,
 	x25->t2    = sysctl_x25_ack_holdback_timeout;
 	x25->state = X25_STATE_0;
 	x25->cudmatchlength = 0;
-	x25->accptapprv = X25_DENY_ACCPT_APPRV;		/* normally no cud  */
+	set_bit(X25_ACCPT_APPRV_FLAG, &x25->flags);	/* normally no cud  */
 							/* on call accept   */
 
 	x25->facilities.winsize_in  = X25_DEFAULT_WINDOW_SIZE;
@@ -639,7 +639,6 @@ static struct sock *x25_make_new(struct sock *osk)
 	x25->facilities = ox25->facilities;
 	x25->dte_facilities = ox25->dte_facilities;
 	x25->cudmatchlength = ox25->cudmatchlength;
-	x25->accptapprv = ox25->accptapprv;
 
 	clear_bit(X25_INTERRUPT_FLAG, &x25->flags);
 	x25_init_timers(sk);
@@ -1057,8 +1056,8 @@ int x25_rx_call_request(struct sk_buff *skb, struct x25_neigh *nb,
 	makex25->vc_facil_mask &= ~X25_MASK_CALLING_AE;
 	makex25->cudmatchlength = x25_sk(sk)->cudmatchlength;
 
-	/* Normally all calls are accepted immediatly */
-	if(makex25->accptapprv & X25_DENY_ACCPT_APPRV) {
+	/* Normally all calls are accepted immediately */
+	if (test_bit(X25_ACCPT_APPRV_FLAG, &makex25->flags)) {
 		x25_write_internal(make, X25_CALL_ACCEPTED);
 		makex25->state = X25_STATE_3;
 	}
@@ -1580,7 +1579,7 @@ static int x25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
 			rc = -EINVAL;
 			if (sk->sk_state != TCP_CLOSE)
 				break;
-			x25->accptapprv = X25_ALLOW_ACCPT_APPRV;
+			clear_bit(X25_ACCPT_APPRV_FLAG, &x25->flags);
 			rc = 0;
 			break;
 		}
@@ -1589,7 +1588,8 @@ static int x25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
 			rc = -EINVAL;
 			if (sk->sk_state != TCP_ESTABLISHED)
 				break;
-			if (x25->accptapprv)	/* must call accptapprv above */
+			/* must call accptapprv above */
+			if (test_bit(X25_ACCPT_APPRV_FLAG, &x25->flags))
 				break;
 			x25_write_internal(sk, X25_CALL_ACCEPTED);
 			x25->state = X25_STATE_3;
-- 
1.5.6.5



^ permalink raw reply related

* [PATCH 4/4] X25: Remove bkl in sockopts
From: Andrew Hendry @ 2010-05-17  9:00 UTC (permalink / raw)
  To: netdev


Removes the BKL in x25 setsock and getsockopts.

Signed-off-by: Andrew Hendry <andrew.hendry@gmail.com>

---
 net/x25/af_x25.c |    4 ----
 1 files changed, 0 insertions(+), 4 deletions(-)

diff --git a/net/x25/af_x25.c b/net/x25/af_x25.c
index e5c1e32..5e86d4e 100644
--- a/net/x25/af_x25.c
+++ b/net/x25/af_x25.c
@@ -453,7 +453,6 @@ static int x25_setsockopt(struct socket *sock, int level, int optname,
 	struct sock *sk = sock->sk;
 	int rc = -ENOPROTOOPT;
 
-	lock_kernel();
 	if (level != SOL_X25 || optname != X25_QBITINCL)
 		goto out;
 
@@ -471,7 +470,6 @@ static int x25_setsockopt(struct socket *sock, int level, int optname,
 		clear_bit(X25_Q_BIT_FLAG, &x25_sk(sk)->flags);
 	rc = 0;
 out:
-	unlock_kernel();
 	return rc;
 }
 
@@ -481,7 +479,6 @@ static int x25_getsockopt(struct socket *sock, int level, int optname,
 	struct sock *sk = sock->sk;
 	int val, len, rc = -ENOPROTOOPT;
 
-	lock_kernel();
 	if (level != SOL_X25 || optname != X25_QBITINCL)
 		goto out;
 
@@ -502,7 +499,6 @@ static int x25_getsockopt(struct socket *sock, int level, int optname,
 	val = test_bit(X25_Q_BIT_FLAG, &x25_sk(sk)->flags);
 	rc = copy_to_user(optval, &val, len) ? -EFAULT : 0;
 out:
-	unlock_kernel();
 	return rc;
 }
 
-- 
1.5.6.5



^ permalink raw reply related

* [PATCH NEXT 4/7] qlcnic: module param for firmware load option
From: Amit Kumar Salecha @ 2010-05-17 11:22 UTC (permalink / raw)
  To: davem; +Cc: netdev, ameen.rahman
In-Reply-To: <1274095334-32362-1-git-send-email-amit.salecha@qlogic.com>

By default fw is loaded from flash, user can
change this priority using load_fw_file module param.

Signed-off-by: Amit Kumar Salecha <amit.salecha@qlogic.com>
---
 drivers/net/qlcnic/qlcnic_main.c |    9 ++++++++-
 1 files changed, 8 insertions(+), 1 deletions(-)

diff --git a/drivers/net/qlcnic/qlcnic_main.c b/drivers/net/qlcnic/qlcnic_main.c
index 0a52d24..b076474 100644
--- a/drivers/net/qlcnic/qlcnic_main.c
+++ b/drivers/net/qlcnic/qlcnic_main.c
@@ -61,6 +61,10 @@ static int auto_fw_reset = AUTO_FW_RESET_ENABLED;
 module_param(auto_fw_reset, int, 0644);
 MODULE_PARM_DESC(auto_fw_reset, "Auto firmware reset (0=disabled, 1=enabled");
 
+static int load_fw_file;
+module_param(load_fw_file, int, 0644);
+MODULE_PARM_DESC(load_fw_file, "Load firmware from (0=flash, 1=file");
+
 static int __devinit qlcnic_probe(struct pci_dev *pdev,
 		const struct pci_device_id *ent);
 static void __devexit qlcnic_remove(struct pci_dev *pdev);
@@ -585,7 +589,10 @@ qlcnic_start_firmware(struct qlcnic_adapter *adapter)
 		/* This is the first boot after power up */
 		QLCWR32(adapter, QLCNIC_CAM_RAM(0x1fc), QLCNIC_BDINFO_MAGIC);
 
-	qlcnic_request_firmware(adapter);
+	if (load_fw_file)
+		qlcnic_request_firmware(adapter);
+	else
+		adapter->fw_type = QLCNIC_FLASH_ROMIMAGE;
 
 	err = qlcnic_need_fw_reset(adapter);
 	if (err < 0)
-- 
1.5.6.1


^ permalink raw reply related

* [PATCH NEXT 1/7] qlcnic: fix memory leaks
From: Amit Kumar Salecha @ 2010-05-17 11:22 UTC (permalink / raw)
  To: davem; +Cc: netdev, ameen.rahman, Anirban Chakraborty
In-Reply-To: <1274095334-32362-1-git-send-email-amit.salecha@qlogic.com>

From: Anirban Chakraborty <anirban.chakraborty@qlogic.com>

Fixes memory leak in error path when memory allocation
for adapter data structures fails.

Signed-off-by: Anirban Chakraborty <anirban.chakraborty@qlogic.com>
Signed-off-by: Amit Kumar Salecha <amit.salecha@qlogic.com>
---
 drivers/net/qlcnic/qlcnic_ctx.c  |    3 ++-
 drivers/net/qlcnic/qlcnic_init.c |    4 ++--
 2 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/drivers/net/qlcnic/qlcnic_ctx.c b/drivers/net/qlcnic/qlcnic_ctx.c
index 0a6a399..c2c1f5c 100644
--- a/drivers/net/qlcnic/qlcnic_ctx.c
+++ b/drivers/net/qlcnic/qlcnic_ctx.c
@@ -421,7 +421,8 @@ int qlcnic_alloc_hw_resources(struct qlcnic_adapter *adapter)
 
 	if (addr == NULL) {
 		dev_err(&pdev->dev, "failed to allocate tx desc ring\n");
-		return -ENOMEM;
+		err = -ENOMEM;
+		goto err_out_free;
 	}
 
 	tx_ring->desc_head = (struct cmd_desc_type0 *)addr;
diff --git a/drivers/net/qlcnic/qlcnic_init.c b/drivers/net/qlcnic/qlcnic_init.c
index 77bfdab..dccd8c3 100644
--- a/drivers/net/qlcnic/qlcnic_init.c
+++ b/drivers/net/qlcnic/qlcnic_init.c
@@ -210,7 +210,7 @@ int qlcnic_alloc_sw_resources(struct qlcnic_adapter *adapter)
 	cmd_buf_arr = vmalloc(TX_BUFF_RINGSIZE(tx_ring));
 	if (cmd_buf_arr == NULL) {
 		dev_err(&netdev->dev, "failed to allocate cmd buffer ring\n");
-		return -ENOMEM;
+		goto err_out;
 	}
 	memset(cmd_buf_arr, 0, TX_BUFF_RINGSIZE(tx_ring));
 	tx_ring->cmd_buf_arr = cmd_buf_arr;
@@ -221,7 +221,7 @@ int qlcnic_alloc_sw_resources(struct qlcnic_adapter *adapter)
 	rds_ring = kzalloc(size, GFP_KERNEL);
 	if (rds_ring == NULL) {
 		dev_err(&netdev->dev, "failed to allocate rds ring struct\n");
-		return -ENOMEM;
+		goto err_out;
 	}
 	recv_ctx->rds_rings = rds_ring;
 
-- 
1.5.6.1


^ permalink raw reply related

* [PATCH NEXT 3/7] qlcnic: fix rx bytes statistics
From: Amit Kumar Salecha @ 2010-05-17 11:22 UTC (permalink / raw)
  To: davem; +Cc: netdev, ameen.rahman, Sucheta Chakraborty
In-Reply-To: <1274095334-32362-1-git-send-email-amit.salecha@qlogic.com>

From: Sucheta Chakraborty <sucheta.chakraborty@qlogic.com>

Added lrobytes to it.

Signed-off-by: Sucheta Chakraborty <sucheta.chakraborty@qlogic.com>
Signed-off-by: Amit Kumar Salecha <amit.salecha@qlogic.com>
---
 drivers/net/qlcnic/qlcnic_main.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/net/qlcnic/qlcnic_main.c b/drivers/net/qlcnic/qlcnic_main.c
index db05635..0a52d24 100644
--- a/drivers/net/qlcnic/qlcnic_main.c
+++ b/drivers/net/qlcnic/qlcnic_main.c
@@ -1702,7 +1702,7 @@ static struct net_device_stats *qlcnic_get_stats(struct net_device *netdev)
 
 	stats->rx_packets = adapter->stats.rx_pkts + adapter->stats.lro_pkts;
 	stats->tx_packets = adapter->stats.xmitfinished;
-	stats->rx_bytes = adapter->stats.rxbytes;
+	stats->rx_bytes = adapter->stats.rxbytes + adapter->stats.lrobytes;
 	stats->tx_bytes = adapter->stats.txbytes;
 	stats->rx_dropped = adapter->stats.rxdropped;
 	stats->tx_dropped = adapter->stats.txdropped;
-- 
1.5.6.1


^ permalink raw reply related

* [PATCH NEXT 5/7] qlcnic: fix internal loopback test
From: Amit Kumar Salecha @ 2010-05-17 11:22 UTC (permalink / raw)
  To: davem; +Cc: netdev, ameen.rahman, Sucheta Chakraborty
In-Reply-To: <1274095334-32362-1-git-send-email-amit.salecha@qlogic.com>

From: Sucheta Chakraborty <sucheta.chakraborty@qlogic.com>

Reset/set DEV_UP bit during allocation and deallocation of resources.

Signed-off-by: Sucheta Chakraborty <sucheta.chakraborty@qlogic.com>
Signed-off-by: Amit Kumar Salecha <amit.salecha@qlogic.com>
---
 drivers/net/qlcnic/qlcnic_main.c |    2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/drivers/net/qlcnic/qlcnic_main.c b/drivers/net/qlcnic/qlcnic_main.c
index b076474..dde1e8a 100644
--- a/drivers/net/qlcnic/qlcnic_main.c
+++ b/drivers/net/qlcnic/qlcnic_main.c
@@ -870,6 +870,7 @@ void qlcnic_diag_free_res(struct net_device *netdev, int max_sds_rings)
 	struct qlcnic_host_sds_ring *sds_ring;
 	int ring;
 
+	clear_bit(__QLCNIC_DEV_UP, &adapter->state);
 	if (adapter->diag_test == QLCNIC_INTERRUPT_TEST) {
 		for (ring = 0; ring < adapter->max_sds_rings; ring++) {
 			sds_ring = &adapter->recv_ctx.sds_rings[ring];
@@ -920,6 +921,7 @@ int qlcnic_diag_alloc_res(struct net_device *netdev, int test)
 			qlcnic_enable_int(sds_ring);
 		}
 	}
+	set_bit(__QLCNIC_DEV_UP, &adapter->state);
 
 	return 0;
 }
-- 
1.5.6.1


^ permalink raw reply related

* [PATCH NEXT 7/7] qlcnic: mark device state fail
From: Amit Kumar Salecha @ 2010-05-17 11:22 UTC (permalink / raw)
  To: davem; +Cc: netdev, ameen.rahman
In-Reply-To: <1274095334-32362-1-git-send-email-amit.salecha@qlogic.com>

Device state need to be mark as FAILED, if fail to start firmware.

Signed-off-by: Amit Kumar Salecha <amit.salecha@qlogic.com>
---
 drivers/net/qlcnic/qlcnic_main.c |   10 ++++++++--
 1 files changed, 8 insertions(+), 2 deletions(-)

diff --git a/drivers/net/qlcnic/qlcnic_main.c b/drivers/net/qlcnic/qlcnic_main.c
index f8bd1bd..1003eb7 100644
--- a/drivers/net/qlcnic/qlcnic_main.c
+++ b/drivers/net/qlcnic/qlcnic_main.c
@@ -635,9 +635,12 @@ wait_init:
 
 	adapter->need_fw_reset = 0;
 
-	/* fall through and release firmware */
+	qlcnic_release_firmware(adapter);
+	return 0;
 
 err_out:
+	QLCWR32(adapter, QLCNIC_CRB_DEV_STATE, QLCNIC_DEV_FAILED);
+	dev_err(&adapter->pdev->dev, "Device state set to failed\n");
 	qlcnic_release_firmware(adapter);
 	return err;
 }
@@ -1100,8 +1103,10 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 		goto err_out_iounmap;
 
 	err = qlcnic_start_firmware(adapter);
-	if (err)
+	if (err) {
+		dev_err(&pdev->dev, "Loading fw failed.Please Reboot\n");
 		goto err_out_decr_ref;
+	}
 
 	qlcnic_clear_stats(adapter);
 
@@ -2061,6 +2066,7 @@ qlcnic_can_start_firmware(struct qlcnic_adapter *adapter)
 		break;
 
 	case QLCNIC_DEV_FAILED:
+		dev_err(&adapter->pdev->dev, "Device in failed state.\n");
 		qlcnic_api_unlock(adapter);
 		return -1;
 
-- 
1.5.6.1


^ permalink raw reply related

* [PATCH NEXT 2/7] qlcnic: change adapter name display
From: Amit Kumar Salecha @ 2010-05-17 11:22 UTC (permalink / raw)
  To: davem; +Cc: netdev, ameen.rahman, Sucheta Chakraborty
In-Reply-To: <1274095334-32362-1-git-send-email-amit.salecha@qlogic.com>

From: Sucheta Chakraborty <sucheta.chakraborty@qlogic.com>

Append mac address to adapter name.

Signed-off-by: Sucheta Chakraborty <sucheta.chakraborty@qlogic.com>
Signed-off-by: Amit Kumar Salecha <amit.salecha@qlogic.com>
---
 drivers/net/qlcnic/qlcnic_main.c |    7 ++++++-
 1 files changed, 6 insertions(+), 1 deletions(-)

diff --git a/drivers/net/qlcnic/qlcnic_main.c b/drivers/net/qlcnic/qlcnic_main.c
index f1949c9..db05635 100644
--- a/drivers/net/qlcnic/qlcnic_main.c
+++ b/drivers/net/qlcnic/qlcnic_main.c
@@ -495,7 +495,9 @@ static void get_brd_name(struct qlcnic_adapter *adapter, char *name)
 			qlcnic_boards[i].device == pdev->device &&
 			qlcnic_boards[i].sub_vendor == pdev->subsystem_vendor &&
 			qlcnic_boards[i].sub_device == pdev->subsystem_device) {
-				strcpy(name, qlcnic_boards[i].short_name);
+				sprintf(name, "%pM: %s" ,
+					adapter->mac_addr,
+					qlcnic_boards[i].short_name);
 				found = 1;
 				break;
 		}
@@ -1083,6 +1085,9 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 		goto err_out_iounmap;
 	}
 
+	if (qlcnic_read_mac_addr(adapter))
+		dev_warn(&pdev->dev, "failed to read mac addr\n");
+
 	if (qlcnic_setup_idc_param(adapter))
 		goto err_out_iounmap;
 
-- 
1.5.6.1


^ permalink raw reply related

* [PATCH NEXT 0/7]qlcnic: bug fixes
From: Amit Kumar Salecha @ 2010-05-17 11:22 UTC (permalink / raw)
  To: davem; +Cc: netdev, ameen.rahman

Hi
  Series of 7 patches to fix minor bugs. Please apply them on
  net-next.

-Amit

^ permalink raw reply

* [PATCH NEXT 6/7] qlcnic: remove unused register
From: Amit Kumar Salecha @ 2010-05-17 11:22 UTC (permalink / raw)
  To: davem; +Cc: netdev, ameen.rahman
In-Reply-To: <1274095334-32362-1-git-send-email-amit.salecha@qlogic.com>

Removing register defines which are not used by Qlgoic CNA device.

Signed-off-by: Amit Kumar Salecha <amit.salecha@qlogic.com>
---
 drivers/net/qlcnic/qlcnic.h      |    2 --
 drivers/net/qlcnic/qlcnic_hdr.h  |   16 ----------------
 drivers/net/qlcnic/qlcnic_init.c |    2 --
 drivers/net/qlcnic/qlcnic_main.c |    1 -
 4 files changed, 0 insertions(+), 21 deletions(-)

diff --git a/drivers/net/qlcnic/qlcnic.h b/drivers/net/qlcnic/qlcnic.h
index 2ed34cd..896d40d 100644
--- a/drivers/net/qlcnic/qlcnic.h
+++ b/drivers/net/qlcnic/qlcnic.h
@@ -149,8 +149,6 @@
 #define get_next_index(index, length)	\
 	(((index) + 1) & ((length) - 1))
 
-#define MPORT_MULTI_FUNCTION_MODE 0x2222
-
 /*
  * Following data structures describe the descriptors that will be used.
  * Added fileds of tcpHdrSize and ipHdrSize, The driver needs to do it only when
diff --git a/drivers/net/qlcnic/qlcnic_hdr.h b/drivers/net/qlcnic/qlcnic_hdr.h
index 1374078..ad9d167 100644
--- a/drivers/net/qlcnic/qlcnic_hdr.h
+++ b/drivers/net/qlcnic/qlcnic_hdr.h
@@ -563,32 +563,16 @@ enum {
 #define CRB_PF_LINK_SPEED_1		(QLCNIC_REG(0xe8))
 #define CRB_PF_LINK_SPEED_2		(QLCNIC_REG(0xec))
 
-#define CRB_MPORT_MODE			(QLCNIC_REG(0xc4))
-#define CRB_DMA_SHIFT			(QLCNIC_REG(0xcc))
-
 #define CRB_TEMP_STATE			(QLCNIC_REG(0x1b4))
 
 #define CRB_V2P_0			(QLCNIC_REG(0x290))
 #define CRB_V2P(port)			(CRB_V2P_0+((port)*4))
 #define CRB_DRIVER_VERSION		(QLCNIC_REG(0x2a0))
 
-#define CRB_SW_INT_MASK_0		(QLCNIC_REG(0x1d8))
-#define CRB_SW_INT_MASK_1		(QLCNIC_REG(0x1e0))
-#define CRB_SW_INT_MASK_2		(QLCNIC_REG(0x1e4))
-#define CRB_SW_INT_MASK_3		(QLCNIC_REG(0x1e8))
-
 #define CRB_FW_CAPABILITIES_1		(QLCNIC_CAM_RAM(0x128))
 #define CRB_MAC_BLOCK_START		(QLCNIC_CAM_RAM(0x1c0))
 
 /*
- * capabilities register, can be used to selectively enable/disable features
- * for backward compability
- */
-#define CRB_NIC_CAPABILITIES_HOST	QLCNIC_REG(0x1a8)
-
-#define INTR_SCHEME_PERPORT	      	0x1
-
-/*
  * CrbPortPhanCntrHi/Lo is used to pass the address of HostPhantomIndex address
  * which can be read by the Phantom host to get producer/consumer indexes from
  * Phantom/Casper. If it is not HOST_SHARED_MEMORY, then the following
diff --git a/drivers/net/qlcnic/qlcnic_init.c b/drivers/net/qlcnic/qlcnic_init.c
index dccd8c3..71a4e66 100644
--- a/drivers/net/qlcnic/qlcnic_init.c
+++ b/drivers/net/qlcnic/qlcnic_init.c
@@ -1184,8 +1184,6 @@ int qlcnic_init_firmware(struct qlcnic_adapter *adapter)
 	if (err)
 		return err;
 
-	QLCWR32(adapter, CRB_NIC_CAPABILITIES_HOST, INTR_SCHEME_PERPORT);
-	QLCWR32(adapter, CRB_MPORT_MODE, MPORT_MULTI_FUNCTION_MODE);
 	QLCWR32(adapter, CRB_CMDPEG_STATE, PHAN_INITIALIZE_ACK);
 
 	return err;
diff --git a/drivers/net/qlcnic/qlcnic_main.c b/drivers/net/qlcnic/qlcnic_main.c
index dde1e8a..f8bd1bd 100644
--- a/drivers/net/qlcnic/qlcnic_main.c
+++ b/drivers/net/qlcnic/qlcnic_main.c
@@ -606,7 +606,6 @@ qlcnic_start_firmware(struct qlcnic_adapter *adapter)
 		msleep(1);
 	}
 
-	QLCWR32(adapter, CRB_DMA_SHIFT, 0x55555555);
 	QLCWR32(adapter, QLCNIC_PEG_HALT_STATUS1, 0);
 	QLCWR32(adapter, QLCNIC_PEG_HALT_STATUS2, 0);
 
-- 
1.5.6.1


^ permalink raw reply related

* [PATCH] Fix SJA1000 command register writes on SMP systems
From: Oliver Hartkopp @ 2010-05-17 11:06 UTC (permalink / raw)
  To: David Miller
  Cc: SocketCAN Core Mailing List, Linux Netdev List,
	stable-DgEjT+Ai2ygdnm+yROfE0A, Wolfgang Grandegger

The SJA1000 command register is concurrently written in the rx-path to free
the receive buffer _and_ in the tx-path to start the transmission.
On SMP systems this leads to a write stall in the tx-path, which can be
solved by adding some locking for the command register in the SMP case.

Thanks to Klaus Hitschler for the original fix and detailed problem
description.

This patch applies on net-2.6 and (with some small offsets) on net-next-2.6.
It is also a candidate for the stable series.

Signed-off-by: Oliver Hartkopp <socketcan-fJ+pQTUTwRTk1uMJSBkQmQ@public.gmane.org>
Acked-by: Wolfgang Grandegger <wg-5Yr1BZd7O62+XT7JhA+gdA@public.gmane.org>

---

diff --git a/drivers/net/can/sja1000/sja1000.c b/drivers/net/can/sja1000/sja1000.c
index 145b1a7..2760085 100644
--- a/drivers/net/can/sja1000/sja1000.c
+++ b/drivers/net/can/sja1000/sja1000.c
@@ -84,6 +84,27 @@ static struct can_bittiming_const sja1000_bittiming_const = {
 	.brp_inc = 1,
 };
 
+static void sja1000_write_cmdreg(struct sja1000_priv *priv, u8 val)
+{
+	/* the command register needs some locking on SMP systems */
+
+#ifdef CONFIG_SMP
+
+	unsigned long flags;
+
+	spin_lock_irqsave(&priv->cmdreg_lock, flags);
+	priv->write_reg(priv, REG_CMR, val);
+	priv->read_reg(priv, REG_SR);
+	spin_unlock_irqrestore(&priv->cmdreg_lock, flags);
+
+#else
+
+	/* write to the command register without locking */
+	priv->write_reg(priv, REG_CMR, val);
+
+#endif
+}
+
 static int sja1000_probe_chip(struct net_device *dev)
 {
 	struct sja1000_priv *priv = netdev_priv(dev);
@@ -297,7 +318,7 @@ static netdev_tx_t sja1000_start_xmit(struct sk_buff *skb,
 
 	can_put_echo_skb(skb, dev, 0);
 
-	priv->write_reg(priv, REG_CMR, CMD_TR);
+	sja1000_write_cmdreg(priv, CMD_TR);
 
 	return NETDEV_TX_OK;
 }
@@ -346,7 +367,7 @@ static void sja1000_rx(struct net_device *dev)
 	cf->can_id = id;
 
 	/* release receive buffer */
-	priv->write_reg(priv, REG_CMR, CMD_RRB);
+	sja1000_write_cmdreg(priv, CMD_RRB);
 
 	netif_rx(skb);
 
@@ -374,7 +395,7 @@ static int sja1000_err(struct net_device *dev, uint8_t isrc, uint8_t status)
 		cf->data[1] = CAN_ERR_CRTL_RX_OVERFLOW;
 		stats->rx_over_errors++;
 		stats->rx_errors++;
-		priv->write_reg(priv, REG_CMR, CMD_CDO);	/* clear bit */
+		sja1000_write_cmdreg(priv, CMD_CDO);	/* clear bit */
 	}
 
 	if (isrc & IRQ_EI) {
diff --git a/drivers/net/can/sja1000/sja1000.h b/drivers/net/can/sja1000/sja1000.h
index 97a622b..4527d95 100644
--- a/drivers/net/can/sja1000/sja1000.h
+++ b/drivers/net/can/sja1000/sja1000.h
@@ -168,6 +168,10 @@ struct sja1000_priv {
 	void __iomem *reg_base;	 /* ioremap'ed address to registers */
 	unsigned long irq_flags; /* for request_irq() */
 
+#ifdef CONFIG_SMP
+	spinlock_t cmdreg_lock; /* lock for concurrent cmd register writes */
+#endif
+
 	u16 flags;		/* custom mode flags */
 	u8 ocr;			/* output control register */
 	u8 cdr;			/* clock divider register */

^ permalink raw reply related

* Re: [PATCH] phy/marvell: Add special settings for D-Link DNS-323 rev C1
From: Benjamin Herrenschmidt @ 2010-05-17 11:36 UTC (permalink / raw)
  To: Wolfram Sang
  Cc: netdev, Nicolas Pitre, linux-arm-kernel, Herbert Valerio Riedel
In-Reply-To: <1274058457.21352.711.camel@pasglop>

On Mon, 2010-05-17 at 11:07 +1000, Benjamin Herrenschmidt wrote:
> On Mon, 2010-05-17 at 02:59 +0200, Wolfram Sang wrote:
> > There is a fixup()-callback to prevent boardcode in the drivers. See
> > Documentation/networking/phy.txt, last chapter.
> 
> Ah nice ! I missed that bit. I'll add a fixup and see if it works.
> 
> The problem is that writing to this register seems to be part of a
> specific initialization sequence, which is done one way in the linux
> driver and differently in the vendor kernel. I don't know whether
> I can just 'override' the value and I have no docs for that part.
> 
> But I'll definitely give it a go tonight.

Ok, that doesn't work.

The problem is that the fixups are called -after- the config_init()
callback of the PHY driver. However, the marvell m88e1118 PHY driver
will unconditionally reset the LEDs setting.

So either we add a layer of PHY fixups to run after init, or I replace
the init completely in my fixup routine. A way to do that would be to do
a small change to allow the fixup code to request the core to skip
config_init().

Something along those lines:

net/phy: Allow platform fixups to completely override the PHY init routine

The fixups are called before the PHY init routine. In some case, that
means that whatever LEDs setup they attempt to do is undone by the said
initialization code.

This patch allows to work around it by enabling the fixups to return the
positive PHY_FIXUP_SKIP_INIT result code, which will cause the core to
skip the normal init routine.

Using this, a platform fixup can effectively replace the entire init
routine for a given PHY.

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
--- 

(untested btw)

diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
index 64be466..48436e6 100644
--- a/drivers/net/phy/phy.c
+++ b/drivers/net/phy/phy.c
@@ -353,10 +353,9 @@ int phy_mii_ioctl(struct phy_device *phydev,
 		phy_write(phydev, mii_data->reg_num, val);
 		
 		if (mii_data->reg_num == MII_BMCR &&
-		    val & BMCR_RESET &&
-		    phydev->drv->config_init) {
-			phy_scan_fixups(phydev);
-			phydev->drv->config_init(phydev);
+		    val & BMCR_RESET && phydev->drv->config_init) {
+			if (phy_scan_fixups(phydev) != PHY_FIXUP_SKIP_INIT)
+				phydev->drv->config_init(phydev);
 		}
 		break;
 
diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
index db17945..44ab890 100644
--- a/drivers/net/phy/phy_device.c
+++ b/drivers/net/phy/phy_device.c
@@ -126,6 +126,7 @@ static int phy_needs_fixup(struct phy_device *phydev, struct phy_fixup *fixup)
 int phy_scan_fixups(struct phy_device *phydev)
 {
 	struct phy_fixup *fixup;
+	int rc = 0;
 
 	mutex_lock(&phy_fixup_lock);
 	list_for_each_entry(fixup, &phy_fixup_list, list) {
@@ -138,11 +139,13 @@ int phy_scan_fixups(struct phy_device *phydev)
 				mutex_unlock(&phy_fixup_lock);
 				return err;
 			}
+			if (err == PHY_FIXUP_SKIP_INIT)
+				rc = err;
 		}
 	}
 	mutex_unlock(&phy_fixup_lock);
 
-	return 0;
+	return rc;
 }
 EXPORT_SYMBOL(phy_scan_fixups);
 
@@ -405,6 +408,8 @@ int phy_init_hw(struct phy_device *phydev)
 	ret = phy_scan_fixups(phydev);
 	if (ret < 0)
 		return ret;
+	if (ret == PHY_FIXUP_SKIP_INIT)
+		return 0;
 
 	return phydev->drv->config_init(phydev);
 }
diff --git a/include/linux/phy.h b/include/linux/phy.h
index 14d7fdf..5e2b026 100644
--- a/include/linux/phy.h
+++ b/include/linux/phy.h
@@ -413,6 +413,12 @@ struct phy_fixup {
 	int (*run)(struct phy_device *phydev);
 };
 
+/* The fixup can return this to skip the PHY driver init routine
+ * (ie. the fixup effectively replaces the init routine)
+ */
+#define PHY_FIXUP_SKIP_INIT	1
+
+
 /**
  * phy_read - Convenience function for reading a given PHY register
  * @phydev: the phy_device struct

^ permalink raw reply related

* Re: [PATCH] phy/marvell: Add special settings for D-Link DNS-323 rev C1
From: Wolfram Sang @ 2010-05-17 12:00 UTC (permalink / raw)
  To: Benjamin Herrenschmidt
  Cc: netdev, Nicolas Pitre, linux-arm-kernel, Herbert Valerio Riedel
In-Reply-To: <1274096214.21352.735.camel@pasglop>

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


> The problem is that the fixups are called -after- the config_init()
> callback of the PHY driver. However, the marvell m88e1118 PHY driver
> will unconditionally reset the LEDs setting.

Haven't checked, just an idea: Is it possible to change the init of the driver
to use Read-Modify-Write and thus keep your settings?

-- 
Pengutronix e.K.                           | Wolfram Sang                |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 197 bytes --]

^ permalink raw reply

* Re: [PATCH] phy/marvell: Add special settings for D-Link DNS-323 rev C1
From: Benjamin Herrenschmidt @ 2010-05-17 12:08 UTC (permalink / raw)
  To: Wolfram Sang
  Cc: netdev, Nicolas Pitre, linux-arm-kernel, Herbert Valerio Riedel
In-Reply-To: <20100517120032.GI22781@pengutronix.de>

On Mon, 2010-05-17 at 14:00 +0200, Wolfram Sang wrote:
> > The problem is that the fixups are called -after- the config_init()
> > callback of the PHY driver. However, the marvell m88e1118 PHY driver
> > will unconditionally reset the LEDs setting.
> 
> Haven't checked, just an idea: Is it possible to change the init of
> the driver to use Read-Modify-Write and thus keep your settings?

Well, the driver just unconditionally blasts the whole register and
the value I want to put there is also a "raw" value of the whole
register based on what the vendor code puts in there (in their old
2.6.12 based port).

So with only that at hand and no documentation for the actual PHY chip,
I don't see a simple solution here.

Cheers,
Ben.

^ permalink raw reply

* [PATCH BUGFIX ] ipv6: fix the bug of address check
From: Shan Wei @ 2010-05-17 12:23 UTC (permalink / raw)
  To: David Miller, Stephen Hemminger; +Cc: netdev@vger.kernel.org


If there are several IPv6 addresses with same hash value in hashlist,
and they are all not matched with addr argument.
In this case, ipv6_chk_addr() should return 0.

This bug is introduced by commit c2e21293c054817c42eb5fa9c613d2ad51954136
(title: ipv6: convert addrconf list to hlist).

Signed-off-by: Shan Wei <shanwei@cn.fujitsu.com>
---
 net/ipv6/addrconf.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index 3984f52..d8e5907 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -1291,7 +1291,7 @@ int ipv6_chk_addr(struct net *net, struct in6_addr *addr,
 	}
 	rcu_read_unlock_bh();
 
-	return ifp != NULL;
+	return node != NULL;
 }
 EXPORT_SYMBOL(ipv6_chk_addr);
 
-- 
1.6.3.3

^ permalink raw reply related

* [PATCH resend] bnx2x: avoid TX timeout when stopping device
From: Stanislaw Gruszka @ 2010-05-17 12:34 UTC (permalink / raw)
  To: David Miller
  Cc: netdev, Eilon Greenstein, Vladislav Zolotarov, Dmitry Kravkov

When stop device call netif_carrier_off() just after disabling TX queue to
avoid possibility of netdev watchdog warning and ->ndo_tx_timeout() invocation.

Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
Acked-by: Eilon Greenstein <eilong@broadcom.com>
---
 drivers/net/bnx2x_main.c |    6 ++----
 1 files changed, 2 insertions(+), 4 deletions(-)

diff --git a/drivers/net/bnx2x_main.c b/drivers/net/bnx2x_main.c
index 2bc35c7..57ff5b3 100644
--- a/drivers/net/bnx2x_main.c
+++ b/drivers/net/bnx2x_main.c
@@ -8499,6 +8499,7 @@ static int bnx2x_nic_unload(struct bnx2x *bp, int unload_mode)
 
 	/* Disable HW interrupts, NAPI and Tx */
 	bnx2x_netif_stop(bp, 1);
+	netif_carrier_off(bp->dev);
 
 	del_timer_sync(&bp->timer);
 	SHMEM_WR(bp, func_mb[BP_FUNC(bp)].drv_pulse_mb,
@@ -8524,8 +8525,6 @@ static int bnx2x_nic_unload(struct bnx2x *bp, int unload_mode)
 
 	bp->state = BNX2X_STATE_CLOSED;
 
-	netif_carrier_off(bp->dev);
-
 	/* The last driver must disable a "close the gate" if there is no
 	 * parity attention or "process kill" pending.
 	 */
@@ -13431,6 +13430,7 @@ static int bnx2x_eeh_nic_unload(struct bnx2x *bp)
 	bp->rx_mode = BNX2X_RX_MODE_NONE;
 
 	bnx2x_netif_stop(bp, 0);
+	netif_carrier_off(bp->dev);
 
 	del_timer_sync(&bp->timer);
 	bp->stats_state = STATS_STATE_DISABLED;
@@ -13457,8 +13457,6 @@ static int bnx2x_eeh_nic_unload(struct bnx2x *bp)
 
 	bp->state = BNX2X_STATE_CLOSED;
 
-	netif_carrier_off(bp->dev);
-
 	return 0;
 }
 
-- 
1.5.5.6


^ permalink raw reply related

* Re: [RFC] NF: IP tables idletimer target implementation
From: Luciano Coelho @ 2010-05-17 13:09 UTC (permalink / raw)
  To: ext Patrick McHardy
  Cc: netdev@vger.kernel.org, Timo Teras,
	Netfilter Development Mailinglist
In-Reply-To: <4BED744D.3040400@trash.net>

Hi,

Thanks for your review.  I'll make the changes you proposed and
resubmit.  My comments below.

On Fri, 2010-05-14 at 18:03 +0200, ext Patrick McHardy wrote:
> Please CC netfilter-devel on future submissions.

Sure, I'm sorry that I didn't do that to start with.  I searched for
net/ipv4/netfilter in the MAINTAINERS file and missed the
net/*/netfilter.


> Luciano Coelho wrote:
> > It adds a file to the sysfs for each interface that is brought up.  The file
> > contains the time remaining before the event is triggered.  This file can
> > also be used to set the timer manually.
> 
> What is this used for? It doesn't seem to smart to poll manually
> if you get an event anyways, and the timeout can already be set
> per rule.

Yes, that's true.  We have some weird things happening in our userspace
and, as you mentioned below, we should probably create the timers when
the rules are set.  I'll look into this and fix it, which will require
some discussions with the userspace people.


> > diff --git a/net/ipv4/netfilter/Kconfig b/net/ipv4/netfilter/Kconfig
> > index 1833bdb..91fba9a 100644
> > --- a/net/ipv4/netfilter/Kconfig
> > +++ b/net/ipv4/netfilter/Kconfig
> > @@ -204,6 +204,23 @@ config IP_NF_TARGET_REDIRECT
> >  
> >  	  To compile it as a module, choose M here.  If unsure, say N.
> >  
> > +config IP_NF_TARGET_IDLETIMER
> 
> This should be a x_tables target, there's nothing IPv4-specific
> about it.

Yeps, I'll fix.


> > diff --git a/net/ipv4/netfilter/ipt_IDLETIMER.c b/net/ipv4/netfilter/ipt_IDLETIMER.c
> > new file mode 100644
> > index 0000000..2c5b465
> > --- /dev/null
> > +++ b/net/ipv4/netfilter/ipt_IDLETIMER.c
> 
> > +
> > +#ifdef CONFIG_IP_NF_TARGET_IDLETIMER_DEBUG
> > +#define DEBUGP(format, args...) printk(KERN_DEBUG \
> > +				       "ipt_IDLETIMER:%s:" format "\n", \
> > +				       __func__ , ## args)
> > +#else
> > +#define DEBUGP(format, args...)
> > +#endif
> 
> Please use pr_debug and get rid of the config option.

I'll fix it.  I thought it was odd that only this module had a debug
config flag, there would certainly be a reason for it.


> > +
> > +/*
> > + * Internal timer management.
> > + */
> > +static ssize_t utimer_attr_show(struct device *dev,
> > +				struct device_attribute *attr, char *buf);
> > +static ssize_t utimer_attr_store(struct device *dev,
> > +				 struct device_attribute *attr,
> > +				 const char *buf, size_t count);
> > +
> > +struct utimer_t {
> > +	char name[IFNAMSIZ];
> > +	struct list_head entry;
> > +	struct timer_list timer;
> > +	struct work_struct work;
> > +	struct net *net;
> > +};
> > +
> > +static LIST_HEAD(active_utimer_head);
> > +static DEFINE_SPINLOCK(list_lock);
> > +static DEVICE_ATTR(idletimer, 0644, utimer_attr_show, utimer_attr_store);
> > +
> > +static void utimer_delete(struct utimer_t *timer)
> > +{
> > +	DEBUGP("Deleting timer '%s'\n", timer->name);
> > +
> > +	list_del(&timer->entry);
> > +	del_timer_sync(&timer->timer);
> > +	put_net(timer->net);
> > +	kfree(timer);
> > +}
> > +
> > +static void utimer_work(struct work_struct *work)
> > +{
> > +	struct utimer_t *timer = container_of(work, struct utimer_t, work);
> > +	struct net_device *netdev = NULL;
> 
> Unnecessary initialization.

I'll remove it.  My code was slightly different before this version and,
in that case, it required the initialization here.


> > +
> > +	netdev = dev_get_by_name(timer->net, timer->name);
> > +
> > +	if (netdev != NULL) {
> > +		sysfs_notify(&netdev->dev.kobj, NULL,
> > +			     "idletimer");
> > +		dev_put(netdev);
> > +	}
> > +}
> > +
> > +static void utimer_expired(unsigned long data)
> > +{
> > +	struct utimer_t *timer = (struct utimer_t *) data;
> > +
> > +	DEBUGP("Timer '%s' expired\n", timer->name);
> > +
> > +	spin_lock_bh(&list_lock);
> > +	utimer_delete(timer);
> > +	spin_unlock_bh(&list_lock);
> > +
> > +	schedule_work(&timer->work);
> 
> Use after free, utimer_delete() frees the timer.

Indeed! Thanks for pointint it out! I'll fix it.


> > +}
> > +
> > +static struct utimer_t *utimer_create(const char *name,
> > +				      struct net *net)
> > +{
> > +	struct utimer_t *timer;
> > +
> > +	timer = kmalloc(sizeof(struct utimer_t), GFP_ATOMIC);
> > +	if (timer == NULL)
> > +		return NULL;
> > +
> > +	list_add(&timer->entry, &active_utimer_head);
> > +	strlcpy(timer->name, name, sizeof(timer->name));
> > +	timer->net = get_net(net);
> 
> How does this handle namespace exit?

Hmmm... very good point.  I'll have to investigate and fix this.


> > +
> > +	init_timer(&timer->timer);
> > +	timer->timer.function = utimer_expired;
> > +	timer->timer.data = (unsigned long) timer;
> 
> setup_timer()

Yup.


> > +
> > +	INIT_WORK(&timer->work, utimer_work);
> > +
> > +	DEBUGP("Created timer '%s'\n", timer->name);
> > +
> > +	return timer;
> > +}
> > +
> > +static struct utimer_t *__utimer_find(const char *name, const struct net *net)
> > +{
> > +	struct utimer_t *entry;
> > +
> > +	list_for_each_entry(entry, &active_utimer_head, entry) {
> > +		if (!strcmp(name, entry->name) && net == entry->net)
> > +			return entry;
> > +	}
> > +
> > +	return NULL;
> > +}
> > +
> > +static void utimer_modify(const char *name,
> > +			  struct net *net,
> > +			  unsigned long expires)
> > +{
> > +	struct utimer_t *timer;
> > +
> > +	DEBUGP("Modifying timer '%s'\n", name);
> > +	spin_lock_bh(&list_lock);
> > +	timer = __utimer_find(name, net);
> 
> So you're scanning the list up to twice per packet? That seems
> highly suboptimal, why not create the timer when the rule is
> created and only update the timeout? You could use the interfaces
> specified in struct ipt_ip.

Yes, indeed.  This is very suboptimal.  I'll try to fix it at the same
time when trying to get rid of the reading/writing to the sysfs file (as
per your second comment above).


> > +	if (timer == NULL)
> > +		timer = utimer_create(name, net);
> > +	mod_timer(&timer->timer, expires);
> > +	spin_unlock_bh(&list_lock);
> > +}
> > +
> > +static ssize_t utimer_attr_show(struct device *dev,
> > +				struct device_attribute *attr, char *buf)
> > +{
> > +	struct utimer_t *timer;
> > +	struct net_device *netdev = to_net_dev(dev);
> > +	unsigned long expires = 0;
> > +
> > +	spin_lock_bh(&list_lock);
> > +	timer = __utimer_find(netdev->name, dev_net(netdev));
> > +	if (timer)
> > +		expires = timer->timer.expires;
> > +	spin_unlock_bh(&list_lock);
> > +
> > +	if (expires)
> > +		return sprintf(buf, "%lu\n", (expires-jiffies) / HZ);
> > +
> > +	return sprintf(buf, "0\n");
> > +}
> > +
> > +static ssize_t utimer_attr_store(struct device *dev,
> > +				 struct device_attribute *attr,
> > +				 const char *buf, size_t count)
> > +{
> > +	int expires;
> > +	struct net_device *netdev = to_net_dev(dev);
> > +
> > +	if (sscanf(buf, "%d", &expires) == 1) {
> > +		if (expires > 0)
> 
> Using %u seems better.

Right.  Will fix.


> > +			utimer_modify(netdev->name,
> > +				      dev_net(netdev),
> > +				      jiffies+HZ*(unsigned long)expires);
> > +	}
> > +
> > +	return count;
> > +}
> > +
> > +static int utimer_notifier_call(struct notifier_block *this,
> > +				unsigned long event, void *ptr)
> > +{
> > +	struct net_device *netdev = ptr;
> > +	int ret;
> > +
> > +	switch (event) {
> > +	case NETDEV_UP:
> > +		DEBUGP("NETDEV_UP: %s\n", netdev->name);
> > +		ret = device_create_file(&netdev->dev,
> > +					 &dev_attr_idletimer);
> > +		WARN_ON(ret);
> > +
> > +		break;
> > +	case NETDEV_DOWN:
> > +		DEBUGP("NETDEV_DOWN: %s\n", netdev->name);
> > +		device_remove_file(&netdev->dev,
> > +				   &dev_attr_idletimer);
> > +		break;
> > +	}
> > +
> > +	return NOTIFY_DONE;
> > +}
> > +
> > +static struct notifier_block utimer_notifier_block = {
> > +	.notifier_call	= utimer_notifier_call,
> > +};
> > +
> > +
> > +static int utimer_init(void)
> > +{
> > +	return register_netdevice_notifier(&utimer_notifier_block);
> > +}
> > +
> > +static void utimer_fini(void)
> > +{
> > +	struct utimer_t *entry, *next;
> > +	struct net_device *dev;
> > +	struct net *net;
> > +
> > +	list_for_each_entry_safe(entry, next, &active_utimer_head, entry)
> > +		utimer_delete(entry);
> > +
> > +	rtnl_lock();
> 
> deadlock? unregister_netdevice_notifier() already takes the RTNL.

Ugh! How come I didn't notice this before? I'll fix it.


> > +	unregister_netdevice_notifier(&utimer_notifier_block);
> > +	for_each_net(net) {
> > +		for_each_netdev(net, dev) {
> > +			utimer_notifier_call(&utimer_notifier_block,
> > +					     NETDEV_DOWN, dev);
> > +		}
> > +	}
> > +	rtnl_unlock();
> > +}
> > +
> > +/*
> > + * The actual iptables plugin.
> > + */
> > +static unsigned int ipt_idletimer_target(struct sk_buff *skb,
> > +					 const struct xt_action_param *par)
> > +{
> > +	const struct ipt_idletimer_info *target = par->targinfo;
> > +	unsigned long expires;
> > +
> > +	expires = jiffies + HZ*target->timeout;
> > +
> > +	if (par->in != NULL)
> > +		utimer_modify(par->in->name,
> > +			      dev_net(par->in),
> > +			      expires);
> > +
> > +	if (par->out != NULL)
> > +		utimer_modify(par->out->name,
> > +			      dev_net(par->out),
> > +			      expires);
> > +
> > +	return XT_CONTINUE;
> > +}
> > +
> > +static int ipt_idletimer_checkentry(const struct xt_tgchk_param *par)
> > +{
> > +	const struct ipt_idletimer_info *info = par->targinfo;
> > +
> > +	if (info->timeout == 0) {
> > +		DEBUGP("timeout value is zero\n");
> > +		return false;
> > +	}
> > +
> > +	return true;
> 
> The return convention in the current net-next tree is 0 for
> no error or an errno code otherwise.

Yes, this seems to have been changing back and forth in the latest
releases.  And the description in the x_targets.h header file seems to
be wrong:

/* Registration hooks for targets. */
struct xt_target {
[...]
	/* Called when user tries to insert an entry of this type:
           hook_mask is a bitmask of hooks from which it can be
           called. */
	/* Should return true or false, or an error code (-Exxxx). */
	int (*checkentry)(const struct xt_tgchk_param *);
[...]
};

Instead of "Should return true or false..." I guess it should read
something like "Should return 0 for success or an error code otherwise".
I'll submit a patch to fix that.


-- 
Cheers,
Luca.


^ permalink raw reply

* [PATCH] vhost: Storage class should be before const qualifier
From: Tobias Klauser @ 2010-05-17 13:12 UTC (permalink / raw)
  To: mst; +Cc: kvm, virtualization, netdev, Tobias Klauser

The C99 specification states in section 6.11.5:

The placement of a storage-class specifier other than at the beginning
of the declaration specifiers in a declaration is an obsolescent
feature.

Signed-off-by: Tobias Klauser <tklauser@distanz.ch>
---
 drivers/vhost/net.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c
index aa88911..cd36f5f 100644
--- a/drivers/vhost/net.c
+++ b/drivers/vhost/net.c
@@ -626,7 +626,7 @@ static long vhost_net_compat_ioctl(struct file *f, unsigned int ioctl,
 }
 #endif
 
-const static struct file_operations vhost_net_fops = {
+static const struct file_operations vhost_net_fops = {
 	.owner          = THIS_MODULE,
 	.release        = vhost_net_release,
 	.unlocked_ioctl = vhost_net_ioctl,
-- 
1.6.3.3


^ permalink raw reply related

* Re: [PATCH] vhost: Storage class should be before const qualifier
From: Michael S. Tsirkin @ 2010-05-17 13:13 UTC (permalink / raw)
  To: Tobias Klauser; +Cc: kvm, virtualization, netdev
In-Reply-To: <1274101969-21109-1-git-send-email-tklauser@distanz.ch>

On Mon, May 17, 2010 at 03:12:49PM +0200, Tobias Klauser wrote:
> The C99 specification states in section 6.11.5:
> 
> The placement of a storage-class specifier other than at the beginning
> of the declaration specifiers in a declaration is an obsolescent
> feature.
> 
> Signed-off-by: Tobias Klauser <tklauser@distanz.ch>


Will apply, thanks!
Just to clarify: does some compiler/checker actually barf on this?

> ---
>  drivers/vhost/net.c |    2 +-
>  1 files changed, 1 insertions(+), 1 deletions(-)
> 
> diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c
> index aa88911..cd36f5f 100644
> --- a/drivers/vhost/net.c
> +++ b/drivers/vhost/net.c
> @@ -626,7 +626,7 @@ static long vhost_net_compat_ioctl(struct file *f, unsigned int ioctl,
>  }
>  #endif
>  
> -const static struct file_operations vhost_net_fops = {
> +static const struct file_operations vhost_net_fops = {
>  	.owner          = THIS_MODULE,
>  	.release        = vhost_net_release,
>  	.unlocked_ioctl = vhost_net_ioctl,
> -- 
> 1.6.3.3

^ permalink raw reply

* Re: [PATCH] vhost: Storage class should be before const qualifier
From: Tobias Klauser @ 2010-05-17 13:27 UTC (permalink / raw)
  To: Michael S. Tsirkin; +Cc: kvm, virtualization, netdev
In-Reply-To: <20100517131335.GA12126@redhat.com>

On 2010-05-17 at 15:13:35 +0200, Michael S. Tsirkin <mst@redhat.com> wrote:
> On Mon, May 17, 2010 at 03:12:49PM +0200, Tobias Klauser wrote:
> > The C99 specification states in section 6.11.5:
> > 
> > The placement of a storage-class specifier other than at the beginning
> > of the declaration specifiers in a declaration is an obsolescent
> > feature.
> > 
> > Signed-off-by: Tobias Klauser <tklauser@distanz.ch>
> 
> 
> Will apply, thanks!
> Just to clarify: does some compiler/checker actually barf on this?

GCC does emit a warning if the options '-std=c99 -W -Wall' are present.
ICC also does warn about this, though I don't know whether this depends
on any commandline options.

Cheers
Tobias

^ permalink raw reply

* [PATCH net-next-2.6] bonding: remove unused variable "found"
From: Jiri Pirko @ 2010-05-17 13:49 UTC (permalink / raw)
  To: netdev; +Cc: davem


Signed-off-by: Jiri Pirko <jpirko@redhat.com>

diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c
index b8bec08..392e291 100644
--- a/drivers/net/bonding/bond_sysfs.c
+++ b/drivers/net/bonding/bond_sysfs.c
@@ -219,7 +219,7 @@ static ssize_t bonding_store_slaves(struct device *d,
 {
 	char command[IFNAMSIZ + 1] = { 0, };
 	char *ifname;
-	int i, res, found, ret = count;
+	int i, res, ret = count;
 	u32 original_mtu;
 	struct slave *slave;
 	struct net_device *dev = NULL;
@@ -245,7 +245,6 @@ static ssize_t bonding_store_slaves(struct device *d,
 	if (command[0] == '+') {
 
 		/* Got a slave name in ifname.  Is it already in the list? */
-		found = 0;
 
 		dev = __dev_get_by_name(dev_net(bond->dev), ifname);
 		if (!dev) {

^ permalink raw reply related


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