* [PATCH v5 3/3] net/fec: add imx6q enet support
From: Shawn Guo @ 2011-09-23 12:12 UTC (permalink / raw)
To: David S. Miller; +Cc: netdev, linux-arm-kernel, patches, Shawn Guo
In-Reply-To: <1316779968-21390-1-git-send-email-shawn.guo@linaro.org>
The imx6q enet is a derivative of imx28 enet controller. It fixed
the frame endian issue found on imx28, and added 1 Gbps support.
It also fixes a typo on vendor name in Kconfig.
Signed-off-by: Shawn Guo <shawn.guo@linaro.org>
---
drivers/net/ethernet/freescale/Kconfig | 9 ++--
drivers/net/ethernet/freescale/fec.c | 66 +++++++++++++++++++++++++------
2 files changed, 57 insertions(+), 18 deletions(-)
diff --git a/drivers/net/ethernet/freescale/Kconfig b/drivers/net/ethernet/freescale/Kconfig
index 4dbe41f..1cf6716 100644
--- a/drivers/net/ethernet/freescale/Kconfig
+++ b/drivers/net/ethernet/freescale/Kconfig
@@ -7,7 +7,7 @@ config NET_VENDOR_FREESCALE
default y
depends on FSL_SOC || QUICC_ENGINE || CPM1 || CPM2 || PPC_MPC512x || \
M523x || M527x || M5272 || M528x || M520x || M532x || \
- IMX_HAVE_PLATFORM_FEC || MXS_HAVE_PLATFORM_FEC || \
+ ARCH_MXC || ARCH_MXS || \
(PPC_MPC52xx && PPC_BESTCOMM)
---help---
If you have a network (Ethernet) card belonging to this class, say Y
@@ -16,16 +16,15 @@ config NET_VENDOR_FREESCALE
Note that the answer to this question doesn't directly affect the
kernel: saying N will just cause the configurator to skip all
- the questions about IBM devices. If you say Y, you will be asked for
- your specific card in the following questions.
+ the questions about Freescale devices. If you say Y, you will be
+ asked for your specific card in the following questions.
if NET_VENDOR_FREESCALE
config FEC
bool "FEC ethernet controller (of ColdFire and some i.MX CPUs)"
depends on (M523x || M527x || M5272 || M528x || M520x || M532x || \
- IMX_HAVE_PLATFORM_FEC || MXS_HAVE_PLATFORM_FEC)
- default IMX_HAVE_PLATFORM_FEC || MXS_HAVE_PLATFORM_FEC if ARM
+ ARCH_MXC || ARCH_MXS)
select PHYLIB
---help---
Say Y here if you want to use the built-in 10/100 Fast ethernet
diff --git a/drivers/net/ethernet/freescale/fec.c b/drivers/net/ethernet/freescale/fec.c
index 2bbe6a5..cce78ce 100644
--- a/drivers/net/ethernet/freescale/fec.c
+++ b/drivers/net/ethernet/freescale/fec.c
@@ -18,7 +18,7 @@
* Bug fixes and cleanup by Philippe De Muyter (phdm@macqel.be)
* Copyright (c) 2004-2006 Macq Electronique SA.
*
- * Copyright (C) 2010 Freescale Semiconductor, Inc.
+ * Copyright (C) 2010-2011 Freescale Semiconductor, Inc.
*/
#include <linux/module.h>
@@ -72,6 +72,8 @@
#define FEC_QUIRK_SWAP_FRAME (1 << 1)
/* Controller uses gasket */
#define FEC_QUIRK_USE_GASKET (1 << 2)
+/* Controller has GBIT support */
+#define FEC_QUIRK_HAS_GBIT (1 << 3)
static struct platform_device_id fec_devtype[] = {
{
@@ -88,6 +90,9 @@ static struct platform_device_id fec_devtype[] = {
.name = "imx28-fec",
.driver_data = FEC_QUIRK_ENET_MAC | FEC_QUIRK_SWAP_FRAME,
}, {
+ .name = "imx6q-fec",
+ .driver_data = FEC_QUIRK_ENET_MAC | FEC_QUIRK_HAS_GBIT,
+ }, {
/* sentinel */
}
};
@@ -97,12 +102,14 @@ enum imx_fec_type {
IMX25_FEC = 1, /* runs on i.mx25/50/53 */
IMX27_FEC, /* runs on i.mx27/35/51 */
IMX28_FEC,
+ IMX6Q_FEC,
};
static const struct of_device_id fec_dt_ids[] = {
{ .compatible = "fsl,imx25-fec", .data = &fec_devtype[IMX25_FEC], },
{ .compatible = "fsl,imx27-fec", .data = &fec_devtype[IMX27_FEC], },
{ .compatible = "fsl,imx28-fec", .data = &fec_devtype[IMX28_FEC], },
+ { .compatible = "fsl,imx6q-fec", .data = &fec_devtype[IMX6Q_FEC], },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, fec_dt_ids);
@@ -373,6 +380,7 @@ fec_restart(struct net_device *ndev, int duplex)
int i;
u32 temp_mac[2];
u32 rcntl = OPT_FRAME_SIZE | 0x04;
+ u32 ecntl = 0x2; /* ETHEREN */
/* Whack a reset. We should wait for this. */
writel(1, fep->hwp + FEC_ECNTRL);
@@ -442,18 +450,23 @@ fec_restart(struct net_device *ndev, int duplex)
/* Enable flow control and length check */
rcntl |= 0x40000000 | 0x00000020;
- /* MII or RMII */
- if (fep->phy_interface == PHY_INTERFACE_MODE_RMII)
+ /* RGMII, RMII or MII */
+ if (fep->phy_interface == PHY_INTERFACE_MODE_RGMII)
+ rcntl |= (1 << 6);
+ else if (fep->phy_interface == PHY_INTERFACE_MODE_RMII)
rcntl |= (1 << 8);
else
rcntl &= ~(1 << 8);
- /* 10M or 100M */
- if (fep->phy_dev && fep->phy_dev->speed == SPEED_100)
- rcntl &= ~(1 << 9);
- else
- rcntl |= (1 << 9);
-
+ /* 1G, 100M or 10M */
+ if (fep->phy_dev) {
+ if (fep->phy_dev->speed == SPEED_1000)
+ ecntl |= (1 << 5);
+ else if (fep->phy_dev->speed == SPEED_100)
+ rcntl &= ~(1 << 9);
+ else
+ rcntl |= (1 << 9);
+ }
} else {
#ifdef FEC_MIIGSK_ENR
if (id_entry->driver_data & FEC_QUIRK_USE_GASKET) {
@@ -478,8 +491,15 @@ fec_restart(struct net_device *ndev, int duplex)
}
writel(rcntl, fep->hwp + FEC_R_CNTRL);
+ if (id_entry->driver_data & FEC_QUIRK_ENET_MAC) {
+ /* enable ENET endian swap */
+ ecntl |= (1 << 8);
+ /* enable ENET store and forward mode */
+ writel(1 << 8, fep->hwp + FEC_X_WMRK);
+ }
+
/* And last, enable the transmit and receive processing */
- writel(2, fep->hwp + FEC_ECNTRL);
+ writel(ecntl, fep->hwp + FEC_ECNTRL);
writel(0, fep->hwp + FEC_R_DES_ACTIVE);
/* Enable interrupts we wish to service */
@@ -490,6 +510,8 @@ static void
fec_stop(struct net_device *ndev)
{
struct fec_enet_private *fep = netdev_priv(ndev);
+ const struct platform_device_id *id_entry =
+ platform_get_device_id(fep->pdev);
/* We cannot expect a graceful transmit stop without link !!! */
if (fep->link) {
@@ -504,6 +526,10 @@ fec_stop(struct net_device *ndev)
udelay(10);
writel(fep->phy_speed, fep->hwp + FEC_MII_SPEED);
writel(FEC_DEFAULT_IMASK, fep->hwp + FEC_IMASK);
+
+ /* We have to keep ENET enabled to have MII interrupt stay working */
+ if (id_entry->driver_data & FEC_QUIRK_ENET_MAC)
+ writel(2, fep->hwp + FEC_ECNTRL);
}
@@ -918,6 +944,8 @@ static int fec_enet_mdio_reset(struct mii_bus *bus)
static int fec_enet_mii_probe(struct net_device *ndev)
{
struct fec_enet_private *fep = netdev_priv(ndev);
+ const struct platform_device_id *id_entry =
+ platform_get_device_id(fep->pdev);
struct phy_device *phy_dev = NULL;
char mdio_bus_id[MII_BUS_ID_SIZE];
char phy_name[MII_BUS_ID_SIZE + 3];
@@ -949,14 +977,18 @@ static int fec_enet_mii_probe(struct net_device *ndev)
snprintf(phy_name, MII_BUS_ID_SIZE, PHY_ID_FMT, mdio_bus_id, phy_id);
phy_dev = phy_connect(ndev, phy_name, &fec_enet_adjust_link, 0,
- PHY_INTERFACE_MODE_MII);
+ fep->phy_interface);
if (IS_ERR(phy_dev)) {
printk(KERN_ERR "%s: could not attach to PHY\n", ndev->name);
return PTR_ERR(phy_dev);
}
/* mask with MAC supported features */
- phy_dev->supported &= PHY_BASIC_FEATURES;
+ if (id_entry->driver_data & FEC_QUIRK_HAS_GBIT)
+ phy_dev->supported &= PHY_GBIT_FEATURES;
+ else
+ phy_dev->supported &= PHY_BASIC_FEATURES;
+
phy_dev->advertising = phy_dev->supported;
fep->phy_dev = phy_dev;
@@ -1006,8 +1038,16 @@ static int fec_enet_mii_init(struct platform_device *pdev)
/*
* Set MII speed to 2.5 MHz (= clk_get_rate() / 2 * phy_speed)
+ *
+ * The formula for FEC MDC is 'ref_freq / (MII_SPEED x 2)' while
+ * for ENET-MAC is 'ref_freq / ((MII_SPEED + 1) x 2)'. The i.MX28
+ * Reference Manual has an error on this, and gets fixed on i.MX6Q
+ * document.
*/
- fep->phy_speed = DIV_ROUND_UP(clk_get_rate(fep->clk), 5000000) << 1;
+ fep->phy_speed = DIV_ROUND_UP(clk_get_rate(fep->clk), 5000000);
+ if (id_entry->driver_data & FEC_QUIRK_ENET_MAC)
+ fep->phy_speed--;
+ fep->phy_speed <<= 1;
writel(fep->phy_speed, fep->hwp + FEC_MII_SPEED);
fep->mii_bus = mdiobus_alloc();
--
1.7.4.1
^ permalink raw reply related
* [PATCH v5 2/3] net/fec: fix fec1 check in fec_enet_mii_init()
From: Shawn Guo @ 2011-09-23 12:12 UTC (permalink / raw)
To: David S. Miller; +Cc: netdev, linux-arm-kernel, patches, Shawn Guo
In-Reply-To: <1316779968-21390-1-git-send-email-shawn.guo@linaro.org>
In function fec_enet_mii_init(), it uses non-zero pdev->id as part
of the condition to check the second fec instance (fec1). This works
before the driver supports device tree probe. But in case of device
tree probe, pdev->id is -1 which is also non-zero, so the logic becomes
broken when device tree probe gets supported.
The patch change the logic to check "pdev->id > 0" as the part of the
condition for identifying fec1.
Signed-off-by: Shawn Guo <shawn.guo@linaro.org>
---
drivers/net/ethernet/freescale/fec.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/drivers/net/ethernet/freescale/fec.c b/drivers/net/ethernet/freescale/fec.c
index 9c1d059..2bbe6a5 100644
--- a/drivers/net/ethernet/freescale/fec.c
+++ b/drivers/net/ethernet/freescale/fec.c
@@ -996,7 +996,7 @@ static int fec_enet_mii_init(struct platform_device *pdev)
* mdio interface in board design, and need to be configured by
* fec0 mii_bus.
*/
- if ((id_entry->driver_data & FEC_QUIRK_ENET_MAC) && pdev->id) {
+ if ((id_entry->driver_data & FEC_QUIRK_ENET_MAC) && pdev->id > 0) {
/* fec1 uses fec0 mii_bus */
fep->mii_bus = fec0_mii_bus;
return 0;
--
1.7.4.1
^ permalink raw reply related
* [PATCH v5 1/3] net/fec: fec_reset_phy() does not need to always succeed
From: Shawn Guo @ 2011-09-23 12:12 UTC (permalink / raw)
To: David S. Miller; +Cc: netdev, linux-arm-kernel, patches, Shawn Guo
In-Reply-To: <1316779968-21390-1-git-send-email-shawn.guo@linaro.org>
FEC can work without a phy reset on some platforms, which means not
very platform necessarily have a phy-reset gpio encoded in device tree.
Even on the platforms that have the gpio, FEC can work without
resetting phy for some cases, e.g. boot loader has done that.
So it makes more sense to have the phy-reset-gpio request failure as
a debug message rather than a warning, and get fec_reset_phy() return
void since the caller does not check the return anyway.
Signed-off-by: Shawn Guo <shawn.guo@linaro.org>
---
drivers/net/ethernet/freescale/fec.c | 13 +++++--------
1 files changed, 5 insertions(+), 8 deletions(-)
diff --git a/drivers/net/ethernet/freescale/fec.c b/drivers/net/ethernet/freescale/fec.c
index 158b82e..9c1d059 100644
--- a/drivers/net/ethernet/freescale/fec.c
+++ b/drivers/net/ethernet/freescale/fec.c
@@ -1411,24 +1411,22 @@ static int __devinit fec_get_phy_mode_dt(struct platform_device *pdev)
return -ENODEV;
}
-static int __devinit fec_reset_phy(struct platform_device *pdev)
+static void __devinit fec_reset_phy(struct platform_device *pdev)
{
int err, phy_reset;
struct device_node *np = pdev->dev.of_node;
if (!np)
- return -ENODEV;
+ return;
phy_reset = of_get_named_gpio(np, "phy-reset-gpios", 0);
err = gpio_request_one(phy_reset, GPIOF_OUT_INIT_LOW, "phy-reset");
if (err) {
- pr_warn("FEC: failed to get gpio phy-reset: %d\n", err);
- return err;
+ pr_debug("FEC: failed to get gpio phy-reset: %d\n", err);
+ return;
}
msleep(1);
gpio_set_value(phy_reset, 1);
-
- return 0;
}
#else /* CONFIG_OF */
static inline int fec_get_phy_mode_dt(struct platform_device *pdev)
@@ -1436,13 +1434,12 @@ static inline int fec_get_phy_mode_dt(struct platform_device *pdev)
return -ENODEV;
}
-static inline int fec_reset_phy(struct platform_device *pdev)
+static inline void fec_reset_phy(struct platform_device *pdev)
{
/*
* In case of platform probe, the reset has been done
* by machine code.
*/
- return 0;
}
#endif /* CONFIG_OF */
--
1.7.4.1
^ permalink raw reply related
* [PATCH v5 0/3] add fec support for imx6q
From: Shawn Guo @ 2011-09-23 12:12 UTC (permalink / raw)
To: David S. Miller; +Cc: netdev, linux-arm-kernel, patches
This series adds imx6q enet support. The imx6q enet is a derivative of
imx28 enet controller. It fixes the frame endian issue found on imx28,
and adds 1 Gbps support.
Changes since v4:
* Confirmed with design team that i.MX28 Reference Manual has an error
on MII_SPEED formula. FEC uses 'ref_freq / (MII_SPEED x 2)' while
ENET-MAC uses 'ref_freq / ((MII_SPEED + 1) x 2)', so that minus one
should really apply for just FEC_QUIRK_ENET_MAC.
Changes since v3:
* The minus one on phy_speed should happen before left shift.
Changes since v2:
* Refine patch #1 to get fec_reset_phy() return void
Changes since v1:
* Fix typo pointed out by Francois Romieu
* Drop patch #3 in the v1
* Rebase on net-next tree
Thanks.
Shawn Guo (3):
net/fec: fec_reset_phy() does not need to always succeed
net/fec: fix fec1 check in fec_enet_mii_init()
net/fec: add imx6q enet support
drivers/net/ethernet/freescale/Kconfig | 9 ++--
drivers/net/ethernet/freescale/fec.c | 81 +++++++++++++++++++++++---------
2 files changed, 63 insertions(+), 27 deletions(-)
^ permalink raw reply
* Re: Question regarding wanrouter module
From: Francois Romieu @ 2011-09-23 11:26 UTC (permalink / raw)
To: Holger Hans Peter Freyther; +Cc: netdev
In-Reply-To: <4E7C528F.4010303@freyther.de>
Holger Hans Peter Freyther <holger@freyther.de> :
[...]
> Fast forward to today, Sangoma provides a wanrouter.ko as well (they didn't
> bother to change the symbol names or module name). I wonder if there are any
> plans to improve the situation, e.g. rename the kernel module, change symbols,
> or if there would be objections to trying to add functionality to the kernel
> wanrouter.ko again ?
There are objections to adding.
The kernel wanrouter code is almost empty. Afaiu it mostly contains a
wan setup API.
Is there a reason why the added functionalities could not go through the
generic hdlc kernel code (see drivers/net/wan/hdlc*) ?
--
Ueimor
^ permalink raw reply
* [PATCH 2/2] wireless: at76c50x: use native hex_pack_byte() method
From: Andy Shevchenko @ 2011-09-23 10:47 UTC (permalink / raw)
To: linux-kernel; +Cc: Andy Shevchenko, John W. Linville, linux-wireless, netdev
In-Reply-To: <fa146966b0ce1e7f04d59eb27cc0e968f51b22de.1316774801.git.andriy.shevchenko@linux.intel.com>
Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Cc: "John W. Linville" <linville@tuxdriver.com>
Cc: linux-wireless@vger.kernel.org
Cc: netdev@vger.kernel.org
---
drivers/net/wireless/at76c50x-usb.c | 5 +----
1 files changed, 1 insertions(+), 4 deletions(-)
diff --git a/drivers/net/wireless/at76c50x-usb.c b/drivers/net/wireless/at76c50x-usb.c
index 2986014..157507a6 100644
--- a/drivers/net/wireless/at76c50x-usb.c
+++ b/drivers/net/wireless/at76c50x-usb.c
@@ -500,7 +500,6 @@ exit:
#define HEX2STR_BUFFERS 4
#define HEX2STR_MAX_LEN 64
-#define BIN2HEX(x) ((x) < 10 ? '0' + (x) : (x) + 'A' - 10)
/* Convert binary data into hex string */
static char *hex2str(void *buf, int len)
@@ -520,10 +519,8 @@ static char *hex2str(void *buf, int len)
}
while (len--) {
- *obuf++ = BIN2HEX(*ibuf >> 4);
- *obuf++ = BIN2HEX(*ibuf & 0xf);
+ obuf = hex_pack_byte(obuf, *ibuf++);
*obuf++ = '-';
- ibuf++;
}
*(--obuf) = '\0';
--
1.7.6.3
^ permalink raw reply related
* RE: [patch v2] caif: add error handling for allocation
From: Sjur BRENDELAND @ 2011-09-23 10:38 UTC (permalink / raw)
To: Dan Carpenter
Cc: David S. Miller, netdev@vger.kernel.org,
kernel-janitors@vger.kernel.org
In-Reply-To: <20110921072159.GJ4999@elgon.mountain>
[Dan]:
> The allocation of "phyinfo" wasn't checked, and also the allocation
> wasn't freed on error paths. Sjur Brændeland pointed out as well
> that "phy_driver" should be freed on the error path too.
>
> Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
Looks good, thank you Dan.
Acked-by: Sjur Brændeland <sjur.brandeland@stericsson.com>
^ permalink raw reply
* Question regarding wanrouter module
From: Holger Hans Peter Freyther @ 2011-09-23 9:34 UTC (permalink / raw)
To: netdev
Hi all,
at some point the Sangoma wanrouter and device drivers were merged in the
kernel. Somewhere in 2006 (8db60bcf3021921e2d10d158641792d640e52fe8) the
drivers were removed as Sangoma wanted to maintain them themselves. Later some
of the functionality got removed (ce0ecd594d78710422599918a608). In the kernel
it appears that cycx_x25.c and isdn_x25iface.c make use of the wanrouter.
Fast forward to today, Sangoma provides a wanrouter.ko as well (they didn't
bother to change the symbol names or module name). I wonder if there are any
plans to improve the situation, e.g. rename the kernel module, change symbols,
or if there would be objections to trying to add functionality to the kernel
wanrouter.ko again?
cheers
holger
^ permalink raw reply
* Re: [PATCH net-next v2] candev: allow SJW user setting for bittiming calculation
From: Pavel Pisa @ 2011-09-23 9:32 UTC (permalink / raw)
To: Wolfgang Grandegger
Cc: SocketCAN Core Mailing List, Oliver Hartkopp, Linux Netdev List
In-Reply-To: <4E7C3424.8030406-5Yr1BZd7O62+XT7JhA+gdA@public.gmane.org>
Hello Oliver and Wolfgang,
On Friday 23 September 2011 09:24:20 Wolfgang Grandegger wrote:
> Hi Oliver,
>
> On 09/22/2011 09:41 PM, Oliver Hartkopp wrote:
> Then let us set it to 4 (maximum), by default. But other documents
> recommend a value of 1.
I am not expert for CAN timing nor I have time to go through
documentation at this moment. But I hope that I have some
sense/experience for electronic and dynamic systems
and we have done more designs utilizing CAN at university
and at our company.
So there are some thought about SJW based on my experience.
There could be some inaccuracies, if you want better
analysis, I need time for that.
1) The CAN needs fast local roundrip time for correct operation
of dominant/recessive arbitration.
The time is sum of propagation from CAN controller chip,
propagation delay of optocoupler or other galvanic isolation,
slew rate and delay in Tx circuitry of transceiver, charging
the wire, Rx part of receiver, optocoupler, controller
Rx filtering and Rx,Tx logic level comparator.
Iw we count necessity to synchronize this between multiple
CAN nodes then whole roundtrip time has to be smaller than
50-80% of single bit bit time quantum.
2) From the noise and stabilization of voltage on the wire
the sampling point should be in the middle of bit pulse
delayed by round-trip delay from 1. This is 50% of bit
time (i.e. dependent on bitrate) + round trip delay (dependent
on delay in controller and concrete board circuitry).
3) But sampling point has to allow to decide about collision
before next bit Tx is started => it cannot be moved after
end of the given Tx bit time interval.
4) It is necessary to synchronize bit timing in all
CAN controllers during arbitration (ID sending) phase.
The first sync is done after receiving of the first
edge on the wire. It can be other node start of Tx
or our own Tx dominant level. Controller shifts its Tx
timing such way, that start of the next Tx bit interval
should result in Rx transition at the end the sensed
Rx bit. I.e. it counts only TSEG2 til next bit start.
5) There are some more things to consider if triple
sampling and filtering is enabled to suppress noise
on wire. It can be used only, if time quantum clocks
are fast enough to fit this sampling interval between
stabilization of delayed Rx logic level and end of Tx bit
time interval.
6) If the clock frequencies of all nodes CAN controllers
are guaranteed to be same, then no more synchronization
is necessary during message Tx/Rx (SJW=0). But that assumption
does not hold. That is why bitstuffing is used and guarantees
that there is at least one logic level transition (edge)
after each 6 bit time. If there is zero roundtrip propagation
delay and sampling in 50% of bit time interval then
maximal skew/frequency difference of the clocks could be
(1+1/6*50%) - 1 i.e. 8%
This means, that SJW bigger than 8% of whole bit time
would not help to synchronize bitrate difference, because
for such case setup cannot work anyway. Propagation delay
is not zero then there is even less time left for sampling
point shift which would not cause incorrect bit data
detection so reasonable maximum is probably lower.
I expect that for reasonable precise setup of bitrate
when exact ratio is found and crystal based oscillators
there is the best option small SJW i.e. 1 or for very
fast TQ clock equivalent of 1% - 2% of bittime.
For nonexact ratio or low quality clocks sources,
bigger SJW values make sense. But big value has other
disadvantage. If there is bigger jitter in Tx/Rx delays
or clocks then it is propagated back to bit timing
and stability of system composed from multiple nodes
could be questionable. There is even bigger interval
where noise pulse could cause lost of the synchronization.
On base of above analysis, I think that blindly set SJW
on maximum is not good idea. It should be at least limited
to 5% of bit time.
Because bit timing calculation is not what everybody
want to do again and again, the actual code tries
to hide differences of CAN controllers and provide
at least partially understandable knobs to user
with parameters independent on concrete setup low level
details to allow set bitrate for usual Joe user.
The basic parameters are chosen such way, that user need
not to care about actual TQ clock and selecting prescaller,
that is why sampling point is in percent of bittime.
SJW is more problematic, but may it be use of 2 or 5%
of bittime by default with assurance that zero is
replaced by one, would serve to most people pleasure.
May it be, that 0.1 of percent should be used as unit
for external parameter too.
I hope that actual calculation works reasonably well.
But if it should be enhanced, then it would worth
to add additional parameter except crystal/controller
clock source freqency to the concrete boards drivers.
It should be measured round-trip delay of given/used
transceiver/optocouplers combination. This would
allow to have sampling point setup yet more independent
on given HW and same value could be used for different
bitrates. But there is still unknown parameter
capacity/length of connected wires so there is still
something left to user consideration.
Best wishes,
Pavel Pisa
e-mail: pisa-/N2ztlQkxE7Ub/6JBqosbQ@public.gmane.org
www: http://cmp.felk.cvut.cz/~pisa
university: http://dce.fel.cvut.cz/
company: http://www.pikron.com/
> > possible. And if an expert told me so and i had a simple config interface
> > to fullfill it, it would be great for me ;-)
>
> Anyway, if SJW does not depend on other bit-timing parameters and it
> usually works fine with the kernel calculated parameters I would no
> longer vote against this patch.
>
> Wolfgang,
^ permalink raw reply
* administrativní zprávy
From: univerzita Karlova @ 2011-09-23 8:02 UTC (permalink / raw)
--
Vážení karlin.mff.cuni.cz účastníka,
Ukončení vašeho karlin.mff.cuni.cz a související poštovním účtem
probíhá, jsme v současné době provádí upgrade na náš systém vzhledem k
tomu, že to přišlo na naše upozornění, že jedna nebo více z našich
předplatitelů zavádějí velmi silný virus do našeho systému a to
ovlivňuje naši síť.
Snažíme se zjistit konkrétní osobu. Z tohoto důvodu se všichni
účastníci jsou povinni poskytnout své uživatelské jméno a heslo pro nás
pro ověření a je zúčtováno proti tomuto viru. Nedodržení povede k
ukončení vašeho účtu v příštích 48 hodin.
Informace k odeslání;
* Uživatelské jméno E-mail} {: (.................) (povinné)
* Heslo :(..........................)( povinné)
* Datum narození: (...........................)( nepovinné)
* Země nebo území: (...................)( nepovinné)
Doufat, aby vám lépe sloužily ..
S pozdravem,
univerzita Karlova
**************************************************
******************************************
Jedná se o administrativní zprávy ze serveru karlin.mff.cuni.cz. To
není spam. Čas od času se karlin.mff.cuni.cz server, posílat zprávy
například pro komunikaci důležité informace o vašem předplatném.
**************************************************
******************************************
^ permalink raw reply
* Re: Introducing open source MSTP daemon
From: Vitalii Demianets @ 2011-09-23 7:36 UTC (permalink / raw)
To: David Lamparter; +Cc: bridge, netdev, Srinivas M.A., Stephen Hemminger
In-Reply-To: <20110922163939.GB1012103@jupiter.n2.diac24.net>
On Thursday 22 September 2011 19:39:40 David Lamparter wrote:
> Very cool!
>
> The code looks quite good to me (i've only looked at 2 files though ;).
> Minor nitpicks:
> - hmac_md5 & epoll could maybe come from an external library. you're
> the 3810583th person to have code for that... libevent?
> OpenSSL/gnutls?
> - libnetlink.c is a copy from iproute2? since it is a fresh clean SVN,
> it's not easy to know whether you made changes. Can you put a note
> which version this is? Or maybe you can link it externally?
> - the "assign" macro and "boolFalse" in mstp.c are weird. I understand
> you want stricter type checking, but this makes the code somewhat
> odd to read. Maybe external tools can be used to do this checking
> (sparse, cppcheck, llvm's static analysis, ...)
>
Happy to hear you are interested )
I suppose these questions are not related to kernel development so I suggest
to continue discussion on above topics at the project discussion board:
http://sourceforge.net/p/mstpd/discussion/
> I assume it works with current Linux kernel bridge code on a RSTP level?
> The code looks considerably more maintainable than rstpd :) - I will try
> running it later!
>
Sorry, at the moment function MSTP_OUT_set_state() does nothing except
logging. But it is valueable thought: although MSTI states do not have
meaning to the kernel bridge code, CIST states can be used to control bridge
slave states, so mstpd can replace rstpd as more generic (and conforming to
more recent standard).
Anyways, the code is basically untested. It compiles and runs in my setup,
that's all for now. But I somehow have gut feeling that the code is mature
enough to be put for the community consideration.
--
Vitalii Demianets
^ permalink raw reply
* Re: [net-next 1/8] pci: Add flag indicating device has been assigned by KVM
From: Ian Campbell @ 2011-09-23 7:27 UTC (permalink / raw)
To: Jeff Kirsher
Cc: davem, konrad.wilk@oracle.com, Jesse Barnes, Greg Rose, netdev,
gospo, linux-pci
In-Reply-To: <CAL3LdT7jDfytZD7WESmiHxvpmxKTEZ=uWRjzgsR9e4GtBPE31A@mail.gmail.com>
On Thu, 2011-09-22 at 21:16 -0700, Jeff Kirsher wrote:
>
>
> Jesse/Konrad/Ian-
>
> I sent this patch out as part of a pull request for David Miller's
> net-next tree. I know that Greg sent this originally out to the
> linux-pci mailing list as a RFC. Since Greg also has a patch against
> ixgbe which implemented this flag, I sent both patches for inclusion
> into David Miller's net-next.
>
> Dave is wanting to ensure that the PCI maintainers have reviewed this
> and are ok with it before pulls my series of patches.
I'm not a PCI maintainer by any stretch of the imagination but FWIW this
change is fine by me.
My original reason for commenting on this patch was just to wonder
whether this would also be useful for Xen and I think the answer is we
should patch xen-pciback to use this new flag but I've not had time to
look into that.
I suppose by that measure the comment could be less KVM specific:
> + /* Provide indication device is assigned by KVM */
> + PCI_DEV_FLAGS_ASSIGNED = (__force pci_dev_flags_t) 4,
but that's not exactly a big deal.
I suppose really the flag indicates "VF in use" rather than necessarily
"assigned"? Would it be just as bad to have a VF driver in the host
active when the PF was unloaded?
Ian.
--
Ian Campbell
Current Noise: Mudhoney - Mudride (Live In Berlin)
Well, I think Perl should run faster than C. :-)
-- Larry Wall in <199801200306.TAA11638@wall.org>
^ permalink raw reply
* Re: [PATCH net-next v2] candev: allow SJW user setting for bittiming calculation
From: Wolfgang Grandegger @ 2011-09-23 7:24 UTC (permalink / raw)
To: Oliver Hartkopp; +Cc: SocketCAN Core Mailing List, Linux Netdev List
In-Reply-To: <4E7B8F63.6060108-fJ+pQTUTwRTk1uMJSBkQmQ@public.gmane.org>
Hi Oliver,
On 09/22/2011 09:41 PM, Oliver Hartkopp wrote:
> Hi Wolfgang,
>
> i put Pavel and Andrey into CC, maybe they also have an opinion about this.
> I just talked to a specialist who told me, that a higher SJW is better - if
Then let us set it to 4 (maximum), by default. But other documents
recommend a value of 1.
> possible. And if an expert told me so and i had a simple config interface to
> fullfill it, it would be great for me ;-)
Anyway, if SJW does not depend on other bit-timing parameters and it
usually works fine with the kernel calculated parameters I would no
longer vote against this patch.
Wolfgang,
^ permalink raw reply
* [PATCH] tcp: ECN blackhole should not force quickack mode
From: Eric Dumazet @ 2011-09-23 6:02 UTC (permalink / raw)
To: David Miller
Cc: netdev, Jerry Chu, Ilpo Järvinen, Jamal Hadi Salim,
Jim Gettys, Dave Taht
While playing with a new ADSL box at home, I discovered that ECN
blackhole can trigger suboptimal quickack mode on linux : We send one
ACK for each incoming data frame, without any delay and eventual
piggyback.
This is because TCP_ECN_check_ce() considers that if no ECT is seen on a
segment, this is because this segment was a retransmit.
Refine this heuristic and apply it only if we seen ECT in a previous
segment, to detect ECN blackhole at IP level.
Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
CC: Jamal Hadi Salim <jhs@mojatatu.com>
CC: Jerry Chu <hkchu@google.com>
CC: Ilpo Järvinen <ilpo.jarvinen@helsinki.fi>
CC: Jim Gettys <jg@freedesktop.org>
CC: Dave Taht <dave.taht@gmail.com>
---
Another possibility is to remove this (not in RFC 3168) heuristic, what
do you think ?
include/net/tcp.h | 1 +
net/ipv4/tcp_input.c | 23 ++++++++++++++++-------
2 files changed, 17 insertions(+), 7 deletions(-)
diff --git a/include/net/tcp.h b/include/net/tcp.h
index f357bef..702aefc 100644
--- a/include/net/tcp.h
+++ b/include/net/tcp.h
@@ -356,6 +356,7 @@ static inline void tcp_dec_quickack_mode(struct sock *sk,
#define TCP_ECN_OK 1
#define TCP_ECN_QUEUE_CWR 2
#define TCP_ECN_DEMAND_CWR 4
+#define TCP_ECN_SEEN 8
static __inline__ void
TCP_ECN_create_request(struct request_sock *req, struct tcphdr *th)
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index a5d01b1..5a4408c 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -217,16 +217,25 @@ static inline void TCP_ECN_withdraw_cwr(struct tcp_sock *tp)
tp->ecn_flags &= ~TCP_ECN_DEMAND_CWR;
}
-static inline void TCP_ECN_check_ce(struct tcp_sock *tp, struct sk_buff *skb)
+static inline void TCP_ECN_check_ce(struct tcp_sock *tp, const struct sk_buff *skb)
{
- if (tp->ecn_flags & TCP_ECN_OK) {
- if (INET_ECN_is_ce(TCP_SKB_CB(skb)->flags))
- tp->ecn_flags |= TCP_ECN_DEMAND_CWR;
+ if (!(tp->ecn_flags & TCP_ECN_OK))
+ return;
+
+ switch (TCP_SKB_CB(skb)->flags & INET_ECN_MASK) {
+ case INET_ECN_NOT_ECT:
/* Funny extension: if ECT is not set on a segment,
- * it is surely retransmit. It is not in ECN RFC,
- * but Linux follows this rule. */
- else if (INET_ECN_is_not_ect((TCP_SKB_CB(skb)->flags)))
+ * and we already seen ECT on a previous segment,
+ * it is probably a retransmit.
+ */
+ if (tp->ecn_flags & TCP_ECN_SEEN)
tcp_enter_quickack_mode((struct sock *)tp);
+ break;
+ case INET_ECN_CE:
+ tp->ecn_flags |= TCP_ECN_DEMAND_CWR;
+ /* fallinto */
+ default:
+ tp->ecn_flags |= TCP_ECN_SEEN;
}
}
^ permalink raw reply related
* Re: discrepancy in ip(7) wrt. IP DF flag for UDP sockets
From: Michael Kerrisk @ 2011-09-23 5:27 UTC (permalink / raw)
To: Benjamin Poirier; +Cc: Neil Horman, linux-man, netdev
In-Reply-To: <20110922124448.GA19801@synalogic.ca>
HI Ben, Neil,
On Thu, Sep 22, 2011 at 2:44 PM, Benjamin Poirier
<benjamin.poirier@gmail.com> wrote:
> 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.
Thanks for catching that! The second of the above sentences is now gone.
>> 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?
That's just an artifact of groff formatting. One can prevent it, but
then the text justification of some lines starts to look very weird.
>> Path MTU discovery flags Meaning
>
> I agree with what Neil said about "flags" here. setsockopt(2) calls
> these "option values".
Changed this to just "value".
> Other than that, LGTM
> Acked-by: Benjamin Poirier <benjamin.poirier@gmail.com>
>
> Thanks Michael,
> -Ben
You're welcome. Thanks for taking the time to write the text and check my work.
Cheers,
Michael
>> 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/
>
--
Michael Kerrisk
Linux man-pages maintainer; http://www.kernel.org/doc/man-pages/
Author of "The Linux Programming Interface"; http://man7.org/tlpi/
^ permalink raw reply
* Re: [net-next 1/8] pci: Add flag indicating device has been assigned by KVM
From: Jeff Kirsher @ 2011-09-23 5:23 UTC (permalink / raw)
To: Jesse Barnes, David Miller; +Cc: netdev, Rose, Gregory V
In-Reply-To: <20110923104957.2f76d1a4@jbarnes-x220>
[-- Attachment #1: Type: text/plain, Size: 3859 bytes --]
On Thu, 2011-09-22 at 22:19 -0700, Jesse Barnes wrote:
> On Thu, 22 Sep 2011 21:16:18 -0700
> Jeff Kirsher <jeffrey.t.kirsher@intel.com> wrote:
>
> > On Wed, Sep 21, 2011 at 03:12, Jeff Kirsher
> > <jeffrey.t.kirsher@intel.com> wrote:
> > > From: Greg Rose <gregory.v.rose@intel.com>
> > >
> > > Device drivers that create and destroy SR-IOV virtual functions via
> > > calls to pci_enable_sriov() and pci_disable_sriov can cause
> > > catastrophic failures if they attempt to destroy VFs while they are
> > > assigned to guest virtual machines. By adding a flag for use by
> > > the KVM module to indicate that a device is assigned a device
> > > driver can check that flag and avoid destroying VFs while they are
> > > assigned and avoid system failures.
> > >
> > > Signed-off-by: Greg Rose <gregory.v.rose@intel.com>
> > > Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
> > > ---
> > > include/linux/pci.h | 2 ++
> > > virt/kvm/assigned-dev.c | 2 ++
> > > virt/kvm/iommu.c | 4 ++++
> > > 3 files changed, 8 insertions(+), 0 deletions(-)
> > >
> > > diff --git a/include/linux/pci.h b/include/linux/pci.h
> > > index f27893b..4f511da 100644
> > > --- a/include/linux/pci.h
> > > +++ b/include/linux/pci.h
> > > @@ -174,6 +174,8 @@ enum pci_dev_flags {
> > > PCI_DEV_FLAGS_MSI_INTX_DISABLE_BUG = (__force
> > > pci_dev_flags_t) 1, /* Device configuration is irrevocably lost if
> > > disabled into D3 */ PCI_DEV_FLAGS_NO_D3 = (__force pci_dev_flags_t)
> > > 2,
> > > + /* Provide indication device is assigned by KVM */
> > > + PCI_DEV_FLAGS_ASSIGNED = (__force pci_dev_flags_t) 4,
> > > };
> > >
> > > enum pci_irq_reroute_variant {
> > > diff --git a/virt/kvm/assigned-dev.c b/virt/kvm/assigned-dev.c
> > > index 4e9eaeb..eaf3a50 100644
> > > --- a/virt/kvm/assigned-dev.c
> > > +++ b/virt/kvm/assigned-dev.c
> > > @@ -205,6 +205,8 @@ static void kvm_free_assigned_device(struct kvm
> > > *kvm, else
> > > pci_restore_state(assigned_dev->dev);
> > >
> > > + assigned_dev->dev->dev_flags &= ~PCI_DEV_FLAGS_ASSIGNED;
> > > +
> > > pci_release_regions(assigned_dev->dev);
> > > pci_disable_device(assigned_dev->dev);
> > > pci_dev_put(assigned_dev->dev);
> > > diff --git a/virt/kvm/iommu.c b/virt/kvm/iommu.c
> > > index 78c80f6..967aba1 100644
> > > --- a/virt/kvm/iommu.c
> > > +++ b/virt/kvm/iommu.c
> > > @@ -187,6 +187,8 @@ int kvm_assign_device(struct kvm *kvm,
> > > goto out_unmap;
> > > }
> > >
> > > + pdev->dev_flags |= PCI_DEV_FLAGS_ASSIGNED;
> > > +
> > > printk(KERN_DEBUG "assign device %x:%x:%x.%x\n",
> > > assigned_dev->host_segnr,
> > > assigned_dev->host_busnr,
> > > @@ -215,6 +217,8 @@ int kvm_deassign_device(struct kvm *kvm,
> > >
> > > iommu_detach_device(domain, &pdev->dev);
> > >
> > > + pdev->dev_flags &= ~PCI_DEV_FLAGS_ASSIGNED;
> > > +
> > > printk(KERN_DEBUG "deassign device %x:%x:%x.%x\n",
> > > assigned_dev->host_segnr,
> > > assigned_dev->host_busnr,
> > > --
> > > 1.7.6.2
> >
> > Jesse/Konrad/Ian-
> >
> > I sent this patch out as part of a pull request for David Miller's
> > net-next tree. I know that Greg sent this originally out to the
> > linux-pci mailing list as a RFC. Since Greg also has a patch against
> > ixgbe which implemented this flag, I sent both patches for inclusion
> > into David Miller's net-next.
> >
> > Dave is wanting to ensure that the PCI maintainers have reviewed this
> > and are ok with it before pulls my series of patches.
>
> Yeah I think I looked at this one in the past, my ack must have been
> dropped. You can add it if you want.
>
> Jesse
Thanks Jesse!
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 490 bytes --]
^ permalink raw reply
* Re: [net-next 1/8] pci: Add flag indicating device has been assigned by KVM
From: Jesse Barnes @ 2011-09-23 5:20 UTC (permalink / raw)
To: Jeff Kirsher
Cc: davem, konrad.wilk@oracle.com, ijc@hellion.org.uk, Greg Rose,
netdev, gospo, linux-pci
In-Reply-To: <CAL3LdT7jDfytZD7WESmiHxvpmxKTEZ=uWRjzgsR9e4GtBPE31A@mail.gmail.com>
[oops meant to cc everyone, yes this has my ack]
On Thu, 22 Sep 2011 21:16:18 -0700
Jeff Kirsher <jeffrey.t.kirsher@intel.com> wrote:
> On Wed, Sep 21, 2011 at 03:12, Jeff Kirsher
> <jeffrey.t.kirsher@intel.com> wrote:
> > From: Greg Rose <gregory.v.rose@intel.com>
> >
> > Device drivers that create and destroy SR-IOV virtual functions via
> > calls to pci_enable_sriov() and pci_disable_sriov can cause
> > catastrophic failures if they attempt to destroy VFs while they are
> > assigned to guest virtual machines. By adding a flag for use by
> > the KVM module to indicate that a device is assigned a device
> > driver can check that flag and avoid destroying VFs while they are
> > assigned and avoid system failures.
> >
> > Signed-off-by: Greg Rose <gregory.v.rose@intel.com>
> > Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
> > ---
> > include/linux/pci.h | 2 ++
> > virt/kvm/assigned-dev.c | 2 ++
> > virt/kvm/iommu.c | 4 ++++
> > 3 files changed, 8 insertions(+), 0 deletions(-)
> >
> > diff --git a/include/linux/pci.h b/include/linux/pci.h
> > index f27893b..4f511da 100644
> > --- a/include/linux/pci.h
> > +++ b/include/linux/pci.h
> > @@ -174,6 +174,8 @@ enum pci_dev_flags {
> > PCI_DEV_FLAGS_MSI_INTX_DISABLE_BUG = (__force
> > pci_dev_flags_t) 1, /* Device configuration is irrevocably lost if
> > disabled into D3 */ PCI_DEV_FLAGS_NO_D3 = (__force pci_dev_flags_t)
> > 2,
> > + /* Provide indication device is assigned by KVM */
> > + PCI_DEV_FLAGS_ASSIGNED = (__force pci_dev_flags_t) 4,
> > };
> >
> > enum pci_irq_reroute_variant {
> > diff --git a/virt/kvm/assigned-dev.c b/virt/kvm/assigned-dev.c
> > index 4e9eaeb..eaf3a50 100644
> > --- a/virt/kvm/assigned-dev.c
> > +++ b/virt/kvm/assigned-dev.c
> > @@ -205,6 +205,8 @@ static void kvm_free_assigned_device(struct kvm
> > *kvm, else
> > pci_restore_state(assigned_dev->dev);
> >
> > + assigned_dev->dev->dev_flags &= ~PCI_DEV_FLAGS_ASSIGNED;
> > +
> > pci_release_regions(assigned_dev->dev);
> > pci_disable_device(assigned_dev->dev);
> > pci_dev_put(assigned_dev->dev);
> > diff --git a/virt/kvm/iommu.c b/virt/kvm/iommu.c
> > index 78c80f6..967aba1 100644
> > --- a/virt/kvm/iommu.c
> > +++ b/virt/kvm/iommu.c
> > @@ -187,6 +187,8 @@ int kvm_assign_device(struct kvm *kvm,
> > goto out_unmap;
> > }
> >
> > + pdev->dev_flags |= PCI_DEV_FLAGS_ASSIGNED;
> > +
> > printk(KERN_DEBUG "assign device %x:%x:%x.%x\n",
> > assigned_dev->host_segnr,
> > assigned_dev->host_busnr,
> > @@ -215,6 +217,8 @@ int kvm_deassign_device(struct kvm *kvm,
> >
> > iommu_detach_device(domain, &pdev->dev);
> >
> > + pdev->dev_flags &= ~PCI_DEV_FLAGS_ASSIGNED;
> > +
> > printk(KERN_DEBUG "deassign device %x:%x:%x.%x\n",
> > assigned_dev->host_segnr,
> > assigned_dev->host_busnr,
> > --
> > 1.7.6.2
>
> Jesse/Konrad/Ian-
>
> I sent this patch out as part of a pull request for David Miller's
> net-next tree. I know that Greg sent this originally out to the
> linux-pci mailing list as a RFC. Since Greg also has a patch against
> ixgbe which implemented this flag, I sent both patches for inclusion
> into David Miller's net-next.
>
> Dave is wanting to ensure that the PCI maintainers have reviewed this
> and are ok with it before pulls my series of patches.
>
^ permalink raw reply
* Re: [net-next 1/8] pci: Add flag indicating device has been assigned by KVM
From: Jeff Kirsher @ 2011-09-23 4:16 UTC (permalink / raw)
To: davem, konrad.wilk@oracle.com, ijc@hellion.org.uk, Jesse Barnes
Cc: Greg Rose, netdev, gospo, Jeff Kirsher, linux-pci
In-Reply-To: <1316599974-23205-2-git-send-email-jeffrey.t.kirsher@intel.com>
On Wed, Sep 21, 2011 at 03:12, Jeff Kirsher <jeffrey.t.kirsher@intel.com> wrote:
> From: Greg Rose <gregory.v.rose@intel.com>
>
> Device drivers that create and destroy SR-IOV virtual functions via
> calls to pci_enable_sriov() and pci_disable_sriov can cause catastrophic
> failures if they attempt to destroy VFs while they are assigned to
> guest virtual machines. By adding a flag for use by the KVM module
> to indicate that a device is assigned a device driver can check that
> flag and avoid destroying VFs while they are assigned and avoid system
> failures.
>
> Signed-off-by: Greg Rose <gregory.v.rose@intel.com>
> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
> ---
> include/linux/pci.h | 2 ++
> virt/kvm/assigned-dev.c | 2 ++
> virt/kvm/iommu.c | 4 ++++
> 3 files changed, 8 insertions(+), 0 deletions(-)
>
> diff --git a/include/linux/pci.h b/include/linux/pci.h
> index f27893b..4f511da 100644
> --- a/include/linux/pci.h
> +++ b/include/linux/pci.h
> @@ -174,6 +174,8 @@ enum pci_dev_flags {
> PCI_DEV_FLAGS_MSI_INTX_DISABLE_BUG = (__force pci_dev_flags_t) 1,
> /* Device configuration is irrevocably lost if disabled into D3 */
> PCI_DEV_FLAGS_NO_D3 = (__force pci_dev_flags_t) 2,
> + /* Provide indication device is assigned by KVM */
> + PCI_DEV_FLAGS_ASSIGNED = (__force pci_dev_flags_t) 4,
> };
>
> enum pci_irq_reroute_variant {
> diff --git a/virt/kvm/assigned-dev.c b/virt/kvm/assigned-dev.c
> index 4e9eaeb..eaf3a50 100644
> --- a/virt/kvm/assigned-dev.c
> +++ b/virt/kvm/assigned-dev.c
> @@ -205,6 +205,8 @@ static void kvm_free_assigned_device(struct kvm *kvm,
> else
> pci_restore_state(assigned_dev->dev);
>
> + assigned_dev->dev->dev_flags &= ~PCI_DEV_FLAGS_ASSIGNED;
> +
> pci_release_regions(assigned_dev->dev);
> pci_disable_device(assigned_dev->dev);
> pci_dev_put(assigned_dev->dev);
> diff --git a/virt/kvm/iommu.c b/virt/kvm/iommu.c
> index 78c80f6..967aba1 100644
> --- a/virt/kvm/iommu.c
> +++ b/virt/kvm/iommu.c
> @@ -187,6 +187,8 @@ int kvm_assign_device(struct kvm *kvm,
> goto out_unmap;
> }
>
> + pdev->dev_flags |= PCI_DEV_FLAGS_ASSIGNED;
> +
> printk(KERN_DEBUG "assign device %x:%x:%x.%x\n",
> assigned_dev->host_segnr,
> assigned_dev->host_busnr,
> @@ -215,6 +217,8 @@ int kvm_deassign_device(struct kvm *kvm,
>
> iommu_detach_device(domain, &pdev->dev);
>
> + pdev->dev_flags &= ~PCI_DEV_FLAGS_ASSIGNED;
> +
> printk(KERN_DEBUG "deassign device %x:%x:%x.%x\n",
> assigned_dev->host_segnr,
> assigned_dev->host_busnr,
> --
> 1.7.6.2
Jesse/Konrad/Ian-
I sent this patch out as part of a pull request for David Miller's
net-next tree. I know that Greg sent this originally out to the
linux-pci mailing list as a RFC. Since Greg also has a patch against
ixgbe which implemented this flag, I sent both patches for inclusion
into David Miller's net-next.
Dave is wanting to ensure that the PCI maintainers have reviewed this
and are ok with it before pulls my series of patches.
--
Cheers,
Jeff
^ permalink raw reply
* [PATCH] net: change capability used by socket options IP{,V6}_TRANSPARENT
From: Maciej Żenczykowski @ 2011-09-22 23:29 UTC (permalink / raw)
To: Maciej Żenczykowski
Cc: netdev, linux-security-module, James Morris,
Maciej Żenczykowski
In-Reply-To: <1315927629.5851.4.camel@bzorp>
From: Maciej Żenczykowski <maze@google.com>
Up till now the IP{,V6}_TRANSPARENT socket options (which actually set
the same bit in the socket struct) have required CAP_NET_ADMIN
privileges to set or clear the option.
- we make clearing the bit not require any privileges.
- we deprecate using CAP_NET_ADMIN for this purpose.
- we introduce a new capability CAP_NET_TRANSPARENT,
which is tailored to allow setting just this bit.
- we allow either one of CAP_NET_TRANSPARENT or CAP_NET_RAW
to set this bit, because raw sockets already effectively
allow you to emulate socket transparency, and make the
transition easier for apps not desiring to use a brand
new capability (because of header file or glibc support)
- we print a warning (but allow it) if you try to set
the socket option with CAP_NET_ADMIN privs, but without
either one of CAP_NET_TRANSPARENT or CAP_NET_RAW.
The reason for introducing a new capability is that while
transparent sockets are potentially dangerous (and can let you
spoof your source IP on traffic), they don't normally give you
the full 'freedom' of eavesdropping and/or spoofing that raw sockets
give you.
Signed-off-by: Maciej Żenczykowski <maze@google.com>
Acked-by: Balazs Scheidler <bazsi@balabit.hu>
Acked-by: David Miller <davem@redhat.com>
---
include/linux/capability.h | 13 +++++++++----
net/ipv4/ip_sockglue.c | 26 ++++++++++++++++++++++----
net/ipv6/ipv6_sockglue.c | 29 ++++++++++++++++++++++++-----
3 files changed, 55 insertions(+), 13 deletions(-)
diff --git a/include/linux/capability.h b/include/linux/capability.h
index c421123..a115ed4 100644
--- a/include/linux/capability.h
+++ b/include/linux/capability.h
@@ -198,7 +198,7 @@ struct cpu_vfs_cap_data {
/* Allow modification of routing tables */
/* Allow setting arbitrary process / process group ownership on
sockets */
-/* Allow binding to any address for transparent proxying */
+/* Allow binding to any address for transparent proxying (deprecated) */
/* Allow setting TOS (type of service) */
/* Allow setting promiscuous mode */
/* Allow clearing driver statistics */
@@ -210,6 +210,7 @@ struct cpu_vfs_cap_data {
/* Allow use of RAW sockets */
/* Allow use of PACKET sockets */
+/* Allow binding to any address for transparent proxying */
#define CAP_NET_RAW 13
@@ -332,7 +333,7 @@ struct cpu_vfs_cap_data {
#define CAP_AUDIT_CONTROL 30
-#define CAP_SETFCAP 31
+#define CAP_SETFCAP 31
/* Override MAC access.
The base kernel enforces no MAC policy.
@@ -357,10 +358,14 @@ struct cpu_vfs_cap_data {
/* Allow triggering something that will wake the system */
-#define CAP_WAKE_ALARM 35
+#define CAP_WAKE_ALARM 35
+
+/* Allow binding to any address for transparent proxying */
+
+#define CAP_NET_TRANSPARENT 36
-#define CAP_LAST_CAP CAP_WAKE_ALARM
+#define CAP_LAST_CAP CAP_NET_TRANSPARENT
#define cap_valid(x) ((x) >= 0 && (x) <= CAP_LAST_CAP)
diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c
index 8905e92..44efa39 100644
--- a/net/ipv4/ip_sockglue.c
+++ b/net/ipv4/ip_sockglue.c
@@ -961,12 +961,30 @@ mc_msf_out:
break;
case IP_TRANSPARENT:
- if (!capable(CAP_NET_ADMIN)) {
- err = -EPERM;
- break;
- }
if (optlen < 1)
goto e_inval;
+ /* Always allow clearing the transparent proxy socket option.
+ * The pre-3.2 permission for setting this was CAP_NET_ADMIN,
+ * and this is still supported - but deprecated. As of Linux
+ * 3.2 the proper permission is one of CAP_NET_TRANSPARENT
+ * (preferred, a new capability) or CAP_NET_RAW. The latter
+ * is supported to make the transition easier (and because
+ * raw sockets already effectively allow one to emulate
+ * socket transparency).
+ */
+ if (!!val && !capable(CAP_NET_TRANSPARENT)
+ && !capable(CAP_NET_RAW)) {
+ if (!capable(CAP_NET_ADMIN)) {
+ err = -EPERM;
+ break;
+ }
+ printk_once(KERN_WARNING "%s (%d): "
+ "deprecated: attempt to set socket option "
+ "IP_TRANSPARENT with CAP_NET_ADMIN but "
+ "without either one of CAP_NET_TRANSPARENT "
+ "or CAP_NET_RAW.\n",
+ current->comm, task_pid_nr(current));
+ }
inet->transparent = !!val;
break;
diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c
index 2fbda5f..b8315c8 100644
--- a/net/ipv6/ipv6_sockglue.c
+++ b/net/ipv6/ipv6_sockglue.c
@@ -343,13 +343,32 @@ static int do_ipv6_setsockopt(struct sock *sk, int level, int optname,
break;
case IPV6_TRANSPARENT:
- if (!capable(CAP_NET_ADMIN)) {
- retv = -EPERM;
- break;
- }
if (optlen < sizeof(int))
goto e_inval;
- /* we don't have a separate transparent bit for IPV6 we use the one in the IPv4 socket */
+ /* Always allow clearing the transparent proxy socket option.
+ * The pre-3.2 permission for setting this was CAP_NET_ADMIN,
+ * and this is still supported - but deprecated. As of Linux
+ * 3.2 the proper permission is one of CAP_NET_TRANSPARENT
+ * (preferred, a new capability) or CAP_NET_RAW. The latter
+ * is supported to make the transition easier (and because
+ * raw sockets already effectively allow one to emulate
+ * socket transparency).
+ */
+ if (valbool && !capable(CAP_NET_TRANSPARENT)
+ && !capable(CAP_NET_RAW)) {
+ if (!capable(CAP_NET_ADMIN)) {
+ retv = -EPERM;
+ break;
+ }
+ printk_once(KERN_WARNING "%s (%d): "
+ "deprecated: attempt to set socket option "
+ "IPV6_TRANSPARENT with CAP_NET_ADMIN but "
+ "without either one of CAP_NET_TRANSPARENT "
+ "or CAP_NET_RAW.\n",
+ current->comm, task_pid_nr(current));
+ }
+ /* we don't have a separate transparent bit for IPV6 we use the
+ * one in the IPv4 socket */
inet_sk(sk)->transparent = valbool;
retv = 0;
break;
--
1.7.3.1
--
To unsubscribe from this list: send the line "unsubscribe linux-security-module" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* Re: [PATCH v3 6/7] tcp buffer limitation: per-cgroup limit
From: Balbir Singh @ 2011-09-22 23:08 UTC (permalink / raw)
To: Glauber Costa
Cc: linux-kernel, paul, lizf, kamezawa.hiroyu, ebiederm, davem,
gthelen, netdev, linux-mm, kirill
In-Reply-To: <1316393805-3005-7-git-send-email-glommer@parallels.com>
On Mon, Sep 19, 2011 at 6:26 AM, Glauber Costa <glommer@parallels.com> wrote:
> This patch uses the "tcp_max_mem" field of the kmem_cgroup to
> effectively control the amount of kernel memory pinned by a cgroup.
>
> We have to make sure that none of the memory pressure thresholds
> specified in the namespace are bigger than the current cgroup.
>
> Signed-off-by: Glauber Costa <glommer@parallels.com>
> CC: David S. Miller <davem@davemloft.net>
> CC: Hiroyouki Kamezawa <kamezawa.hiroyu@jp.fujitsu.com>
> CC: Eric W. Biederman <ebiederm@xmission.com>
> ---
> Documentation/cgroups/memory.txt | 1 +
> include/linux/memcontrol.h | 10 ++++
> mm/memcontrol.c | 89 +++++++++++++++++++++++++++++++++++---
> net/ipv4/sysctl_net_ipv4.c | 20 ++++++++
> 4 files changed, 113 insertions(+), 7 deletions(-)
>
> diff --git a/Documentation/cgroups/memory.txt b/Documentation/cgroups/memory.txt
> index 6f1954a..1ffde3e 100644
> --- a/Documentation/cgroups/memory.txt
> +++ b/Documentation/cgroups/memory.txt
> @@ -78,6 +78,7 @@ Brief summary of control files.
>
> memory.independent_kmem_limit # select whether or not kernel memory limits are
> independent of user limits
> + memory.kmem.tcp.max_memory # set/show hard limit for tcp buf memory
>
> 1. History
>
> diff --git a/include/linux/memcontrol.h b/include/linux/memcontrol.h
> index 6b8c0c0..2df6db8 100644
> --- a/include/linux/memcontrol.h
> +++ b/include/linux/memcontrol.h
> @@ -416,6 +416,9 @@ int tcp_init_cgroup_fill(struct proto *prot, struct cgroup *cgrp,
> struct cgroup_subsys *ss);
> void tcp_destroy_cgroup(struct proto *prot, struct cgroup *cgrp,
> struct cgroup_subsys *ss);
> +
> +unsigned long tcp_max_memory(struct mem_cgroup *cg);
> +void tcp_prot_mem(struct mem_cgroup *cg, long val, int idx);
> #else
> /* memcontrol includes sockets.h, that includes memcontrol.h ... */
> static inline void memcg_sock_mem_alloc(struct mem_cgroup *mem,
> @@ -441,6 +444,13 @@ static inline void sock_update_memcg(struct sock *sk)
> static inline void sock_release_memcg(struct sock *sk)
> {
> }
> +static inline unsigned long tcp_max_memory(struct mem_cgroup *cg)
> +{
> + return 0;
> +}
> +static inline void tcp_prot_mem(struct mem_cgroup *cg, long val, int idx)
> +{
> +}
> #endif /* CONFIG_CGROUP_MEM_RES_CTLR_KMEM */
> #endif /* CONFIG_INET */
> #endif /* _LINUX_MEMCONTROL_H */
> diff --git a/mm/memcontrol.c b/mm/memcontrol.c
> index 5e9b2c7..be5ab89 100644
> --- a/mm/memcontrol.c
> +++ b/mm/memcontrol.c
> @@ -345,6 +345,7 @@ struct mem_cgroup {
> spinlock_t pcp_counter_lock;
>
> /* per-cgroup tcp memory pressure knobs */
> + int tcp_max_memory;
Aren't we better of abstracting this in a different structure?
Including all the tcp parameters in that abstraction and adding that
structure here?
> atomic_long_t tcp_memory_allocated;
> struct percpu_counter tcp_sockets_allocated;
> /* those two are read-mostly, leave them at the end */
> @@ -352,6 +353,11 @@ struct mem_cgroup {
> int tcp_memory_pressure;
> };
>
> +static inline bool mem_cgroup_is_root(struct mem_cgroup *mem)
> +{
> + return (mem == root_mem_cgroup);
> +}
> +
> static struct mem_cgroup *parent_mem_cgroup(struct mem_cgroup *mem);
> /* Writing them here to avoid exposing memcg's inner layout */
> #ifdef CONFIG_CGROUP_MEM_RES_CTLR_KMEM
> @@ -466,6 +472,56 @@ struct percpu_counter *sockets_allocated_tcp(struct mem_cgroup *sg)
> return &sg->tcp_sockets_allocated;
> }
>
> +static int tcp_write_maxmem(struct cgroup *cgrp, struct cftype *cft, u64 val)
> +{
> + struct mem_cgroup *sg = mem_cgroup_from_cont(cgrp);
sg, I'd prefer memcg, does sg stand for socket group?
> + struct mem_cgroup *parent = parent_mem_cgroup(sg);
> + struct net *net = current->nsproxy->net_ns;
> + int i;
> +
> + if (!cgroup_lock_live_group(cgrp))
> + return -ENODEV;
> +
> + /*
> + * We can't allow more memory than our parents. Since this
> + * will be tested for all calls, by induction, there is no need
> + * to test any parent other than our own
> + * */
> + if (parent && (val > parent->tcp_max_memory))
> + val = parent->tcp_max_memory;
> +
> + sg->tcp_max_memory = val;
> +
> + for (i = 0; i < 3; i++)
> + sg->tcp_prot_mem[i] = min_t(long, val,
> + net->ipv4.sysctl_tcp_mem[i]);
> +
> + cgroup_unlock();
> +
> + return 0;
> +}
> +
> +static u64 tcp_read_maxmem(struct cgroup *cgrp, struct cftype *cft)
> +{
> + struct mem_cgroup *sg = mem_cgroup_from_cont(cgrp);
sg? We generally use memcg as a convention
> + u64 ret;
> +
> + if (!cgroup_lock_live_group(cgrp))
> + return -ENODEV;
> + ret = sg->tcp_max_memory;
> +
> + cgroup_unlock();
> + return ret;
> +}
> +
> +static struct cftype tcp_files[] = {
> + {
> + .name = "kmem.tcp.max_memory",
> + .write_u64 = tcp_write_maxmem,
> + .read_u64 = tcp_read_maxmem,
> + },
> +};
> +
> /*
> * For ipv6, we only need to fill in the function pointers (can't initialize
> * things twice). So keep it separated
> @@ -487,8 +543,10 @@ int tcp_init_cgroup(struct proto *prot, struct cgroup *cgrp,
> struct cgroup_subsys *ss)
> {
> struct mem_cgroup *cg = mem_cgroup_from_cont(cgrp);
> + struct mem_cgroup *parent = parent_mem_cgroup(cg);
> unsigned long limit;
> struct net *net = current->nsproxy->net_ns;
> + int ret = 0;
>
> cg->tcp_memory_pressure = 0;
> atomic_long_set(&cg->tcp_memory_allocated, 0);
> @@ -497,12 +555,25 @@ int tcp_init_cgroup(struct proto *prot, struct cgroup *cgrp,
> limit = nr_free_buffer_pages() / 8;
> limit = max(limit, 128UL);
>
> + if (parent)
> + cg->tcp_max_memory = parent->tcp_max_memory;
> + else
> + cg->tcp_max_memory = limit * 2;
> +
> cg->tcp_prot_mem[0] = net->ipv4.sysctl_tcp_mem[0];
> cg->tcp_prot_mem[1] = net->ipv4.sysctl_tcp_mem[1];
> cg->tcp_prot_mem[2] = net->ipv4.sysctl_tcp_mem[2];
>
> tcp_init_cgroup_fill(prot, cgrp, ss);
> - return 0;
> + /*
> + * For non-root cgroup, we need to set up all tcp-related variables,
> + * but to be consistent with the rest of kmem management, we don't
> + * expose any of the controls
> + */
> + if (!mem_cgroup_is_root(cg))
> + ret = cgroup_add_files(cgrp, ss, tcp_files,
> + ARRAY_SIZE(tcp_files));
> + return ret;
> }
> EXPORT_SYMBOL(tcp_init_cgroup);
>
> @@ -514,6 +585,16 @@ void tcp_destroy_cgroup(struct proto *prot, struct cgroup *cgrp,
> percpu_counter_destroy(&cg->tcp_sockets_allocated);
> }
> EXPORT_SYMBOL(tcp_destroy_cgroup);
> +
> +unsigned long tcp_max_memory(struct mem_cgroup *cg)
> +{
> + return cg->tcp_max_memory;
> +}
> +
> +void tcp_prot_mem(struct mem_cgroup *cg, long val, int idx)
> +{
> + cg->tcp_prot_mem[idx] = val;
> +}
> #endif /* CONFIG_INET */
> #endif /* CONFIG_CGROUP_MEM_RES_CTLR_KMEM */
>
> @@ -1092,12 +1173,6 @@ static struct mem_cgroup *mem_cgroup_get_next(struct mem_cgroup *iter,
> #define for_each_mem_cgroup_all(iter) \
> for_each_mem_cgroup_tree_cond(iter, NULL, true)
>
> -
> -static inline bool mem_cgroup_is_root(struct mem_cgroup *mem)
> -{
> - return (mem == root_mem_cgroup);
> -}
> -
> void mem_cgroup_count_vm_event(struct mm_struct *mm, enum vm_event_item idx)
> {
> struct mem_cgroup *mem;
> diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c
> index bbd67ab..cdc35f6 100644
> --- a/net/ipv4/sysctl_net_ipv4.c
> +++ b/net/ipv4/sysctl_net_ipv4.c
> @@ -14,6 +14,7 @@
> #include <linux/init.h>
> #include <linux/slab.h>
> #include <linux/nsproxy.h>
> +#include <linux/memcontrol.h>
> #include <linux/swap.h>
> #include <net/snmp.h>
> #include <net/icmp.h>
> @@ -182,6 +183,10 @@ static int ipv4_tcp_mem(ctl_table *ctl, int write,
> int ret;
> unsigned long vec[3];
> struct net *net = current->nsproxy->net_ns;
> +#ifdef CONFIG_CGROUP_MEM_RES_CTLR_KMEM
> + int i;
> + struct mem_cgroup *cg;
> +#endif
>
> ctl_table tmp = {
> .data = &vec,
> @@ -198,6 +203,21 @@ static int ipv4_tcp_mem(ctl_table *ctl, int write,
> if (ret)
> return ret;
>
> +#ifdef CONFIG_CGROUP_MEM_RES_CTLR_KMEM
> + rcu_read_lock();
> + cg = mem_cgroup_from_task(current);
> + for (i = 0; i < 3; i++)
> + if (vec[i] > tcp_max_memory(cg)) {
> + rcu_read_unlock();
> + return -EINVAL;
> + }
> +
> + tcp_prot_mem(cg, vec[0], 0);
> + tcp_prot_mem(cg, vec[1], 1);
> + tcp_prot_mem(cg, vec[2], 2);
> + rcu_read_unlock();
> +#endif
> +
> net->ipv4.sysctl_tcp_mem[0] = vec[0];
> net->ipv4.sysctl_tcp_mem[1] = vec[1];
> net->ipv4.sysctl_tcp_mem[2] = vec[2];
Balbir Singh
--
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
* [RFC PATCH V2] ethtool: Add command to configure IOV features
From: Greg Rose @ 2011-09-22 21:35 UTC (permalink / raw)
To: netdev
New command to allow configuration of IOV features such as the number of
Virtual Functions to allocate for a given Physical Function interface,
the number of semi-independent net devices to allocate from partitioned
I/O resources in the PF and to set the number of queues per VF.
Signed-off-by: Greg Rose <gregory.v.rose@intel.com>
---
ethtool.c | 94 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 93 insertions(+), 1 deletions(-)
diff --git a/ethtool.c b/ethtool.c
index 35c3733..1ebf6f3 100644
--- a/ethtool.c
+++ b/ethtool.c
@@ -99,6 +99,8 @@ static int do_flash(int fd, struct ifreq *ifr);
static int do_permaddr(int fd, struct ifreq *ifr);
static int do_getfwdump(int fd, struct ifreq *ifr);
static int do_setfwdump(int fd, struct ifreq *ifr);
+static int do_get_iov(int fd, struct ifreq *ifr);
+static int do_set_iov(int fd, struct ifreq *ifr);
static int send_ioctl(int fd, struct ifreq *ifr);
@@ -133,6 +135,8 @@ static enum {
MODE_PERMADDR,
MODE_SET_DUMP,
MODE_GET_DUMP,
+ MODE_GET_IOV,
+ MODE_SET_IOV,
} mode = MODE_GSET;
static struct option {
@@ -266,6 +270,8 @@ static struct option {
{ "-W", "--set-dump", MODE_SET_DUMP,
"Set dump flag of the device",
" N\n"},
+ { "-v", "--get-iov", MODE_GET_IOV, "Get IOV parameters", "\n" },
+ { "-V", "--set_iov", MODE_SET_IOV, "Set IOV parameters", "[ N ]\n" },
{ "-h", "--help", MODE_HELP, "Show this help" },
{ NULL, "--version", MODE_VERSION, "Show version number" },
{}
@@ -392,6 +398,10 @@ static char **rxfhindir_weight = NULL;
static char *flash_file = NULL;
static int flash = -1;
static int flash_region = -1;
+static int iov_changed = 0;
+static int iov_numvfs_wanted = -1;
+static int iov_numnetdevs_wanted = -1;
+static int iov_numvqueues_wanted = -1;
static int msglvl_changed;
static u32 msglvl_wanted = 0;
@@ -549,6 +559,12 @@ static struct cmdline_info cmdline_msglvl[] = {
NETIF_MSG_WOL, &msglvl_mask },
};
+static struct cmdline_info cmdline_iov[] = {
+ { "vfs", CMDL_S32, &iov_numvfs_wanted, NULL },
+ { "netdevs", CMDL_S32, &iov_numnetdevs_wanted, NULL },
+ { "vqueues", CMDL_S32, &iov_numvqueues_wanted, NULL },
+};
+
static long long
get_int_range(char *str, int base, long long min, long long max)
{
@@ -792,7 +808,9 @@ static void parse_cmdline(int argc, char **argp)
(mode == MODE_FLASHDEV) ||
(mode == MODE_PERMADDR) ||
(mode == MODE_SET_DUMP) ||
- (mode == MODE_GET_DUMP)) {
+ (mode == MODE_GET_DUMP) ||
+ (mode == MODE_GET_IOV) ||
+ (mode == MODE_SET_IOV)) {
devname = argp[i];
break;
}
@@ -1007,6 +1025,14 @@ static void parse_cmdline(int argc, char **argp)
i = argc;
break;
}
+ if (mode == MODE_SET_IOV) {
+ parse_generic_cmdline(argc, argp, i,
+ &iov_changed,
+ cmdline_iov,
+ ARRAY_SIZE(cmdline_iov));
+ i = argc;
+ break;
+ }
if (mode != MODE_SSET)
exit_bad_args();
if (!strcmp(argp[i], "speed")) {
@@ -1949,6 +1975,10 @@ static int doit(void)
return do_getfwdump(fd, &ifr);
} else if (mode == MODE_SET_DUMP) {
return do_setfwdump(fd, &ifr);
+ } else if (mode == MODE_GET_IOV) {
+ return do_get_iov(fd, &ifr);
+ } else if (mode == MODE_SET_IOV) {
+ return do_set_iov(fd, &ifr);
}
return 69;
@@ -3338,6 +3368,68 @@ static int do_setfwdump(int fd, struct ifreq *ifr)
return 0;
}
+static int do_get_iov(int fd, struct ifreq *ifr)
+{
+ int err;
+ struct ethtool_iov_get_cmd iov_cmd;
+
+ iov_cmd.cmd = ETHTOOL_IOV_GET_CMD;
+ ifr->ifr_data = (caddr_t)&iov_cmd;
+ err = send_ioctl(fd, ifr);
+ if (err < 0) {
+ perror("Can not get current IOV mode\n");
+ return 1;
+ }
+
+ memcpy(&iov_cmd, ifr->ifr_data, sizeof(iov_cmd));
+
+ switch(iov_cmd.mode) {
+ case ETHTOOL_IOV_MODE_SRIOV:
+ printf("Device %s is configured for SR-IOV mode\n", devname);
+ break;
+ case ETHTOOL_IOV_MODE_VM_QUEUES:
+ printf("Device %s is configured for VM Queues mode\n", devname);
+ break;
+ case ETHTOOL_IOV_MODE_NONE:
+ default:
+ printf("Device %s is not configured for IO Virtualization\n",
+ devname);
+ break;
+ }
+
+ return 0;
+}
+
+static int do_set_iov(int fd, struct ifreq *ifr)
+{
+ int err;
+ struct ethtool_iov_set_cmd iov_cmd;
+
+ if (iov_changed) {
+ iov_cmd.cmd = ETHTOOL_IOV_SET_CMD;
+ if (iov_numvfs_wanted >= 0) {
+ iov_cmd.set_cmd = ETHTOOL_IOV_CMD_CONFIGURE_SRIOV;
+ iov_cmd.cmd_param = iov_numvfs_wanted;
+ } else if (iov_numnetdevs_wanted >= 0) {
+ iov_cmd.set_cmd = ETHTOOL_IOV_CMD_CONFIGURE_NETDEVS;
+ iov_cmd.cmd_param = iov_numnetdevs_wanted;
+ } else if (iov_numvqueues_wanted >= 0) {
+ iov_cmd.set_cmd = ETHTOOL_IOV_CMD_CONFIGURE_VF_QUEUES;
+ iov_cmd.cmd_param = iov_numvqueues_wanted;
+ } else {
+ return -EINVAL;
+ }
+ ifr->ifr_data = (caddr_t)&iov_cmd;
+ err = send_ioctl(fd, ifr);
+ if (err < 0) {
+ perror("Can not set new IOV mode\n");
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
static int send_ioctl(int fd, struct ifreq *ifr)
{
return ioctl(fd, SIOCETHTOOL, ifr);
^ permalink raw reply related
* [RFC PATCH V2 2/2] ixgbe: Add support for new ethtool IOV configuration commands
From: Greg Rose @ 2011-09-22 21:35 UTC (permalink / raw)
To: netdev
In-Reply-To: <20110922213522.26654.59301.stgit@gitlad.jf.intel.com>
Implement driver support for the new ethtool command to configure
the number of VFs per PF independently. The framework is in place
for support of two other features that allow the user to partition
some of the I/O resources of the device to additional semi-independent
net devices and to set the number of queues per VF.
Signed-off-by: Greg Rose <gregory.v.rose@intel.com>
---
drivers/net/ethernet/intel/ixgbe/ixgbe.h | 1
drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c | 110 ++++++++++++++++++++++
drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 3 +
3 files changed, 113 insertions(+), 1 deletions(-)
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe.h b/drivers/net/ethernet/intel/ixgbe/ixgbe.h
index 8fab322..cea2323 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe.h
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe.h
@@ -528,6 +528,7 @@ struct ixgbe_adapter {
int fdir_filter_count;
u32 timer_event_accumulator;
u32 vferr_refcount;
+ const struct ixgbe_info *saved_ii;
};
struct ixgbe_fdir_filter {
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c
index 08c9994..c695362 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c
@@ -38,7 +38,7 @@
#include <linux/uaccess.h>
#include "ixgbe.h"
-
+#include "ixgbe_sriov.h"
#define IXGBE_ALL_RAR_ENTRIES 16
@@ -2577,6 +2577,112 @@ static int ixgbe_set_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd)
return ret;
}
+static int ixgbe_reinit_sriov(struct net_device *netdev, int new_vfs)
+{
+ struct ixgbe_adapter *adapter = netdev_priv(netdev);
+ struct pci_dev *pdev = adapter->pdev;
+ int err;
+ int i;
+
+ if (adapter->flags & IXGBE_FLAG_SRIOV_ENABLED) {
+ if (ixgbe_check_vf_assignment(adapter)) {
+ netdev_warn(netdev, "%s ",
+ "reconfigure of SR-IOV VFs "
+ "not supported while VFs are "
+ "assigned to guest VMs\n");
+ return -EBUSY;
+ }
+ }
+ if (netif_running(netdev)) {
+ netdev_warn(netdev, "%s",
+ "Cannot reconfigure SR-IOV "
+ "while interface is up\n"
+ "Please bring the interface "
+ "down first\n");
+ return -EBUSY;
+ }
+
+ ixgbe_clear_interrupt_scheme(adapter);
+
+ if (adapter->num_vfs)
+ ixgbe_disable_sriov(adapter);
+
+ adapter->num_vfs = (new_vfs > 63) ? 63 : new_vfs;
+
+ if (adapter->num_vfs) {
+ ixgbe_enable_sriov(adapter, adapter->saved_ii);
+ for (i = 0; i < adapter->num_vfs; i++)
+ ixgbe_vf_configuration(pdev, (i | 0x10000000));
+ }
+
+ if (adapter->flags & IXGBE_FLAG_SRIOV_ENABLED) {
+ adapter->flags &= ~(IXGBE_FLAG_RSS_ENABLED |
+ IXGBE_FLAG_DCB_ENABLED);
+ netdev->features &= ~NETIF_F_RXHASH;
+ } else {
+ adapter->flags |= IXGBE_FLAG_RSS_ENABLED;
+ netdev->features |= NETIF_F_RXHASH;
+ }
+
+ err = ixgbe_init_interrupt_scheme(adapter);
+ /*
+ * If we can't init some sort of interrupt scheme then the device
+ * is hosed - just print a warning and bail. Nothing will work
+ * but at least we've put a message in the system log telling why.
+ */
+ if (err)
+ e_dev_err("Cannot initialize interrupts for device\n");
+ else
+ ixgbe_reset(adapter);
+
+ return err;
+}
+
+static int ixgbe_iov_set_cmd(struct net_device *dev,
+ struct ethtool_iov_set_cmd *iov_cmd)
+{
+ struct ixgbe_adapter *adapter = netdev_priv(dev);
+ struct ixgbe_hw *hw = &adapter->hw;
+ int err = 0;
+
+ if (iov_cmd->set_cmd == ETHTOOL_IOV_CMD_CONFIGURE_SRIOV &&
+ hw->mac.type == ixgbe_mac_82598EB)
+ return -EOPNOTSUPP;
+
+ switch (iov_cmd->set_cmd) {
+ case ETHTOOL_IOV_CMD_CONFIGURE_SRIOV:
+ if (iov_cmd->cmd_param != adapter->num_vfs &&
+ !(adapter->flags & IXGBE_FLAG_DCB_ENABLED))
+ err = ixgbe_reinit_sriov(dev, iov_cmd->cmd_param);
+ else
+ err = -EINVAL;
+ break;
+ case ETHTOOL_IOV_CMD_CONFIGURE_NETDEVS:
+ err = -ENOTSUPP;
+ break;
+ case ETHTOOL_IOV_CMD_CONFIGURE_VF_QUEUES:
+ err = -ENOTSUPP;
+ break;
+ default:
+ err = -EINVAL;
+ break;
+ }
+
+ return err;
+}
+
+static int ixgbe_iov_get_cmd(struct net_device *dev,
+ struct ethtool_iov_get_cmd *iov_cmd)
+{
+ struct ixgbe_adapter *adapter = netdev_priv(dev);
+
+ iov_cmd->mode = ETHTOOL_IOV_MODE_NONE;
+ if (adapter->flags & IXGBE_FLAG_SRIOV_ENABLED)
+ iov_cmd->mode = ETHTOOL_IOV_MODE_SRIOV;
+
+ return 0;
+}
+
static const struct ethtool_ops ixgbe_ethtool_ops = {
.get_settings = ixgbe_get_settings,
.set_settings = ixgbe_set_settings,
@@ -2605,6 +2711,8 @@ static const struct ethtool_ops ixgbe_ethtool_ops = {
.set_coalesce = ixgbe_set_coalesce,
.get_rxnfc = ixgbe_get_rxnfc,
.set_rxnfc = ixgbe_set_rxnfc,
+ .iov_set_cmd = ixgbe_iov_set_cmd,
+ .iov_get_cmd = ixgbe_iov_get_cmd,
};
void ixgbe_set_ethtool_ops(struct net_device *netdev)
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
index 99ff8b2..546f3ba 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
@@ -7591,6 +7591,9 @@ static void __devinit ixgbe_probe_vf(struct ixgbe_adapter *adapter,
if (hw->mac.type == ixgbe_mac_82598EB)
return;
+ /* need to save this away in case SR-IOV is reconfigured */
+ adapter->saved_ii = ii;
+
/* The 82599 supports up to 64 VFs per physical function
* but this implementation limits allocation to 63 so that
* basic networking resources are still available to the
^ permalink raw reply related
* [RFC PATCH V2 1/2] net/core/ethtool: New Commands to Configure IOV features
From: Greg Rose @ 2011-09-22 21:35 UTC (permalink / raw)
To: netdev
The only currently supported method of configuring the number of VFs
is through the max_vfs module parameter. This method is inadequate to
support scenarios in which the user might wish to have varying numbers
of VFs per PF. There is additional support for drivers that want to
partition some driver resources to additional net devices and for
configuring the number of Tx/Rx queue pairs per VF.
Signed-off-by: Greg Rose <gregory.v.rose@intel.com>
---
include/linux/ethtool.h | 30 +++++++++++++++++++++++++++++-
net/core/ethtool.c | 38 ++++++++++++++++++++++++++++++++++++++
2 files changed, 67 insertions(+), 1 deletions(-)
diff --git a/include/linux/ethtool.h b/include/linux/ethtool.h
index 45f00b6..448730f 100644
--- a/include/linux/ethtool.h
+++ b/include/linux/ethtool.h
@@ -720,6 +720,27 @@ enum ethtool_sfeatures_retval_bits {
#define ETHTOOL_F_WISH (1 << ETHTOOL_F_WISH__BIT)
#define ETHTOOL_F_COMPAT (1 << ETHTOOL_F_COMPAT__BIT)
+enum ethtool_iov_modes {
+ ETHTOOL_IOV_MODE_NONE,
+ ETHTOOL_IOV_MODE_SRIOV,
+ ETHTOOL_IOV_MODE_NETDEVS,
+};
+
+#define ETHTOOL_IOV_CMD_CONFIGURE_SRIOV 1
+#define ETHTOOL_IOV_CMD_CONFIGURE_NETDEVS 2
+#define ETHTOOL_IOV_CMD_CONFIGURE_VF_QUEUES 3
+
+struct ethtool_iov_set_cmd {
+ __u32 cmd;
+ __u32 set_cmd;
+ __u32 cmd_param;
+};
+
+struct ethtool_iov_get_cmd {
+ __u32 cmd;
+ __u32 mode;
+};
+
#ifdef __KERNEL__
#include <linux/rculist.h>
@@ -879,6 +900,8 @@ bool ethtool_invalid_flags(struct net_device *dev, u32 data, u32 supported);
* and flag of the device.
* @get_dump_data: Get dump data.
* @set_dump: Set dump specific flags to the device.
+ * @iov_set_cmd: Set IOV parameters - number of VFs or VM Queues
+ * @iov_get_cmd: Get current IOV parameters and configuration
*
* All operations are optional (i.e. the function pointer may be set
* to %NULL) and callers must take this into account. Callers must
@@ -956,7 +979,10 @@ struct ethtool_ops {
int (*get_dump_data)(struct net_device *,
struct ethtool_dump *, void *);
int (*set_dump)(struct net_device *, struct ethtool_dump *);
-
+ int (*iov_set_cmd)(struct net_device *,
+ struct ethtool_iov_set_cmd *);
+ int (*iov_get_cmd)(struct net_device *,
+ struct ethtool_iov_get_cmd *);
};
#endif /* __KERNEL__ */
@@ -1030,6 +1056,8 @@ struct ethtool_ops {
#define ETHTOOL_SET_DUMP 0x0000003e /* Set dump settings */
#define ETHTOOL_GET_DUMP_FLAG 0x0000003f /* Get dump settings */
#define ETHTOOL_GET_DUMP_DATA 0x00000040 /* Get dump data */
+#define ETHTOOL_IOV_SET_CMD 0x00000041 /* Set IOV parameters */
+#define ETHTOOL_IOV_GET_CMD 0x00000042 /* Get IOV parameters */
/* compatibility with older code */
#define SPARC_ETH_GSET ETHTOOL_GSET
diff --git a/net/core/ethtool.c b/net/core/ethtool.c
index f444817..a469e40 100644
--- a/net/core/ethtool.c
+++ b/net/core/ethtool.c
@@ -1633,6 +1633,38 @@ out:
return ret;
}
+static int ethtool_iov_set_command(struct net_device *dev,
+ void __user *useraddr)
+{
+ struct ethtool_iov_set_cmd iov_cmd;
+
+ if (!dev->ethtool_ops->iov_set_cmd)
+ return -EOPNOTSUPP;
+ if (copy_from_user(&iov_cmd, useraddr, sizeof(iov_cmd)))
+ return -EFAULT;
+
+ return dev->ethtool_ops->iov_set_cmd(dev, &iov_cmd);
+}
+
+static int ethtool_iov_get_command(struct net_device *dev,
+ void __user *useraddr)
+{
+ int ret;
+ struct ethtool_iov_get_cmd iov_cmd;
+
+ if (!dev->ethtool_ops->iov_get_cmd)
+ return -EOPNOTSUPP;
+ if (copy_from_user(&iov_cmd, useraddr, sizeof(iov_cmd)))
+ return -EFAULT;
+
+ ret = dev->ethtool_ops->iov_get_cmd(dev, &iov_cmd);
+ if (!ret)
+ ret = copy_to_user(useraddr, &iov_cmd, sizeof(iov_cmd));
+
+ return ret;
+}
+
+
/* The main entry point in this file. Called from net/core/dev.c */
int dev_ethtool(struct net *net, struct ifreq *ifr)
@@ -1855,6 +1887,12 @@ int dev_ethtool(struct net *net, struct ifreq *ifr)
case ETHTOOL_GET_DUMP_DATA:
rc = ethtool_get_dump_data(dev, useraddr);
break;
+ case ETHTOOL_IOV_SET_CMD:
+ rc = ethtool_iov_set_command(dev, useraddr);
+ break;
+ case ETHTOOL_IOV_GET_CMD:
+ rc = ethtool_iov_get_command(dev, useraddr);
+ break;
default:
rc = -EOPNOTSUPP;
}
^ permalink raw reply related
* [PATCH next 4/4] r8169: jumbo fixes.
From: Francois Romieu @ 2011-09-22 21:06 UTC (permalink / raw)
To: davem; +Cc: netdev, Realtek linux nic maintainers, Hayes Wang
In-Reply-To: <20110922210202.GA16362@electric-eye.fr.zoreil.com>
- fix features : jumbo frames and checksumming can not be used at the
same time.
- introduce hw_jumbo_{enable / disable} helpers. Their content has been
creatively extracted from Realtek's own drivers. As an illustration,
it would be nice to know how/if the MaxTxPacketSize register operates
when the device can work with a 9k jumbo frame as its documentation
(8168c) can not be applied beyond ~7k.
- rtl_tx_performance_tweak is moved forward. No change.
Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>
---
drivers/net/ethernet/realtek/r8169.c | 308 +++++++++++++++++++++++++++------
1 files changed, 252 insertions(+), 56 deletions(-)
diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c
index 30bba23..2ce6070 100644
--- a/drivers/net/ethernet/realtek/r8169.c
+++ b/drivers/net/ethernet/realtek/r8169.c
@@ -145,88 +145,110 @@ enum rtl_tx_desc_version {
RTL_TD_1 = 1,
};
-#define _R(NAME,TD,FW) \
- { .name = NAME, .txd_version = TD, .fw_name = FW }
+#define JUMBO_1K ETH_DATA_LEN
+#define JUMBO_4K (4*1024 - ETH_HLEN - 2)
+#define JUMBO_6K (6*1024 - ETH_HLEN - 2)
+#define JUMBO_7K (7*1024 - ETH_HLEN - 2)
+#define JUMBO_9K (9*1024 - ETH_HLEN - 2)
+
+#define _R(NAME,TD,FW,SZ,B) { \
+ .name = NAME, \
+ .txd_version = TD, \
+ .fw_name = FW, \
+ .jumbo_max = SZ, \
+ .jumbo_tx_csum = B \
+}
static const struct {
const char *name;
enum rtl_tx_desc_version txd_version;
const char *fw_name;
+ u16 jumbo_max;
+ bool jumbo_tx_csum;
} rtl_chip_infos[] = {
/* PCI devices. */
[RTL_GIGA_MAC_VER_01] =
- _R("RTL8169", RTL_TD_0, NULL),
+ _R("RTL8169", RTL_TD_0, NULL, JUMBO_7K, true),
[RTL_GIGA_MAC_VER_02] =
- _R("RTL8169s", RTL_TD_0, NULL),
+ _R("RTL8169s", RTL_TD_0, NULL, JUMBO_7K, true),
[RTL_GIGA_MAC_VER_03] =
- _R("RTL8110s", RTL_TD_0, NULL),
+ _R("RTL8110s", RTL_TD_0, NULL, JUMBO_7K, true),
[RTL_GIGA_MAC_VER_04] =
- _R("RTL8169sb/8110sb", RTL_TD_0, NULL),
+ _R("RTL8169sb/8110sb", RTL_TD_0, NULL, JUMBO_7K, true),
[RTL_GIGA_MAC_VER_05] =
- _R("RTL8169sc/8110sc", RTL_TD_0, NULL),
+ _R("RTL8169sc/8110sc", RTL_TD_0, NULL, JUMBO_7K, true),
[RTL_GIGA_MAC_VER_06] =
- _R("RTL8169sc/8110sc", RTL_TD_0, NULL),
+ _R("RTL8169sc/8110sc", RTL_TD_0, NULL, JUMBO_7K, true),
/* PCI-E devices. */
[RTL_GIGA_MAC_VER_07] =
- _R("RTL8102e", RTL_TD_1, NULL),
+ _R("RTL8102e", RTL_TD_1, NULL, JUMBO_1K, true),
[RTL_GIGA_MAC_VER_08] =
- _R("RTL8102e", RTL_TD_1, NULL),
+ _R("RTL8102e", RTL_TD_1, NULL, JUMBO_1K, true),
[RTL_GIGA_MAC_VER_09] =
- _R("RTL8102e", RTL_TD_1, NULL),
+ _R("RTL8102e", RTL_TD_1, NULL, JUMBO_1K, true),
[RTL_GIGA_MAC_VER_10] =
- _R("RTL8101e", RTL_TD_0, NULL),
+ _R("RTL8101e", RTL_TD_0, NULL, JUMBO_1K, true),
[RTL_GIGA_MAC_VER_11] =
- _R("RTL8168b/8111b", RTL_TD_0, NULL),
+ _R("RTL8168b/8111b", RTL_TD_0, NULL, JUMBO_4K, false),
[RTL_GIGA_MAC_VER_12] =
- _R("RTL8168b/8111b", RTL_TD_0, NULL),
+ _R("RTL8168b/8111b", RTL_TD_0, NULL, JUMBO_4K, false),
[RTL_GIGA_MAC_VER_13] =
- _R("RTL8101e", RTL_TD_0, NULL),
+ _R("RTL8101e", RTL_TD_0, NULL, JUMBO_1K, true),
[RTL_GIGA_MAC_VER_14] =
- _R("RTL8100e", RTL_TD_0, NULL),
+ _R("RTL8100e", RTL_TD_0, NULL, JUMBO_1K, true),
[RTL_GIGA_MAC_VER_15] =
- _R("RTL8100e", RTL_TD_0, NULL),
+ _R("RTL8100e", RTL_TD_0, NULL, JUMBO_1K, true),
[RTL_GIGA_MAC_VER_16] =
- _R("RTL8101e", RTL_TD_0, NULL),
+ _R("RTL8101e", RTL_TD_0, NULL, JUMBO_1K, true),
[RTL_GIGA_MAC_VER_17] =
- _R("RTL8168b/8111b", RTL_TD_0, NULL),
+ _R("RTL8168b/8111b", RTL_TD_1, NULL, JUMBO_4K, false),
[RTL_GIGA_MAC_VER_18] =
- _R("RTL8168cp/8111cp", RTL_TD_1, NULL),
+ _R("RTL8168cp/8111cp", RTL_TD_1, NULL, JUMBO_6K, false),
[RTL_GIGA_MAC_VER_19] =
- _R("RTL8168c/8111c", RTL_TD_1, NULL),
+ _R("RTL8168c/8111c", RTL_TD_1, NULL, JUMBO_6K, false),
[RTL_GIGA_MAC_VER_20] =
- _R("RTL8168c/8111c", RTL_TD_1, NULL),
+ _R("RTL8168c/8111c", RTL_TD_1, NULL, JUMBO_6K, false),
[RTL_GIGA_MAC_VER_21] =
- _R("RTL8168c/8111c", RTL_TD_1, NULL),
+ _R("RTL8168c/8111c", RTL_TD_1, NULL, JUMBO_6K, false),
[RTL_GIGA_MAC_VER_22] =
- _R("RTL8168c/8111c", RTL_TD_1, NULL),
+ _R("RTL8168c/8111c", RTL_TD_1, NULL, JUMBO_6K, false),
[RTL_GIGA_MAC_VER_23] =
- _R("RTL8168cp/8111cp", RTL_TD_1, NULL),
+ _R("RTL8168cp/8111cp", RTL_TD_1, NULL, JUMBO_6K, false),
[RTL_GIGA_MAC_VER_24] =
- _R("RTL8168cp/8111cp", RTL_TD_1, NULL),
+ _R("RTL8168cp/8111cp", RTL_TD_1, NULL, JUMBO_6K, false),
[RTL_GIGA_MAC_VER_25] =
- _R("RTL8168d/8111d", RTL_TD_1, FIRMWARE_8168D_1),
+ _R("RTL8168d/8111d", RTL_TD_1, FIRMWARE_8168D_1,
+ JUMBO_9K, false),
[RTL_GIGA_MAC_VER_26] =
- _R("RTL8168d/8111d", RTL_TD_1, FIRMWARE_8168D_2),
+ _R("RTL8168d/8111d", RTL_TD_1, FIRMWARE_8168D_2,
+ JUMBO_9K, false),
[RTL_GIGA_MAC_VER_27] =
- _R("RTL8168dp/8111dp", RTL_TD_1, NULL),
+ _R("RTL8168dp/8111dp", RTL_TD_1, NULL, JUMBO_9K, false),
[RTL_GIGA_MAC_VER_28] =
- _R("RTL8168dp/8111dp", RTL_TD_1, NULL),
+ _R("RTL8168dp/8111dp", RTL_TD_1, NULL, JUMBO_9K, false),
[RTL_GIGA_MAC_VER_29] =
- _R("RTL8105e", RTL_TD_1, FIRMWARE_8105E_1),
+ _R("RTL8105e", RTL_TD_1, FIRMWARE_8105E_1,
+ JUMBO_1K, true),
[RTL_GIGA_MAC_VER_30] =
- _R("RTL8105e", RTL_TD_1, FIRMWARE_8105E_1),
+ _R("RTL8105e", RTL_TD_1, FIRMWARE_8105E_1,
+ JUMBO_1K, true),
[RTL_GIGA_MAC_VER_31] =
- _R("RTL8168dp/8111dp", RTL_TD_1, NULL),
+ _R("RTL8168dp/8111dp", RTL_TD_1, NULL, JUMBO_9K, false),
[RTL_GIGA_MAC_VER_32] =
- _R("RTL8168e/8111e", RTL_TD_1, FIRMWARE_8168E_1),
+ _R("RTL8168e/8111e", RTL_TD_1, FIRMWARE_8168E_1,
+ JUMBO_9K, false),
[RTL_GIGA_MAC_VER_33] =
- _R("RTL8168e/8111e", RTL_TD_1, FIRMWARE_8168E_2),
+ _R("RTL8168e/8111e", RTL_TD_1, FIRMWARE_8168E_2,
+ JUMBO_9K, false),
[RTL_GIGA_MAC_VER_34] =
- _R("RTL8168evl/8111evl",RTL_TD_1, FIRMWARE_8168E_3),
+ _R("RTL8168evl/8111evl",RTL_TD_1, FIRMWARE_8168E_3,
+ JUMBO_9K, false),
[RTL_GIGA_MAC_VER_35] =
- _R("RTL8168f/8111f", RTL_TD_1, FIRMWARE_8168F_1),
+ _R("RTL8168f/8111f", RTL_TD_1, FIRMWARE_8168F_1,
+ JUMBO_9K, false),
[RTL_GIGA_MAC_VER_36] =
- _R("RTL8168f/8111f", RTL_TD_1, FIRMWARE_8168F_2)
+ _R("RTL8168f/8111f", RTL_TD_1, FIRMWARE_8168F_2,
+ JUMBO_9K, false),
};
#undef _R
@@ -469,8 +491,12 @@ enum rtl_register_content {
/* Config3 register p.25 */
MagicPacket = (1 << 5), /* Wake up when receives a Magic Packet */
LinkUp = (1 << 4), /* Wake up when the cable connection is re-established */
+ Jumbo_En0 = (1 << 2), /* 8168 only. Reserved in the 8168b */
Beacon_en = (1 << 0), /* 8168 only. Reserved in the 8168b */
+ /* Config4 register */
+ Jumbo_En1 = (1 << 1), /* 8168 only. Reserved in the 8168b */
+
/* Config5 register p.27 */
BWF = (1 << 6), /* Accept Broadcast wakeup frame */
MWF = (1 << 5), /* Accept Multicast wakeup frame */
@@ -679,6 +705,11 @@ struct rtl8169_private {
void (*up)(struct rtl8169_private *);
} pll_power_ops;
+ struct jumbo_ops {
+ void (*enable)(struct rtl8169_private *);
+ void (*disable)(struct rtl8169_private *);
+ } jumbo_ops;
+
int (*set_speed)(struct net_device *, u8 aneg, u16 sp, u8 dpx, u32 adv);
int (*get_settings)(struct net_device *, struct ethtool_cmd *);
void (*phy_reset_enable)(struct rtl8169_private *tp);
@@ -743,6 +774,19 @@ static void rtl8169_down(struct net_device *dev);
static void rtl8169_rx_clear(struct rtl8169_private *tp);
static int rtl8169_poll(struct napi_struct *napi, int budget);
+static void rtl_tx_performance_tweak(struct pci_dev *pdev, u16 force)
+{
+ int cap = pci_pcie_cap(pdev);
+
+ if (cap) {
+ u16 ctl;
+
+ pci_read_config_word(pdev, cap + PCI_EXP_DEVCTL, &ctl);
+ ctl = (ctl & ~PCI_EXP_DEVCTL_READRQ) | force;
+ pci_write_config_word(pdev, cap + PCI_EXP_DEVCTL, ctl);
+ }
+}
+
static u32 ocp_read(struct rtl8169_private *tp, u8 mask, u16 reg)
{
void __iomem *ioaddr = tp->mmio_addr;
@@ -1511,9 +1555,15 @@ static int rtl8169_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
static u32 rtl8169_fix_features(struct net_device *dev, u32 features)
{
+ struct rtl8169_private *tp = netdev_priv(dev);
+
if (dev->mtu > TD_MSS_MAX)
features &= ~NETIF_F_ALL_TSO;
+ if (dev->mtu > JUMBO_1K &&
+ !rtl_chip_infos[tp->mac_version].jumbo_tx_csum)
+ features &= ~NETIF_F_IP_CSUM;
+
return features;
}
@@ -3608,8 +3658,8 @@ static void r8168_pll_power_up(struct rtl8169_private *tp)
r8168_phy_power_up(tp);
}
-static void rtl_pll_power_op(struct rtl8169_private *tp,
- void (*op)(struct rtl8169_private *))
+static void rtl_generic_op(struct rtl8169_private *tp,
+ void (*op)(struct rtl8169_private *))
{
if (op)
op(tp);
@@ -3617,12 +3667,12 @@ static void rtl_pll_power_op(struct rtl8169_private *tp,
static void rtl_pll_power_down(struct rtl8169_private *tp)
{
- rtl_pll_power_op(tp, tp->pll_power_ops.down);
+ rtl_generic_op(tp, tp->pll_power_ops.down);
}
static void rtl_pll_power_up(struct rtl8169_private *tp)
{
- rtl_pll_power_op(tp, tp->pll_power_ops.up);
+ rtl_generic_op(tp, tp->pll_power_ops.up);
}
static void __devinit rtl_init_pll_power_ops(struct rtl8169_private *tp)
@@ -3713,6 +3763,150 @@ static void rtl8169_init_ring_indexes(struct rtl8169_private *tp)
tp->dirty_tx = tp->dirty_rx = tp->cur_tx = tp->cur_rx = 0;
}
+static void rtl_hw_jumbo_enable(struct rtl8169_private *tp)
+{
+ rtl_generic_op(tp, tp->jumbo_ops.enable);
+}
+
+static void rtl_hw_jumbo_disable(struct rtl8169_private *tp)
+{
+ rtl_generic_op(tp, tp->jumbo_ops.disable);
+}
+
+static void r8168c_hw_jumbo_enable(struct rtl8169_private *tp)
+{
+ void __iomem *ioaddr = tp->mmio_addr;
+
+ RTL_W8(Config3, RTL_R8(Config3) | Jumbo_En0);
+ RTL_W8(Config4, RTL_R8(Config4) | Jumbo_En1);
+ rtl_tx_performance_tweak(tp->pci_dev, 0x2 << MAX_READ_REQUEST_SHIFT);
+}
+
+static void r8168c_hw_jumbo_disable(struct rtl8169_private *tp)
+{
+ void __iomem *ioaddr = tp->mmio_addr;
+
+ RTL_W8(Config3, RTL_R8(Config3) & ~Jumbo_En0);
+ RTL_W8(Config4, RTL_R8(Config4) & ~Jumbo_En1);
+ rtl_tx_performance_tweak(tp->pci_dev, 0x5 << MAX_READ_REQUEST_SHIFT);
+}
+
+static void r8168dp_hw_jumbo_enable(struct rtl8169_private *tp)
+{
+ void __iomem *ioaddr = tp->mmio_addr;
+
+ RTL_W8(Config3, RTL_R8(Config3) | Jumbo_En0);
+}
+
+static void r8168dp_hw_jumbo_disable(struct rtl8169_private *tp)
+{
+ void __iomem *ioaddr = tp->mmio_addr;
+
+ RTL_W8(Config3, RTL_R8(Config3) & ~Jumbo_En0);
+}
+
+static void r8168e_hw_jumbo_enable(struct rtl8169_private *tp)
+{
+ void __iomem *ioaddr = tp->mmio_addr;
+ struct pci_dev *pdev = tp->pci_dev;
+
+ RTL_W8(MaxTxPacketSize, 0x3f);
+ RTL_W8(Config3, RTL_R8(Config3) | Jumbo_En0);
+ RTL_W8(Config4, RTL_R8(Config4) | 0x01);
+ pci_write_config_byte(pdev, 0x79, 0x20);
+}
+
+static void r8168e_hw_jumbo_disable(struct rtl8169_private *tp)
+{
+ void __iomem *ioaddr = tp->mmio_addr;
+ struct pci_dev *pdev = tp->pci_dev;
+
+ RTL_W8(MaxTxPacketSize, 0x0c);
+ RTL_W8(Config3, RTL_R8(Config3) & ~Jumbo_En0);
+ RTL_W8(Config4, RTL_R8(Config4) & ~0x01);
+ pci_write_config_byte(pdev, 0x79, 0x50);
+}
+
+static void r8168b_0_hw_jumbo_enable(struct rtl8169_private *tp)
+{
+ rtl_tx_performance_tweak(tp->pci_dev,
+ (0x2 << MAX_READ_REQUEST_SHIFT) | PCI_EXP_DEVCTL_NOSNOOP_EN);
+}
+
+static void r8168b_0_hw_jumbo_disable(struct rtl8169_private *tp)
+{
+ rtl_tx_performance_tweak(tp->pci_dev,
+ (0x5 << MAX_READ_REQUEST_SHIFT) | PCI_EXP_DEVCTL_NOSNOOP_EN);
+}
+
+static void r8168b_1_hw_jumbo_enable(struct rtl8169_private *tp)
+{
+ void __iomem *ioaddr = tp->mmio_addr;
+
+ r8168b_0_hw_jumbo_enable(tp);
+
+ RTL_W8(Config4, RTL_R8(Config4) | (1 << 0));
+}
+
+static void r8168b_1_hw_jumbo_disable(struct rtl8169_private *tp)
+{
+ void __iomem *ioaddr = tp->mmio_addr;
+
+ r8168b_0_hw_jumbo_disable(tp);
+
+ RTL_W8(Config4, RTL_R8(Config4) & ~(1 << 0));
+}
+
+static void __devinit rtl_init_jumbo_ops(struct rtl8169_private *tp)
+{
+ struct jumbo_ops *ops = &tp->jumbo_ops;
+
+ switch (tp->mac_version) {
+ case RTL_GIGA_MAC_VER_11:
+ ops->disable = r8168b_0_hw_jumbo_disable;
+ ops->enable = r8168b_0_hw_jumbo_enable;
+ break;
+ case RTL_GIGA_MAC_VER_12:
+ case RTL_GIGA_MAC_VER_17:
+ ops->disable = r8168b_1_hw_jumbo_disable;
+ ops->enable = r8168b_1_hw_jumbo_enable;
+ break;
+ case RTL_GIGA_MAC_VER_18: /* Wild guess. Needs info from Realtek. */
+ case RTL_GIGA_MAC_VER_19:
+ case RTL_GIGA_MAC_VER_20:
+ case RTL_GIGA_MAC_VER_21: /* Wild guess. Needs info from Realtek. */
+ case RTL_GIGA_MAC_VER_22:
+ case RTL_GIGA_MAC_VER_23:
+ case RTL_GIGA_MAC_VER_24:
+ case RTL_GIGA_MAC_VER_25:
+ case RTL_GIGA_MAC_VER_26:
+ ops->disable = r8168c_hw_jumbo_disable;
+ ops->enable = r8168c_hw_jumbo_enable;
+ break;
+ case RTL_GIGA_MAC_VER_27:
+ case RTL_GIGA_MAC_VER_28:
+ ops->disable = r8168dp_hw_jumbo_disable;
+ ops->enable = r8168dp_hw_jumbo_enable;
+ break;
+ case RTL_GIGA_MAC_VER_31: /* Wild guess. Needs info from Realtek. */
+ case RTL_GIGA_MAC_VER_32:
+ case RTL_GIGA_MAC_VER_33:
+ case RTL_GIGA_MAC_VER_34:
+ ops->disable = r8168e_hw_jumbo_disable;
+ ops->enable = r8168e_hw_jumbo_enable;
+ break;
+
+ /*
+ * No action needed for jumbo frames with 8169.
+ * No jumbo for 810x at all.
+ */
+ default:
+ ops->disable = NULL;
+ ops->enable = NULL;
+ break;
+ }
+}
+
static void rtl_hw_reset(struct rtl8169_private *tp)
{
void __iomem *ioaddr = tp->mmio_addr;
@@ -3857,6 +4051,7 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
rtl_init_mdio_ops(tp);
rtl_init_pll_power_ops(tp);
+ rtl_init_jumbo_ops(tp);
rtl8169_print_mac_version(tp);
@@ -3940,6 +4135,12 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
netif_info(tp, probe, dev, "%s at 0x%lx, %pM, XID %08x IRQ %d\n",
rtl_chip_infos[chipset].name, dev->base_addr, dev->dev_addr,
(u32)(RTL_R32(TxConfig) & 0x9cf0f8ff), dev->irq);
+ if (rtl_chip_infos[chipset].jumbo_max != JUMBO_1K) {
+ netif_info(tp, probe, dev, "jumbo features [frames: %d bytes, "
+ "tx checksumming: %s]\n",
+ rtl_chip_infos[chipset].jumbo_max,
+ rtl_chip_infos[chipset].jumbo_tx_csum ? "ok" : "ko");
+ }
if (tp->mac_version == RTL_GIGA_MAC_VER_27 ||
tp->mac_version == RTL_GIGA_MAC_VER_28 ||
@@ -4296,19 +4497,6 @@ static void rtl_hw_start_8169(struct net_device *dev)
RTL_W16(IntrMask, tp->intr_event);
}
-static void rtl_tx_performance_tweak(struct pci_dev *pdev, u16 force)
-{
- int cap = pci_pcie_cap(pdev);
-
- if (cap) {
- u16 ctl;
-
- pci_read_config_word(pdev, cap + PCI_EXP_DEVCTL, &ctl);
- ctl = (ctl & ~PCI_EXP_DEVCTL_READRQ) | force;
- pci_write_config_word(pdev, cap + PCI_EXP_DEVCTL, ctl);
- }
-}
-
static void rtl_csi_access_enable(void __iomem *ioaddr, u32 bits)
{
u32 csi;
@@ -4936,9 +5124,17 @@ static void rtl_hw_start_8101(struct net_device *dev)
static int rtl8169_change_mtu(struct net_device *dev, int new_mtu)
{
- if (new_mtu < ETH_ZLEN || new_mtu > SafeMtu)
+ struct rtl8169_private *tp = netdev_priv(dev);
+
+ if (new_mtu < ETH_ZLEN ||
+ new_mtu > rtl_chip_infos[tp->mac_version].jumbo_max)
return -EINVAL;
+ if (new_mtu > ETH_DATA_LEN)
+ rtl_hw_jumbo_enable(tp);
+ else
+ rtl_hw_jumbo_disable(tp);
+
dev->mtu = new_mtu;
netdev_update_features(dev);
--
1.7.6
^ permalink raw reply related
* [PATCH next 3/4] r8169: expand received packet length indication.
From: Francois Romieu @ 2011-09-22 21:04 UTC (permalink / raw)
To: davem; +Cc: netdev, Realtek linux nic maintainers, Hayes Wang
In-Reply-To: <20110922210202.GA16362@electric-eye.fr.zoreil.com>
8168d and above allow jumbo frames beyond 8k. Bump the received
packet length check before enabling jumbo frames on these chipsets.
Frame length indication covers bits 0..13 of the first Rx descriptor
32 bits for the 8169 and 8168. I only have authoritative documentation
for the allowed use of the extra (13) bit with the 8169 and 8168c.
Realtek's drivers use the same mask for the 816x and the fast ethernet
only 810x.
Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>
---
drivers/net/ethernet/realtek/r8169.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c
index 9a5965e..30bba23 100644
--- a/drivers/net/ethernet/realtek/r8169.c
+++ b/drivers/net/ethernet/realtek/r8169.c
@@ -5533,7 +5533,7 @@ static int rtl8169_rx_interrupt(struct net_device *dev,
} else {
struct sk_buff *skb;
dma_addr_t addr = le64_to_cpu(desc->addr);
- int pkt_size = (status & 0x00001FFF) - 4;
+ int pkt_size = (status & 0x00003fff) - 4;
/*
* The driver does not support incoming fragmented
--
1.7.6
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox