Netdev List
 help / color / mirror / Atom feed
* Re: [PATCH] socketcan: add a driver for FlexCAN controllers.
From: Wolfgang Grandegger @ 2010-06-18 11:04 UTC (permalink / raw)
  To: Marc Kleine-Budde
  Cc: socketcan-core-0fE9KPoRgkgATYTw5x5z8w,
	netdev-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <4C1B4DF0.2090103-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>

On 06/18/2010 12:44 PM, Marc Kleine-Budde wrote:
> Wolfgang Grandegger wrote:
>> On 06/18/2010 12:16 PM, Marc Kleine-Budde wrote:
>>> Wolfgang Grandegger wrote:
>>>> Hi Hans-Jürgen,
>>>>
>>>> On 06/17/2010 12:52 PM, Hans J. Koch wrote:
>>>>> This adds a driver for FlexCAN based CAN controllers,
>>>>> e.g. found in Freescale i.MX35 SoCs.
>>>>>
>>>>> The original version of this driver was posted by Sascha Hauer in July 2009:
>>>>> http://kerneltrap.org/mailarchive/linux-netdev/2009/7/29/6251621
>>>>>
>>>>> I took this version, added NAPI support, and fixed some problems found
>>>>> during testing. Well, here is the result. Please review.
>>>> I briefly browsed the patch and various bits and pieces are missing or
>>>> not correctly implemented. Marc already pointed out a few of them:
>>>>
>>>> - I do not find can_put/get_echo_skb functions in the code. How is
>>>>   IFF_ECHO supposed to work?
>>> the driver uses hardware loopback
>>
>> OK, then
>>
>>   dev = alloc_candev(sizeof(struct flexcan_priv), 0);
>>
>> should be used (and TX_ECHO_SKB_MAX removed) in Hans-Jürgens driver.
>>
>>>> - Support for CAN_CTRLMODE_BERR_REPORTING and do_get_berr_counter()
>>>>   seems to be missing.
>>>>
>>>> - Make use of alloc_can_skb() and alloc_can_err_skb().
>>> the last two points are already addressed in my version of the driver.
>>
>> I do not see support for CAN_CTRLMODE_BERR_REPORTING in your driver
>> (which has nothing to do with do_get_berr_counter).
> 
> oh yes...sorry, got confused.
> 
> However I implemented CAN_CTRLMODE_BERR_REPORTING, i.e. turning of the
> bit error interrupts by default. This has the effect that no bus warning
> and bus passive interrupt was signalled.
> 
> I should add a comment to my driver.

I'm confused, CAN_CTRLMODE_BERR_REPORTING means that the user can enable
bus error reporting, which seems not be handled in the driver your sent.
See:

http://lxr.linux.no/linux/drivers/net/can/sja1000/sja1000.c#L134
http://lxr.linux.no/linux/drivers/net/can/sja1000/sja1000.c#L588

Wolfgang.

^ permalink raw reply

* Re: Distributed Switch Architecture(DSA)
From: Joakim Tjernlund @ 2010-06-18 11:09 UTC (permalink / raw)
  To: Lennert Buytenhek; +Cc: netdev
In-Reply-To: <20100618095923.GC14513@mail.wantstofly.org>

Lennert Buytenhek <buytenh@wantstofly.org> wrote on 2010/06/18 11:59:23:
>
> On Fri, Jun 18, 2010 at 11:15:09AM +0200, Joakim Tjernlund wrote:
>
> > > > I am trying to wrap my head around DSA and I need some help.
> > > >
> > > > Assume the example from Lennert:
> > > >
> > > >        +-----------+       +-----------+
> > > >        |           | RGMII |           |
> > > >        |           +-------+           +------ 1000baseT MDI ("WAN")
> > > >        |           |       |  6-port   +------ 1000baseT MDI ("LAN1")
> > > >        |    CPU    |       |  ethernet +------ 1000baseT MDI ("LAN2")
> > > >        |           |MIImgmt|  switch   +------ 1000baseT MDI ("LAN3")
> > > >        |           +-------+  w/5 PHYs +------ 1000baseT MDI ("LAN4")
> > > >        |           |       |           |
> > > >        +-----------+       +-----------+
> > > >
> > > > If I understand this correctly I get at least 5 virtual I/Fs corresponding
> > > > to WAN, LAN1-4, but how is the RGMII I/F modelled?
> > >
> > > The RGMII interface is just the interface that your "real" network
> > > driver exports.  In the case of the Kirkwood 6281 A0 Reference Design
> > > (which I developed this code on), that would be eth0.  After the DSA
> > > driver is instantiated, you don't send or receive over eth0 directly
> > > anymore -- eth0 becomes purely a transport for DSA-tagged packets.
> >
> > hmm, but how do I send normal pkgs form the CPU to the switch then?
>
> Define what you mean by 'normal pkgs'.

An ethernet broadcast pkg flooded onto all ports.
A normal ethernet host DST address would be looked up by
the switch HW and sent to the appropriate port.

>
>
> > I envision I would get some interface in the CPU I can set an IP address
> > on and use as a normal I/F which would be switched by the HW switch to
> > the appropriate port.
>
> Yes, these are the DSA/slave interfaces created by net/dsa/slave.c.
> You are free to attach IP addresses to the wan/lanX interfaces, and
> things will work as you'd expect them to.

Not sure what to expect here actually.

>
>
> > > > I guess I will have one "real" ethX I/F which maps to RGMII but do I
> > > > get one virtual I/F too?
> > >
> > > You get a virtual interface for each of the ports on the switch (that
> > > are not CPU or inter-switch ports), i.e. all ports on the right of the
> > > diagram -- wan, lan1, lan2, lan3, lan4.  These interfaces are created
> > > by net/dsa/slave.c and are called DSA interfaces or slave interfaces.
> > >
> > >
> > > > What use are these virtual I/Fs? Just to read status from the
> > > > corresponding ports?
> > >
> > > That's one of the purposes, yes.  There's a polling routine that
> > > periodically checks the status of each of the ports on the switch (via
> > > the MII management interface) and feeds back that status to the virtual
> > > interfaces.  I.e. if you plug a cable into lan3, you'll see a syslog
> > > message about the link on the virtual interface lan3 having come up,
> > > with the link speed, etc.
> > >
> > >
> > > > Can one TX and RX network pkgs over these I/Fs too?
> > >
> > > Sure -- that's the whole point.
> >
> > TX:ing pkgs on such virtual I/F would go directly to the port, bypassing
> > normal switching?
>
> Define what you mean by 'normal switching'.
>
>
> > What about RX? What decides which pkg to route through the switch and
> > which pgk to send up to the virtual I/F?
>
> By default, which is until you enable bridging on some subset of the
> ports, all ports have their own address database, and all received
> packets are passed directly up to the CPU, where the DSA code will
> then make those packets be received on the DSA slave interfaces.

ah, so until I enable bridging, all ports are viewed as a separate
network I/F?
Once I create a linux bridge device and add the virtual I/Fs, one
enables the bridge function.
One drawback with that is that you kill the bridge when you reboot
linux.

>
>
> > > > Now I want to add STP/RSTP to the switch. How would one do that?
> > >
> > > First, you'll want the hardware bridging patches that I posted to
> > > netdev@ a while back, e.g.:
> > >
> > >    http://patchwork.ozlabs.org/patch/16578/
> >
> > I see, will have to study this a bit closer. One question though,
> > does this disable MAC learning in the linux bridge?
>
> No, why should it?

Doesn't the HW switch handle all MAC leaning? Why duplicate
this in the SW bridge?
I figured the HW switch would offload the SW bridge this task.

>
>
> > Do you have any idea how to do DSA on a Broadcom switch?
>
> I have no idea.  When I originally submitted the DSA code for merging,
> I contacted Broadcom people about adding support for Broadcom switch
> chips to it, but I never heard back from them.

OK. With DSA, how does one configure VLANs, policing and parameters in the
HW switch that don't map or exist in the linux bridge?

 Jocke


^ permalink raw reply

* Re: [v3 Patch 2/2] mlx4: add dynamic LRO disable support
From: Stanislaw Gruszka @ 2010-06-18 11:09 UTC (permalink / raw)
  To: Amerigo Wang
  Cc: netdev, nhorman, herbert.xu, bhutchings, Ramkrishna.Vepa, davem
In-Reply-To: <20100618105945.6496.67648.sendpatchset@localhost.localdomain>

On Fri, Jun 18, 2010 at 06:55:38AM -0400, Amerigo Wang wrote:
> +static int mlx4_ethtool_op_set_flags(struct net_device *dev, u32 data)
> +{
> +	struct mlx4_en_priv *priv = netdev_priv(dev);
> +	struct mlx4_en_dev *mdev = priv->mdev;
> +	int rc = 0;
> +	int changed = 0;
> +
> +	if (data & (ETH_FLAG_NTUPLE | ETH_FLAG_RXHASH))
> +		return -EOPNOTSUPP;
> +
> +	if (data & ETH_FLAG_LRO) {
> +		if (!(dev->features & NETIF_F_LRO))
> +			changed = 1;
> +	} else if (dev->features & NETIF_F_LRO) {
> +		changed = 1;
> +		mdev->profile.num_lro = 0;

Everything fine except that, what for you zero num_lro value?

If we set it to zero it will stay zero and we will not create
proper number of lro descriptors in mlx4_en_create_rx_ring()
(called from mlx4_en_set_ringparam() ->  mlx4_en_alloc_resources())
when someone enable LRO again on.

Stanislaw

^ permalink raw reply

* Re: [PATCH] socketcan: add a driver for FlexCAN controllers.
From: Marc Kleine-Budde @ 2010-06-18 11:21 UTC (permalink / raw)
  To: Wolfgang Grandegger
  Cc: socketcan-core-0fE9KPoRgkgATYTw5x5z8w,
	netdev-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <4C1B52A7.3060607-5Yr1BZd7O62+XT7JhA+gdA@public.gmane.org>


[-- Attachment #1.1: Type: text/plain, Size: 2970 bytes --]

Wolfgang Grandegger wrote:
> On 06/18/2010 12:44 PM, Marc Kleine-Budde wrote:
>> Wolfgang Grandegger wrote:
>>> On 06/18/2010 12:16 PM, Marc Kleine-Budde wrote:
>>>> Wolfgang Grandegger wrote:
>>>>> Hi Hans-Jürgen,
>>>>>
>>>>> On 06/17/2010 12:52 PM, Hans J. Koch wrote:
>>>>>> This adds a driver for FlexCAN based CAN controllers,
>>>>>> e.g. found in Freescale i.MX35 SoCs.
>>>>>>
>>>>>> The original version of this driver was posted by Sascha Hauer in July 2009:
>>>>>> http://kerneltrap.org/mailarchive/linux-netdev/2009/7/29/6251621
>>>>>>
>>>>>> I took this version, added NAPI support, and fixed some problems found
>>>>>> during testing. Well, here is the result. Please review.
>>>>> I briefly browsed the patch and various bits and pieces are missing or
>>>>> not correctly implemented. Marc already pointed out a few of them:
>>>>>
>>>>> - I do not find can_put/get_echo_skb functions in the code. How is
>>>>>   IFF_ECHO supposed to work?
>>>> the driver uses hardware loopback
>>> OK, then
>>>
>>>   dev = alloc_candev(sizeof(struct flexcan_priv), 0);
>>>
>>> should be used (and TX_ECHO_SKB_MAX removed) in Hans-Jürgens driver.
>>>
>>>>> - Support for CAN_CTRLMODE_BERR_REPORTING and do_get_berr_counter()
>>>>>   seems to be missing.
>>>>>
>>>>> - Make use of alloc_can_skb() and alloc_can_err_skb().
>>>> the last two points are already addressed in my version of the driver.
>>> I do not see support for CAN_CTRLMODE_BERR_REPORTING in your driver
>>> (which has nothing to do with do_get_berr_counter).
>> oh yes...sorry, got confused.
>>
>> However I implemented CAN_CTRLMODE_BERR_REPORTING, i.e. turning of the
>> bit error interrupts by default. This has the effect that no bus warning
>> and bus passive interrupt was signalled.
>>
>> I should add a comment to my driver.
> 
> I'm confused, CAN_CTRLMODE_BERR_REPORTING means that the user can enable
> bus error reporting, which seems not be handled in the driver your sent.
> See:
> 
> http://lxr.linux.no/linux/drivers/net/can/sja1000/sja1000.c#L134
> http://lxr.linux.no/linux/drivers/net/can/sja1000/sja1000.c#L588

Which interrupts does "IRQ_BEI" include? What should
CAN_CTRLMODE_BERR_REPORTING do?

Looking at:
http://lxr.linux.no/linux+v2.6.34/drivers/net/can/sja1000/sja1000.c#L393
it seems that BEI on the SJA just effects bit, form and stuff errors.

If I disable the corresponding interrupt in the flexcan. This is
ERR_MSK, (1 << 14 in CTRL), I don't get error warning or error passive
interrupts either. I'm not sure about the bus off interrupt.

From my point of view this is not that what CAN_CTRLMODE_BERR_REPORTING
should do, is it?

Marc

-- 
Pengutronix e.K.                  | Marc Kleine-Budde           |
Industrial Linux Solutions        | Phone: +49-231-2826-924     |
Vertretung West/Dortmund          | Fax:   +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686  | http://www.pengutronix.de   |


[-- Attachment #1.2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 260 bytes --]

[-- Attachment #2: Type: text/plain, Size: 188 bytes --]

_______________________________________________
Socketcan-core mailing list
Socketcan-core-0fE9KPoRgkgATYTw5x5z8w@public.gmane.org
https://lists.berlios.de/mailman/listinfo/socketcan-core

^ permalink raw reply

* Re: [PATCH] socketcan: add a driver for FlexCAN controllers.
From: Wolfgang Grandegger @ 2010-06-18 11:53 UTC (permalink / raw)
  To: Marc Kleine-Budde
  Cc: socketcan-core-0fE9KPoRgkgATYTw5x5z8w,
	netdev-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <4C1B56BC.1050303-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>

On 06/18/2010 01:21 PM, Marc Kleine-Budde wrote:
> Wolfgang Grandegger wrote:
>> On 06/18/2010 12:44 PM, Marc Kleine-Budde wrote:
>>> Wolfgang Grandegger wrote:
>>>> On 06/18/2010 12:16 PM, Marc Kleine-Budde wrote:
>>>>> Wolfgang Grandegger wrote:
>>>>>> Hi Hans-Jürgen,
>>>>>>
>>>>>> On 06/17/2010 12:52 PM, Hans J. Koch wrote:
>>>>>>> This adds a driver for FlexCAN based CAN controllers,
>>>>>>> e.g. found in Freescale i.MX35 SoCs.
>>>>>>>
>>>>>>> The original version of this driver was posted by Sascha Hauer in July 2009:
>>>>>>> http://kerneltrap.org/mailarchive/linux-netdev/2009/7/29/6251621
>>>>>>>
>>>>>>> I took this version, added NAPI support, and fixed some problems found
>>>>>>> during testing. Well, here is the result. Please review.
>>>>>> I briefly browsed the patch and various bits and pieces are missing or
>>>>>> not correctly implemented. Marc already pointed out a few of them:
>>>>>>
>>>>>> - I do not find can_put/get_echo_skb functions in the code. How is
>>>>>>   IFF_ECHO supposed to work?
>>>>> the driver uses hardware loopback
>>>> OK, then
>>>>
>>>>   dev = alloc_candev(sizeof(struct flexcan_priv), 0);
>>>>
>>>> should be used (and TX_ECHO_SKB_MAX removed) in Hans-Jürgens driver.
>>>>
>>>>>> - Support for CAN_CTRLMODE_BERR_REPORTING and do_get_berr_counter()
>>>>>>   seems to be missing.
>>>>>>
>>>>>> - Make use of alloc_can_skb() and alloc_can_err_skb().
>>>>> the last two points are already addressed in my version of the driver.
>>>> I do not see support for CAN_CTRLMODE_BERR_REPORTING in your driver
>>>> (which has nothing to do with do_get_berr_counter).
>>> oh yes...sorry, got confused.
>>>
>>> However I implemented CAN_CTRLMODE_BERR_REPORTING, i.e. turning of the
>>> bit error interrupts by default. This has the effect that no bus warning
>>> and bus passive interrupt was signalled.
>>>
>>> I should add a comment to my driver.
>>
>> I'm confused, CAN_CTRLMODE_BERR_REPORTING means that the user can enable
>> bus error reporting, which seems not be handled in the driver your sent.
>> See:
>>
>> http://lxr.linux.no/linux/drivers/net/can/sja1000/sja1000.c#L134
>> http://lxr.linux.no/linux/drivers/net/can/sja1000/sja1000.c#L588
> 
> Which interrupts does "IRQ_BEI" include? What should
> CAN_CTRLMODE_BERR_REPORTING do?
> 
> Looking at:
> http://lxr.linux.no/linux+v2.6.34/drivers/net/can/sja1000/sja1000.c#L393
> it seems that BEI on the SJA just effects bit, form and stuff errors.

Yes, it effects *bus errors*... actually the one you handle in
at91_poll_err_frame(). Especially the AT91_IRQ_AERR does cause the
infamous interrupt flooding (which is, btw, not treated correctly as
bus error in your driver).

> If I disable the corresponding interrupt in the flexcan. This is
> ERR_MSK, (1 << 14 in CTRL), I don't get error warning or error passive
> interrupts either. I'm not sure about the bus off interrupt.

Hm, my understanding is that you can disable those bus error
interrupts individually via AT91_IRQ_ERR_FRAME.

> From my point of view this is not that what CAN_CTRLMODE_BERR_REPORTING
> should do, is it?

It should *not* disable state change interrupts, of course. I have
started to fix some issues in the at91 driver some time ago, which 
I have attached below.

Wolfgang.

---
diff --git a/drivers/net/can/at91_can.c b/drivers/net/can/at91_can.c
index a2f29a3..ad36b59 100644
--- a/drivers/net/can/at91_can.c
+++ b/drivers/net/can/at91_can.c
@@ -164,6 +164,7 @@ struct at91_priv {
 	void __iomem		*reg_base;
 
 	u32			reg_sr;
+	u32			reg_ie_napi;
 	unsigned int		tx_next;
 	unsigned int		tx_echo;
 	unsigned int		rx_next;
@@ -273,7 +274,7 @@ static int at91_set_bittiming(struct net_device *dev)
 static void at91_chip_start(struct net_device *dev)
 {
 	struct at91_priv *priv = netdev_priv(dev);
-	u32 reg_mr, reg_ier;
+	u32 reg_mr;
 
 	/* disable interrupts */
 	at91_write(priv, AT91_IDR, AT91_IRQ_ALL);
@@ -290,10 +291,12 @@ static void at91_chip_start(struct net_device *dev)
 
 	priv->can.state = CAN_STATE_ERROR_ACTIVE;
 
-	/* Enable interrupts */
-	reg_ier = AT91_IRQ_MB_RX | AT91_IRQ_ERRP | AT91_IRQ_ERR_FRAME;
+	/* enable interrupts */
+	priv->reg_ir_napi = AT91_IRQ_MB_RX;
+	if (priv->can.ctrlmode & CAN_CTRLMODE_BERR_REPORTING)
+		priv->reg_ir_napi |= AT91_IRQ_ERR_FRAME;
 	at91_write(priv, AT91_IDR, AT91_IRQ_ALL);
-	at91_write(priv, AT91_IER, reg_ier);
+	at91_write(priv, AT91_IER, priv->reg_ir_napi | AT91_IRQ_ERRP);
 }
 
 static void at91_chip_stop(struct net_device *dev, enum can_state state)
@@ -604,20 +607,21 @@ static void at91_poll_err_frame(struct net_device *dev,
 {
 	struct at91_priv *priv = netdev_priv(dev);
 
+	priv->can.can_stats.bus_error++;
+	cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR;
+
 	/* CRC error */
 	if (reg_sr & AT91_IRQ_CERR) {
 		dev_dbg(dev->dev.parent, "CERR irq\n");
 		dev->stats.rx_errors++;
-		priv->can.can_stats.bus_error++;
-		cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR;
+		cf->data[3] |= CAN_ERR_PROT_LOC_CRC_SEQ |
+			CAN_ERR_PROT_LOC_CRC_DEL;
 	}
 
 	/* Stuffing Error */
 	if (reg_sr & AT91_IRQ_SERR) {
 		dev_dbg(dev->dev.parent, "SERR irq\n");
 		dev->stats.rx_errors++;
-		priv->can.can_stats.bus_error++;
-		cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR;
 		cf->data[2] |= CAN_ERR_PROT_STUFF;
 	}
 
@@ -626,14 +630,13 @@ static void at91_poll_err_frame(struct net_device *dev,
 		dev_dbg(dev->dev.parent, "AERR irq\n");
 		dev->stats.tx_errors++;
 		cf->can_id |= CAN_ERR_ACK;
+		cf->data[3] |= CAN_ERR_PROT_LOC_ACK;
 	}
 
 	/* Form error */
 	if (reg_sr & AT91_IRQ_FERR) {
 		dev_dbg(dev->dev.parent, "FERR irq\n");
 		dev->stats.rx_errors++;
-		priv->can.can_stats.bus_error++;
-		cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR;
 		cf->data[2] |= CAN_ERR_PROT_FORM;
 	}
 
@@ -641,9 +644,7 @@ static void at91_poll_err_frame(struct net_device *dev,
 	if (reg_sr & AT91_IRQ_BERR) {
 		dev_dbg(dev->dev.parent, "BERR irq\n");
 		dev->stats.tx_errors++;
-		priv->can.can_stats.bus_error++;
-		cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR;
-		cf->data[2] |= CAN_ERR_PROT_BIT;
+		cf->data[2] |= CAN_ERR_PROT_BIT0 | CAN_ERR_PROT_BIT1;
 	}
 }
 
@@ -662,7 +663,6 @@ static int at91_poll_err(struct net_device *dev, int quota, u32 reg_sr)
 	at91_poll_err_frame(dev, cf, reg_sr);
 	netif_receive_skb(skb);
 
-	dev->last_rx = jiffies;
 	dev->stats.rx_packets++;
 	dev->stats.rx_bytes += cf->can_dlc;
 
@@ -688,12 +688,10 @@ static int at91_poll(struct napi_struct *napi, int quota)
 		work_done += at91_poll_err(dev, quota - work_done, reg_sr);
 
 	if (work_done < quota) {
-		/* enable IRQs for frame errors and all mailboxes >= rx_next */
-		u32 reg_ier = AT91_IRQ_ERR_FRAME;
-		reg_ier |= AT91_IRQ_MB_RX & ~AT91_MB_RX_MASK(priv->rx_next);
-
 		napi_complete(napi);
-		at91_write(priv, AT91_IER, reg_ier);
+		/* enable IRQs for frame errors and all mailboxes >= rx_next */
+		at91_write(priv, AT91_IER, priv->reg_ir_napi &
+			   ~AT91_MB_RX_MASK(priv->rx_next));
 	}
 
 	return work_done;
@@ -899,7 +897,6 @@ static void at91_irq_err(struct net_device *dev)
 	at91_irq_err_state(dev, cf, new_state);
 	netif_rx(skb);
 
-	dev->last_rx = jiffies;
 	dev->stats.rx_packets++;
 	dev->stats.rx_bytes += cf->can_dlc;
 
@@ -933,8 +930,7 @@ static irqreturn_t at91_irq(int irq, void *dev_id)
 		 * save for later use.
 		 */
 		priv->reg_sr = reg_sr;
-		at91_write(priv, AT91_IDR,
-			   AT91_IRQ_MB_RX | AT91_IRQ_ERR_FRAME);
+		at91_write(priv, AT91_IDR, priv->reg_ir_napi);
 		napi_schedule(&priv->napi);
 	}
 
@@ -1073,7 +1069,8 @@ static int __init at91_can_probe(struct platform_device *pdev)
 	priv->can.bittiming_const = &at91_bittiming_const;
 	priv->can.do_set_bittiming = at91_set_bittiming;
 	priv->can.do_set_mode = at91_set_mode;
-	priv->can.ctrlmode_supported = CAN_CTRLMODE_3_SAMPLES;
+	priv->can.ctrlmode_supported = CAN_CTRLMODE_3_SAMPLES |
+ 		CAN_CTRLMODE_BERR_REPORTING;
 	priv->reg_base = addr;
 	priv->dev = dev;
 	priv->clk = clk;
diff --git a/drivers/net/can/sja1000/sja1000.c b/drivers/net/can/sja1000/sja1000.c
index 145b1a7..77b5fbc 100644
--- a/drivers/net/can/sja1000/sja1000.c
+++ b/drivers/net/can/sja1000/sja1000.c
@@ -89,8 +89,8 @@ static int sja1000_probe_chip(struct net_device *dev)
 	struct sja1000_priv *priv = netdev_priv(dev);
 
 	if (priv->reg_base && (priv->read_reg(priv, 0) == 0xFF)) {
-		printk(KERN_INFO "%s: probing @0x%lX failed\n",
-		       DRV_NAME, dev->base_addr);
+		dev_info(dev->dev.parent, "probing @0x%p failed\n",
+			 priv->reg_base);
 		return 0;
 	}
 	return -1;
@@ -254,7 +254,7 @@ static void chipset_init(struct net_device *dev)
  * [  can-id ] [flags] [len] [can data (up to 8 bytes]
  */
 static netdev_tx_t sja1000_start_xmit(struct sk_buff *skb,
-					    struct net_device *dev)
+				      struct net_device *dev)
 {
 	struct sja1000_priv *priv = netdev_priv(dev);
 	struct can_frame *cf = (struct can_frame *)skb->data;
@@ -602,9 +602,9 @@ void free_sja1000dev(struct net_device *dev)
 EXPORT_SYMBOL_GPL(free_sja1000dev);
 
 static const struct net_device_ops sja1000_netdev_ops = {
-       .ndo_open               = sja1000_open,
-       .ndo_stop               = sja1000_close,
-       .ndo_start_xmit         = sja1000_start_xmit,
+	.ndo_open = sja1000_open,
+	.ndo_stop = sja1000_close,
+	.ndo_start_xmit = sja1000_start_xmit,
 };
 
 int register_sja1000dev(struct net_device *dev)

^ permalink raw reply related

* Re: [PATCH] socketcan: add a driver for FlexCAN controllers.
From: Hans J. Koch @ 2010-06-18 12:00 UTC (permalink / raw)
  To: Wolfgang Grandegger
  Cc: socketcan-core-0fE9KPoRgkgATYTw5x5z8w,
	netdev-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <4C1B4098.3090800-5Yr1BZd7O62+XT7JhA+gdA@public.gmane.org>

On Fri, Jun 18, 2010 at 11:47:04AM +0200, Wolfgang Grandegger wrote:
> Hi Hans-Jürgen,
> 
> On 06/17/2010 12:52 PM, Hans J. Koch wrote:
> > This adds a driver for FlexCAN based CAN controllers,
> > e.g. found in Freescale i.MX35 SoCs.
> > 
> > The original version of this driver was posted by Sascha Hauer in July 2009:
> > http://kerneltrap.org/mailarchive/linux-netdev/2009/7/29/6251621
> > 
> > I took this version, added NAPI support, and fixed some problems found
> > during testing. Well, here is the result. Please review.
> 
> I briefly browsed the patch and various bits and pieces are missing or
> not correctly implemented. Marc already pointed out a few of them:

Before we continue, we should address the fact that we now have two versions
of the driver. It doesn't make sense to work on both.
Just for the record, I knew that Marc was working on this, and offered
cooperation in a private mail a few weeks ago. He never answered, so I made
it work myself, and posted it as soon as I could. A few hours after he saw
that, he came up with his version...

So, instead of continuing wasting engineering powers, you should decide
which of the two versions is in the better shape already, and we continue
working on that. I don't mind at all if you choose Marc's version. I'm
not running after copyright lines, I just want to see flexcan in mainline
as soon as possible.

Thanks,
Hans

_______________________________________________
Socketcan-core mailing list
Socketcan-core@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/socketcan-core

^ permalink raw reply

* Re: Distributed Switch Architecture(DSA)
From: Lennert Buytenhek @ 2010-06-18 12:12 UTC (permalink / raw)
  To: Joakim Tjernlund; +Cc: netdev
In-Reply-To: <OF8E185B56.9B8AB610-ONC1257746.003A78DF-C1257746.003D4C6C@transmode.se>

On Fri, Jun 18, 2010 at 01:09:32PM +0200, Joakim Tjernlund wrote:

> > > > > I am trying to wrap my head around DSA and I need some help.
> > > > >
> > > > > Assume the example from Lennert:
> > > > >
> > > > >        +-----------+       +-----------+
> > > > >        |           | RGMII |           |
> > > > >        |           +-------+           +------ 1000baseT MDI ("WAN")
> > > > >        |           |       |  6-port   +------ 1000baseT MDI ("LAN1")
> > > > >        |    CPU    |       |  ethernet +------ 1000baseT MDI ("LAN2")
> > > > >        |           |MIImgmt|  switch   +------ 1000baseT MDI ("LAN3")
> > > > >        |           +-------+  w/5 PHYs +------ 1000baseT MDI ("LAN4")
> > > > >        |           |       |           |
> > > > >        +-----------+       +-----------+
> > > > >
> > > > > If I understand this correctly I get at least 5 virtual I/Fs corresponding
> > > > > to WAN, LAN1-4, but how is the RGMII I/F modelled?
> > > >
> > > > The RGMII interface is just the interface that your "real" network
> > > > driver exports.  In the case of the Kirkwood 6281 A0 Reference Design
> > > > (which I developed this code on), that would be eth0.  After the DSA
> > > > driver is instantiated, you don't send or receive over eth0 directly
> > > > anymore -- eth0 becomes purely a transport for DSA-tagged packets.
> > >
> > > hmm, but how do I send normal pkgs form the CPU to the switch then?
> >
> > Define what you mean by 'normal pkgs'.
> 
> An ethernet broadcast pkg flooded onto all ports.

This statement assumes that all ports have been configured into a
bridge, which is not the default case.  (And why would it be?  Having each
port in the same VLAN/subnet is only one of the many possible ways of
configuring your switch ports -- and regular (non-DSA) Linux network
interfaces aren't bridged together by default either.)  I.e. after boot,
each of the switch ports behaves as if it's independent.


> A normal ethernet host DST address would be looked up by
> the switch HW and sent to the appropriate port.

In current upstream kernels, if you in fact bridge all switch ports
together using Linux bridging, this address lookup will be done by the
Linux bridging code.


> > > I envision I would get some interface in the CPU I can set an IP address
> > > on and use as a normal I/F which would be switched by the HW switch to
> > > the appropriate port.
> >
> > Yes, these are the DSA/slave interfaces created by net/dsa/slave.c.
> > You are free to attach IP addresses to the wan/lanX interfaces, and
> > things will work as you'd expect them to.
> 
> Not sure what to expect here actually.

That the DSA interfaces will behave just like non-DSA Linux network
interfaces.


> > > What about RX? What decides which pkg to route through the switch and
> > > which pgk to send up to the virtual I/F?
> >
> > By default, which is until you enable bridging on some subset of the
> > ports, all ports have their own address database, and all received
> > packets are passed directly up to the CPU, where the DSA code will
> > then make those packets be received on the DSA slave interfaces.
> 
> ah, so until I enable bridging, all ports are viewed as a separate
> network I/F?

Yes.  The original DSA commit message says as much:

    The switch driver presents each port on the switch as a separate
    network interface to Linux, [...]


> Once I create a linux bridge device and add the virtual I/Fs, one
> enables the bridge function.

Yes and no.  Right now there is no hardware switch offload code in the
upstream kernel, so all bridging will still be done in software.  You
will need something along the lines of the patch I pointed you to to
enable hardware bridging.


> One drawback with that is that you kill the bridge when you reboot
> linux.

With the hardware bridging patch, hardware bridging will continue if
you don't break down your br0 interface before rebooting.  (Of course,
your board might still have a hardware reset line that resets the
switch when the CPU resets.)


> > > > > Now I want to add STP/RSTP to the switch. How would one do that?
> > > >
> > > > First, you'll want the hardware bridging patches that I posted to
> > > > netdev@ a while back, e.g.:
> > > >
> > > >    http://patchwork.ozlabs.org/patch/16578/
> > >
> > > I see, will have to study this a bit closer. One question though,
> > > does this disable MAC learning in the linux bridge?
> >
> > No, why should it?
> 
> Doesn't the HW switch handle all MAC leaning? Why duplicate
> this in the SW bridge?
> I figured the HW switch would offload the SW bridge this task.

Imagine the case where you bridge lan1, lan2 (both on the switch chip)
into br0, together with wlan0 (which is not on the switch chip).

Now a packet is sent out of br0.  Should it be sent to wlan0 or to the
switch chip?  How will you make this decision without an address database
on the Linux side?


> > > Do you have any idea how to do DSA on a Broadcom switch?
> >
> > I have no idea.  When I originally submitted the DSA code for merging,
> > I contacted Broadcom people about adding support for Broadcom switch
> > chips to it, but I never heard back from them.
> 
> OK. With DSA, how does one configure VLANs, policing and parameters in the
> HW switch that don't map or exist in the linux bridge?

The idea is to use existing kernel interface for this as much as
possible.  So e.g. if you do:

	vconfig add lan1 123
	vconfig add lan2 123
	brctl addbr br123
	brctl addif br123 lan1.123
	brctl addif br123 lan2.123

Then the DSA code (or some userspace netlink listener helper, or some
combination of both) should ideally also detect that VLAN 123 on
interfaces lan1 and lan2 are to be bridged together, and program the
switch chip accordingly.  I think all VLAN configurations that at least
the Marvell hardware supports can be expressed this way.

To configure things like ingress/egress rate limiting and such in the
switch chip for which there is no Linux counterpart interface, I suppose
some sysfs interface or so might suffice.

^ permalink raw reply

* Re: [PATCH] socketcan: add a driver for FlexCAN controllers.
From: Wolfgang Grandegger @ 2010-06-18 12:19 UTC (permalink / raw)
  To: Hans J. Koch
  Cc: socketcan-core-0fE9KPoRgkgATYTw5x5z8w,
	netdev-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <20100618120044.GB2007-hikPBsva6T+Nj9Bq2fkWzw@public.gmane.org>

On 06/18/2010 02:00 PM, Hans J. Koch wrote:
> On Fri, Jun 18, 2010 at 11:47:04AM +0200, Wolfgang Grandegger wrote:
>> Hi Hans-Jürgen,
>>
>> On 06/17/2010 12:52 PM, Hans J. Koch wrote:
>>> This adds a driver for FlexCAN based CAN controllers,
>>> e.g. found in Freescale i.MX35 SoCs.
>>>
>>> The original version of this driver was posted by Sascha Hauer in July 2009:
>>> http://kerneltrap.org/mailarchive/linux-netdev/2009/7/29/6251621
>>>
>>> I took this version, added NAPI support, and fixed some problems found
>>> during testing. Well, here is the result. Please review.
>>
>> I briefly browsed the patch and various bits and pieces are missing or
>> not correctly implemented. Marc already pointed out a few of them:
> 
> Before we continue, we should address the fact that we now have two versions
> of the driver. It doesn't make sense to work on both.
> Just for the record, I knew that Marc was working on this, and offered
> cooperation in a private mail a few weeks ago. He never answered, so I made
> it work myself, and posted it as soon as I could. A few hours after he saw
> that, he came up with his version...
> 
> So, instead of continuing wasting engineering powers, you should decide
> which of the two versions is in the better shape already, and we continue
> working on that. I don't mind at all if you choose Marc's version. I'm
> not running after copyright lines, I just want to see flexcan in mainline
> as soon as possible.

Me too. Marc's version is definitely more up-to-date and should be taken
as starting point.

Wolfgang.

^ permalink raw reply

* Re: [PATCH] socketcan: add a driver for FlexCAN controllers.
From: Wolfgang Grandegger @ 2010-06-18 12:30 UTC (permalink / raw)
  To: Marc Kleine-Budde
  Cc: socketcan-core-0fE9KPoRgkgATYTw5x5z8w,
	netdev-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <4C1B5E1F.5080702-5Yr1BZd7O62+XT7JhA+gdA@public.gmane.org>

On 06/18/2010 01:53 PM, Wolfgang Grandegger wrote:
> On 06/18/2010 01:21 PM, Marc Kleine-Budde wrote:
>> Wolfgang Grandegger wrote:
>>> On 06/18/2010 12:44 PM, Marc Kleine-Budde wrote:
>>>> Wolfgang Grandegger wrote:
>>>>> On 06/18/2010 12:16 PM, Marc Kleine-Budde wrote:
>>>>>> Wolfgang Grandegger wrote:
>>>>>>> Hi Hans-Jürgen,
>>>>>>>
>>>>>>> On 06/17/2010 12:52 PM, Hans J. Koch wrote:
>>>>>>>> This adds a driver for FlexCAN based CAN controllers,
>>>>>>>> e.g. found in Freescale i.MX35 SoCs.
>>>>>>>>
>>>>>>>> The original version of this driver was posted by Sascha Hauer in July 2009:
>>>>>>>> http://kerneltrap.org/mailarchive/linux-netdev/2009/7/29/6251621
>>>>>>>>
>>>>>>>> I took this version, added NAPI support, and fixed some problems found
>>>>>>>> during testing. Well, here is the result. Please review.
>>>>>>> I briefly browsed the patch and various bits and pieces are missing or
>>>>>>> not correctly implemented. Marc already pointed out a few of them:
>>>>>>>
>>>>>>> - I do not find can_put/get_echo_skb functions in the code. How is
>>>>>>>   IFF_ECHO supposed to work?
>>>>>> the driver uses hardware loopback
>>>>> OK, then
>>>>>
>>>>>   dev = alloc_candev(sizeof(struct flexcan_priv), 0);
>>>>>
>>>>> should be used (and TX_ECHO_SKB_MAX removed) in Hans-Jürgens driver.
>>>>>
>>>>>>> - Support for CAN_CTRLMODE_BERR_REPORTING and do_get_berr_counter()
>>>>>>>   seems to be missing.
>>>>>>>
>>>>>>> - Make use of alloc_can_skb() and alloc_can_err_skb().
>>>>>> the last two points are already addressed in my version of the driver.
>>>>> I do not see support for CAN_CTRLMODE_BERR_REPORTING in your driver
>>>>> (which has nothing to do with do_get_berr_counter).
>>>> oh yes...sorry, got confused.
>>>>
>>>> However I implemented CAN_CTRLMODE_BERR_REPORTING, i.e. turning of the
>>>> bit error interrupts by default. This has the effect that no bus warning
>>>> and bus passive interrupt was signalled.
>>>>
>>>> I should add a comment to my driver.
>>>
>>> I'm confused, CAN_CTRLMODE_BERR_REPORTING means that the user can enable
>>> bus error reporting, which seems not be handled in the driver your sent.
>>> See:
>>>
>>> http://lxr.linux.no/linux/drivers/net/can/sja1000/sja1000.c#L134
>>> http://lxr.linux.no/linux/drivers/net/can/sja1000/sja1000.c#L588
>>
>> Which interrupts does "IRQ_BEI" include? What should
>> CAN_CTRLMODE_BERR_REPORTING do?
>>
>> Looking at:
>> http://lxr.linux.no/linux+v2.6.34/drivers/net/can/sja1000/sja1000.c#L393
>> it seems that BEI on the SJA just effects bit, form and stuff errors.
> 
> Yes, it effects *bus errors*... actually the one you handle in
> at91_poll_err_frame(). Especially the AT91_IRQ_AERR does cause the
> infamous interrupt flooding (which is, btw, not treated correctly as
> bus error in your driver).
> 
>> If I disable the corresponding interrupt in the flexcan. This is
>> ERR_MSK, (1 << 14 in CTRL), I don't get error warning or error passive
>> interrupts either. I'm not sure about the bus off interrupt.
> 
> Hm, my understanding is that you can disable those bus error
> interrupts individually via AT91_IRQ_ERR_FRAME.
> 
>> From my point of view this is not that what CAN_CTRLMODE_BERR_REPORTING
>> should do, is it?
> 
> It should *not* disable state change interrupts, of course. I have
> started to fix some issues in the at91 driver some time ago, which 
> I have attached below.

Sorry, I drifted away to the at91 driver. If the flexcan hardware does
not allow to disable bus error reporting individually, just do *not*
support CAN_CTRLMODE_BERR_REPORTING, as you already do in your patch.

Wolfgang.

^ permalink raw reply

* [PATCH 1/2] net/fec: clean suspend/resume
From: Eric Bénard @ 2010-06-18 14:19 UTC (permalink / raw)
  Cc: netdev, s.hauer, amit.kucheria, davem, linux-arm-kernel

Commit 59d4289b83b11379d867e2f7146904b19cc96404 converted fec to dev_pm_ops but
didn't update the suspend/resume functions thus leading to the following warning :
"initialization from incompatible pointer type" when CONFIG_PM is set.

This patch also fixe a few indentation and style around CONFIG_PM area.

Signed-off-by: Eric Bénard <eric@eukrea.com>
Cc: netdev@vger.kernel.org
Cc: davem@davemloft.net
Cc: amit.kucheria@canonical.com
Cc: s.hauer@pengutronix.de
Cc: linux-arm-kernel@lists.infradead.org
---
 drivers/net/fec.c |   30 ++++++++++++------------------
 1 files changed, 12 insertions(+), 18 deletions(-)

diff --git a/drivers/net/fec.c b/drivers/net/fec.c
index a3cae4e..b4afd7a 100644
--- a/drivers/net/fec.c
+++ b/drivers/net/fec.c
@@ -1360,11 +1360,10 @@ fec_drv_remove(struct platform_device *pdev)
 }
 
 #ifdef CONFIG_PM
-
 static int
-fec_suspend(struct platform_device *dev, pm_message_t state)
+fec_suspend(struct device *dev)
 {
-	struct net_device *ndev = platform_get_drvdata(dev);
+	struct net_device *ndev = dev_get_drvdata(dev);
 	struct fec_enet_private *fep;
 
 	if (ndev) {
@@ -1377,9 +1376,9 @@ fec_suspend(struct platform_device *dev, pm_message_t state)
 }
 
 static int
-fec_resume(struct platform_device *dev)
+fec_resume(struct device *dev)
 {
-	struct net_device *ndev = platform_get_drvdata(dev);
+	struct net_device *ndev = dev_get_drvdata(dev);
 	struct fec_enet_private *fep;
 
 	if (ndev) {
@@ -1399,23 +1398,18 @@ static const struct dev_pm_ops fec_pm_ops = {
 	.poweroff	= fec_suspend,
 	.restore	= fec_resume,
 };
-
-#define FEC_PM_OPS (&fec_pm_ops)
-
-#else /* !CONFIG_PM */
-
-#define FEC_PM_OPS NULL
-
-#endif /* !CONFIG_PM */
+#endif
 
 static struct platform_driver fec_driver = {
 	.driver	= {
-		.name    = "fec",
-		.owner	 = THIS_MODULE,
-		.pm		 = FEC_PM_OPS,
+		.name	= "fec",
+		.owner	= THIS_MODULE,
+#ifdef CONFIG_PM
+		.pm	= &fec_pm_ops,
+#endif
 	},
-	.probe   = fec_probe,
-	.remove  = __devexit_p(fec_drv_remove),
+	.probe	= fec_probe,
+	.remove	= __devexit_p(fec_drv_remove),
 };
 
 static int __init
-- 
1.6.3.3


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related

* RE: [Bugme-new] [Bug 16187] New: Carrier detection failed in dhcpcd when link is up
From: Allan, Bruce W @ 2010-06-18 15:04 UTC (permalink / raw)
  To: Grant Grundler, Andrew Morton
  Cc: netdev@vger.kernel.org, Kyle McMartin,
	bugzilla-daemon@bugzilla.kernel.org,
	bugme-daemon@bugzilla.kernel.org, casteyde.christian@free.fr
In-Reply-To: <20100618061641.GA7039@lackof.org>

On Thursday, June 17, 2010 11:17 PM, Grant Grundler wrote:
> On Tue, Jun 15, 2010 at 02:24:18PM -0700, Andrew Morton wrote:
>> 
>> (switched to email.  Please respond via emailed reply-to-all, not
>> via the bugzilla web interface).
> 
> I've resync to linus' tree (2.6.35-rc3) and reviewed the output of:
>     git diff v2.6.34 drivers/net/tulip/
> 
> I don't see anything that would affect how link state
> changes get reported to user space.
> 
> I'm not inclined to believe this is a tulip "bug" unless
> core netdev behavior changed and tulip is not longer
> doing the right thing.
> 
> hth,
> grant

I don't believe this is a tulip specific bug - the same thing has been reported against e1000e and bnx2 (IIRC); I have not had the time to investigate further.

Bruce.

^ permalink raw reply

* Re: Distributed Switch Architecture(DSA)
From: Joakim Tjernlund @ 2010-06-18 15:13 UTC (permalink / raw)
  To: Lennert Buytenhek; +Cc: netdev
In-Reply-To: <20100618121223.GH14513@mail.wantstofly.org>

Lennert Buytenhek <buytenh@wantstofly.org> wrote on 2010/06/18 14:12:23:
>
> On Fri, Jun 18, 2010 at 01:09:32PM +0200, Joakim Tjernlund wrote:
>
> > > > > > I am trying to wrap my head around DSA and I need some help.
> > > > > >
> > > > > > Assume the example from Lennert:
> > > > > >
> > > > > >        +-----------+       +-----------+
> > > > > >        |           | RGMII |           |
> > > > > >        |           +-------+           +------ 1000baseT MDI ("WAN")
> > > > > >        |           |       |  6-port   +------ 1000baseT MDI ("LAN1")
> > > > > >        |    CPU    |       |  ethernet +------ 1000baseT MDI ("LAN2")
> > > > > >        |           |MIImgmt|  switch   +------ 1000baseT MDI ("LAN3")
> > > > > >        |           +-------+  w/5 PHYs +------ 1000baseT MDI ("LAN4")
> > > > > >        |           |       |           |
> > > > > >        +-----------+       +-----------+
> > > > > >
> > > > > > If I understand this correctly I get at least 5 virtual I/Fs corresponding
> > > > > > to WAN, LAN1-4, but how is the RGMII I/F modelled?
> > > > >
> > > > > The RGMII interface is just the interface that your "real" network
> > > > > driver exports.  In the case of the Kirkwood 6281 A0 Reference Design
> > > > > (which I developed this code on), that would be eth0.  After the DSA
> > > > > driver is instantiated, you don't send or receive over eth0 directly
> > > > > anymore -- eth0 becomes purely a transport for DSA-tagged packets.
> > > >
> > > > hmm, but how do I send normal pkgs form the CPU to the switch then?
> > >
> > > Define what you mean by 'normal pkgs'.
> >
> > An ethernet broadcast pkg flooded onto all ports.
>
> This statement assumes that all ports have been configured into a
> bridge, which is not the default case.  (And why would it be?  Having each
> port in the same VLAN/subnet is only one of the many possible ways of
> configuring your switch ports -- and regular (non-DSA) Linux network
> interfaces aren't bridged together by default either.)  I.e. after boot,
> each of the switch ports behaves as if it's independent.
>
>
> > A normal ethernet host DST address would be looked up by
> > the switch HW and sent to the appropriate port.
>
> In current upstream kernels, if you in fact bridge all switch ports
> together using Linux bridging, this address lookup will be done by the
> Linux bridging code.

Yes, I am getting there mentally. I just have a hard time letting go of
viewing the HW switch as an external entity :)

[SNIP]

>
> > Once I create a linux bridge device and add the virtual I/Fs, one
> > enables the bridge function.
>
> Yes and no.  Right now there is no hardware switch offload code in the
> upstream kernel, so all bridging will still be done in software.  You
> will need something along the lines of the patch I pointed you to to
> enable hardware bridging.
>
>
> > One drawback with that is that you kill the bridge when you reboot
> > linux.
>
> With the hardware bridging patch, hardware bridging will continue if
> you don't break down your br0 interface before rebooting.  (Of course,
> your board might still have a hardware reset line that resets the
> switch when the CPU resets.)

hmm, one will have to recreate the exact config in several steps(create br0, add each
I/F etc.). I guess if done carefully one can avoid disturbing the switch.

>
> > > > > > Now I want to add STP/RSTP to the switch. How would one do that?
> > > > >
> > > > > First, you'll want the hardware bridging patches that I posted to
> > > > > netdev@ a while back, e.g.:
> > > > >
> > > > >    http://patchwork.ozlabs.org/patch/16578/
> > > >
> > > > I see, will have to study this a bit closer. One question though,
> > > > does this disable MAC learning in the linux bridge?
> > >
> > > No, why should it?
> >
> > Doesn't the HW switch handle all MAC leaning? Why duplicate
> > this in the SW bridge?
> > I figured the HW switch would offload the SW bridge this task.
>
> Imagine the case where you bridge lan1, lan2 (both on the switch chip)
> into br0, together with wlan0 (which is not on the switch chip).
>
> Now a packet is sent out of br0.  Should it be sent to wlan0 or to the
> switch chip?  How will you make this decision without an address database
> on the Linux side?

True, in this case you need it, but for only HW switch I/Fs you don't
need it and there can be several hundreds of MAC addresses passing
trough the HW switch. It would be nice if one didn't need to pass
all those up to the SW bridge, especially if you have a small embedded
CPU.

>
>
> > > > Do you have any idea how to do DSA on a Broadcom switch?
> > >
> > > I have no idea.  When I originally submitted the DSA code for merging,
> > > I contacted Broadcom people about adding support for Broadcom switch
> > > chips to it, but I never heard back from them.
> >
> > OK. With DSA, how does one configure VLANs, policing and parameters in the
> > HW switch that don't map or exist in the linux bridge?
>
> The idea is to use existing kernel interface for this as much as
> possible.  So e.g. if you do:
>
>    vconfig add lan1 123
>    vconfig add lan2 123
>    brctl addbr br123
>    brctl addif br123 lan1.123
>    brctl addif br123 lan2.123
>
> Then the DSA code (or some userspace netlink listener helper, or some
> combination of both) should ideally also detect that VLAN 123 on
> interfaces lan1 and lan2 are to be bridged together, and program the
> switch chip accordingly.  I think all VLAN configurations that at least
> the Marvell hardware supports can be expressed this way.

Yes, but I image that this breaks down when you want to do something a bit more
advanced. For example I don't think linux VLANs supports "shared VLAN learning"(SVL)
and to configure a HW switch to do SVL one would first have to impl.
that in Linux VLAN and then add the DSA code to get the config to the switch.

Not sure how one would express whether VLAN tags should be stripped off or not when
egressing the HW switch's physical port.

Furthermore, suppose one have a big HW switch, 48 ports, and lots of VLANs in that
HW switch one would have to create a lot of virtual I/Fs and VLANs in linux
just to configure the HW switch. This wastes resources on the CPU.

>
> To configure things like ingress/egress rate limiting and such in the
> switch chip for which there is no Linux counterpart interface, I suppose
> some sysfs interface or so might suffice.

Yes, there are aspects of a HW switch that doesn't map into DSA currently.
Perhaps one should add some framework to support this?

     Jocke


^ permalink raw reply

* Re: pull request: wireless-next-2.6 2010-06-17
From: David Miller @ 2010-06-18 16:01 UTC (permalink / raw)
  To: linville-2XuSBdqkA4R54TAoqtyWWQ
  Cc: linux-wireless-u79uwXL29TY76Z2rM5mHXA,
	netdev-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <20100617210242.GB2368-2XuSBdqkA4R54TAoqtyWWQ@public.gmane.org>

From: "John W. Linville" <linville-2XuSBdqkA4R54TAoqtyWWQ@public.gmane.org>
Date: Thu, 17 Jun 2010 17:02:42 -0400

> Another week, another bunch of patches intende for 2.6.36...
> This week's batch includes the usual updates to ath5k, ath9k,
> iwlwifi, rt2x00, and other drivers.  Also included are a lot of
> cleanup/maintenance for mac80211 from Johannes and some IBSS-related
> changes from Teemu, as well as a number of other patches from a
> variety of contributors.
> 
> Please let me know if there are problems!

Pulled, thanks JOhn.
--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" 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

* [PATCH net-next 1/9] cxgb4: dynamically determine flash size and FW image location
From: Dimitris Michailidis @ 2010-06-18 20:05 UTC (permalink / raw)
  To: netdev; +Cc: Dimitris Michailidis
In-Reply-To: <1276891535-13967-1-git-send-email-dm@chelsio.com>

Handle the larger flash memories on newer boards:

- get the size and number of sectors by probing the flash
- writes and erases can take longer, adjust the timeouts for these operations
- the FW image can be at different locations depending on flash size,
  find its location dynamically as well.

Signed-off-by: Dimitris Michailidis <dm@chelsio.com>
---
 drivers/net/cxgb4/cxgb4.h   |    4 ++
 drivers/net/cxgb4/t4_hw.c   |   75 +++++++++++++++++++++++++++++++------------
 drivers/net/cxgb4/t4_hw.h   |    2 -
 drivers/net/cxgb4/t4_regs.h |    3 ++
 4 files changed, 61 insertions(+), 23 deletions(-)

diff --git a/drivers/net/cxgb4/cxgb4.h b/drivers/net/cxgb4/cxgb4.h
index dd1770e..bfa1366 100644
--- a/drivers/net/cxgb4/cxgb4.h
+++ b/drivers/net/cxgb4/cxgb4.h
@@ -219,6 +219,10 @@ struct adapter_params {
 	struct vpd_params vpd;
 	struct pci_params pci;
 
+	unsigned int sf_size;             /* serial flash size in bytes */
+	unsigned int sf_nsec;             /* # of flash sectors */
+	unsigned int sf_fw_start;         /* start of FW image in flash */
+
 	unsigned int fw_vers;
 	unsigned int tp_vers;
 	u8 api_vers[7];
diff --git a/drivers/net/cxgb4/t4_hw.c b/drivers/net/cxgb4/t4_hw.c
index da272a9..5c81c55 100644
--- a/drivers/net/cxgb4/t4_hw.c
+++ b/drivers/net/cxgb4/t4_hw.c
@@ -449,12 +449,10 @@ enum {
 	SF_RD_STATUS    = 5,          /* read status register */
 	SF_WR_ENABLE    = 6,          /* enable writes */
 	SF_RD_DATA_FAST = 0xb,        /* read flash */
+	SF_RD_ID        = 0x9f,       /* read ID */
 	SF_ERASE_SECTOR = 0xd8,       /* erase sector */
 
-	FW_START_SEC = 8,             /* first flash sector for FW */
-	FW_END_SEC = 15,              /* last flash sector for FW */
-	FW_IMG_START = FW_START_SEC * SF_SEC_SIZE,
-	FW_MAX_SIZE = (FW_END_SEC - FW_START_SEC + 1) * SF_SEC_SIZE,
+	FW_MAX_SIZE = 512 * 1024,
 };
 
 /**
@@ -558,7 +556,7 @@ static int t4_read_flash(struct adapter *adapter, unsigned int addr,
 {
 	int ret;
 
-	if (addr + nwords * sizeof(u32) > SF_SIZE || (addr & 3))
+	if (addr + nwords * sizeof(u32) > adapter->params.sf_size || (addr & 3))
 		return -EINVAL;
 
 	addr = swab32(addr) | SF_RD_DATA_FAST;
@@ -596,7 +594,7 @@ static int t4_write_flash(struct adapter *adapter, unsigned int addr,
 	u32 buf[64];
 	unsigned int i, c, left, val, offset = addr & 0xff;
 
-	if (addr >= SF_SIZE || offset + n > SF_PAGE_SIZE)
+	if (addr >= adapter->params.sf_size || offset + n > SF_PAGE_SIZE)
 		return -EINVAL;
 
 	val = swab32(addr) | SF_PROG_PAGE;
@@ -614,7 +612,7 @@ static int t4_write_flash(struct adapter *adapter, unsigned int addr,
 		if (ret)
 			goto unlock;
 	}
-	ret = flash_wait_op(adapter, 5, 1);
+	ret = flash_wait_op(adapter, 8, 1);
 	if (ret)
 		goto unlock;
 
@@ -647,9 +645,8 @@ unlock:
  */
 static int get_fw_version(struct adapter *adapter, u32 *vers)
 {
-	return t4_read_flash(adapter,
-			     FW_IMG_START + offsetof(struct fw_hdr, fw_ver), 1,
-			     vers, 0);
+	return t4_read_flash(adapter, adapter->params.sf_fw_start +
+			     offsetof(struct fw_hdr, fw_ver), 1, vers, 0);
 }
 
 /**
@@ -661,8 +658,8 @@ static int get_fw_version(struct adapter *adapter, u32 *vers)
  */
 static int get_tp_version(struct adapter *adapter, u32 *vers)
 {
-	return t4_read_flash(adapter, FW_IMG_START + offsetof(struct fw_hdr,
-							      tp_microcode_ver),
+	return t4_read_flash(adapter, adapter->params.sf_fw_start +
+			     offsetof(struct fw_hdr, tp_microcode_ver),
 			     1, vers, 0);
 }
 
@@ -684,9 +681,9 @@ int t4_check_fw_version(struct adapter *adapter)
 	if (!ret)
 		ret = get_tp_version(adapter, &adapter->params.tp_vers);
 	if (!ret)
-		ret = t4_read_flash(adapter,
-			FW_IMG_START + offsetof(struct fw_hdr, intfver_nic),
-			2, api_vers, 1);
+		ret = t4_read_flash(adapter, adapter->params.sf_fw_start +
+				    offsetof(struct fw_hdr, intfver_nic),
+				    2, api_vers, 1);
 	if (ret)
 		return ret;
 
@@ -726,7 +723,7 @@ static int t4_flash_erase_sectors(struct adapter *adapter, int start, int end)
 		if ((ret = sf1_write(adapter, 1, 0, 1, SF_WR_ENABLE)) != 0 ||
 		    (ret = sf1_write(adapter, 4, 0, 1,
 				     SF_ERASE_SECTOR | (start << 8))) != 0 ||
-		    (ret = flash_wait_op(adapter, 5, 500)) != 0) {
+		    (ret = flash_wait_op(adapter, 14, 500)) != 0) {
 			dev_err(adapter->pdev_dev,
 				"erase of flash sector %d failed, error %d\n",
 				start, ret);
@@ -754,6 +751,9 @@ int t4_load_fw(struct adapter *adap, const u8 *fw_data, unsigned int size)
 	u8 first_page[SF_PAGE_SIZE];
 	const u32 *p = (const u32 *)fw_data;
 	const struct fw_hdr *hdr = (const struct fw_hdr *)fw_data;
+	unsigned int sf_sec_size = adap->params.sf_size / adap->params.sf_nsec;
+	unsigned int fw_img_start = adap->params.sf_fw_start;
+	unsigned int fw_start_sec = fw_img_start / sf_sec_size;
 
 	if (!size) {
 		dev_err(adap->pdev_dev, "FW image has no data\n");
@@ -784,8 +784,8 @@ int t4_load_fw(struct adapter *adap, const u8 *fw_data, unsigned int size)
 		return -EINVAL;
 	}
 
-	i = DIV_ROUND_UP(size, SF_SEC_SIZE);        /* # of sectors spanned */
-	ret = t4_flash_erase_sectors(adap, FW_START_SEC, FW_START_SEC + i - 1);
+	i = DIV_ROUND_UP(size, sf_sec_size);        /* # of sectors spanned */
+	ret = t4_flash_erase_sectors(adap, fw_start_sec, fw_start_sec + i - 1);
 	if (ret)
 		goto out;
 
@@ -796,11 +796,11 @@ int t4_load_fw(struct adapter *adap, const u8 *fw_data, unsigned int size)
 	 */
 	memcpy(first_page, fw_data, SF_PAGE_SIZE);
 	((struct fw_hdr *)first_page)->fw_ver = htonl(0xffffffff);
-	ret = t4_write_flash(adap, FW_IMG_START, SF_PAGE_SIZE, first_page);
+	ret = t4_write_flash(adap, fw_img_start, SF_PAGE_SIZE, first_page);
 	if (ret)
 		goto out;
 
-	addr = FW_IMG_START;
+	addr = fw_img_start;
 	for (size -= SF_PAGE_SIZE; size; size -= SF_PAGE_SIZE) {
 		addr += SF_PAGE_SIZE;
 		fw_data += SF_PAGE_SIZE;
@@ -810,7 +810,7 @@ int t4_load_fw(struct adapter *adap, const u8 *fw_data, unsigned int size)
 	}
 
 	ret = t4_write_flash(adap,
-			     FW_IMG_START + offsetof(struct fw_hdr, fw_ver),
+			     fw_img_start + offsetof(struct fw_hdr, fw_ver),
 			     sizeof(hdr->fw_ver), (const u8 *)&hdr->fw_ver);
 out:
 	if (ret)
@@ -3053,6 +3053,33 @@ static int __devinit wait_dev_ready(struct adapter *adap)
 	return t4_read_reg(adap, PL_WHOAMI) != 0xffffffff ? 0 : -EIO;
 }
 
+static int __devinit get_flash_params(struct adapter *adap)
+{
+	int ret;
+	u32 info;
+
+	ret = sf1_write(adap, 1, 1, 0, SF_RD_ID);
+	if (!ret)
+		ret = sf1_read(adap, 3, 0, 1, &info);
+	t4_write_reg(adap, SF_OP, 0);                    /* unlock SF */
+	if (ret)
+		return ret;
+
+	if ((info & 0xff) != 0x20)             /* not a Numonix flash */
+		return -EINVAL;
+	info >>= 16;                           /* log2 of size */
+	if (info >= 0x14 && info < 0x18)
+		adap->params.sf_nsec = 1 << (info - 16);
+	else if (info == 0x18)
+		adap->params.sf_nsec = 64;
+	else
+		return -EINVAL;
+	adap->params.sf_size = 1 << info;
+	adap->params.sf_fw_start =
+		t4_read_reg(adap, CIM_BOOT_CFG) & BOOTADDR_MASK;
+	return 0;
+}
+
 /**
  *	t4_prep_adapter - prepare SW and HW for operation
  *	@adapter: the adapter
@@ -3073,6 +3100,12 @@ int __devinit t4_prep_adapter(struct adapter *adapter)
 	get_pci_mode(adapter, &adapter->params.pci);
 	adapter->params.rev = t4_read_reg(adapter, PL_REV);
 
+	ret = get_flash_params(adapter);
+	if (ret < 0) {
+		dev_err(adapter->pdev_dev, "error %d identifying flash\n", ret);
+		return ret;
+	}
+
 	ret = get_vpd_params(adapter, &adapter->params.vpd);
 	if (ret < 0)
 		return ret;
diff --git a/drivers/net/cxgb4/t4_hw.h b/drivers/net/cxgb4/t4_hw.h
index 0256232..f886677 100644
--- a/drivers/net/cxgb4/t4_hw.h
+++ b/drivers/net/cxgb4/t4_hw.h
@@ -57,8 +57,6 @@ enum {
 
 enum {
 	SF_PAGE_SIZE = 256,           /* serial flash page size */
-	SF_SEC_SIZE = 64 * 1024,      /* serial flash sector size */
-	SF_SIZE = SF_SEC_SIZE * 16,   /* serial flash size */
 };
 
 enum { RSP_TYPE_FLBUF, RSP_TYPE_CPL, RSP_TYPE_INTR }; /* response entry types */
diff --git a/drivers/net/cxgb4/t4_regs.h b/drivers/net/cxgb4/t4_regs.h
index 5ed5648..8fed46d 100644
--- a/drivers/net/cxgb4/t4_regs.h
+++ b/drivers/net/cxgb4/t4_regs.h
@@ -326,6 +326,9 @@
 
 #define EDC_1_BASE_ADDR 0x7980
 
+#define CIM_BOOT_CFG 0x7b00
+#define  BOOTADDR_MASK 0xffffff00U
+
 #define CIM_PF_MAILBOX_DATA 0x240
 #define CIM_PF_MAILBOX_CTRL 0x280
 #define  MBMSGVALID     0x00000008U
-- 
1.5.4


^ permalink raw reply related

* [PATCH net-next 0/9] cxgb4 update v2
From: Dimitris Michailidis @ 2010-06-18 20:05 UTC (permalink / raw)
  To: netdev


Here's v2 of the cxgb4 series.  Of the 9 patches patch 8 has been updated to
fix the iw_cxgb4 breakage and the rest are as before.

 drivers/net/cxgb4/cxgb4.h      |    6 +-
 drivers/net/cxgb4/cxgb4_main.c |  281 ++++++++++++++++++++++++++++++----------
 drivers/net/cxgb4/cxgb4_uld.h  |    2 +
 drivers/net/cxgb4/l2t.c        |    7 +
 drivers/net/cxgb4/t4_hw.c      |   94 ++++++++++----
 drivers/net/cxgb4/t4_hw.h      |    2 -
 drivers/net/cxgb4/t4_regs.h    |    3 +
 drivers/net/cxgb4/t4fw_api.h   |   34 ++++-
 8 files changed, 325 insertions(+), 104 deletions(-)

^ permalink raw reply

* [PATCH net-next 2/9] cxgb4: rearrange initialization code in preparation for EEH
From: Dimitris Michailidis @ 2010-06-18 20:05 UTC (permalink / raw)
  To: netdev; +Cc: Dimitris Michailidis
In-Reply-To: <1276891535-13967-2-git-send-email-dm@chelsio.com>

Split some existing initialization code into a separate function for use
by EEH next.  No functional changes.

Signed-off-by: Dimitris Michailidis <dm@chelsio.com>
---
 drivers/net/cxgb4/cxgb4_main.c |  109 ++++++++++++++++++++++------------------
 1 files changed, 60 insertions(+), 49 deletions(-)

diff --git a/drivers/net/cxgb4/cxgb4_main.c b/drivers/net/cxgb4/cxgb4_main.c
index 58045b0..60f6ea0 100644
--- a/drivers/net/cxgb4/cxgb4_main.c
+++ b/drivers/net/cxgb4/cxgb4_main.c
@@ -2709,6 +2709,65 @@ static void setup_memwin(struct adapter *adap)
 		     WINDOW(ilog2(MEMWIN2_APERTURE) - 10));
 }
 
+static int adap_init1(struct adapter *adap, struct fw_caps_config_cmd *c)
+{
+	u32 v;
+	int ret;
+
+	/* get device capabilities */
+	memset(c, 0, sizeof(*c));
+	c->op_to_write = htonl(FW_CMD_OP(FW_CAPS_CONFIG_CMD) |
+			       FW_CMD_REQUEST | FW_CMD_READ);
+	c->retval_len16 = htonl(FW_LEN16(*c));
+	ret = t4_wr_mbox(adap, 0, c, sizeof(*c), c);
+	if (ret < 0)
+		return ret;
+
+	/* select capabilities we'll be using */
+	if (c->niccaps & htons(FW_CAPS_CONFIG_NIC_VM)) {
+		if (!vf_acls)
+			c->niccaps ^= htons(FW_CAPS_CONFIG_NIC_VM);
+		else
+			c->niccaps = htons(FW_CAPS_CONFIG_NIC_VM);
+	} else if (vf_acls) {
+		dev_err(adap->pdev_dev, "virtualization ACLs not supported");
+		return ret;
+	}
+	c->op_to_write = htonl(FW_CMD_OP(FW_CAPS_CONFIG_CMD) |
+			       FW_CMD_REQUEST | FW_CMD_WRITE);
+	ret = t4_wr_mbox(adap, 0, c, sizeof(*c), NULL);
+	if (ret < 0)
+		return ret;
+
+	ret = t4_config_glbl_rss(adap, 0,
+				 FW_RSS_GLB_CONFIG_CMD_MODE_BASICVIRTUAL,
+				 FW_RSS_GLB_CONFIG_CMD_TNLMAPEN |
+				 FW_RSS_GLB_CONFIG_CMD_TNLALLLKP);
+	if (ret < 0)
+		return ret;
+
+	ret = t4_cfg_pfvf(adap, 0, 0, 0, 64, 64, 64, 0, 0, 4, 0xf, 0xf, 16,
+			  FW_CMD_CAP_PF, FW_CMD_CAP_PF);
+	if (ret < 0)
+		return ret;
+
+	t4_sge_init(adap);
+
+	/* get basic stuff going */
+	ret = t4_early_init(adap, 0);
+	if (ret < 0)
+		return ret;
+
+	/* tweak some settings */
+	t4_write_reg(adap, TP_SHIFT_CNT, 0x64f8849);
+	t4_write_reg(adap, ULP_RX_TDDP_PSZ, HPZ0(PAGE_SHIFT - 12));
+	t4_write_reg(adap, TP_PIO_ADDR, TP_INGRESS_CONFIG);
+	v = t4_read_reg(adap, TP_PIO_DATA);
+	t4_write_reg(adap, TP_PIO_DATA, v & ~CSUM_HAS_PSEUDO_HDR);
+	setup_memwin(adap);
+	return 0;
+}
+
 /*
  * Max # of ATIDs.  The absolute HW max is 16K but we keep it lower.
  */
@@ -2746,43 +2805,6 @@ static int adap_init0(struct adapter *adap)
 	if (ret < 0)
 		goto bye;
 
-	/* get device capabilities */
-	memset(&c, 0, sizeof(c));
-	c.op_to_write = htonl(FW_CMD_OP(FW_CAPS_CONFIG_CMD) |
-			      FW_CMD_REQUEST | FW_CMD_READ);
-	c.retval_len16 = htonl(FW_LEN16(c));
-	ret = t4_wr_mbox(adap, 0, &c, sizeof(c), &c);
-	if (ret < 0)
-		goto bye;
-
-	/* select capabilities we'll be using */
-	if (c.niccaps & htons(FW_CAPS_CONFIG_NIC_VM)) {
-		if (!vf_acls)
-			c.niccaps ^= htons(FW_CAPS_CONFIG_NIC_VM);
-		else
-			c.niccaps = htons(FW_CAPS_CONFIG_NIC_VM);
-	} else if (vf_acls) {
-		dev_err(adap->pdev_dev, "virtualization ACLs not supported");
-		goto bye;
-	}
-	c.op_to_write = htonl(FW_CMD_OP(FW_CAPS_CONFIG_CMD) |
-			      FW_CMD_REQUEST | FW_CMD_WRITE);
-	ret = t4_wr_mbox(adap, 0, &c, sizeof(c), NULL);
-	if (ret < 0)
-		goto bye;
-
-	ret = t4_config_glbl_rss(adap, 0,
-				 FW_RSS_GLB_CONFIG_CMD_MODE_BASICVIRTUAL,
-				 FW_RSS_GLB_CONFIG_CMD_TNLMAPEN |
-				 FW_RSS_GLB_CONFIG_CMD_TNLALLLKP);
-	if (ret < 0)
-		goto bye;
-
-	ret = t4_cfg_pfvf(adap, 0, 0, 0, 64, 64, 64, 0, 0, 4, 0xf, 0xf, 16,
-			  FW_CMD_CAP_PF, FW_CMD_CAP_PF);
-	if (ret < 0)
-		goto bye;
-
 	for (v = 0; v < SGE_NTIMERS - 1; v++)
 		adap->sge.timer_val[v] = min(intr_holdoff[v], MAX_SGE_TIMERVAL);
 	adap->sge.timer_val[SGE_NTIMERS - 1] = MAX_SGE_TIMERVAL;
@@ -2790,10 +2812,7 @@ static int adap_init0(struct adapter *adap)
 	for (v = 1; v < SGE_NCOUNTERS; v++)
 		adap->sge.counter_val[v] = min(intr_cnt[v - 1],
 					       THRESHOLD_3_MASK);
-	t4_sge_init(adap);
-
-	/* get basic stuff going */
-	ret = t4_early_init(adap, 0);
+	ret = adap_init1(adap, &c);
 	if (ret < 0)
 		goto bye;
 
@@ -2876,14 +2895,6 @@ static int adap_init0(struct adapter *adap)
 	t4_read_mtu_tbl(adap, adap->params.mtus, NULL);
 	t4_load_mtus(adap, adap->params.mtus, adap->params.a_wnd,
 		     adap->params.b_wnd);
-
-	/* tweak some settings */
-	t4_write_reg(adap, TP_SHIFT_CNT, 0x64f8849);
-	t4_write_reg(adap, ULP_RX_TDDP_PSZ, HPZ0(PAGE_SHIFT - 12));
-	t4_write_reg(adap, TP_PIO_ADDR, TP_INGRESS_CONFIG);
-	v = t4_read_reg(adap, TP_PIO_DATA);
-	t4_write_reg(adap, TP_PIO_DATA, v & ~CSUM_HAS_PSEUDO_HDR);
-	setup_memwin(adap);
 	return 0;
 
 	/*
-- 
1.5.4


^ permalink raw reply related

* [PATCH net-next 8/9] cxgb4: update FW definitions
From: Dimitris Michailidis @ 2010-06-18 20:05 UTC (permalink / raw)
  To: netdev; +Cc: Dimitris Michailidis
In-Reply-To: <1276891535-13967-8-git-send-email-dm@chelsio.com>

Update to latest FW API.  Most changes here pertain to port types and
querying FW for parameter values.

Signed-off-by: Dimitris Michailidis <dm@chelsio.com>
---
 drivers/net/cxgb4/cxgb4_main.c |   55 ++++++++++++++++++++++++++++++---------
 drivers/net/cxgb4/cxgb4_uld.h  |    2 +
 drivers/net/cxgb4/t4_hw.c      |    6 ++--
 drivers/net/cxgb4/t4fw_api.h   |   36 +++++++++++++++++++------
 4 files changed, 74 insertions(+), 25 deletions(-)

diff --git a/drivers/net/cxgb4/cxgb4_main.c b/drivers/net/cxgb4/cxgb4_main.c
index eb1492f..352c770 100644
--- a/drivers/net/cxgb4/cxgb4_main.c
+++ b/drivers/net/cxgb4/cxgb4_main.c
@@ -216,7 +216,7 @@ void t4_os_link_changed(struct adapter *adapter, int port_id, int link_stat)
 void t4_os_portmod_changed(const struct adapter *adap, int port_id)
 {
 	static const char *mod_str[] = {
-		NULL, "LR", "SR", "ER", "passive DA", "active DA"
+		NULL, "LR", "SR", "ER", "passive DA", "active DA", "LRM"
 	};
 
 	const struct net_device *dev = adap->port[port_id];
@@ -224,7 +224,7 @@ void t4_os_portmod_changed(const struct adapter *adap, int port_id)
 
 	if (pi->mod_type == FW_PORT_MOD_TYPE_NONE)
 		netdev_info(dev, "port module unplugged\n");
-	else
+	else if (pi->mod_type < ARRAY_SIZE(mod_str))
 		netdev_info(dev, "%s module inserted\n", mod_str[pi->mod_type]);
 }
 
@@ -1234,7 +1234,8 @@ static unsigned int from_fw_linkcaps(unsigned int type, unsigned int caps)
 {
 	unsigned int v = 0;
 
-	if (type == FW_PORT_TYPE_BT_SGMII || type == FW_PORT_TYPE_BT_XAUI) {
+	if (type == FW_PORT_TYPE_BT_SGMII || type == FW_PORT_TYPE_BT_XFI ||
+	    type == FW_PORT_TYPE_BT_XAUI) {
 		v |= SUPPORTED_TP;
 		if (caps & FW_PORT_CAP_SPEED_100M)
 			v |= SUPPORTED_100baseT_Full;
@@ -1250,7 +1251,10 @@ static unsigned int from_fw_linkcaps(unsigned int type, unsigned int caps)
 			v |= SUPPORTED_10000baseKX4_Full;
 	} else if (type == FW_PORT_TYPE_KR)
 		v |= SUPPORTED_Backplane | SUPPORTED_10000baseKR_Full;
-	else if (type == FW_PORT_TYPE_FIBER)
+	else if (type == FW_PORT_TYPE_BP_AP)
+		v |= SUPPORTED_Backplane | SUPPORTED_10000baseR_FEC;
+	else if (type == FW_PORT_TYPE_FIBER_XFI ||
+		 type == FW_PORT_TYPE_FIBER_XAUI || type == FW_PORT_TYPE_SFP)
 		v |= SUPPORTED_FIBRE;
 
 	if (caps & FW_PORT_CAP_ANEG)
@@ -1276,13 +1280,19 @@ static int get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 	const struct port_info *p = netdev_priv(dev);
 
 	if (p->port_type == FW_PORT_TYPE_BT_SGMII ||
+	    p->port_type == FW_PORT_TYPE_BT_XFI ||
 	    p->port_type == FW_PORT_TYPE_BT_XAUI)
 		cmd->port = PORT_TP;
-	else if (p->port_type == FW_PORT_TYPE_FIBER)
+	else if (p->port_type == FW_PORT_TYPE_FIBER_XFI ||
+		 p->port_type == FW_PORT_TYPE_FIBER_XAUI)
 		cmd->port = PORT_FIBRE;
-	else if (p->port_type == FW_PORT_TYPE_TWINAX)
-		cmd->port = PORT_DA;
-	else
+	else if (p->port_type == FW_PORT_TYPE_SFP) {
+		if (p->mod_type == FW_PORT_MOD_TYPE_TWINAX_PASSIVE ||
+		    p->mod_type == FW_PORT_MOD_TYPE_TWINAX_ACTIVE)
+			cmd->port = PORT_DA;
+		else
+			cmd->port = PORT_FIBRE;
+	} else
 		cmd->port = PORT_OTHER;
 
 	if (p->mdio_addr >= 0) {
@@ -2814,14 +2824,20 @@ static int adap_init0(struct adapter *adap)
 	for (v = 1; v < SGE_NCOUNTERS; v++)
 		adap->sge.counter_val[v] = min(intr_cnt[v - 1],
 					       THRESHOLD_3_MASK);
-	ret = adap_init1(adap, &c);
-	if (ret < 0)
-		goto bye;
-
 #define FW_PARAM_DEV(param) \
 	(FW_PARAMS_MNEM(FW_PARAMS_MNEM_DEV) | \
 	 FW_PARAMS_PARAM_X(FW_PARAMS_PARAM_DEV_##param))
 
+	params[0] = FW_PARAM_DEV(CCLK);
+	ret = t4_query_params(adap, 0, 0, 0, 1, params, val);
+	if (ret < 0)
+		goto bye;
+	adap->params.vpd.cclk = val[0];
+
+	ret = adap_init1(adap, &c);
+	if (ret < 0)
+		goto bye;
+
 #define FW_PARAM_PFVF(param) \
 	(FW_PARAMS_MNEM(FW_PARAMS_MNEM_PFVF) | \
 	 FW_PARAMS_PARAM_X(FW_PARAMS_PARAM_PFVF_##param))
@@ -2874,6 +2890,18 @@ static int adap_init0(struct adapter *adap)
 		adap->vres.rq.size = val[3] - val[2] + 1;
 		adap->vres.pbl.start = val[4];
 		adap->vres.pbl.size = val[5] - val[4] + 1;
+
+		params[0] = FW_PARAM_PFVF(SQRQ_START);
+		params[1] = FW_PARAM_PFVF(SQRQ_END);
+		params[2] = FW_PARAM_PFVF(CQ_START);
+		params[3] = FW_PARAM_PFVF(CQ_END);
+		ret = t4_query_params(adap, 0, 0, 0, 4, params, val);
+		if (ret < 0)
+			goto bye;
+		adap->vres.qp.start = val[0];
+		adap->vres.qp.size = val[1] - val[0] + 1;
+		adap->vres.cq.start = val[2];
+		adap->vres.cq.size = val[3] - val[2] + 1;
 	}
 	if (c.iscsicaps) {
 		params[0] = FW_PARAM_PFVF(ISCSI_START);
@@ -3194,7 +3222,8 @@ static int __devinit enable_msix(struct adapter *adap)
 static void __devinit print_port_info(struct adapter *adap)
 {
 	static const char *base[] = {
-		"R", "KX4", "T", "KX", "T", "KR", "CX4"
+		"R XFI", "R XAUI", "T SGMII", "T XFI", "T XAUI", "KX4", "CX4",
+		"KX", "KR", "KR SFP+", "KR FEC"
 	};
 
 	int i;
diff --git a/drivers/net/cxgb4/cxgb4_uld.h b/drivers/net/cxgb4/cxgb4_uld.h
index 5b98546..0dc0866 100644
--- a/drivers/net/cxgb4/cxgb4_uld.h
+++ b/drivers/net/cxgb4/cxgb4_uld.h
@@ -185,6 +185,8 @@ struct cxgb4_virt_res {                      /* virtualized HW resources */
 	struct cxgb4_range stag;
 	struct cxgb4_range rq;
 	struct cxgb4_range pbl;
+	struct cxgb4_range qp;
+	struct cxgb4_range cq;
 };
 
 /*
diff --git a/drivers/net/cxgb4/t4_hw.c b/drivers/net/cxgb4/t4_hw.c
index 5c058ea..d92129b 100644
--- a/drivers/net/cxgb4/t4_hw.c
+++ b/drivers/net/cxgb4/t4_hw.c
@@ -2580,7 +2580,7 @@ int t4_alloc_vi(struct adapter *adap, unsigned int mbox, unsigned int port,
 	}
 	if (rss_size)
 		*rss_size = FW_VI_CMD_RSSSIZE_GET(ntohs(c.rsssize_pkd));
-	return ntohs(c.viid_pkd);
+	return FW_VI_CMD_VIID_GET(ntohs(c.type_viid));
 }
 
 /**
@@ -2603,7 +2603,7 @@ int t4_free_vi(struct adapter *adap, unsigned int mbox, unsigned int pf,
 			    FW_CMD_EXEC | FW_VI_CMD_PFN(pf) |
 			    FW_VI_CMD_VFN(vf));
 	c.alloc_to_len16 = htonl(FW_VI_CMD_FREE | FW_LEN16(c));
-	c.viid_pkd = htons(FW_VI_CMD_VIID(viid));
+	c.type_viid = htons(FW_VI_CMD_VIID(viid));
 	return t4_wr_mbox(adap, mbox, &c, sizeof(c), &c);
 }
 
@@ -3169,7 +3169,7 @@ int __devinit t4_port_init(struct adapter *adap, int mbox, int pf, int vf)
 		p->mdio_addr = (ret & FW_PORT_CMD_MDIOCAP) ?
 			FW_PORT_CMD_MDIOADDR_GET(ret) : -1;
 		p->port_type = FW_PORT_CMD_PTYPE_GET(ret);
-		p->mod_type = FW_PORT_CMD_MODTYPE_GET(ret);
+		p->mod_type = FW_PORT_MOD_TYPE_NA;
 
 		init_link_config(&p->link_cfg, ntohs(c.u.info.pcap));
 		j++;
diff --git a/drivers/net/cxgb4/t4fw_api.h b/drivers/net/cxgb4/t4fw_api.h
index 63991d6..a6643c6 100644
--- a/drivers/net/cxgb4/t4fw_api.h
+++ b/drivers/net/cxgb4/t4fw_api.h
@@ -475,7 +475,13 @@ enum fw_params_param_pfvf {
 	FW_PARAMS_PARAM_PFVF_PBL_END	= 0x12,
 	FW_PARAMS_PARAM_PFVF_L2T_START = 0x13,
 	FW_PARAMS_PARAM_PFVF_L2T_END = 0x14,
+	FW_PARAMS_PARAM_PFVF_SQRQ_START = 0x15,
+	FW_PARAMS_PARAM_PFVF_SQRQ_END	= 0x16,
+	FW_PARAMS_PARAM_PFVF_CQ_START	= 0x17,
+	FW_PARAMS_PARAM_PFVF_CQ_END	= 0x18,
 	FW_PARAMS_PARAM_PFVF_SCHEDCLASS_ETH = 0x20,
+	FW_PARAMS_PARAM_PFVF_VIID       = 0x24,
+	FW_PARAMS_PARAM_PFVF_CPMASK     = 0x25,
 };
 
 /*
@@ -804,16 +810,16 @@ struct fw_eq_ofld_cmd {
 struct fw_vi_cmd {
 	__be32 op_to_vfn;
 	__be32 alloc_to_len16;
-	__be16 viid_pkd;
+	__be16 type_viid;
 	u8 mac[6];
 	u8 portid_pkd;
 	u8 nmac;
 	u8 nmac0[6];
 	__be16 rsssize_pkd;
 	u8 nmac1[6];
-	__be16 r7;
+	__be16 idsiiq_pkd;
 	u8 nmac2[6];
-	__be16 r8;
+	__be16 idseiq_pkd;
 	u8 nmac3[6];
 	__be64 r9;
 	__be64 r10;
@@ -824,6 +830,7 @@ struct fw_vi_cmd {
 #define FW_VI_CMD_ALLOC (1U << 31)
 #define FW_VI_CMD_FREE (1U << 30)
 #define FW_VI_CMD_VIID(x) ((x) << 0)
+#define FW_VI_CMD_VIID_GET(x) ((x) & 0xfff)
 #define FW_VI_CMD_PORTID(x) ((x) << 4)
 #define FW_VI_CMD_RSSSIZE_GET(x) (((x) >> 0) & 0x7ff)
 
@@ -1136,6 +1143,11 @@ struct fw_port_cmd {
 			__be32 lstatus_to_modtype;
 			__be16 pcap;
 			__be16 acap;
+			__be16 mtu;
+			__u8   cbllen;
+			__u8   r9;
+			__be32 r10;
+			__be64 r11;
 		} info;
 		struct fw_port_ppp {
 			__be32 pppen_to_ncsich;
@@ -1196,14 +1208,17 @@ struct fw_port_cmd {
 #define FW_PORT_CMD_NCSICH(x) ((x) << 4)
 
 enum fw_port_type {
-	FW_PORT_TYPE_FIBER,
-	FW_PORT_TYPE_KX4,
+	FW_PORT_TYPE_FIBER_XFI,
+	FW_PORT_TYPE_FIBER_XAUI,
 	FW_PORT_TYPE_BT_SGMII,
-	FW_PORT_TYPE_KX,
+	FW_PORT_TYPE_BT_XFI,
 	FW_PORT_TYPE_BT_XAUI,
-	FW_PORT_TYPE_KR,
+	FW_PORT_TYPE_KX4,
 	FW_PORT_TYPE_CX4,
-	FW_PORT_TYPE_TWINAX,
+	FW_PORT_TYPE_KX,
+	FW_PORT_TYPE_KR,
+	FW_PORT_TYPE_SFP,
+	FW_PORT_TYPE_BP_AP,
 
 	FW_PORT_TYPE_NONE = FW_PORT_CMD_PTYPE_MASK
 };
@@ -1213,6 +1228,9 @@ enum fw_port_module_type {
 	FW_PORT_MOD_TYPE_LR,
 	FW_PORT_MOD_TYPE_SR,
 	FW_PORT_MOD_TYPE_ER,
+	FW_PORT_MOD_TYPE_TWINAX_PASSIVE,
+	FW_PORT_MOD_TYPE_TWINAX_ACTIVE,
+	FW_PORT_MOD_TYPE_LRM,
 
 	FW_PORT_MOD_TYPE_NONE = FW_PORT_CMD_MODTYPE_MASK
 };
-- 
1.5.4


^ permalink raw reply related

* [PATCH net-next 6/9] cxgb4: propagate link initialization errors to .ndo_open's callers
From: Dimitris Michailidis @ 2010-06-18 20:05 UTC (permalink / raw)
  To: netdev; +Cc: Dimitris Michailidis
In-Reply-To: <1276891535-13967-6-git-send-email-dm@chelsio.com>

Signed-off-by: Dimitris Michailidis <dm@chelsio.com>
---
 drivers/net/cxgb4/cxgb4_main.c |    7 ++++---
 1 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/drivers/net/cxgb4/cxgb4_main.c b/drivers/net/cxgb4/cxgb4_main.c
index 6bfe7d6..eb1492f 100644
--- a/drivers/net/cxgb4/cxgb4_main.c
+++ b/drivers/net/cxgb4/cxgb4_main.c
@@ -2512,9 +2512,10 @@ static int cxgb_open(struct net_device *dev)
 	}
 
 	dev->real_num_tx_queues = pi->nqsets;
-	link_start(dev);
-	netif_tx_start_all_queues(dev);
-	return 0;
+	err = link_start(dev);
+	if (!err)
+		netif_tx_start_all_queues(dev);
+	return err;
 }
 
 static int cxgb_close(struct net_device *dev)
-- 
1.5.4


^ permalink raw reply related

* [PATCH net-next 9/9] cxgb4: minor cleanup
From: Dimitris Michailidis @ 2010-06-18 20:05 UTC (permalink / raw)
  To: netdev; +Cc: Dimitris Michailidis
In-Reply-To: <1276891535-13967-9-git-send-email-dm@chelsio.com>

Remove an unused flag and replace couple constants with enums.

Signed-off-by: Dimitris Michailidis <dm@chelsio.com>
---
 drivers/net/cxgb4/cxgb4.h      |    1 -
 drivers/net/cxgb4/cxgb4_main.c |    4 ++--
 2 files changed, 2 insertions(+), 3 deletions(-)

diff --git a/drivers/net/cxgb4/cxgb4.h b/drivers/net/cxgb4/cxgb4.h
index 5e37c1e..62804bb 100644
--- a/drivers/net/cxgb4/cxgb4.h
+++ b/drivers/net/cxgb4/cxgb4.h
@@ -309,7 +309,6 @@ enum {                                 /* adapter flags */
 	FULL_INIT_DONE     = (1 << 0),
 	USING_MSI          = (1 << 1),
 	USING_MSIX         = (1 << 2),
-	QUEUES_BOUND       = (1 << 3),
 	FW_OK              = (1 << 4),
 };
 
diff --git a/drivers/net/cxgb4/cxgb4_main.c b/drivers/net/cxgb4/cxgb4_main.c
index 352c770..27f65b5 100644
--- a/drivers/net/cxgb4/cxgb4_main.c
+++ b/drivers/net/cxgb4/cxgb4_main.c
@@ -2758,8 +2758,8 @@ static int adap_init1(struct adapter *adap, struct fw_caps_config_cmd *c)
 	if (ret < 0)
 		return ret;
 
-	ret = t4_cfg_pfvf(adap, 0, 0, 0, 64, 64, 64, 0, 0, 4, 0xf, 0xf, 16,
-			  FW_CMD_CAP_PF, FW_CMD_CAP_PF);
+	ret = t4_cfg_pfvf(adap, 0, 0, 0, MAX_EGRQ, 64, MAX_INGQ, 0, 0, 4,
+			  0xf, 0xf, 16, FW_CMD_CAP_PF, FW_CMD_CAP_PF);
 	if (ret < 0)
 		return ret;
 
-- 
1.5.4


^ permalink raw reply related

* [PATCH net-next 7/9] cxgb4: add a missing error interrupt
From: Dimitris Michailidis @ 2010-06-18 20:05 UTC (permalink / raw)
  To: netdev; +Cc: Dimitris Michailidis
In-Reply-To: <1276891535-13967-7-git-send-email-dm@chelsio.com>

Signed-off-by: Dimitris Michailidis <dm@chelsio.com>
---
 drivers/net/cxgb4/t4_hw.c |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/drivers/net/cxgb4/t4_hw.c b/drivers/net/cxgb4/t4_hw.c
index 4c956fb..5c058ea 100644
--- a/drivers/net/cxgb4/t4_hw.c
+++ b/drivers/net/cxgb4/t4_hw.c
@@ -1135,6 +1135,7 @@ static void cim_intr_handler(struct adapter *adapter)
 static void ulprx_intr_handler(struct adapter *adapter)
 {
 	static struct intr_info ulprx_intr_info[] = {
+		{ 0x1800000, "ULPRX context error", -1, 1 },
 		{ 0x7fffff, "ULPRX parity error", -1, 1 },
 		{ 0 }
 	};
-- 
1.5.4


^ permalink raw reply related

* [PATCH net-next 4/9] cxgb4: set dev_id to the port number
From: Dimitris Michailidis @ 2010-06-18 20:05 UTC (permalink / raw)
  To: netdev; +Cc: Dimitris Michailidis
In-Reply-To: <1276891535-13967-4-git-send-email-dm@chelsio.com>

Signed-off-by: Dimitris Michailidis <dm@chelsio.com>
---
 drivers/net/cxgb4/t4_hw.c |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/drivers/net/cxgb4/t4_hw.c b/drivers/net/cxgb4/t4_hw.c
index 0c8a84a..4c956fb 100644
--- a/drivers/net/cxgb4/t4_hw.c
+++ b/drivers/net/cxgb4/t4_hw.c
@@ -3162,6 +3162,7 @@ int __devinit t4_port_init(struct adapter *adap, int mbox, int pf, int vf)
 		p->rss_size = rss_size;
 		memcpy(adap->port[i]->dev_addr, addr, ETH_ALEN);
 		memcpy(adap->port[i]->perm_addr, addr, ETH_ALEN);
+		adap->port[i]->dev_id = j;
 
 		ret = ntohl(c.u.info.lstatus_to_modtype);
 		p->mdio_addr = (ret & FW_PORT_CMD_MDIOCAP) ?
-- 
1.5.4


^ permalink raw reply related

* [PATCH net-next 3/9] cxgb4: implement EEH
From: Dimitris Michailidis @ 2010-06-18 20:05 UTC (permalink / raw)
  To: netdev; +Cc: Dimitris Michailidis
In-Reply-To: <1276891535-13967-3-git-send-email-dm@chelsio.com>

Implement the pci_error_handlers methods for EEH.

Signed-off-by: Dimitris Michailidis <dm@chelsio.com>
---
 drivers/net/cxgb4/cxgb4.h      |    1 +
 drivers/net/cxgb4/cxgb4_main.c |  108 +++++++++++++++++++++++++++++++++++++++-
 drivers/net/cxgb4/l2t.c        |    7 +++
 drivers/net/cxgb4/t4_hw.c      |   11 +++-
 4 files changed, 124 insertions(+), 3 deletions(-)

diff --git a/drivers/net/cxgb4/cxgb4.h b/drivers/net/cxgb4/cxgb4.h
index bfa1366..5e37c1e 100644
--- a/drivers/net/cxgb4/cxgb4.h
+++ b/drivers/net/cxgb4/cxgb4.h
@@ -650,6 +650,7 @@ void t4_intr_disable(struct adapter *adapter);
 void t4_intr_clear(struct adapter *adapter);
 int t4_slow_intr_handler(struct adapter *adapter);
 
+int t4_wait_dev_ready(struct adapter *adap);
 int t4_link_start(struct adapter *adap, unsigned int mbox, unsigned int port,
 		  struct link_config *lc);
 int t4_restart_aneg(struct adapter *adap, unsigned int mbox, unsigned int port);
diff --git a/drivers/net/cxgb4/cxgb4_main.c b/drivers/net/cxgb4/cxgb4_main.c
index 60f6ea0..baf4f0a 100644
--- a/drivers/net/cxgb4/cxgb4_main.c
+++ b/drivers/net/cxgb4/cxgb4_main.c
@@ -2483,6 +2483,7 @@ static void cxgb_down(struct adapter *adapter)
 	t4_intr_disable(adapter);
 	cancel_work_sync(&adapter->tid_release_task);
 	adapter->tid_release_task_busy = false;
+	adapter->tid_release_head = NULL;
 
 	if (adapter->flags & USING_MSIX) {
 		free_msix_queue_irqs(adapter);
@@ -2907,6 +2908,108 @@ bye:	if (ret != -ETIMEDOUT && ret != -EIO)
 	return ret;
 }
 
+/* EEH callbacks */
+
+static pci_ers_result_t eeh_err_detected(struct pci_dev *pdev,
+					 pci_channel_state_t state)
+{
+	int i;
+	struct adapter *adap = pci_get_drvdata(pdev);
+
+	if (!adap)
+		goto out;
+
+	rtnl_lock();
+	adap->flags &= ~FW_OK;
+	notify_ulds(adap, CXGB4_STATE_START_RECOVERY);
+	for_each_port(adap, i) {
+		struct net_device *dev = adap->port[i];
+
+		netif_device_detach(dev);
+		netif_carrier_off(dev);
+	}
+	if (adap->flags & FULL_INIT_DONE)
+		cxgb_down(adap);
+	rtnl_unlock();
+	pci_disable_device(pdev);
+out:	return state == pci_channel_io_perm_failure ?
+		PCI_ERS_RESULT_DISCONNECT : PCI_ERS_RESULT_NEED_RESET;
+}
+
+static pci_ers_result_t eeh_slot_reset(struct pci_dev *pdev)
+{
+	int i, ret;
+	struct fw_caps_config_cmd c;
+	struct adapter *adap = pci_get_drvdata(pdev);
+
+	if (!adap) {
+		pci_restore_state(pdev);
+		pci_save_state(pdev);
+		return PCI_ERS_RESULT_RECOVERED;
+	}
+
+	if (pci_enable_device(pdev)) {
+		dev_err(&pdev->dev, "cannot reenable PCI device after reset\n");
+		return PCI_ERS_RESULT_DISCONNECT;
+	}
+
+	pci_set_master(pdev);
+	pci_restore_state(pdev);
+	pci_save_state(pdev);
+	pci_cleanup_aer_uncorrect_error_status(pdev);
+
+	if (t4_wait_dev_ready(adap) < 0)
+		return PCI_ERS_RESULT_DISCONNECT;
+	if (t4_fw_hello(adap, 0, 0, MASTER_MUST, NULL))
+		return PCI_ERS_RESULT_DISCONNECT;
+	adap->flags |= FW_OK;
+	if (adap_init1(adap, &c))
+		return PCI_ERS_RESULT_DISCONNECT;
+
+	for_each_port(adap, i) {
+		struct port_info *p = adap2pinfo(adap, i);
+
+		ret = t4_alloc_vi(adap, 0, p->tx_chan, 0, 0, 1, NULL, NULL);
+		if (ret < 0)
+			return PCI_ERS_RESULT_DISCONNECT;
+		p->viid = ret;
+		p->xact_addr_filt = -1;
+	}
+
+	t4_load_mtus(adap, adap->params.mtus, adap->params.a_wnd,
+		     adap->params.b_wnd);
+	if (cxgb_up(adap))
+		return PCI_ERS_RESULT_DISCONNECT;
+	return PCI_ERS_RESULT_RECOVERED;
+}
+
+static void eeh_resume(struct pci_dev *pdev)
+{
+	int i;
+	struct adapter *adap = pci_get_drvdata(pdev);
+
+	if (!adap)
+		return;
+
+	rtnl_lock();
+	for_each_port(adap, i) {
+		struct net_device *dev = adap->port[i];
+
+		if (netif_running(dev)) {
+			link_start(dev);
+			cxgb_set_rxmode(dev);
+		}
+		netif_device_attach(dev);
+	}
+	rtnl_unlock();
+}
+
+static struct pci_error_handlers cxgb4_eeh = {
+	.error_detected = eeh_err_detected,
+	.slot_reset     = eeh_slot_reset,
+	.resume         = eeh_resume,
+};
+
 static inline bool is_10g_port(const struct link_config *lc)
 {
 	return (lc->supported & FW_PORT_CAP_SPEED_10G) != 0;
@@ -3154,8 +3257,10 @@ static int __devinit init_one(struct pci_dev *pdev,
 
 	/* We control everything through PF 0 */
 	func = PCI_FUNC(pdev->devfn);
-	if (func > 0)
+	if (func > 0) {
+		pci_save_state(pdev);        /* to restore SR-IOV later */
 		goto sriov;
+	}
 
 	err = pci_enable_device(pdev);
 	if (err) {
@@ -3396,6 +3501,7 @@ static struct pci_driver cxgb4_driver = {
 	.id_table = cxgb4_pci_tbl,
 	.probe    = init_one,
 	.remove   = __devexit_p(remove_one),
+	.err_handler = &cxgb4_eeh,
 };
 
 static int __init cxgb4_init_module(void)
diff --git a/drivers/net/cxgb4/l2t.c b/drivers/net/cxgb4/l2t.c
index 9f96724..5b990d2 100644
--- a/drivers/net/cxgb4/l2t.c
+++ b/drivers/net/cxgb4/l2t.c
@@ -310,6 +310,13 @@ static void t4_l2e_free(struct l2t_entry *e)
 			neigh_release(e->neigh);
 			e->neigh = NULL;
 		}
+		while (e->arpq_head) {
+			struct sk_buff *skb = e->arpq_head;
+
+			e->arpq_head = skb->next;
+			kfree(skb);
+		}
+		e->arpq_tail = NULL;
 	}
 	spin_unlock_bh(&e->lock);
 
diff --git a/drivers/net/cxgb4/t4_hw.c b/drivers/net/cxgb4/t4_hw.c
index 5c81c55..0c8a84a 100644
--- a/drivers/net/cxgb4/t4_hw.c
+++ b/drivers/net/cxgb4/t4_hw.c
@@ -221,6 +221,13 @@ int t4_wr_mbox_meat(struct adapter *adap, int mbox, const void *cmd, int size,
 	if ((size & 15) || size > MBOX_LEN)
 		return -EINVAL;
 
+	/*
+	 * If the device is off-line, as in EEH, commands will time out.
+	 * Fail them early so we don't waste time waiting.
+	 */
+	if (adap->pdev->error_state != pci_channel_io_normal)
+		return -EIO;
+
 	v = MBOWNER_GET(t4_read_reg(adap, ctl_reg));
 	for (i = 0; v == MBOX_OWNER_NONE && i < 3; i++)
 		v = MBOWNER_GET(t4_read_reg(adap, ctl_reg));
@@ -3045,7 +3052,7 @@ static void __devinit init_link_config(struct link_config *lc,
 	}
 }
 
-static int __devinit wait_dev_ready(struct adapter *adap)
+int t4_wait_dev_ready(struct adapter *adap)
 {
 	if (t4_read_reg(adap, PL_WHOAMI) != 0xffffffff)
 		return 0;
@@ -3093,7 +3100,7 @@ int __devinit t4_prep_adapter(struct adapter *adapter)
 {
 	int ret;
 
-	ret = wait_dev_ready(adapter);
+	ret = t4_wait_dev_ready(adapter);
 	if (ret < 0)
 		return ret;
 
-- 
1.5.4


^ permalink raw reply related

* [PATCH net-next 5/9] cxgb4: switch to 64 bit inteface statistics
From: Dimitris Michailidis @ 2010-06-18 20:05 UTC (permalink / raw)
  To: netdev; +Cc: Dimitris Michailidis
In-Reply-To: <1276891535-13967-5-git-send-email-dm@chelsio.com>

Implement ndo_get_stats64, remove ndo_get_stats.

Signed-off-by: Dimitris Michailidis <dm@chelsio.com>
---
 drivers/net/cxgb4/cxgb4_main.c |    6 +++---
 1 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/net/cxgb4/cxgb4_main.c b/drivers/net/cxgb4/cxgb4_main.c
index baf4f0a..6bfe7d6 100644
--- a/drivers/net/cxgb4/cxgb4_main.c
+++ b/drivers/net/cxgb4/cxgb4_main.c
@@ -2527,12 +2527,12 @@ static int cxgb_close(struct net_device *dev)
 	return t4_enable_vi(adapter, 0, pi->viid, false, false);
 }
 
-static struct net_device_stats *cxgb_get_stats(struct net_device *dev)
+static struct rtnl_link_stats64 *cxgb_get_stats(struct net_device *dev)
 {
 	struct port_stats stats;
 	struct port_info *p = netdev_priv(dev);
 	struct adapter *adapter = p->adapter;
-	struct net_device_stats *ns = &dev->stats;
+	struct rtnl_link_stats64 *ns = &dev->stats64;
 
 	spin_lock(&adapter->stats_lock);
 	t4_get_port_stats(adapter, p->tx_chan, &stats);
@@ -2675,7 +2675,7 @@ static const struct net_device_ops cxgb4_netdev_ops = {
 	.ndo_open             = cxgb_open,
 	.ndo_stop             = cxgb_close,
 	.ndo_start_xmit       = t4_eth_xmit,
-	.ndo_get_stats        = cxgb_get_stats,
+	.ndo_get_stats64      = cxgb_get_stats,
 	.ndo_set_rx_mode      = cxgb_set_rxmode,
 	.ndo_set_mac_address  = cxgb_set_mac_addr,
 	.ndo_validate_addr    = eth_validate_addr,
-- 
1.5.4


^ permalink raw reply related

* Re: Distributed Switch Architecture(DSA)
From: Lennert Buytenhek @ 2010-06-18 20:12 UTC (permalink / raw)
  To: Joakim Tjernlund; +Cc: netdev
In-Reply-To: <OF4FC7639D.8FBCAF3B-ONC1257746.004AF9D3-C1257746.005397F6@transmode.se>

On Fri, Jun 18, 2010 at 05:13:03PM +0200, Joakim Tjernlund wrote:

> > > > > > > Now I want to add STP/RSTP to the switch. How would one do that?
> > > > > >
> > > > > > First, you'll want the hardware bridging patches that I posted to
> > > > > > netdev@ a while back, e.g.:
> > > > > >
> > > > > >    http://patchwork.ozlabs.org/patch/16578/
> > > > >
> > > > > I see, will have to study this a bit closer. One question though,
> > > > > does this disable MAC learning in the linux bridge?
> > > >
> > > > No, why should it?
> > >
> > > Doesn't the HW switch handle all MAC leaning? Why duplicate
> > > this in the SW bridge?
> > > I figured the HW switch would offload the SW bridge this task.
> >
> > Imagine the case where you bridge lan1, lan2 (both on the switch chip)
> > into br0, together with wlan0 (which is not on the switch chip).
> >
> > Now a packet is sent out of br0.  Should it be sent to wlan0 or to the
> > switch chip?  How will you make this decision without an address database
> > on the Linux side?
> 
> True, in this case you need it, but for only HW switch I/Fs you don't
> need it and there can be several hundreds of MAC addresses passing
> trough the HW switch. It would be nice if one didn't need to pass
> all those up to the SW bridge, especially if you have a small embedded
> CPU.

I think you overestimate the effect that address learning will have on
the host CPU.  It only needs to happen for the first packet for every
new MAC address, and address flooding attacks is something you'll need
to address in either case.

If you're really worried about this scenario, then just configure your
boot loader to bridge all switch ports together, and don't load the DSA
driver.  The switch will then appear as a single interface, 'eth0' (or
whatever your SoC calls it), over which you can talk directly without
any form of tagging.  You won't be able to use any advanced features,
though.


> > > > > Do you have any idea how to do DSA on a Broadcom switch?
> > > >
> > > > I have no idea.  When I originally submitted the DSA code for merging,
> > > > I contacted Broadcom people about adding support for Broadcom switch
> > > > chips to it, but I never heard back from them.
> > >
> > > OK. With DSA, how does one configure VLANs, policing and parameters in the
> > > HW switch that don't map or exist in the linux bridge?
> >
> > The idea is to use existing kernel interface for this as much as
> > possible.  So e.g. if you do:
> >
> >    vconfig add lan1 123
> >    vconfig add lan2 123
> >    brctl addbr br123
> >    brctl addif br123 lan1.123
> >    brctl addif br123 lan2.123
> >
> > Then the DSA code (or some userspace netlink listener helper, or some
> > combination of both) should ideally also detect that VLAN 123 on
> > interfaces lan1 and lan2 are to be bridged together, and program the
> > switch chip accordingly.  I think all VLAN configurations that at least
> > the Marvell hardware supports can be expressed this way.
> 
> Yes, but I image that this breaks down when you want to do something
> a bit more advanced. For example I don't think linux VLANs supports
> "shared VLAN learning"(SVL) and to configure a HW switch to do SVL
> one would first have to impl. that in Linux VLAN and then add the DSA
> code to get the config to the switch.

Yes.  But that's really the best way to do it, in my humble opinion.

If you don't go the host networking stack integration route, you end
up with something like the vendor drivers.  Which work fine for most
scenarios.. until you want to do something like talking TCP/IP using
the host TCP stack over some of the switch ports, at which point the
lack of host networking stack integration comes to bite you.


> Not sure how one would express whether VLAN tags should be stripped
> off or not when egressing the HW switch's physical port.

If you transmit a packet onto 'lan', it will be sent to the switch chip
with an "untagged" DSA tag.  If you transmit a packet onto 'lan.123',
it will be sent to the switch chip with a "tagged" DSA tag.  See
net/dsa/tag_dsa.c for details.


> Furthermore, suppose one have a big HW switch, 48 ports, and lots of
> VLANs in that HW switch one would have to create a lot of virtual I/Fs
> and VLANs in linux just to configure the HW switch. This wastes
> resources on the CPU.

Where the 'resource waste' is on the order of a couple of tens or
hundreds of kilobytes of RAM.  If this is a problem for your host
CPU, I think you have bigger problems anyway.


> > To configure things like ingress/egress rate limiting and such in the
> > switch chip for which there is no Linux counterpart interface, I suppose
> > some sysfs interface or so might suffice.
> 
> Yes, there are aspects of a HW switch that doesn't map into DSA currently.
> Perhaps one should add some framework to support this?

Sounds good.

^ permalink raw reply

* Re: inconsistent lock state
From: Andrew Morton @ 2010-06-18 20:30 UTC (permalink / raw)
  To: Sergey Senozhatsky
  Cc: Alexander Viro, Peter Zijlstra, Sage Weil, linux-fsdevel,
	linux-kernel, Dominik Brodowski, Maciej Rutecki, Eric Dumazet,
	Paul E. McKenney, Lai Jiangshan, David S. Miller, netdev
In-Reply-To: <20100615112434.GA3967@swordfish.minsk.epam.com>


This was also reported by Dominik and is being tracked at
https://bugzilla.kernel.org/show_bug.cgi?id=16230

On Tue, 15 Jun 2010 14:24:34 +0300
Sergey Senozhatsky <sergey.senozhatsky@gmail.com> wrote:

> Hello,
> 
> kernel: [ 3272.351191] 
> kernel: [ 3272.351194] =================================
> kernel: [ 3272.351199] [ INFO: inconsistent lock state ]
> kernel: [ 3272.351204] 2.6.35-rc3-dbg-00106-ga75e02b-dirty #15
> kernel: [ 3272.351206] ---------------------------------
> kernel: [ 3272.351210] inconsistent {IN-HARDIRQ-W} -> {HARDIRQ-ON-W} usage.
> kernel: [ 3272.351215] X/3827 [HC0[0]:SC0[0]:HE1:SE1] takes:
> kernel: [ 3272.351218]  (&(&new->fa_lock)->rlock){?.-...}, at: [<c10aefb4>] kill_fasync+0x37/0x71
> kernel: [ 3272.351232] {IN-HARDIRQ-W} state was registered at:
> kernel: [ 3272.351235]   [<c104e95c>] __lock_acquire+0x281/0xbe1
> kernel: [ 3272.351243]   [<c104f652>] lock_acquire+0x59/0x70
> kernel: [ 3272.351248]   [<c12c6c48>] _raw_spin_lock+0x25/0x34
> kernel: [ 3272.351255]   [<c10aefb4>] kill_fasync+0x37/0x71
> kernel: [ 3272.351261]   [<fd220c81>] evdev_event+0x135/0x190 [evdev]
> kernel: [ 3272.351275]   [<c1232003>] input_pass_event+0x6f/0xae
> kernel: [ 3272.351283]   [<c1232ef5>] input_handle_event+0x38d/0x396
> kernel: [ 3272.351288]   [<c1232fbf>] input_event+0x4f/0x62
> kernel: [ 3272.351293]   [<c12368e4>] input_sync+0xe/0x11
> kernel: [ 3272.351299]   [<c1236d72>] atkbd_interrupt+0x48b/0x541
> kernel: [ 3272.351304]   [<c122ecb2>] serio_interrupt+0x35/0x68
> kernel: [ 3272.351309]   [<c122fbff>] i8042_interrupt+0x264/0x26e
> kernel: [ 3272.351314]   [<c106bb02>] handle_IRQ_event+0x1d/0x98
> kernel: [ 3272.351321]   [<c106d506>] handle_edge_irq+0xc0/0x107
> kernel: [ 3272.351326]   [<c10045ca>] handle_irq+0x1a/0x20
> kernel: [ 3272.351332]   [<c100435f>] do_IRQ+0x43/0x8d
> kernel: [ 3272.351337]   [<c1002d75>] common_interrupt+0x35/0x3c
> kernel: [ 3272.351342]   [<c124723d>] cpuidle_idle_call+0x6a/0xa0
> kernel: [ 3272.351349]   [<c100170d>] cpu_idle+0x89/0xbe
> kernel: [ 3272.351354]   [<c12b6d11>] rest_init+0xb5/0xba
> kernel: [ 3272.351361]   [<c148a7bf>] start_kernel+0x33b/0x340
> kernel: [ 3272.351368]   [<c148a0c9>] i386_start_kernel+0xc9/0xd0
> kernel: [ 3272.351374] irq event stamp: 54104917
> kernel: [ 3272.351377] hardirqs last  enabled at (54104917): [<c12c70f2>] _raw_spin_unlock_irqrestore+0x36/0x5b
> kernel: [ 3272.351384] hardirqs last disabled at (54104916): [<c12c6ced>] _raw_spin_lock_irqsave+0x13/0x42
> kernel: [ 3272.351391] softirqs last  enabled at (54104732): [<c1032cf2>] __do_softirq+0xfd/0x10c
> kernel: [ 3272.351398] softirqs last disabled at (54104703): [<c1032d30>] do_softirq+0x2f/0x47
> kernel: [ 3272.351404] 
> kernel: [ 3272.351405] other info that might help us debug this:
> kernel: [ 3272.351409] 3 locks held by X/3827:
> kernel: [ 3272.351412]  #0:  (rcu_read_lock){.+.+..}, at: [<c124fdfa>] rcu_read_lock+0x0/0x26
> kernel: [ 3272.351423]  #1:  (rcu_read_lock){.+.+..}, at: [<c124d5d9>] rcu_read_lock+0x0/0x26
> kernel: [ 3272.351432]  #2:  (rcu_read_lock){.+.+..}, at: [<c10ae429>] rcu_read_lock+0x0/0x26
> kernel: [ 3272.351442] 
> kernel: [ 3272.351443] stack backtrace:
> kernel: [ 3272.351448] Pid: 3827, comm: X Not tainted 2.6.35-rc3-dbg-00106-ga75e02b-dirty #15
> kernel: [ 3272.351451] Call Trace:
> kernel: [ 3272.351456]  [<c12c4ff1>] ? printk+0xf/0x11
> kernel: [ 3272.351462]  [<c104e51a>] valid_state+0x133/0x141
> kernel: [ 3272.351468]  [<c104e5f7>] mark_lock+0xcf/0x1b3
> kernel: [ 3272.351473]  [<c104e54e>] ? mark_lock+0x26/0x1b3
> kernel: [ 3272.351479]  [<c104dfd2>] ? check_usage_backwards+0x0/0x68
> kernel: [ 3272.351484]  [<c104e9d0>] __lock_acquire+0x2f5/0xbe1
> kernel: [ 3272.351489]  [<c104ea44>] ? __lock_acquire+0x369/0xbe1
> kernel: [ 3272.351495]  [<c104ea44>] ? __lock_acquire+0x369/0xbe1
> kernel: [ 3272.351502]  [<c102ab40>] ? try_to_wake_up+0x2a8/0x2bb
> kernel: [ 3272.351508]  [<c104f652>] lock_acquire+0x59/0x70
> kernel: [ 3272.351513]  [<c10aefb4>] ? kill_fasync+0x37/0x71
> kernel: [ 3272.351519]  [<c12c6c48>] _raw_spin_lock+0x25/0x34
> kernel: [ 3272.351524]  [<c10aefb4>] ? kill_fasync+0x37/0x71
> kernel: [ 3272.351529]  [<c10aefb4>] kill_fasync+0x37/0x71
> kernel: [ 3272.351534]  [<c124d694>] sock_wake_async+0x77/0x83
> kernel: [ 3272.351540]  [<c124fe4d>] sk_wake_async+0x2d/0x32
> kernel: [ 3272.351545]  [<c1250004>] sock_def_readable+0x45/0x51
> kernel: [ 3272.351551]  [<c12b0247>] unix_stream_sendmsg+0x1e2/0x269
> kernel: [ 3272.351557]  [<c124fe6e>] ? rcu_read_unlock+0x1c/0x1e
> kernel: [ 3272.351562]  [<c124cf1a>] __sock_sendmsg+0x51/0x5a
> kernel: [ 3272.351567]  [<c124cff7>] sock_aio_write+0xd4/0xdd
> kernel: [ 3272.351575]  [<c10a4d95>] do_sync_readv_writev+0x84/0xb7
> kernel: [ 3272.351582]  [<c10a4288>] ? copy_from_user+0x8/0xa
> kernel: [ 3272.351587]  [<c10a4e69>] ? rw_copy_check_uvector+0x55/0xc7
> kernel: [ 3272.351594]  [<c1164082>] ? security_file_permission+0xf/0x11
> kernel: [ 3272.351599]  [<c10a47e5>] ? rw_verify_area+0x90/0xac
> kernel: [ 3272.351605]  [<c10a4f58>] do_readv_writev+0x7d/0xdf
> kernel: [ 3272.351610]  [<c124cf23>] ? sock_aio_write+0x0/0xdd
> kernel: [ 3272.351615]  [<c1164082>] ? security_file_permission+0xf/0x11
> kernel: [ 3272.351621]  [<c10a47e5>] ? rw_verify_area+0x90/0xac
> kernel: [ 3272.351626]  [<c10a4ff3>] vfs_writev+0x39/0x42
> kernel: [ 3272.351632]  [<c10a5102>] sys_writev+0x3b/0x8c
> kernel: [ 3272.351637]  [<c10027d3>] sysenter_do_call+0x12/0x32
> 

This, I think?


From: Andrew Morton <akpm@linux-foundation.org>

Fix a lockdep-splat-causing regression introduced by

: commit 989a2979205dd34269382b357e6d4b4b6956b889
: Author:     Eric Dumazet <eric.dumazet@gmail.com>
: AuthorDate: Wed Apr 14 09:55:35 2010 +0000
: Commit:     David S. Miller <davem@davemloft.net>
: CommitDate: Wed Apr 21 16:19:29 2010 -0700
: 
:     fasync: RCU and fine grained locking

kill_fasync() can be called from both process and hard-irq context, so
fa_lock must be taken with IRQs disabled.

Addresses https://bugzilla.kernel.org/show_bug.cgi?id=16230

Reported-by: Sergey Senozhatsky <sergey.senozhatsky@gmail.com>
Reported-by: Dominik Brodowski <linux@dominikbrodowski.net>
Cc: Maciej Rutecki <maciej.rutecki@gmail.com>
Cc: Eric Dumazet <eric.dumazet@gmail.com>
Cc: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Cc: Lai Jiangshan <laijs@cn.fujitsu.com>
Cc: "David S. Miller" <davem@davemloft.net>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
---

 fs/fcntl.c |    6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff -puN fs/fcntl.c~fs-fcntlc-kill_fasync_rcu-fa_lock-must-be-irq-safe fs/fcntl.c
--- a/fs/fcntl.c~fs-fcntlc-kill_fasync_rcu-fa_lock-must-be-irq-safe
+++ a/fs/fcntl.c
@@ -733,12 +733,14 @@ static void kill_fasync_rcu(struct fasyn
 {
 	while (fa) {
 		struct fown_struct *fown;
+		unsigned long flags;
+
 		if (fa->magic != FASYNC_MAGIC) {
 			printk(KERN_ERR "kill_fasync: bad magic number in "
 			       "fasync_struct!\n");
 			return;
 		}
-		spin_lock(&fa->fa_lock);
+		spin_lock_irqsave(&fa->fa_lock, flags);
 		if (fa->fa_file) {
 			fown = &fa->fa_file->f_owner;
 			/* Don't send SIGURG to processes which have not set a
@@ -747,7 +749,7 @@ static void kill_fasync_rcu(struct fasyn
 			if (!(sig == SIGURG && fown->signum == 0))
 				send_sigio(fown, fa->fa_fd, band);
 		}
-		spin_unlock(&fa->fa_lock);
+		spin_unlock_irqrestore(&fa->fa_lock, flags);
 		fa = rcu_dereference(fa->fa_next);
 	}
 }
_


afaict all other lockers of fa_lock are OK (but one never really knows
with spin_lock_irq()).

Guys, please review-and-ack and I'll get it merged up.

^ 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