Netdev List
 help / color / mirror / Atom feed
* [PATCH 34/55] ISDN: irq: Remove IRQF_DISABLED
From: Yong Zhang @ 2011-09-22  8:59 UTC (permalink / raw)
  To: linux-kernel, linux-arch
  Cc: tglx, yong.zhang0, Armin Schindler, Karsten Keil, netdev
In-Reply-To: <1316681962-8217-1-git-send-email-yong.zhang0@gmail.com>

Since commit [e58aa3d2: genirq: Run irq handlers with interrupts disabled],
We run all interrupt handlers with interrupts disabled
and we even check and yell when an interrupt handler
returns with interrupts enabled (see commit [b738a50a:
genirq: Warn when handler enables interrupts]).

So now this flag is a NOOP and can be removed.

Signed-off-by: Yong Zhang <yong.zhang0@gmail.com>
---
 drivers/isdn/hardware/eicon/divasmain.c |    2 +-
 drivers/isdn/sc/init.c                  |    2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/isdn/hardware/eicon/divasmain.c b/drivers/isdn/hardware/eicon/divasmain.c
index f332b60..8a0a831 100644
--- a/drivers/isdn/hardware/eicon/divasmain.c
+++ b/drivers/isdn/hardware/eicon/divasmain.c
@@ -481,7 +481,7 @@ void __inline__ outpp(void __iomem *addr, word p)
 int diva_os_register_irq(void *context, byte irq, const char *name)
 {
 	int result = request_irq(irq, diva_os_irq_wrapper,
-				 IRQF_DISABLED | IRQF_SHARED, name, context);
+				 IRQF_SHARED, name, context);
 	return (result);
 }
 
diff --git a/drivers/isdn/sc/init.c b/drivers/isdn/sc/init.c
index ca710ab..a3127fb 100644
--- a/drivers/isdn/sc/init.c
+++ b/drivers/isdn/sc/init.c
@@ -336,7 +336,7 @@ static int __init sc_init(void)
 		 */
 		sc_adapter[cinst]->interrupt = irq[b];
 		if (request_irq(sc_adapter[cinst]->interrupt, interrupt_handler,
-				IRQF_DISABLED, interface->id,
+				0, interface->id,
 				(void *)(unsigned long) cinst))
 		{
 			kfree(sc_adapter[cinst]->channel);
-- 
1.7.4.1

^ permalink raw reply related

* (unknown), 
From: Pepsi Bottling Company Plc @ 2011-09-22  9:30 UTC (permalink / raw)





Your email has won £500,000.00 POUNDS (Five Hundred Thousand Pounds) from Pepsi online promotions2011,send your Full names, Age, Sex,Occupation,Phone and Address to the Promotion Manager for claims. Tel: +447011150911

^ permalink raw reply

* Re: [PATCH v3 6/7] tcp buffer limitation: per-cgroup limit
From: Kirill A. Shutemov @ 2011-09-22  9:58 UTC (permalink / raw)
  To: Greg Thelen
  Cc: Glauber Costa, linux-kernel, paul, lizf, kamezawa.hiroyu,
	ebiederm, davem, netdev, linux-mm
In-Reply-To: <CAHH2K0Yuji2_2pMdzEaMvRx0KE7OOaoEGT+OK4gJgTcOPKuT9g@mail.gmail.com>

On Wed, Sep 21, 2011 at 11:01:46PM -0700, Greg Thelen wrote:
> On Sun, Sep 18, 2011 at 5:56 PM, Glauber Costa <glommer@parallels.com> wrote:
> > +static inline bool mem_cgroup_is_root(struct mem_cgroup *mem)
> > +{
> > +       return (mem == root_mem_cgroup);
> > +}
> > +
> 
> Why are you adding a copy of mem_cgroup_is_root().  I see one already
> in v3.0.  Was it deleted in a previous patch?

mem_cgroup_is_root() moved up in the file.

-- 
 Kirill A. Shutemov

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Fight unfair telecom internet charges in Canada: sign http://stopthemeter.ca/
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply

* [PATCH net-next] candev: allow SJW user setting for bittiming calculation
From: Oliver Hartkopp @ 2011-09-22 10:24 UTC (permalink / raw)
  To: David Miller
  Cc: SocketCAN Core Mailing List, Linux Netdev List,
	Pavel-XecQL68PM4x789tOGE2Ojw, Píša, Wolfgang Grandegger

This patch adds support for SJW user settings to not set the synchronization
jump width (SJW) to 1 in any case when using the in-kernel bittiming
calculation.

The ip-tool from iproute2 already supports to pass the user defined SJW
value. The given SJW value is sanitized with the controller specific sjw_max
and the calculated tseg2 value. As the SJW can have values up to 4 providing
this value will lead to the maximum possible SJW automatically. A higher SJW
allows higher controller oscillator tolerances.

Signed-off-by: Oliver Hartkopp <socketcan-fJ+pQTUTwRTk1uMJSBkQmQ@public.gmane.org>

---

diff --git a/drivers/net/can/dev.c b/drivers/net/can/dev.c
index 9bf1116..25695bd 100644
--- a/drivers/net/can/dev.c
+++ b/drivers/net/can/dev.c
@@ -150,7 +150,19 @@ static int can_calc_bittiming(struct net_device *dev, struct can_bittiming *bt)
 	bt->prop_seg = tseg1 / 2;
 	bt->phase_seg1 = tseg1 - bt->prop_seg;
 	bt->phase_seg2 = tseg2;
-	bt->sjw = 1;
+
+	/* check for sjw user settings */
+	if (!bt->sjw || !btc->sjw_max)
+		bt->sjw = 1;
+	else {
+		/* bt->sjw is at least 1 -> sanitize upper bound to sjw_max */
+		if (bt->sjw > btc->sjw_max)
+			bt->sjw = btc->sjw_max;
+		/* bt->sjw must not be higher than tseg2 */
+		if (tseg2 < bt->sjw)
+			bt->sjw = tseg2;
+	}
+
 	bt->brp = best_brp;
 	/* real bit-rate */
 	bt->bitrate = priv->clock.freq / (bt->brp * (tseg1 + tseg2 + 1));

^ permalink raw reply related

* [PATCH net-next v2] candev: allow SJW user setting for bittiming calculation
From: Oliver Hartkopp @ 2011-09-22 10:28 UTC (permalink / raw)
  To: David Miller
  Cc: Linux Netdev List, Wolfgang Grandegger, Pavel Píša,
	SocketCAN Core Mailing List

This patch adds support for SJW user settings to not set the synchronization
jump width (SJW) to 1 in any case when using the in-kernel bittiming
calculation.

The ip-tool from iproute2 already supports to pass the user defined SJW
value. The given SJW value is sanitized with the controller specific sjw_max
and the calculated tseg2 value. As the SJW can have values up to 4 providing
this value will lead to the maximum possible SJW automatically. A higher SJW
allows higher controller oscillator tolerances.

Signed-off-by: Oliver Hartkopp <socketcan@hartkopp.net>

---

v2: Resend due to wrong mail address header encoding.

diff --git a/drivers/net/can/dev.c b/drivers/net/can/dev.c
index 9bf1116..25695bd 100644
--- a/drivers/net/can/dev.c
+++ b/drivers/net/can/dev.c
@@ -150,7 +150,19 @@ static int can_calc_bittiming(struct net_device *dev,
struct can_bittiming *bt)
 	bt->prop_seg = tseg1 / 2;
 	bt->phase_seg1 = tseg1 - bt->prop_seg;
 	bt->phase_seg2 = tseg2;
-	bt->sjw = 1;
+
+	/* check for sjw user settings */
+	if (!bt->sjw || !btc->sjw_max)
+		bt->sjw = 1;
+	else {
+		/* bt->sjw is at least 1 -> sanitize upper bound to sjw_max */
+		if (bt->sjw > btc->sjw_max)
+			bt->sjw = btc->sjw_max;
+		/* bt->sjw must not be higher than tseg2 */
+		if (tseg2 < bt->sjw)
+			bt->sjw = tseg2;
+	}
+
 	bt->brp = best_brp;
 	/* real bit-rate */
 	bt->bitrate = priv->clock.freq / (bt->brp * (tseg1 + tseg2 + 1));

^ permalink raw reply related

* Re: discrepancy in ip(7) wrt. IP DF flag for UDP sockets
From: Neil Horman @ 2011-09-22 10:48 UTC (permalink / raw)
  To: Michael Kerrisk
  Cc: Benjamin Poirier, linux-man-u79uwXL29TY76Z2rM5mHXA,
	netdev-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <CAKgNAkiSrGdXd2e1dpcC0fPmARRwkMrUvB8vCJ7eQ8SYsCuuUw-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>

On Thu, Sep 22, 2011 at 06:15:53AM +0200, Michael Kerrisk wrote:
> Ben, Neil,
> 
> On Tue, Sep 20, 2011 at 4:31 PM, Neil Horman <nhorman-2XuSBdqkA4R54TAoqtyWWQ@public.gmane.org> wrote:
> > On Tue, Sep 20, 2011 at 10:12:34AM -0400, Benjamin Poirier wrote:
> >> On 11-09-20 09:38, Neil Horman wrote:
> >> > On Tue, Sep 20, 2011 at 09:29:54AM -0400, Benjamin Poirier wrote:
> >> > > On 11-09-20 08:14, Michael Kerrisk wrote:
> >> > > > Hello Benjamin, Neil,
> >> > > >
> >> [snip]
> >> > > >
> >> > > > Could you describe the required change in terms of how the man page
> >> > > > text should look--i.e., rewrite the passage as you think it should
> >> > > > look?
> >> > >
> >> > > How about changing it to:
> >> > >   IP_MTU_DISCOVER (since Linux 2.2)
> >> > >   Set or receive the Path MTU Discovery setting for a socket. When
> >> > >   enabled, the don't-fragment flag is set on all outgoing packets.
> >> > >   Linux will perform Path MTU Discovery as defined in RFC 1191 on
> >> > >   SOCK_STREAM sockets. For non-SOCK_STREAM sockets, it is the
> >> > >   user's responsibility to packetize the data in MTU sized chunks
> >> > >   and to do the retransmits if necessary. The kernel will reject
> >> > >   (with EMSGSIZE) datagrams that are bigger than the known path
> >> > >   MTU. The system-wide default is controlled by the
> >> > >   /proc/sys/net/ipv4/ip_no_pmtu_disc file.
> >> > >
> >> > >   Path MTU discovery flags   Meaning
> >> > >   [...]
> >> > >
> >> > > There are some differences between _DO and _WANT that are glossed over
> >> > > in this description, but I suppose there's only so much detail you can
> >> > > put in...
> >> > >
> >> > > Thanks,
> >> > > -Ben
> >> > >
> >> > Yeah, I think thats close, but its only the users responsibility to package
> >> > datagrams in mtu sized chunks if they force the dont fragment bit on.  If they
> >> > go wtih the default, the stack will fragment a datagram is it sees fit according
> >> > to the mtu of the path it traverses
> >>
> >> Exactly. To get into this level of detail, I think we have to mention
> >> the option value, not just enabled/disabled. Let's try like this:
> >>
> >>       IP_MTU_DISCOVER (since Linux 2.2)
> >>       Set or receive the Path MTU Discovery setting for a socket. When
> >>       enabled, Linux will perform Path MTU Discovery as defined in RFC
> >>       1191 on SOCK_STREAM sockets.  For non-SOCK_STREAM sockets,
> >>       IP_PMTUDISC_DO forces the don't-fragment flag to be set on all
> >>       outgoing packets.  It is the user's responsibility to packetize
> >>       the data in MTU sized chunks and to do the retransmits if
> >>       necessary.  The kernel will reject (with EMSGSIZE) datagrams
> >>       that are bigger than the known path MTU.  IP_PMTUDISC_WANT will
> >>       fragment a datagram if needed according to the path MTU or will
> >>       set the don't-fragment flag otherwise.
> >>
> >>       The system-wide default can be toggled between IP_PMTUDISC_WANT
> >>       and IP_PMTUDISC_DONT by writting to the
> >>       /proc/sys/net/ipv4/ip_no_pmtu_disc file.
> >>
> > Yes, that sounds good to me.  Thanks for doing this!
> > Acked-by: Neil Horman <nhorman-2XuSBdqkA4R54TAoqtyWWQ@public.gmane.org>
> 
> Ben, thanks for writing this, and Neil, thanks for reviewing it. I've
> applied that change for man-pages-3.34.
> 
> Ben, I added one small piece ti the description of
> /proc/sys/net/ipv4/ip_no_pmtu_disc. For completeness, I've reproduced
> the entire text below. Perhaps you could take a quick scan, to make
> sure that the changed text is consistent with the whole piece.
> 
This looks good to me.  A minor nit in the chunk you added thoguh.  Calling the
MTU discovery value 'flags' suggests they can be or-together, or somehow
otherwise combined, which is non-sensical.  It may be better to use the term
values rather than flags.

Other than that
Acked-by: Neil Horman <nhorman-2XuSBdqkA4R54TAoqtyWWQ@public.gmane.org>

Thanks!
Neil

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

^ permalink raw reply

* Re: [PATCH net-next] candev: allow SJW user setting for bittiming calculation
From: Wolfgang Grandegger @ 2011-09-22 11:00 UTC (permalink / raw)
  To: Oliver Hartkopp
  Cc: SocketCAN Core Mailing List, Linux Netdev List, Píša,
	David Miller, Pavel-XecQL68PM4x789tOGE2Ojw
In-Reply-To: <4E7B0CE4.3070402-fJ+pQTUTwRTk1uMJSBkQmQ@public.gmane.org>

Hi Oliver,

On 09/22/2011 12:24 PM, Oliver Hartkopp wrote:
> This patch adds support for SJW user settings to not set the synchronization
> jump width (SJW) to 1 in any case when using the in-kernel bittiming
> calculation.
> 
> The ip-tool from iproute2 already supports to pass the user defined SJW
> value. The given SJW value is sanitized with the controller specific sjw_max
> and the calculated tseg2 value. As the SJW can have values up to 4 providing
> this value will lead to the maximum possible SJW automatically. A higher SJW
> allows higher controller oscillator tolerances.
> 
> Signed-off-by: Oliver Hartkopp <socketcan-fJ+pQTUTwRTk1uMJSBkQmQ@public.gmane.org>
> 
> ---
> 
> diff --git a/drivers/net/can/dev.c b/drivers/net/can/dev.c
> index 9bf1116..25695bd 100644
> --- a/drivers/net/can/dev.c
> +++ b/drivers/net/can/dev.c
> @@ -150,7 +150,19 @@ static int can_calc_bittiming(struct net_device *dev, struct can_bittiming *bt)
>  	bt->prop_seg = tseg1 / 2;
>  	bt->phase_seg1 = tseg1 - bt->prop_seg;
>  	bt->phase_seg2 = tseg2;
> -	bt->sjw = 1;
> +
> +	/* check for sjw user settings */
> +	if (!bt->sjw || !btc->sjw_max)
> +		bt->sjw = 1;
> +	else {
> +		/* bt->sjw is at least 1 -> sanitize upper bound to sjw_max */
> +		if (bt->sjw > btc->sjw_max)
> +			bt->sjw = btc->sjw_max;
> +		/* bt->sjw must not be higher than tseg2 */
> +		if (tseg2 < bt->sjw)
> +			bt->sjw = tseg2;
> +	}
> +


Hm, bt->sjw is always 0 when can_calc_bittiming() is called!? Or have I
missed something.

Wolfgang,

^ permalink raw reply

* Re: pull request: batman-adv 2011-09-08
From: Marek Lindner @ 2011-09-22 11:05 UTC (permalink / raw)
  To: b.a.t.m.a.n-ZwoEplunGu2X36UT3dwllkB+6BGkLq7r
  Cc: netdev-u79uwXL29TY76Z2rM5mHXA, David Miller
In-Reply-To: <20110921.201153.1030355996800820632.davem-fT/PcQaiUtIeIZ0/mPfg9Q@public.gmane.org>

On Thursday, September 22, 2011 02:11:53 David Miller wrote:
> From: Marek Lindner <lindner_marek-LWAfsSFWpa4@public.gmane.org>
> Date: Thu, 22 Sep 2011 02:10:04 +0200
> 
> > No, the data structures for the routing lookups remain the same but there
> > will be more than one way to fill them with data. You will only use one
> > "filling algorithm" at a time, so you will need to select the one you
> > want.
> 
> Extend the userspace interface for adding route entries with a boolean
> flag.  You're using netlink right?  If so, this should be trivial by
> simply adding a flags attribute if you don't have one already.

Not really. It's rather the tcp westwood vs tcp reno type of story. But I 
think we simply make this a runtime option to keep everybody happy.

Thanks,
Marek

^ permalink raw reply

* [PATCH net 1/3] bnx2x: fix hw attention handling
From: Dmitry Kravkov @ 2011-09-22 12:33 UTC (permalink / raw)
  To: davem, netdev; +Cc: Dmitry Kravkov, Eilon Greenstein

Use register name to initialize attention mask

Signed-off-by: Dmitry Kravkov <dmitry@broadcom.com>
Signed-off-by: Eilon Greenstein <eilong@broadcom.com>
---
 drivers/net/bnx2x/bnx2x_main.c |    6 ++++--
 drivers/net/bnx2x/bnx2x_reg.h  |   12 ++++++++++++
 2 files changed, 16 insertions(+), 2 deletions(-)

diff --git a/drivers/net/bnx2x/bnx2x_main.c b/drivers/net/bnx2x/bnx2x_main.c
index c027e93..6b46917 100644
--- a/drivers/net/bnx2x/bnx2x_main.c
+++ b/drivers/net/bnx2x/bnx2x_main.c
@@ -4943,7 +4943,7 @@ static void bnx2x_init_def_sb(struct bnx2x *bp)
 	int igu_seg_id;
 	int port = BP_PORT(bp);
 	int func = BP_FUNC(bp);
-	int reg_offset;
+	int reg_offset, reg_offset_en5;
 	u64 section;
 	int index;
 	struct hc_sp_status_block_data sp_sb_data;
@@ -4966,6 +4966,8 @@ static void bnx2x_init_def_sb(struct bnx2x *bp)
 
 	reg_offset = (port ? MISC_REG_AEU_ENABLE1_FUNC_1_OUT_0 :
 			     MISC_REG_AEU_ENABLE1_FUNC_0_OUT_0);
+	reg_offset_en5 = (port ? MISC_REG_AEU_ENABLE5_FUNC_1_OUT_0 :
+				 MISC_REG_AEU_ENABLE5_FUNC_0_OUT_0);
 	for (index = 0; index < MAX_DYNAMIC_ATTN_GRPS; index++) {
 		int sindex;
 		/* take care of sig[0]..sig[4] */
@@ -4980,7 +4982,7 @@ static void bnx2x_init_def_sb(struct bnx2x *bp)
 			 * and not 16 between the different groups
 			 */
 			bp->attn_group[index].sig[4] = REG_RD(bp,
-					reg_offset + 0x10 + 0x4*index);
+					reg_offset_en5 + 0x4*index);
 		else
 			bp->attn_group[index].sig[4] = 0;
 	}
diff --git a/drivers/net/bnx2x/bnx2x_reg.h b/drivers/net/bnx2x/bnx2x_reg.h
index 750e844..fc7bd0f 100644
--- a/drivers/net/bnx2x/bnx2x_reg.h
+++ b/drivers/net/bnx2x/bnx2x_reg.h
@@ -1384,6 +1384,18 @@
    Latched ump_tx_parity; [31] MCP Latched scpad_parity; */
 #define MISC_REG_AEU_ENABLE4_PXP_0				 0xa108
 #define MISC_REG_AEU_ENABLE4_PXP_1				 0xa1a8
+/* [RW 32] fifth 32b for enabling the output for function 0 output0. Mapped
+ * as follows: [0] PGLUE config_space; [1] PGLUE misc_flr; [2] PGLUE B RBC
+ * attention [3] PGLUE B RBC parity; [4] ATC attention; [5] ATC parity; [6]
+ * mstat0 attention; [7] mstat0 parity; [8] mstat1 attention; [9] mstat1
+ * parity; [31-10] Reserved; */
+#define MISC_REG_AEU_ENABLE5_FUNC_0_OUT_0			 0xa688
+/* [RW 32] Fifth 32b for enabling the output for function 1 output0. Mapped
+ * as follows: [0] PGLUE config_space; [1] PGLUE misc_flr; [2] PGLUE B RBC
+ * attention [3] PGLUE B RBC parity; [4] ATC attention; [5] ATC parity; [6]
+ * mstat0 attention; [7] mstat0 parity; [8] mstat1 attention; [9] mstat1
+ * parity; [31-10] Reserved; */
+#define MISC_REG_AEU_ENABLE5_FUNC_1_OUT_0			 0xa6b0
 /* [RW 1] set/clr general attention 0; this will set/clr bit 94 in the aeu
    128 bit vector */
 #define MISC_REG_AEU_GENERAL_ATTN_0				 0xa000
-- 
1.7.2.2

^ permalink raw reply related

* [PATCH net 2/3] bnx2x: fix WOL by enablement PME in config space
From: Dmitry Kravkov @ 2011-09-22 12:33 UTC (permalink / raw)
  To: davem, netdev; +Cc: Dmitry Kravkov, Eilon Greenstein
In-Reply-To: <1316694813-25274-1-git-send-email-dmitry@broadcom.com>


Signed-off-by: Dmitry Kravkov <dmitry@broadcom.com>
Signed-off-by: Eilon Greenstein <eilong@broadcom.com>
---
 drivers/net/bnx2x/bnx2x_main.c |   10 +++++++++-
 1 files changed, 9 insertions(+), 1 deletions(-)

diff --git a/drivers/net/bnx2x/bnx2x_main.c b/drivers/net/bnx2x/bnx2x_main.c
index 6b46917..15f8000 100644
--- a/drivers/net/bnx2x/bnx2x_main.c
+++ b/drivers/net/bnx2x/bnx2x_main.c
@@ -7627,8 +7627,11 @@ u32 bnx2x_send_unload_req(struct bnx2x *bp, int unload_mode)
 		u32 emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
 		u8 *mac_addr = bp->dev->dev_addr;
 		u32 val;
+		u16 pmc;
+
 		/* The mac address is written to entries 1-4 to
-		   preserve entry 0 which is used by the PMF */
+		 * preserve entry 0 which is used by the PMF
+		 */
 		u8 entry = (BP_VN(bp) + 1)*8;
 
 		val = (mac_addr[0] << 8) | mac_addr[1];
@@ -7638,6 +7641,11 @@ u32 bnx2x_send_unload_req(struct bnx2x *bp, int unload_mode)
 		      (mac_addr[4] << 8) | mac_addr[5];
 		EMAC_WR(bp, EMAC_REG_EMAC_MAC_MATCH + entry + 4, val);
 
+		/* Enable the PME and clear the status */
+		pci_read_config_word(bp->pdev, bp->pm_cap + PCI_PM_CTRL, &pmc);
+		pmc |= PCI_PM_CTRL_PME_ENABLE | PCI_PM_CTRL_PME_STATUS;
+		pci_write_config_word(bp->pdev, bp->pm_cap + PCI_PM_CTRL, pmc);
+
 		reset_code = DRV_MSG_CODE_UNLOAD_REQ_WOL_EN;
 
 	} else
-- 
1.7.2.2

^ permalink raw reply related

* [PATCH net 3/3] bnx2x: add missing break in bnx2x_dcbnl_get_cap
From: Dmitry Kravkov @ 2011-09-22 12:33 UTC (permalink / raw)
  To: davem, netdev; +Cc: Dmitry Kravkov, Shmulik Ravid, Eilon Greenstein
In-Reply-To: <1316694813-25274-1-git-send-email-dmitry@broadcom.com>

From: Shmulik Ravid <shmulikr@broadcom.com>

Signed-off-by: Dmitry Kravkov <dmitry@broadcom.com>
Signed-off-by: Eilon Greenstein <eilong@broadcom.com>
---
 drivers/net/bnx2x/bnx2x_dcb.c |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/drivers/net/bnx2x/bnx2x_dcb.c b/drivers/net/bnx2x/bnx2x_dcb.c
index a1e004a..0b4acf6 100644
--- a/drivers/net/bnx2x/bnx2x_dcb.c
+++ b/drivers/net/bnx2x/bnx2x_dcb.c
@@ -2120,6 +2120,7 @@ static u8 bnx2x_dcbnl_get_cap(struct net_device *netdev, int capid, u8 *cap)
 			break;
 		case DCB_CAP_ATTR_DCBX:
 			*cap = BNX2X_DCBX_CAPS;
+			break;
 		default:
 			rval = -EINVAL;
 			break;
-- 
1.7.2.2

^ permalink raw reply related

* Re: discrepancy in ip(7) wrt. IP DF flag for UDP sockets
From: Benjamin Poirier @ 2011-09-22 12:44 UTC (permalink / raw)
  To: Michael Kerrisk
  Cc: Neil Horman, linux-man-u79uwXL29TY76Z2rM5mHXA,
	netdev-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <CAKgNAkiSrGdXd2e1dpcC0fPmARRwkMrUvB8vCJ7eQ8SYsCuuUw-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>

On 11-09-22 06:15, Michael Kerrisk wrote:
> Ben, Neil,
> 
[snip]
> 
> Ben, thanks for writing this, and Neil, thanks for reviewing it. I've
> applied that change for man-pages-3.34.
> 
> Ben, I added one small piece ti the description of
> /proc/sys/net/ipv4/ip_no_pmtu_disc. For completeness, I've reproduced
> the entire text below. Perhaps you could take a quick scan, to make
> sure that the changed text is consistent with the whole piece.
> 
> Thanks,
> 
> Michael
> 
>        IP_MTU_DISCOVER (since Linux 2.2)
>               Set or receive the Path  MTU  Discovery  setting  for  a
>               socket.   When enabled, Linux will perform Path MTU Dis-
>               covery as defined in RFC 1191  on  SOCK_STREAM  sockets.

Oops, seems like there's a repetition that crept in here. I'd keep only
the first of those two sentences:

>               For  non-SOCK_STREAM  sockets, IP_PMTUDISC_DO forces the
>               don't-fragment flag to be set on all  outgoing  packets.
>               The  don't-fragment  flag  is  set on all outgoing data-
>               grams.  It is the user's responsibility to packetize the
>               data  in  MTU-sized  chunks and to do the retransmits if
>               necessary.  The kernel will reject (with EMSGSIZE) data-
>               grams   that   are  bigger  than  the  known  path  MTU.
>               IP_PMTUDISC_WANT will  fragment  a  datagram  if  needed
>               according  to  the path MTU, or will set the don't-frag-
>               ment flag otherwise.
> 
>               The system-wide default can be toggled between IP_PMTUD-
>               ISC_WANT  and IP_PMTUDISC_DONT by writing (respectively,
>               zero      and      nonzero      values)      to      the
>               /proc/sys/net/ipv4/ip_no_pmtu_disc file.

I think it's a welcome clarification. Is is normal that IP_PMTUDISC_WANT
gets hyphenated?

> 
>               Path MTU discovery flags   Meaning

I agree with what Neil said about "flags" here. setsockopt(2) calls
these "option values".

Other than that, LGTM
Acked-by: Benjamin Poirier <benjamin.poirier-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>

Thanks Michael,
-Ben


>               IP_PMTUDISC_WANT           Use per-route settings.
>               IP_PMTUDISC_DONT           Never do Path MTU Discovery.
>               IP_PMTUDISC_DO             Always do Path MTU Discovery.
>               IP_PMTUDISC_PROBE          Set DF but ignore Path MTU.
> 
>               When PMTU discovery is enabled, the kernel automatically
>               keeps track of the path MTU per destination host.   When
>               it  is connected to a specific peer with connect(2), the
>               currently known path MTU can be  retrieved  conveniently
>               using  the IP_MTU socket option (e.g., after an EMSGSIZE
>               error occurred).  The path MTU  may  change  over  time.
>               For  connectionless  sockets with many destinations, the
>               new MTU for a given destination  can  also  be  accessed
>               using  the  error  queue  (see IP_RECVERR).  A new error
>               will be queued for every incoming MTU update.
> 
>               While MTU discovery is in progress, initial packets from
>               datagram sockets may be dropped.  Applications using UDP
>               should be aware of this and not take it into account for
>               their packet retransmit strategy.
> 
>               To  bootstrap  the  path MTU discovery process on uncon-
>               nected sockets, it is possible to start with a big data-
>               gram  size  (up  to  64K-headers  bytes long) and let it
>               shrink by updates of the path MTU.
> 
>               To get an initial estimate of the path  MTU,  connect  a
>               datagram  socket  to  the destination address using con-
>               nect(2) and retrieve the MTU  by  calling  getsockopt(2)
>               with the IP_MTU option.
> 
>               It  is  possible  to implement RFC 4821 MTU probing with
>               SOCK_DGRAM or SOCK_RAW sockets by  setting  a  value  of
>               IP_PMTUDISC_PROBE  (available since Linux 2.6.22).  This
>               is also particularly useful for diagnostic tools such as
>               tracepath(8)  that wish to deliberately send probe pack-
>               ets larger than the observed Path MTU.
> 
> 
> -- 
> Michael Kerrisk
> Linux man-pages maintainer; http://www.kernel.org/doc/man-pages/
> Author of "The Linux Programming Interface"; http://man7.org/tlpi/
--
To unsubscribe from this list: send the line "unsubscribe linux-man" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* Re: [PATCH net-next v2] candev: allow SJW user setting for bittiming calculation
From: Wolfgang Grandegger @ 2011-09-22 13:07 UTC (permalink / raw)
  To: Oliver Hartkopp
  Cc: SocketCAN Core Mailing List, Linux Netdev List, David Miller
In-Reply-To: <4E7B0DE6.9020807-fJ+pQTUTwRTk1uMJSBkQmQ@public.gmane.org>

Hi Oliver,

On 09/22/2011 12:28 PM, Oliver Hartkopp wrote:
> This patch adds support for SJW user settings to not set the synchronization
> jump width (SJW) to 1 in any case when using the in-kernel bittiming
> calculation.
> 
> The ip-tool from iproute2 already supports to pass the user defined SJW
> value. The given SJW value is sanitized with the controller specific sjw_max
> and the calculated tseg2 value. As the SJW can have values up to 4 providing
> this value will lead to the maximum possible SJW automatically. A higher SJW
> allows higher controller oscillator tolerances.
> 
> Signed-off-by: Oliver Hartkopp <socketcan-fJ+pQTUTwRTk1uMJSBkQmQ@public.gmane.org>
> 
> ---
> 
> v2: Resend due to wrong mail address header encoding.
> 
> diff --git a/drivers/net/can/dev.c b/drivers/net/can/dev.c
> index 9bf1116..25695bd 100644
> --- a/drivers/net/can/dev.c
> +++ b/drivers/net/can/dev.c
> @@ -150,7 +150,19 @@ static int can_calc_bittiming(struct net_device *dev,
> struct can_bittiming *bt)
>  	bt->prop_seg = tseg1 / 2;
>  	bt->phase_seg1 = tseg1 - bt->prop_seg;
>  	bt->phase_seg2 = tseg2;
> -	bt->sjw = 1;
> +
> +	/* check for sjw user settings */
> +	if (!bt->sjw || !btc->sjw_max)
> +		bt->sjw = 1;
> +	else {
> +		/* bt->sjw is at least 1 -> sanitize upper bound to sjw_max */
> +		if (bt->sjw > btc->sjw_max)
> +			bt->sjw = btc->sjw_max;
> +		/* bt->sjw must not be higher than tseg2 */
> +		if (tseg2 < bt->sjw)
> +			bt->sjw = tseg2;
> +	}
> +

As I already said, I expected "bt->sjw" to be always 0 when
can_calc_bittiming() is called. But the software somehow allows to
preset "bt->sjw", which is not intended as the help of the ip utility shows:

 $ ip link set can0 type can help
   Usage: ip link set DEVICE type can
       [ bitrate BITRATE [ sample-point SAMPLE-POINT] ] |
       [ tq TQ prop-seg PROP_SEG phase-seg1 PHASE-SEG1
         phase-seg2 PHASE-SEG2 [ sjw SJW ] ]

I actually hesitate to extend can_calc_bittiming(). I suggest using an
external tool to calculate proper bit-timing parameters and set them
with "ip link set DEVICE type can tq ...".

See also:

http://lxr.linux.no/#linux+v3.0.4/Documentation/networking/can.txt#L742

Wolfgang.

^ permalink raw reply

* [net-next-2.6 PATCH 0/3] enic: updates to version 2.1.1.28
From: Roopa Prabhu @ 2011-09-22 13:44 UTC (permalink / raw)
  To: netdev; +Cc: davem

This patch series implements the following enic driver updates:

01/3 - Add SRIOV support
02/3 - Helper code for SRIOV proxy commands
03/3 - Add support for port profile association on a enic SRIOV VF

Signed-off-by: Roopa Prabhu <roprabhu@cisco.com>
Signed-off-by: Sujith Sankar <ssujith@cisco.com>
Signed-off-by: Christian Benvenuti <benve@cisco.com>
Signed-off-by: David Wang <dwang2@cisco.com>

^ permalink raw reply

* [net-next-2.6 PATCH 1/3] enic: Add SRIOV support
From: Roopa Prabhu @ 2011-09-22 13:44 UTC (permalink / raw)
  To: netdev; +Cc: davem
In-Reply-To: <20110922134410.2145.72210.stgit@savbu-pc100.cisco.com>

From: Roopa Prabhu <roprabhu@cisco.com>

This patch adds support to enable SRIOV on enic devices. Enic SRIOV VF's are dynamic vnics and will use the same driver code as dynamic vnics.

Signed-off-by: Roopa Prabhu <roprabhu@cisco.com>
Signed-off-by: Sujith Sankar <ssujith@cisco.com>
Signed-off-by: Christian Benvenuti <benve@cisco.com>
Signed-off-by: David Wang <dwang2@cisco.com>
---
 drivers/net/ethernet/cisco/enic/enic.h      |   11 ++++++
 drivers/net/ethernet/cisco/enic/enic_main.c |   48 ++++++++++++++++++++++++++-
 2 files changed, 57 insertions(+), 2 deletions(-)


diff --git a/drivers/net/ethernet/cisco/enic/enic.h b/drivers/net/ethernet/cisco/enic/enic.h
index ce76d9a..13ff78e 100644
--- a/drivers/net/ethernet/cisco/enic/enic.h
+++ b/drivers/net/ethernet/cisco/enic/enic.h
@@ -32,7 +32,7 @@
 
 #define DRV_NAME		"enic"
 #define DRV_DESCRIPTION		"Cisco VIC Ethernet NIC Driver"
-#define DRV_VERSION		"2.1.1.24"
+#define DRV_VERSION		"2.1.1.28"
 #define DRV_COPYRIGHT		"Copyright 2008-2011 Cisco Systems, Inc"
 
 #define ENIC_BARS_MAX		6
@@ -49,6 +49,10 @@ struct enic_msix_entry {
 	void *devid;
 };
 
+/* priv_flags */
+#define ENIC_SRIOV_ENABLED		(1 << 0)
+
+/* enic port profile set flags */
 #define ENIC_PORT_REQUEST_APPLIED	(1 << 0)
 #define ENIC_SET_REQUEST		(1 << 1)
 #define ENIC_SET_NAME			(1 << 2)
@@ -83,11 +87,15 @@ struct enic {
 	u8 mc_addr[ENIC_MULTICAST_PERFECT_FILTERS][ETH_ALEN];
 	u8 uc_addr[ENIC_UNICAST_PERFECT_FILTERS][ETH_ALEN];
 	unsigned int flags;
+	unsigned int priv_flags;
 	unsigned int mc_count;
 	unsigned int uc_count;
 	u32 port_mtu;
 	u32 rx_coalesce_usecs;
 	u32 tx_coalesce_usecs;
+#ifdef CONFIG_PCI_IOV
+	u32 num_vfs;
+#endif
 	struct enic_port_profile pp;
 
 	/* work queue cache line section */
@@ -120,5 +128,6 @@ static inline struct device *enic_get_dev(struct enic *enic)
 }
 
 void enic_reset_addr_lists(struct enic *enic);
+int enic_sriov_enabled(struct enic *enic);
 
 #endif /* _ENIC_H_ */
diff --git a/drivers/net/ethernet/cisco/enic/enic_main.c b/drivers/net/ethernet/cisco/enic/enic_main.c
index c751c25..ad6580e 100644
--- a/drivers/net/ethernet/cisco/enic/enic_main.c
+++ b/drivers/net/ethernet/cisco/enic/enic_main.c
@@ -127,6 +127,11 @@ static int enic_is_dynamic(struct enic *enic)
 	return enic->pdev->device == PCI_DEVICE_ID_CISCO_VIC_ENET_DYN;
 }
 
+int enic_sriov_enabled(struct enic *enic)
+{
+	return (enic->priv_flags & ENIC_SRIOV_ENABLED) ? 1 : 0;
+}
+
 static inline unsigned int enic_cq_rq(struct enic *enic, unsigned int rq)
 {
 	return rq;
@@ -2240,6 +2245,9 @@ static int __devinit enic_probe(struct pci_dev *pdev,
 	int using_dac = 0;
 	unsigned int i;
 	int err;
+#ifdef CONFIG_PCI_IOV
+	int pos = 0;
+#endif
 
 	/* Allocate net device structure and initialize.  Private
 	 * instance data is initialized to zero.
@@ -2331,13 +2339,32 @@ static int __devinit enic_probe(struct pci_dev *pdev,
 		goto err_out_iounmap;
 	}
 
+#ifdef CONFIG_PCI_IOV
+	/* Get number of subvnics */
+	pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_SRIOV);
+	if (pos) {
+		pci_read_config_word(pdev, pos + PCI_SRIOV_TOTAL_VF,
+			(u16 *)&enic->num_vfs);
+		if (enic->num_vfs) {
+			err = pci_enable_sriov(pdev, enic->num_vfs);
+			if (err) {
+				dev_err(dev, "SRIOV enable failed, aborting."
+					" pci_enable_sriov() returned %d\n",
+					err);
+				goto err_out_vnic_unregister;
+			}
+			enic->priv_flags |= ENIC_SRIOV_ENABLED;
+		}
+	}
+
+#endif
 	/* Issue device open to get device in known state
 	 */
 
 	err = enic_dev_open(enic);
 	if (err) {
 		dev_err(dev, "vNIC dev open failed, aborting\n");
-		goto err_out_vnic_unregister;
+		goto err_out_disable_sriov;
 	}
 
 	/* Setup devcmd lock
@@ -2404,6 +2431,12 @@ static int __devinit enic_probe(struct pci_dev *pdev,
 	enic->port_mtu = enic->config.mtu;
 	(void)enic_change_mtu(netdev, enic->port_mtu);
 
+#ifdef CONFIG_PCI_IOV
+	if (enic_is_dynamic(enic) && pdev->is_virtfn &&
+		is_zero_ether_addr(enic->mac_addr))
+		random_ether_addr(enic->mac_addr);
+#endif
+
 	err = enic_set_mac_addr(netdev, enic->mac_addr);
 	if (err) {
 		dev_err(dev, "Invalid MAC address, aborting\n");
@@ -2455,8 +2488,15 @@ err_out_dev_deinit:
 	enic_dev_deinit(enic);
 err_out_dev_close:
 	vnic_dev_close(enic->vdev);
+err_out_disable_sriov:
+#ifdef CONFIG_PCI_IOV
+	if (enic_sriov_enabled(enic)) {
+		pci_disable_sriov(pdev);
+		enic->priv_flags &= ~ENIC_SRIOV_ENABLED;
+	}
 err_out_vnic_unregister:
 	vnic_dev_unregister(enic->vdev);
+#endif
 err_out_iounmap:
 	enic_iounmap(enic);
 err_out_release_regions:
@@ -2482,6 +2522,12 @@ static void __devexit enic_remove(struct pci_dev *pdev)
 		unregister_netdev(netdev);
 		enic_dev_deinit(enic);
 		vnic_dev_close(enic->vdev);
+#ifdef CONFIG_PCI_IOV
+		if (enic_sriov_enabled(enic)) {
+			pci_disable_sriov(pdev);
+			enic->priv_flags &= ~ENIC_SRIOV_ENABLED;
+		}
+#endif
 		vnic_dev_unregister(enic->vdev);
 		enic_iounmap(enic);
 		pci_release_regions(pdev);

^ permalink raw reply related

* [net-next-2.6 PATCH 2/3] enic: Helper code for SRIOV proxy commands
From: Roopa Prabhu @ 2011-09-22 13:44 UTC (permalink / raw)
  To: netdev; +Cc: davem
In-Reply-To: <20110922134410.2145.72210.stgit@savbu-pc100.cisco.com>

From: Roopa Prabhu <roprabhu@cisco.com>

This patch adds helper functions to use PF as proxy for SRIOV VF firmware
commands.

Signed-off-by: Roopa Prabhu <roprabhu@cisco.com>
Signed-off-by: Sujith Sankar <ssujith@cisco.com>
Signed-off-by: Christian Benvenuti <benve@cisco.com>
Signed-off-by: David Wang <dwang2@cisco.com>
---
 drivers/net/ethernet/cisco/enic/enic.h      |    1 +
 drivers/net/ethernet/cisco/enic/enic_dev.h  |   19 ++++++++++++++++++
 drivers/net/ethernet/cisco/enic/enic_main.c |    9 +++++++++
 drivers/net/ethernet/cisco/enic/vnic_dev.c  |   28 ++++++++++++++++++++++-----
 drivers/net/ethernet/cisco/enic/vnic_dev.h  |    2 ++
 5 files changed, 54 insertions(+), 5 deletions(-)


diff --git a/drivers/net/ethernet/cisco/enic/enic.h b/drivers/net/ethernet/cisco/enic/enic.h
index 13ff78e..8c5cfb5 100644
--- a/drivers/net/ethernet/cisco/enic/enic.h
+++ b/drivers/net/ethernet/cisco/enic/enic.h
@@ -129,5 +129,6 @@ static inline struct device *enic_get_dev(struct enic *enic)
 
 void enic_reset_addr_lists(struct enic *enic);
 int enic_sriov_enabled(struct enic *enic);
+int enic_is_valid_vf(struct enic *enic, int vf);
 
 #endif /* _ENIC_H_ */
diff --git a/drivers/net/ethernet/cisco/enic/enic_dev.h b/drivers/net/ethernet/cisco/enic/enic_dev.h
index ff8e87f..1f83a47 100644
--- a/drivers/net/ethernet/cisco/enic/enic_dev.h
+++ b/drivers/net/ethernet/cisco/enic/enic_dev.h
@@ -19,6 +19,25 @@
 #ifndef _ENIC_DEV_H_
 #define _ENIC_DEV_H_
 
+#include "vnic_dev.h"
+
+/*
+ * Calls the devcmd function given by argument vnicdevcmdfn.
+ * If vf argument is valid, it proxies the devcmd
+ */
+#define ENIC_DEVCMD_PROXY_BY_INDEX(vf, err, enic, vnicdevcmdfn, ...) \
+	do { \
+		spin_lock(&enic->devcmd_lock); \
+		if (enic_is_valid_vf(enic, vf)) { \
+			vnic_dev_cmd_proxy_by_index_start(enic->vdev, vf); \
+			err = vnicdevcmdfn(enic->vdev, ##__VA_ARGS__); \
+			vnic_dev_cmd_proxy_end(enic->vdev); \
+		} else { \
+			err = vnicdevcmdfn(enic->vdev, ##__VA_ARGS__); \
+		} \
+		spin_unlock(&enic->devcmd_lock); \
+	} while (0)
+
 int enic_dev_fw_info(struct enic *enic, struct vnic_devcmd_fw_info **fw_info);
 int enic_dev_stats_dump(struct enic *enic, struct vnic_stats **vstats);
 int enic_dev_add_station_addr(struct enic *enic);
diff --git a/drivers/net/ethernet/cisco/enic/enic_main.c b/drivers/net/ethernet/cisco/enic/enic_main.c
index ad6580e..154cb99 100644
--- a/drivers/net/ethernet/cisco/enic/enic_main.c
+++ b/drivers/net/ethernet/cisco/enic/enic_main.c
@@ -132,6 +132,15 @@ int enic_sriov_enabled(struct enic *enic)
 	return (enic->priv_flags & ENIC_SRIOV_ENABLED) ? 1 : 0;
 }
 
+int enic_is_valid_vf(struct enic *enic, int vf)
+{
+#ifdef CONFIG_PCI_IOV
+	return vf >= 0 && vf < enic->num_vfs;
+#else
+	return 0;
+#endif
+}
+
 static inline unsigned int enic_cq_rq(struct enic *enic, unsigned int rq)
 {
 	return rq;
diff --git a/drivers/net/ethernet/cisco/enic/vnic_dev.c b/drivers/net/ethernet/cisco/enic/vnic_dev.c
index 8c4c8cf..31e7f9b 100644
--- a/drivers/net/ethernet/cisco/enic/vnic_dev.c
+++ b/drivers/net/ethernet/cisco/enic/vnic_dev.c
@@ -32,6 +32,7 @@
 enum vnic_proxy_type {
 	PROXY_NONE,
 	PROXY_BY_BDF,
+	PROXY_BY_INDEX,
 };
 
 struct vnic_res {
@@ -328,20 +329,21 @@ static int _vnic_dev_cmd(struct vnic_dev *vdev, enum vnic_devcmd_cmd cmd,
 	return -ETIMEDOUT;
 }
 
-static int vnic_dev_cmd_proxy_by_bdf(struct vnic_dev *vdev,
-	enum vnic_devcmd_cmd cmd, u64 *a0, u64 *a1, int wait)
+static int vnic_dev_cmd_proxy(struct vnic_dev *vdev,
+	enum vnic_devcmd_cmd proxy_cmd, enum vnic_devcmd_cmd cmd,
+	u64 *a0, u64 *a1, int wait)
 {
 	u32 status;
 	int err;
 
 	memset(vdev->args, 0, sizeof(vdev->args));
 
-	vdev->args[0] = vdev->proxy_index; /* bdf */
+	vdev->args[0] = vdev->proxy_index;
 	vdev->args[1] = cmd;
 	vdev->args[2] = *a0;
 	vdev->args[3] = *a1;
 
-	err = _vnic_dev_cmd(vdev, CMD_PROXY_BY_BDF, wait);
+	err = _vnic_dev_cmd(vdev, proxy_cmd, wait);
 	if (err)
 		return err;
 
@@ -376,14 +378,30 @@ static int vnic_dev_cmd_no_proxy(struct vnic_dev *vdev,
 	return err;
 }
 
+void vnic_dev_cmd_proxy_by_index_start(struct vnic_dev *vdev, u16 index)
+{
+	vdev->proxy = PROXY_BY_INDEX;
+	vdev->proxy_index = index;
+}
+
+void vnic_dev_cmd_proxy_end(struct vnic_dev *vdev)
+{
+	vdev->proxy = PROXY_NONE;
+	vdev->proxy_index = 0;
+}
+
 int vnic_dev_cmd(struct vnic_dev *vdev, enum vnic_devcmd_cmd cmd,
 	u64 *a0, u64 *a1, int wait)
 {
 	memset(vdev->args, 0, sizeof(vdev->args));
 
 	switch (vdev->proxy) {
+	case PROXY_BY_INDEX:
+		return vnic_dev_cmd_proxy(vdev, CMD_PROXY_BY_INDEX, cmd,
+				a0, a1, wait);
 	case PROXY_BY_BDF:
-		return vnic_dev_cmd_proxy_by_bdf(vdev, cmd, a0, a1, wait);
+		return vnic_dev_cmd_proxy(vdev, CMD_PROXY_BY_BDF, cmd,
+				a0, a1, wait);
 	case PROXY_NONE:
 	default:
 		return vnic_dev_cmd_no_proxy(vdev, cmd, a0, a1, wait);
diff --git a/drivers/net/ethernet/cisco/enic/vnic_dev.h b/drivers/net/ethernet/cisco/enic/vnic_dev.h
index 852b698..6a138b6 100644
--- a/drivers/net/ethernet/cisco/enic/vnic_dev.h
+++ b/drivers/net/ethernet/cisco/enic/vnic_dev.h
@@ -85,6 +85,8 @@ void vnic_dev_free_desc_ring(struct vnic_dev *vdev,
 	struct vnic_dev_ring *ring);
 int vnic_dev_cmd(struct vnic_dev *vdev, enum vnic_devcmd_cmd cmd,
 	u64 *a0, u64 *a1, int wait);
+void vnic_dev_cmd_proxy_by_index_start(struct vnic_dev *vdev, u16 index);
+void vnic_dev_cmd_proxy_end(struct vnic_dev *vdev);
 int vnic_dev_fw_info(struct vnic_dev *vdev,
 	struct vnic_devcmd_fw_info **fw_info);
 int vnic_dev_spec(struct vnic_dev *vdev, unsigned int offset, unsigned int size,

^ permalink raw reply related

* [net-next-2.6 PATCH 3/3] enic: Add support for port profile association on a enic SRIOV VF
From: Roopa Prabhu @ 2011-09-22 13:44 UTC (permalink / raw)
  To: netdev; +Cc: davem
In-Reply-To: <20110922134410.2145.72210.stgit@savbu-pc100.cisco.com>

From: Roopa Prabhu <roprabhu@cisco.com>

This patch touchs most of the enic port profile handling code.
Tried to break it into sub patches without success.

The patch mainly does the following:
- Port profile operations for a SRIOV VF are modified to work
  only via its PF
- Changes the port profile static struct in struct enic to a pointer.
  This is because a SRIOV PF has to now hold the port profile information
  for all its VF's
- Moved address registration for VF's during port profile ASSOCIATE time
- Most changes in port profile handling code are changes related to indexing
  into the port profile struct array of a PF for the VF port profile
  information

Signed-off-by: Roopa Prabhu <roprabhu@cisco.com>
Signed-off-by: Sujith Sankar <ssujith@cisco.com>
Signed-off-by: Christian Benvenuti <benve@cisco.com>
Signed-off-by: David Wang <dwang2@cisco.com>
---
 drivers/net/ethernet/cisco/enic/enic.h      |    3 
 drivers/net/ethernet/cisco/enic/enic_main.c |  118 ++++++++++-------
 drivers/net/ethernet/cisco/enic/enic_pp.c   |  192 +++++++++++++++++++++------
 drivers/net/ethernet/cisco/enic/enic_pp.h   |   15 ++
 4 files changed, 232 insertions(+), 96 deletions(-)


diff --git a/drivers/net/ethernet/cisco/enic/enic.h b/drivers/net/ethernet/cisco/enic/enic.h
index 8c5cfb5..fe0c29a 100644
--- a/drivers/net/ethernet/cisco/enic/enic.h
+++ b/drivers/net/ethernet/cisco/enic/enic.h
@@ -96,7 +96,7 @@ struct enic {
 #ifdef CONFIG_PCI_IOV
 	u32 num_vfs;
 #endif
-	struct enic_port_profile pp;
+	struct enic_port_profile *pp;
 
 	/* work queue cache line section */
 	____cacheline_aligned struct vnic_wq wq[ENIC_WQ_MAX];
@@ -130,5 +130,6 @@ static inline struct device *enic_get_dev(struct enic *enic)
 void enic_reset_addr_lists(struct enic *enic);
 int enic_sriov_enabled(struct enic *enic);
 int enic_is_valid_vf(struct enic *enic, int vf);
+int enic_is_dynamic(struct enic *enic);
 
 #endif /* _ENIC_H_ */
diff --git a/drivers/net/ethernet/cisco/enic/enic_main.c b/drivers/net/ethernet/cisco/enic/enic_main.c
index 154cb99..bf95348 100644
--- a/drivers/net/ethernet/cisco/enic/enic_main.c
+++ b/drivers/net/ethernet/cisco/enic/enic_main.c
@@ -122,7 +122,7 @@ static const struct enic_stat enic_rx_stats[] = {
 static const unsigned int enic_n_tx_stats = ARRAY_SIZE(enic_tx_stats);
 static const unsigned int enic_n_rx_stats = ARRAY_SIZE(enic_rx_stats);
 
-static int enic_is_dynamic(struct enic *enic)
+int enic_is_dynamic(struct enic *enic)
 {
 	return enic->pdev->device == PCI_DEVICE_ID_CISCO_VIC_ENET_DYN;
 }
@@ -1054,15 +1054,15 @@ static void enic_tx_timeout(struct net_device *netdev)
 static int enic_set_vf_mac(struct net_device *netdev, int vf, u8 *mac)
 {
 	struct enic *enic = netdev_priv(netdev);
+	struct enic_port_profile *pp;
+	int err;
 
-	if (vf != PORT_SELF_VF)
-		return -EOPNOTSUPP;
+	ENIC_PP_BY_INDEX(enic, vf, pp, &err);
+	if (err)
+		return err;
 
-	/* Ignore the vf argument for now. We can assume the request
-	 * is coming on a vf.
-	 */
 	if (is_valid_ether_addr(mac)) {
-		memcpy(enic->pp.vf_mac, mac, ETH_ALEN);
+		memcpy(pp->vf_mac, mac, ETH_ALEN);
 		return 0;
 	} else
 		return -EINVAL;
@@ -1073,71 +1073,74 @@ static int enic_set_vf_port(struct net_device *netdev, int vf,
 {
 	struct enic *enic = netdev_priv(netdev);
 	struct enic_port_profile prev_pp;
+	struct enic_port_profile *pp;
 	int err = 0, restore_pp = 1;
 
-	/* don't support VFs, yet */
-	if (vf != PORT_SELF_VF)
-		return -EOPNOTSUPP;
+	ENIC_PP_BY_INDEX(enic, vf, pp, &err);
+	if (err)
+		return err;
 
 	if (!port[IFLA_PORT_REQUEST])
 		return -EOPNOTSUPP;
 
-	memcpy(&prev_pp, &enic->pp, sizeof(enic->pp));
-	memset(&enic->pp, 0, sizeof(enic->pp));
+	memcpy(&prev_pp, pp, sizeof(*enic->pp));
+	memset(pp, 0, sizeof(*enic->pp));
 
-	enic->pp.set |= ENIC_SET_REQUEST;
-	enic->pp.request = nla_get_u8(port[IFLA_PORT_REQUEST]);
+	pp->set |= ENIC_SET_REQUEST;
+	pp->request = nla_get_u8(port[IFLA_PORT_REQUEST]);
 
 	if (port[IFLA_PORT_PROFILE]) {
-		enic->pp.set |= ENIC_SET_NAME;
-		memcpy(enic->pp.name, nla_data(port[IFLA_PORT_PROFILE]),
+		pp->set |= ENIC_SET_NAME;
+		memcpy(pp->name, nla_data(port[IFLA_PORT_PROFILE]),
 			PORT_PROFILE_MAX);
 	}
 
 	if (port[IFLA_PORT_INSTANCE_UUID]) {
-		enic->pp.set |= ENIC_SET_INSTANCE;
-		memcpy(enic->pp.instance_uuid,
+		pp->set |= ENIC_SET_INSTANCE;
+		memcpy(pp->instance_uuid,
 			nla_data(port[IFLA_PORT_INSTANCE_UUID]), PORT_UUID_MAX);
 	}
 
 	if (port[IFLA_PORT_HOST_UUID]) {
-		enic->pp.set |= ENIC_SET_HOST;
-		memcpy(enic->pp.host_uuid,
+		pp->set |= ENIC_SET_HOST;
+		memcpy(pp->host_uuid,
 			nla_data(port[IFLA_PORT_HOST_UUID]), PORT_UUID_MAX);
 	}
 
 	/* Special case handling: mac came from IFLA_VF_MAC */
 	if (!is_zero_ether_addr(prev_pp.vf_mac))
-		memcpy(enic->pp.mac_addr, prev_pp.vf_mac, ETH_ALEN);
+		memcpy(pp->mac_addr, prev_pp.vf_mac, ETH_ALEN);
 
-		if (is_zero_ether_addr(netdev->dev_addr))
-			random_ether_addr(netdev->dev_addr);
+	if (vf == PORT_SELF_VF && is_zero_ether_addr(netdev->dev_addr))
+		random_ether_addr(netdev->dev_addr);
 
-	err = enic_process_set_pp_request(enic, &prev_pp, &restore_pp);
+	err = enic_process_set_pp_request(enic, vf, &prev_pp, &restore_pp);
 	if (err) {
 		if (restore_pp) {
 			/* Things are still the way they were: Implicit
 			 * DISASSOCIATE failed
 			 */
-			memcpy(&enic->pp, &prev_pp, sizeof(enic->pp));
+			memcpy(pp, &prev_pp, sizeof(*pp));
 		} else {
-			memset(&enic->pp, 0, sizeof(enic->pp));
-			memset(netdev->dev_addr, 0, ETH_ALEN);
+			memset(pp, 0, sizeof(*pp));
+			if (vf == PORT_SELF_VF)
+				memset(netdev->dev_addr, 0, ETH_ALEN);
 		}
 	} else {
 		/* Set flag to indicate that the port assoc/disassoc
 		 * request has been sent out to fw
 		 */
-		enic->pp.set |= ENIC_PORT_REQUEST_APPLIED;
+		pp->set |= ENIC_PORT_REQUEST_APPLIED;
 
 		/* If DISASSOCIATE, clean up all assigned/saved macaddresses */
-		if (enic->pp.request == PORT_REQUEST_DISASSOCIATE) {
-			memset(enic->pp.mac_addr, 0, ETH_ALEN);
-			memset(netdev->dev_addr, 0, ETH_ALEN);
+		if (pp->request == PORT_REQUEST_DISASSOCIATE) {
+			memset(pp->mac_addr, 0, ETH_ALEN);
+			if (vf == PORT_SELF_VF)
+				memset(netdev->dev_addr, 0, ETH_ALEN);
 		}
 	}
 
-	memset(enic->pp.vf_mac, 0, ETH_ALEN);
+	memset(pp->vf_mac, 0, ETH_ALEN);
 
 	return err;
 }
@@ -1147,26 +1150,31 @@ static int enic_get_vf_port(struct net_device *netdev, int vf,
 {
 	struct enic *enic = netdev_priv(netdev);
 	u16 response = PORT_PROFILE_RESPONSE_SUCCESS;
+	struct enic_port_profile *pp;
 	int err;
 
-	if (!(enic->pp.set & ENIC_PORT_REQUEST_APPLIED))
+	ENIC_PP_BY_INDEX(enic, vf, pp, &err);
+	if (err)
+		return err;
+
+	if (!(pp->set & ENIC_PORT_REQUEST_APPLIED))
 		return -ENODATA;
 
-	err = enic_process_get_pp_request(enic, enic->pp.request, &response);
+	err = enic_process_get_pp_request(enic, vf, pp->request, &response);
 	if (err)
 		return err;
 
-	NLA_PUT_U16(skb, IFLA_PORT_REQUEST, enic->pp.request);
+	NLA_PUT_U16(skb, IFLA_PORT_REQUEST, pp->request);
 	NLA_PUT_U16(skb, IFLA_PORT_RESPONSE, response);
-	if (enic->pp.set & ENIC_SET_NAME)
+	if (pp->set & ENIC_SET_NAME)
 		NLA_PUT(skb, IFLA_PORT_PROFILE, PORT_PROFILE_MAX,
-			enic->pp.name);
-	if (enic->pp.set & ENIC_SET_INSTANCE)
+			pp->name);
+	if (pp->set & ENIC_SET_INSTANCE)
 		NLA_PUT(skb, IFLA_PORT_INSTANCE_UUID, PORT_UUID_MAX,
-			enic->pp.instance_uuid);
-	if (enic->pp.set & ENIC_SET_HOST)
+			pp->instance_uuid);
+	if (pp->set & ENIC_SET_HOST)
 		NLA_PUT(skb, IFLA_PORT_HOST_UUID, PORT_UUID_MAX,
-			enic->pp.host_uuid);
+			pp->host_uuid);
 
 	return 0;
 
@@ -1600,10 +1608,9 @@ static int enic_open(struct net_device *netdev)
 	for (i = 0; i < enic->rq_count; i++)
 		vnic_rq_enable(&enic->rq[i]);
 
-	if (enic_is_dynamic(enic) && !is_zero_ether_addr(enic->pp.mac_addr))
-		enic_dev_add_addr(enic, enic->pp.mac_addr);
-	else
+	if (!enic_is_dynamic(enic))
 		enic_dev_add_station_addr(enic);
+
 	enic_set_rx_mode(netdev);
 
 	netif_wake_queue(netdev);
@@ -1651,9 +1658,8 @@ static int enic_stop(struct net_device *netdev)
 
 	netif_carrier_off(netdev);
 	netif_tx_disable(netdev);
-	if (enic_is_dynamic(enic) && !is_zero_ether_addr(enic->pp.mac_addr))
-		enic_dev_del_addr(enic, enic->pp.mac_addr);
-	else
+
+	if (!enic_is_dynamic(enic))
 		enic_dev_del_station_addr(enic);
 
 	for (i = 0; i < enic->wq_count; i++) {
@@ -2143,6 +2149,9 @@ static const struct net_device_ops enic_netdev_ops = {
 	.ndo_vlan_rx_add_vid	= enic_vlan_rx_add_vid,
 	.ndo_vlan_rx_kill_vid	= enic_vlan_rx_kill_vid,
 	.ndo_tx_timeout		= enic_tx_timeout,
+	.ndo_set_vf_port	= enic_set_vf_port,
+	.ndo_get_vf_port	= enic_get_vf_port,
+	.ndo_set_vf_mac		= enic_set_vf_mac,
 #ifdef CONFIG_NET_POLL_CONTROLLER
 	.ndo_poll_controller	= enic_poll_controller,
 #endif
@@ -2254,6 +2263,7 @@ static int __devinit enic_probe(struct pci_dev *pdev,
 	int using_dac = 0;
 	unsigned int i;
 	int err;
+	int num_pps = 1;
 #ifdef CONFIG_PCI_IOV
 	int pos = 0;
 #endif
@@ -2363,17 +2373,26 @@ static int __devinit enic_probe(struct pci_dev *pdev,
 				goto err_out_vnic_unregister;
 			}
 			enic->priv_flags |= ENIC_SRIOV_ENABLED;
+			num_pps = enic->num_vfs;
 		}
 	}
 
 #endif
+	/* Allocate structure for port profiles */
+	enic->pp = kzalloc(num_pps * sizeof(*enic->pp), GFP_KERNEL);
+	if (!enic->pp) {
+		pr_err("port profile alloc failed, aborting\n");
+		err = -ENOMEM;
+		goto err_out_disable_sriov;
+	}
+
 	/* Issue device open to get device in known state
 	 */
 
 	err = enic_dev_open(enic);
 	if (err) {
 		dev_err(dev, "vNIC dev open failed, aborting\n");
-		goto err_out_disable_sriov;
+		goto err_out_free_pp;
 	}
 
 	/* Setup devcmd lock
@@ -2497,6 +2516,8 @@ err_out_dev_deinit:
 	enic_dev_deinit(enic);
 err_out_dev_close:
 	vnic_dev_close(enic->vdev);
+err_out_free_pp:
+	kfree(enic->pp);
 err_out_disable_sriov:
 #ifdef CONFIG_PCI_IOV
 	if (enic_sriov_enabled(enic)) {
@@ -2537,6 +2558,7 @@ static void __devexit enic_remove(struct pci_dev *pdev)
 			enic->priv_flags &= ~ENIC_SRIOV_ENABLED;
 		}
 #endif
+		kfree(enic->pp);
 		vnic_dev_unregister(enic->vdev);
 		enic_iounmap(enic);
 		pci_release_regions(pdev);
diff --git a/drivers/net/ethernet/cisco/enic/enic_pp.c b/drivers/net/ethernet/cisco/enic/enic_pp.c
index ffaa75d..22bf03a 100644
--- a/drivers/net/ethernet/cisco/enic/enic_pp.c
+++ b/drivers/net/ethernet/cisco/enic/enic_pp.c
@@ -29,10 +29,47 @@
 #include "enic_res.h"
 #include "enic.h"
 #include "enic_dev.h"
+#include "enic_pp.h"
 
-static int enic_set_port_profile(struct enic *enic)
+/*
+ * Checks validity of vf index that came in
+ * port profile request
+ */
+int enic_is_valid_pp_vf(struct enic *enic, int vf, int *err)
+{
+	if (vf != PORT_SELF_VF) {
+#ifdef CONFIG_PCI_IOV
+		if (enic_sriov_enabled(enic)) {
+			if (vf < 0 || vf >= enic->num_vfs) {
+				*err = -EINVAL;
+				goto err_out;
+			}
+		} else {
+			*err = -EOPNOTSUPP;
+			goto err_out;
+		}
+#else
+		*err = -EOPNOTSUPP;
+		goto err_out;
+#endif
+	}
+
+	if (vf == PORT_SELF_VF && !enic_is_dynamic(enic)) {
+		*err = -EOPNOTSUPP;
+		goto err_out;
+	}
+
+	*err = 0;
+	return 1;
+
+err_out:
+	return 0;
+}
+
+static int enic_set_port_profile(struct enic *enic, int vf)
 {
 	struct net_device *netdev = enic->netdev;
+	struct enic_port_profile *pp;
 	struct vic_provinfo *vp;
 	const u8 oui[3] = VIC_PROVINFO_CISCO_OUI;
 	const u16 os_type = htons(VIC_GENERIC_PROV_OS_TYPE_LINUX);
@@ -41,7 +78,11 @@ static int enic_set_port_profile(struct enic *enic)
 	u8 *client_mac;
 	int err;
 
-	if (!(enic->pp.set & ENIC_SET_NAME) || !strlen(enic->pp.name))
+	ENIC_PP_BY_INDEX(enic, vf, pp, &err);
+	if (err)
+		return err;
+
+	if (!(pp->set & ENIC_SET_NAME) || !strlen(pp->name))
 		return -EINVAL;
 
 	vp = vic_provinfo_alloc(GFP_KERNEL, oui,
@@ -51,12 +92,18 @@ static int enic_set_port_profile(struct enic *enic)
 
 	VIC_PROVINFO_ADD_TLV(vp,
 		VIC_GENERIC_PROV_TLV_PORT_PROFILE_NAME_STR,
-		strlen(enic->pp.name) + 1, enic->pp.name);
+		strlen(pp->name) + 1, pp->name);
 
-	if (!is_zero_ether_addr(enic->pp.mac_addr))
-		client_mac = enic->pp.mac_addr;
-	else
+	if (!is_zero_ether_addr(pp->mac_addr)) {
+		client_mac = pp->mac_addr;
+	} else if (vf == PORT_SELF_VF) {
 		client_mac = netdev->dev_addr;
+	} else {
+		netdev_err(netdev, "Cannot find pp mac address "
+			"for VF %d\n", vf);
+		err = -EINVAL;
+		goto add_tlv_failure;
+	}
 
 	VIC_PROVINFO_ADD_TLV(vp,
 		VIC_GENERIC_PROV_TLV_CLIENT_MAC_ADDR,
@@ -67,15 +114,15 @@ static int enic_set_port_profile(struct enic *enic)
 		VIC_GENERIC_PROV_TLV_CLUSTER_PORT_UUID_STR,
 		sizeof(client_mac_str), client_mac_str);
 
-	if (enic->pp.set & ENIC_SET_INSTANCE) {
-		sprintf(uuid_str, "%pUB", enic->pp.instance_uuid);
+	if (pp->set & ENIC_SET_INSTANCE) {
+		sprintf(uuid_str, "%pUB", pp->instance_uuid);
 		VIC_PROVINFO_ADD_TLV(vp,
 			VIC_GENERIC_PROV_TLV_CLIENT_UUID_STR,
 			sizeof(uuid_str), uuid_str);
 	}
 
-	if (enic->pp.set & ENIC_SET_HOST) {
-		sprintf(uuid_str, "%pUB", enic->pp.host_uuid);
+	if (pp->set & ENIC_SET_HOST) {
+		sprintf(uuid_str, "%pUB", pp->host_uuid);
 		VIC_PROVINFO_ADD_TLV(vp,
 			VIC_GENERIC_PROV_TLV_HOST_UUID_STR,
 			sizeof(uuid_str), uuid_str);
@@ -85,7 +132,9 @@ static int enic_set_port_profile(struct enic *enic)
 		VIC_GENERIC_PROV_TLV_OS_TYPE,
 		sizeof(os_type), &os_type);
 
-	err = enic_dev_status_to_errno(enic_dev_init_prov2(enic, vp));
+	ENIC_DEVCMD_PROXY_BY_INDEX(vf, err, enic, vnic_dev_init_prov2, (u8 *)vp,
+		vic_provinfo_size(vp));
+	err = enic_dev_status_to_errno(err);
 
 add_tlv_failure:
 	vic_provinfo_free(vp);
@@ -93,15 +142,16 @@ add_tlv_failure:
 	return err;
 }
 
-static int enic_unset_port_profile(struct enic *enic)
+static int enic_unset_port_profile(struct enic *enic, int vf)
 {
 	int err;
 
-	err = enic_vnic_dev_deinit(enic);
+	ENIC_DEVCMD_PROXY_BY_INDEX(vf, err, enic, vnic_dev_deinit);
 	if (err)
 		return enic_dev_status_to_errno(err);
 
-	enic_reset_addr_lists(enic);
+	if (vf == PORT_SELF_VF)
+		enic_reset_addr_lists(enic);
 
 	return 0;
 }
@@ -115,17 +165,18 @@ static int enic_are_pp_different(struct enic_port_profile *pp1,
 		!!memcmp(pp1->mac_addr, pp2->mac_addr, ETH_ALEN);
 }
 
-static int enic_pp_preassociate(struct enic *enic,
+static int enic_pp_preassociate(struct enic *enic, int vf,
 	struct enic_port_profile *prev_pp, int *restore_pp);
-static int enic_pp_disassociate(struct enic *enic,
+static int enic_pp_disassociate(struct enic *enic, int vf,
 	struct enic_port_profile *prev_pp, int *restore_pp);
-static int enic_pp_preassociate_rr(struct enic *enic,
+static int enic_pp_preassociate_rr(struct enic *enic, int vf,
 	struct enic_port_profile *prev_pp, int *restore_pp);
-static int enic_pp_associate(struct enic *enic,
+static int enic_pp_associate(struct enic *enic, int vf,
 	struct enic_port_profile *prev_pp, int *restore_pp);
 
-static int (*enic_pp_handlers[])(struct enic *enic,
-		struct enic_port_profile *prev_state, int *restore_pp) = {
+static int (*enic_pp_handlers[])(struct enic *enic, int vf,
+		struct enic_port_profile *prev_state,
+		int *restore_pp) = {
 	[PORT_REQUEST_PREASSOCIATE]	= enic_pp_preassociate,
 	[PORT_REQUEST_PREASSOCIATE_RR]	= enic_pp_preassociate_rr,
 	[PORT_REQUEST_ASSOCIATE]	= enic_pp_associate,
@@ -135,28 +186,49 @@ static int (*enic_pp_handlers[])(struct enic *enic,
 static const int enic_pp_handlers_count =
 			sizeof(enic_pp_handlers)/sizeof(*enic_pp_handlers);
 
-static int enic_pp_preassociate(struct enic *enic,
+static int enic_pp_preassociate(struct enic *enic, int vf,
 	struct enic_port_profile *prev_pp, int *restore_pp)
 {
 	return -EOPNOTSUPP;
 }
 
-static int enic_pp_disassociate(struct enic *enic,
+static int enic_pp_disassociate(struct enic *enic, int vf,
 	struct enic_port_profile *prev_pp, int *restore_pp)
 {
-	return enic_unset_port_profile(enic);
+	struct net_device *netdev = enic->netdev;
+	struct enic_port_profile *pp;
+	int err;
+
+	ENIC_PP_BY_INDEX(enic, vf, pp, &err);
+	if (err)
+		return err;
+
+	/* Deregister mac addresses */
+	if (!is_zero_ether_addr(pp->mac_addr))
+		ENIC_DEVCMD_PROXY_BY_INDEX(vf, err, enic, vnic_dev_del_addr,
+			pp->mac_addr);
+	else if (!is_zero_ether_addr(netdev->dev_addr))
+		ENIC_DEVCMD_PROXY_BY_INDEX(vf, err, enic, vnic_dev_del_addr,
+			netdev->dev_addr);
+
+	return enic_unset_port_profile(enic, vf);
 }
 
-static int enic_pp_preassociate_rr(struct enic *enic,
+static int enic_pp_preassociate_rr(struct enic *enic, int vf,
 	struct enic_port_profile *prev_pp, int *restore_pp)
 {
+	struct enic_port_profile *pp;
 	int err;
 	int active = 0;
 
-	if (enic->pp.request != PORT_REQUEST_ASSOCIATE) {
+	ENIC_PP_BY_INDEX(enic, vf, pp, &err);
+	if (err)
+		return err;
+
+	if (pp->request != PORT_REQUEST_ASSOCIATE) {
 		/* If pre-associate is not part of an associate.
 		We always disassociate first */
-		err = enic_pp_handlers[PORT_REQUEST_DISASSOCIATE](enic,
+		err = enic_pp_handlers[PORT_REQUEST_DISASSOCIATE](enic, vf,
 			prev_pp, restore_pp);
 		if (err)
 			return err;
@@ -166,29 +238,39 @@ static int enic_pp_preassociate_rr(struct enic *enic,
 
 	*restore_pp = 0;
 
-	err = enic_set_port_profile(enic);
+	err = enic_set_port_profile(enic, vf);
 	if (err)
 		return err;
 
 	/* If pre-associate is not part of an associate. */
-	if (enic->pp.request != PORT_REQUEST_ASSOCIATE)
-		err = enic_dev_status_to_errno(enic_dev_enable2(enic, active));
+	if (pp->request != PORT_REQUEST_ASSOCIATE) {
+		/* Enable device as standby */
+		ENIC_DEVCMD_PROXY_BY_INDEX(vf, err, enic, vnic_dev_enable2,
+			active);
+		err = enic_dev_status_to_errno(err);
+	}
 
 	return err;
 }
 
-static int enic_pp_associate(struct enic *enic,
+static int enic_pp_associate(struct enic *enic, int vf,
 	struct enic_port_profile *prev_pp, int *restore_pp)
 {
+	struct net_device *netdev = enic->netdev;
+	struct enic_port_profile *pp;
 	int err;
 	int active = 1;
 
+	ENIC_PP_BY_INDEX(enic, vf, pp, &err);
+	if (err)
+		return err;
+
 	/* Check if a pre-associate was called before */
 	if (prev_pp->request != PORT_REQUEST_PREASSOCIATE_RR ||
 		(prev_pp->request == PORT_REQUEST_PREASSOCIATE_RR &&
-			enic_are_pp_different(prev_pp, &enic->pp))) {
+			enic_are_pp_different(prev_pp, pp))) {
 		err = enic_pp_handlers[PORT_REQUEST_DISASSOCIATE](
-			enic, prev_pp, restore_pp);
+			enic, vf, prev_pp, restore_pp);
 		if (err)
 			return err;
 
@@ -196,28 +278,48 @@ static int enic_pp_associate(struct enic *enic,
 	}
 
 	err = enic_pp_handlers[PORT_REQUEST_PREASSOCIATE_RR](
-			enic, prev_pp, restore_pp);
+			enic, vf, prev_pp, restore_pp);
 	if (err)
 		return err;
 
 	*restore_pp = 0;
 
-	return enic_dev_status_to_errno(enic_dev_enable2(enic, active));
+	/* Enable device as active */
+	ENIC_DEVCMD_PROXY_BY_INDEX(vf, err, enic, vnic_dev_enable2, active);
+	err = enic_dev_status_to_errno(err);
+	if (err)
+		return err;
+
+	/* Register mac address */
+	if (!is_zero_ether_addr(pp->mac_addr))
+		ENIC_DEVCMD_PROXY_BY_INDEX(vf, err, enic, vnic_dev_add_addr,
+			pp->mac_addr);
+	else if (!is_zero_ether_addr(netdev->dev_addr))
+		ENIC_DEVCMD_PROXY_BY_INDEX(vf, err, enic, vnic_dev_add_addr,
+			netdev->dev_addr);
+
+	return 0;
 }
 
-int enic_process_set_pp_request(struct enic *enic,
+int enic_process_set_pp_request(struct enic *enic, int vf,
 	struct enic_port_profile *prev_pp, int *restore_pp)
 {
-	if (enic->pp.request < enic_pp_handlers_count
-		&& enic_pp_handlers[enic->pp.request])
-		return enic_pp_handlers[enic->pp.request](enic,
-			prev_pp, restore_pp);
-	else
+	struct enic_port_profile *pp;
+	int err;
+
+	ENIC_PP_BY_INDEX(enic, vf, pp, &err);
+	if (err)
+		return err;
+
+	if (pp->request >= enic_pp_handlers_count
+		|| !enic_pp_handlers[pp->request])
 		return -EOPNOTSUPP;
+
+	return enic_pp_handlers[pp->request](enic, vf, prev_pp, restore_pp);
 }
 
-int enic_process_get_pp_request(struct enic *enic, int request,
-	u16 *response)
+int enic_process_get_pp_request(struct enic *enic, int vf,
+	int request, u16 *response)
 {
 	int err, status = ERR_SUCCESS;
 
@@ -225,11 +327,13 @@ int enic_process_get_pp_request(struct enic *enic, int request,
 
 	case PORT_REQUEST_PREASSOCIATE_RR:
 	case PORT_REQUEST_ASSOCIATE:
-		err = enic_dev_enable2_done(enic, &status);
+		ENIC_DEVCMD_PROXY_BY_INDEX(vf, err, enic,
+			vnic_dev_enable2_done, &status);
 		break;
 
 	case PORT_REQUEST_DISASSOCIATE:
-		err = enic_dev_deinit_done(enic, &status);
+		ENIC_DEVCMD_PROXY_BY_INDEX(vf, err, enic,
+			vnic_dev_deinit_done, &status);
 		break;
 
 	default:
diff --git a/drivers/net/ethernet/cisco/enic/enic_pp.h b/drivers/net/ethernet/cisco/enic/enic_pp.h
index 699e365..a09ff39 100644
--- a/drivers/net/ethernet/cisco/enic/enic_pp.h
+++ b/drivers/net/ethernet/cisco/enic/enic_pp.h
@@ -19,9 +19,18 @@
 #ifndef _ENIC_PP_H_
 #define _ENIC_PP_H_
 
-int enic_process_set_pp_request(struct enic *enic,
+#define ENIC_PP_BY_INDEX(enic, vf, pp, err) \
+	do { \
+		if (enic_is_valid_pp_vf(enic, vf, err)) \
+			pp = (vf == PORT_SELF_VF) ? enic->pp : enic->pp + vf; \
+		else \
+			pp = NULL; \
+	} while (0)
+
+int enic_process_set_pp_request(struct enic *enic, int vf,
 	struct enic_port_profile *prev_pp, int *restore_pp);
-int enic_process_get_pp_request(struct enic *enic, int request,
-	u16 *response);
+int enic_process_get_pp_request(struct enic *enic, int vf,
+	int request, u16 *response);
+int enic_is_valid_pp_vf(struct enic *enic, int vf, int *err);
 
 #endif /* _ENIC_PP_H_ */

^ permalink raw reply related

* [PATCH net-next] ehea: Remove sleep at .ndo_get_stats
From: brenohl @ 2011-09-22 14:10 UTC (permalink / raw)
  To: davem; +Cc: netdev, Breno Leitao

Currently ehea ndo_get_stats can sleep in two places, in a hcall
and in a GFP_KERNEL alloc, which is not correct.
This patch creates a workqueue that grabs the information from time
to time from the hardware, and place it into the device structure,
so that, .ndo_get_stats quickly returns the device structure statistics
block.

Signed-off-by: Breno Leitao <leitao@linux.vnet.ibm.com>
---
 drivers/net/ehea/ehea.h      |    1 +
 drivers/net/ehea/ehea_main.c |   20 +++++++++++++++++---
 2 files changed, 18 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ehea/ehea.h b/drivers/net/ehea/ehea.h
index 7dd5e6a..05c39ae 100644
--- a/drivers/net/ehea/ehea.h
+++ b/drivers/net/ehea/ehea.h
@@ -459,6 +459,7 @@ struct ehea_port {
 	struct ehea_mc_list *mc_list;	 /* Multicast MAC addresses */
 	struct ehea_eq *qp_eq;
 	struct work_struct reset_task;
+	struct work_struct stats_task;
 	struct mutex port_lock;
 	char int_aff_name[EHEA_IRQ_NAME_SIZE];
 	int allmulti;			 /* Indicates IFF_ALLMULTI state */
diff --git a/drivers/net/ehea/ehea_main.c b/drivers/net/ehea/ehea_main.c
index be2cb4a..7465553 100644
--- a/drivers/net/ehea/ehea_main.c
+++ b/drivers/net/ehea/ehea_main.c
@@ -330,6 +330,15 @@ out:
 static struct net_device_stats *ehea_get_stats(struct net_device *dev)
 {
 	struct ehea_port *port = netdev_priv(dev);
+
+	return &port->stats;
+}
+
+static void ehea_update_stats(struct work_struct *work)
+{
+	struct ehea_port *port =
+		container_of(work, struct ehea_port, stats_task);
+	struct net_device *dev = port->netdev;
 	struct net_device_stats *stats = &port->stats;
 	struct hcp_ehea_port_cb2 *cb2;
 	u64 hret, rx_packets, tx_packets, rx_bytes = 0, tx_bytes = 0;
@@ -340,7 +349,7 @@ static struct net_device_stats *ehea_get_stats(struct net_device *dev)
 	cb2 = (void *)get_zeroed_page(GFP_KERNEL);
 	if (!cb2) {
 		netdev_err(dev, "no mem for cb2\n");
-		goto out;
+		return;
 	}
 
 	hret = ehea_h_query_ehea_port(port->adapter->handle,
@@ -375,8 +384,6 @@ static struct net_device_stats *ehea_get_stats(struct net_device *dev)
 
 out_herr:
 	free_page((unsigned long)cb2);
-out:
-	return stats;
 }
 
 static void ehea_refill_rq1(struct ehea_port_res *pr, int index, int nr_of_wqes)
@@ -789,6 +796,8 @@ static int ehea_proc_rwqes(struct net_device *dev,
 	ehea_refill_rq2(pr, processed_rq2);
 	ehea_refill_rq3(pr, processed_rq3);
 
+	schedule_work(&port->stats_task);
+
 	return processed;
 }
 
@@ -953,6 +962,7 @@ static int ehea_poll(struct napi_struct *napi, int budget)
 		rx += ehea_proc_rwqes(dev, pr, budget - rx);
 	}
 
+	ehea_update_stats(dev);
 	pr->poll_counter++;
 	return rx;
 }
@@ -2651,6 +2661,7 @@ static int ehea_open(struct net_device *dev)
 	}
 
 	mutex_unlock(&port->port_lock);
+	schedule_work(&port->stats_task);
 
 	return ret;
 }
@@ -2690,6 +2701,7 @@ static int ehea_stop(struct net_device *dev)
 
 	set_bit(__EHEA_DISABLE_PORT_RESET, &port->flags);
 	cancel_work_sync(&port->reset_task);
+	cancel_work_sync(&port->stats_task);
 	mutex_lock(&port->port_lock);
 	netif_stop_queue(dev);
 	port_napi_disable(port);
@@ -3235,6 +3247,7 @@ struct ehea_port *ehea_setup_single_port(struct ehea_adapter *adapter,
 		dev->features |= NETIF_F_LRO;
 
 	INIT_WORK(&port->reset_task, ehea_reset_port);
+	INIT_WORK(&port->stats_task, ehea_update_stats);
 
 	init_waitqueue_head(&port->swqe_avail_wq);
 	init_waitqueue_head(&port->restart_wq);
@@ -3278,6 +3291,7 @@ static void ehea_shutdown_single_port(struct ehea_port *port)
 	struct ehea_adapter *adapter = port->adapter;
 
 	cancel_work_sync(&port->reset_task);
+	cancel_work_sync(&port->stats_task);
 	unregister_netdev(port->netdev);
 	ehea_unregister_port(port);
 	kfree(port->mc_list);
-- 
1.7.1

^ permalink raw reply related

* Introducing open source MSTP daemon
From: Vitalii Demianets @ 2011-09-22 14:27 UTC (permalink / raw)
  To: bridge, netdev
  Cc: Srinivas M.A., Stephen Hemminger, Alex Rozin, Michael Rozhavsky

Good day!
I am happy to introduce open source MSTP daemon:
http://sourceforge.net/p/mstpd

Of course due to current limitations of the Linux bridge code, namely:
 - no integration with VLAN code
 - no support of different FIDs (independent learning)
 - no support of the per-MSTI port states
this daemon is not very useful for the bare Linux box. It can work only with 
support of specialized driver which talks to the MSTP-aware hardware (most of 
the today ethernet switching parts are MSTP-aware and support FIDs and 
per-MSTI port states).
Nevertheless I hope to find some interest in my work. Maybe it will stimulate 
in some way the integration of the Linux bridge and VLAN code, who knows? 
>From the IEEE point of view they are already merged, see 802.1Q-2005 which 
incorporates previous editions of 802.1q and 802.1d and 802.1w/s.

Once again, all interested are welcome. Please review, criticize, test, 
modify, patch, deploy and do other things :) Any kind of feedback is 
extremely welcome :)

-- 
Vitalii Demianets

^ permalink raw reply

* niu: eth0: Transmit timed out, resetting
From: Hans-Juergen Schnitzer @ 2011-09-22 14:27 UTC (permalink / raw)
  To: netdev

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

Hi,

we have installed Scientific Linux 6.1 (Kernel
2.6.32-131.12.1.el6.x86_64) on a server with a Sun Neptune 10g card.
Shortly after transmitting data we get the error

niu: eth0: Transmit timed out, resetting

and the system stops to respond. This behaviour was already reported
before on this list and I was wondering if there is a fix available.

Thank you,
Hans Schnitzer



[-- Attachment #2: S/MIME Cryptographic Signature --]
[-- Type: application/x-pkcs7-signature, Size: 5750 bytes --]

^ permalink raw reply

* Re: [PATCH v3 2/7] socket: initial cgroup code.
From: Balbir Singh @ 2011-09-22 15:09 UTC (permalink / raw)
  To: Greg Thelen
  Cc: Glauber Costa, linux-kernel, paul, lizf, kamezawa.hiroyu,
	ebiederm, davem, netdev, linux-mm, kirill
In-Reply-To: <CAHH2K0Z_2LJPL0sLVHqkh_6b_BLQnknULTB9a9WfEuibk5kONg@mail.gmail.com>

On Thu, Sep 22, 2011 at 11:30 AM, Greg Thelen <gthelen@google.com> wrote:
> On Wed, Sep 21, 2011 at 11:59 AM, Glauber Costa <glommer@parallels.com> wrote:
>> Right now I am working under the assumption that tasks are long lived inside
>> the cgroup. Migration potentially introduces some nasty locking problems in
>> the mem_schedule path.
>>
>> Also, unless I am missing something, the memcg already has the policy of
>> not carrying charges around, probably because of this very same complexity.
>>
>> True that at least it won't EBUSY you... But I think this is at least a way
>> to guarantee that the cgroup under our nose won't disappear in the middle of
>> our allocations.
>
> Here's the memcg user page behavior using the same pattern:
>
> 1. user page P is allocate by task T in memcg M1
> 2. T is moved to memcg M2.  The P charge is left behind still charged
> to M1 if memory.move_charge_at_immigrate=0; or the charge is moved to
> M2 if memory.move_charge_at_immigrate=1.
> 3. rmdir M1 will try to reclaim P (if P was left in M1).  If unable to
> reclaim, then P is recharged to parent(M1).
>

We also have some magic in page_referenced() to remove pages
referenced from different containers. What we do is try not to
penalize a cgroup if another cgroup is referencing this page and the
page under consideration is being reclaimed from the cgroup that
touched it.

Balbir Singh

^ permalink raw reply

* Re: [PATCH net-next] ehea: Remove sleep at .ndo_get_stats
From: Eric Dumazet @ 2011-09-22 15:14 UTC (permalink / raw)
  To: brenohl; +Cc: davem, netdev, Breno Leitao
In-Reply-To: <1316700657-14980-1-git-send-email-brenohl@br.ibm.com>

Le jeudi 22 septembre 2011 à 11:10 -0300, brenohl@br.ibm.com a écrit :
> Currently ehea ndo_get_stats can sleep in two places, in a hcall
> and in a GFP_KERNEL alloc, which is not correct.
> This patch creates a workqueue that grabs the information from time
> to time from the hardware, and place it into the device structure,
> so that, .ndo_get_stats quickly returns the device structure statistics
> block.
> 
> Signed-off-by: Breno Leitao <leitao@linux.vnet.ibm.com>
> ---


Hmm... trigerring a work queue everytime NAPI is run ? That seems very
expensive to me, if for example no one wants device stats at all.

I read ehea correctly, this blocking suff is only used to compute
stats->multicast and stats->rx_errors. 

They probably could be updated once per second, nobody will complain.
(So use a workqueue, and trigger the job once per second, not once per
incoming packet)

Also, you dont provide a safe ndo_get_stats() implementation.

Think that several process might read your device stats in //

So the memset(stats, 0, sizeof(*stats)) is wrong :
You can clear stats that are currently read by another thread.

This makes SNMP readers read intermediate null values, and they dont
like this.

Fix is real easy : remove the memset(stats, 0, sizeof(*stats)) :

You only write on some fields, other fields are already 0

^ permalink raw reply

* Re: [PATCH v3 6/7] tcp buffer limitation: per-cgroup limit
From: Greg Thelen @ 2011-09-22 15:44 UTC (permalink / raw)
  To: Kirill A. Shutemov
  Cc: Glauber Costa, linux-kernel, paul, lizf, kamezawa.hiroyu,
	ebiederm, davem, netdev, linux-mm
In-Reply-To: <20110922095803.GA4530@shutemov.name>

On Thu, Sep 22, 2011 at 2:58 AM, Kirill A. Shutemov
<kirill@shutemov.name> wrote:
> On Wed, Sep 21, 2011 at 11:01:46PM -0700, Greg Thelen wrote:
>> On Sun, Sep 18, 2011 at 5:56 PM, Glauber Costa <glommer@parallels.com> wrote:
>> > +static inline bool mem_cgroup_is_root(struct mem_cgroup *mem)
>> > +{
>> > +       return (mem == root_mem_cgroup);
>> > +}
>> > +
>>
>> Why are you adding a copy of mem_cgroup_is_root().  I see one already
>> in v3.0.  Was it deleted in a previous patch?
>
> mem_cgroup_is_root() moved up in the file.

Got it.  Thanks.

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Fight unfair telecom internet charges in Canada: sign http://stopthemeter.ca/
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply

* Hello
From: Jun Huan @ 2011-09-22 14:10 UTC (permalink / raw)


I have a Project for you, Please contact me for more details

^ permalink raw reply

* routing table error in 2.6.39 ..
From: ratheesh kannoth @ 2011-09-22 15:55 UTC (permalink / raw)
  To: user-mode-linux-user, user-mode-linux-devel, netdev

I built UML  (user mode linux ) for 2.6.38 and 2.6.39 kernels.

in 2.6.38 routing  table is  correct. But in 2.6.39 default gw appears
on top of the routing table. same problem persist in 3.0.0 also.

is it a known problem or fixed in higher versions ?

-Ratheesh

^ 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