* [PATCH 5/9] stmmac: export DMA TX/RX rings via debugfs (v2)
From: Giuseppe CAVALLARO @ 2011-08-30 14:21 UTC (permalink / raw)
To: netdev; +Cc: Giuseppe Cavallaro
In-Reply-To: <1314714064-29101-1-git-send-email-peppe.cavallaro@st.com>
This patch adds the following debugFs entry to dump the
RX/TX DMA rings:
/sys/kernel/debug/stmmaceth/descriptors_status
This is an example:
=======================
RX descriptor ring
=======================
[0] DES0=0x85ee0320 DES1=0x1fff1fff BUF1=0x5fae2022 BUF2=0x0
[1] DES0=0x85ee0320 DES1=0x1fff1fff BUF1=0x5fae0022 BUF2=0x0
[2] DES0=0x81460320 DES1=0x1fff1fff BUF1=0x5f9dd022 BUF2=0x0
Signed-off-by: Giuseppe Cavallaro <peppe.cavallaro@st.com>
---
drivers/net/stmmac/Kconfig | 7 +++
drivers/net/stmmac/stmmac_main.c | 105 ++++++++++++++++++++++++++++++++++++++
2 files changed, 112 insertions(+), 0 deletions(-)
diff --git a/drivers/net/stmmac/Kconfig b/drivers/net/stmmac/Kconfig
index 7df7df4..c253012 100644
--- a/drivers/net/stmmac/Kconfig
+++ b/drivers/net/stmmac/Kconfig
@@ -11,6 +11,13 @@ config STMMAC_ETH
if STMMAC_ETH
+config STMMAC_DEBUG_FS
+ bool "Enable monitoring via sysFS "
+ default n
+ depends on STMMAC_ETH && DEBUG_FS
+ -- help
+ The stmmac entry in /sys reports DMA TX/RX rings.
+
config STMMAC_DA
bool "STMMAC DMA arbitration scheme"
default n
diff --git a/drivers/net/stmmac/stmmac_main.c b/drivers/net/stmmac/stmmac_main.c
index 88b2973..1319b4c 100644
--- a/drivers/net/stmmac/stmmac_main.c
+++ b/drivers/net/stmmac/stmmac_main.c
@@ -47,6 +47,10 @@
#include <linux/slab.h>
#include <linux/prefetch.h>
#include "stmmac.h"
+#ifdef CONFIG_STMMAC_DEBUG_FS
+#include <linux/debugfs.h>
+#include <linux/seq_file.h>
+#endif
#define STMMAC_RESOURCE_NAME "stmmaceth"
@@ -1424,6 +1428,96 @@ static int stmmac_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
return ret;
}
+#ifdef CONFIG_STMMAC_DEBUG_FS
+static struct dentry *stmmac_fs_dir;
+static struct dentry *stmmac_rings_status;
+
+static int stmmac_sysfs_ring_read(struct seq_file *seq, void *v)
+{
+ struct tmp_s {
+ u64 a;
+ unsigned int b;
+ unsigned int c;
+ };
+ int i;
+ struct net_device *dev = seq->private;
+ struct stmmac_priv *priv = netdev_priv(dev);
+
+ seq_printf(seq, "=======================\n");
+ seq_printf(seq, " RX descriptor ring\n");
+ seq_printf(seq, "=======================\n");
+
+ for (i = 0; i < priv->dma_rx_size; i++) {
+ struct tmp_s *x = (struct tmp_s *)(priv->dma_rx + i);
+ seq_printf(seq, "[%d] DES0=0x%x DES1=0x%x BUF1=0x%x BUF2=0x%x",
+ i, (unsigned int)(x->a),
+ (unsigned int)((x->a) >> 32), x->b, x->c);
+ seq_printf(seq, "\n");
+ }
+
+ seq_printf(seq, "\n");
+ seq_printf(seq, "=======================\n");
+ seq_printf(seq, " TX descriptor ring\n");
+ seq_printf(seq, "=======================\n");
+
+ for (i = 0; i < priv->dma_tx_size; i++) {
+ struct tmp_s *x = (struct tmp_s *)(priv->dma_tx + i);
+ seq_printf(seq, "[%d] DES0=0x%x DES1=0x%x BUF1=0x%x BUF2=0x%x",
+ i, (unsigned int)(x->a),
+ (unsigned int)((x->a) >> 32), x->b, x->c);
+ seq_printf(seq, "\n");
+ }
+
+ return 0;
+}
+
+static int stmmac_sysfs_ring_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, stmmac_sysfs_ring_read, inode->i_private);
+}
+
+static const struct file_operations stmmac_rings_status_fops = {
+ .owner = THIS_MODULE,
+ .open = stmmac_sysfs_ring_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = seq_release,
+};
+
+static int stmmac_init_fs(struct net_device *dev)
+{
+ /* Create debugfs entries */
+ stmmac_fs_dir = debugfs_create_dir(STMMAC_RESOURCE_NAME, NULL);
+
+ if (!stmmac_fs_dir || IS_ERR(stmmac_fs_dir)) {
+ pr_err("ERROR %s, debugfs create directory failed\n",
+ STMMAC_RESOURCE_NAME);
+
+ return -ENOMEM;
+ }
+
+ /* Entry to report DMA RX/TX rings */
+ stmmac_rings_status = debugfs_create_file("descriptors_status",
+ S_IRUGO, stmmac_fs_dir, dev,
+ &stmmac_rings_status_fops);
+
+ if (!stmmac_rings_status || IS_ERR(stmmac_rings_status)) {
+ pr_info("ERROR creating stmmac ring debugfs file\n");
+ debugfs_remove(stmmac_fs_dir);
+
+ return -ENOMEM;
+ }
+
+ return 0;
+}
+
+static void stmmac_exit_fs(void)
+{
+ debugfs_remove(stmmac_rings_status);
+ debugfs_remove(stmmac_fs_dir);
+}
+#endif /* CONFIG_STMMAC_DEBUG_FS */
+
static const struct net_device_ops stmmac_netdev_ops = {
.ndo_open = stmmac_open,
.ndo_start_xmit = stmmac_xmit,
@@ -1648,6 +1742,13 @@ static int stmmac_dvr_probe(struct platform_device *pdev)
if (ret < 0)
goto out_unregister;
pr_debug("registered!\n");
+
+#ifdef CONFIG_STMMAC_DEBUG_FS
+ ret = stmmac_init_fs(ndev);
+ if (ret < 0)
+ pr_warning("\tFailed debugFS registration");
+#endif
+
return 0;
out_unregister:
@@ -1700,6 +1801,10 @@ static int stmmac_dvr_remove(struct platform_device *pdev)
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
release_mem_region(res->start, resource_size(res));
+#ifdef CONFIG_STMMAC_DEBUG_FS
+ stmmac_exit_fs();
+#endif
+
free_netdev(ndev);
return 0;
--
1.7.4.4
^ permalink raw reply related
* [PATCH 6/9] stmmac: rework the code to get the Synopsys ID (v2)
From: Giuseppe CAVALLARO @ 2011-08-30 14:21 UTC (permalink / raw)
To: netdev; +Cc: Giuseppe Cavallaro
In-Reply-To: <1314714064-29101-1-git-send-email-peppe.cavallaro@st.com>
The Synopsys ID is now passed from the MAC core
to the main. This info will be used for managing
the HW cap register (supported in the new GMAC
generations).
Signed-off-by: Giuseppe Cavallaro <peppe.cavallaro@st.com>
---
drivers/net/stmmac/common.h | 1 +
drivers/net/stmmac/dwmac1000_core.c | 6 ++----
drivers/net/stmmac/dwmac100_core.c | 1 +
drivers/net/stmmac/stmmac_main.c | 20 +++++++++++++++++++-
4 files changed, 23 insertions(+), 5 deletions(-)
diff --git a/drivers/net/stmmac/common.h b/drivers/net/stmmac/common.h
index e08fee8..65b1e56 100644
--- a/drivers/net/stmmac/common.h
+++ b/drivers/net/stmmac/common.h
@@ -230,6 +230,7 @@ struct mac_device_info {
const struct stmmac_dma_ops *dma;
struct mii_regs mii; /* MII register Addresses */
struct mac_link link;
+ unsigned int synopsys_uid;
};
struct mac_device_info *dwmac1000_setup(void __iomem *ioaddr);
diff --git a/drivers/net/stmmac/dwmac1000_core.c b/drivers/net/stmmac/dwmac1000_core.c
index 9ba9cae..b1c48b9 100644
--- a/drivers/net/stmmac/dwmac1000_core.c
+++ b/drivers/net/stmmac/dwmac1000_core.c
@@ -224,10 +224,7 @@ static const struct stmmac_ops dwmac1000_ops = {
struct mac_device_info *dwmac1000_setup(void __iomem *ioaddr)
{
struct mac_device_info *mac;
- u32 uid = readl(ioaddr + GMAC_VERSION);
-
- pr_info("\tDWMAC1000 - user ID: 0x%x, Synopsys ID: 0x%x\n",
- ((uid & 0x0000ff00) >> 8), (uid & 0x000000ff));
+ u32 hwid = readl(ioaddr + GMAC_VERSION);
mac = kzalloc(sizeof(const struct mac_device_info), GFP_KERNEL);
if (!mac)
@@ -241,6 +238,7 @@ struct mac_device_info *dwmac1000_setup(void __iomem *ioaddr)
mac->link.speed = GMAC_CONTROL_FES;
mac->mii.addr = GMAC_MII_ADDR;
mac->mii.data = GMAC_MII_DATA;
+ mac->synopsys_uid = hwid;
return mac;
}
diff --git a/drivers/net/stmmac/dwmac100_core.c b/drivers/net/stmmac/dwmac100_core.c
index aacfc6e..138fb8d 100644
--- a/drivers/net/stmmac/dwmac100_core.c
+++ b/drivers/net/stmmac/dwmac100_core.c
@@ -188,6 +188,7 @@ struct mac_device_info *dwmac100_setup(void __iomem *ioaddr)
mac->link.speed = 0;
mac->mii.addr = MAC_MII_ADDR;
mac->mii.data = MAC_MII_DATA;
+ mac->synopsys_uid = 0;
return mac;
}
diff --git a/drivers/net/stmmac/stmmac_main.c b/drivers/net/stmmac/stmmac_main.c
index 1319b4c..f9ba0f7 100644
--- a/drivers/net/stmmac/stmmac_main.c
+++ b/drivers/net/stmmac/stmmac_main.c
@@ -762,6 +762,23 @@ static void stmmac_mmc_setup(struct stmmac_priv *priv)
memset(&priv->mmc, 0, sizeof(struct stmmac_counters));
}
+static u32 stmmac_get_synopsys_id(struct stmmac_priv *priv)
+{
+ u32 hwid = priv->hw->synopsys_uid;
+
+ /* Only check valid Synopsys Id because old MAC chips
+ * have no HW registers where get the ID */
+ if (likely(hwid)) {
+ u32 uid = ((hwid & 0x0000ff00) >> 8);
+ u32 synid = (hwid & 0x000000ff);
+
+ pr_info("STMMAC - user ID: 0x%x, Synopsys ID: 0x%x\n",
+ uid, synid);
+
+ return synid;
+ }
+ return 0;
+}
/**
* stmmac_open - open entry point of the driver
* @dev : pointer to the device structure.
@@ -834,7 +851,8 @@ static int stmmac_open(struct net_device *dev)
/* Initialize the MAC Core */
priv->hw->mac->core_init(priv->ioaddr);
- priv->rx_coe = priv->hw->mac->rx_coe(priv->ioaddr);
+ stmmac_get_synopsys_id(priv);
+
if (priv->rx_coe)
pr_info("stmmac: Rx Checksum Offload Engine supported\n");
if (priv->plat->tx_coe)
--
1.7.4.4
^ permalink raw reply related
* [PATCH 7/9] stmmac: add HW DMA feature register (v2)
From: Giuseppe CAVALLARO @ 2011-08-30 14:21 UTC (permalink / raw)
To: netdev; +Cc: Giuseppe Cavallaro
In-Reply-To: <1314714064-29101-1-git-send-email-peppe.cavallaro@st.com>
New GMAC chips have an extra register to indicate
the presence of the optional features/functions of
the DMA core.
This patch adds this support and all the HW cap
are exported via debugfs.
Signed-off-by: Giuseppe Cavallaro <peppe.cavallaro@st.com>
---
drivers/net/stmmac/Kconfig | 3 +-
drivers/net/stmmac/common.h | 33 +++++++++
drivers/net/stmmac/dwmac1000_dma.c | 6 ++
drivers/net/stmmac/dwmac_dma.h | 1 +
drivers/net/stmmac/stmmac.h | 1 +
drivers/net/stmmac/stmmac_main.c | 131 ++++++++++++++++++++++++++++++++++++
6 files changed, 174 insertions(+), 1 deletions(-)
diff --git a/drivers/net/stmmac/Kconfig b/drivers/net/stmmac/Kconfig
index c253012..c4be14e 100644
--- a/drivers/net/stmmac/Kconfig
+++ b/drivers/net/stmmac/Kconfig
@@ -16,7 +16,8 @@ config STMMAC_DEBUG_FS
default n
depends on STMMAC_ETH && DEBUG_FS
-- help
- The stmmac entry in /sys reports DMA TX/RX rings.
+ The stmmac entry in /sys reports DMA TX/RX rings
+ or (if supported) the HW cap register.
config STMMAC_DA
bool "STMMAC DMA arbitration scheme"
diff --git a/drivers/net/stmmac/common.h b/drivers/net/stmmac/common.h
index 65b1e56..22c61b2 100644
--- a/drivers/net/stmmac/common.h
+++ b/drivers/net/stmmac/common.h
@@ -116,6 +116,37 @@ enum tx_dma_irq_status {
handle_tx_rx = 3,
};
+/* DMA HW capabilities */
+struct dma_features {
+ unsigned int mbps_10_100;
+ unsigned int mbps_1000;
+ unsigned int half_duplex;
+ unsigned int hash_filter;
+ unsigned int multi_addr;
+ unsigned int pcs;
+ unsigned int sma_mdio;
+ unsigned int pmt_remote_wake_up;
+ unsigned int pmt_magic_frame;
+ unsigned int rmon;
+ /* IEEE 1588-2002*/
+ unsigned int time_stamp;
+ /* IEEE 1588-2008*/
+ unsigned int atime_stamp;
+ /* 802.3az - Energy-Efficient Ethernet (EEE) */
+ unsigned int eee;
+ unsigned int av;
+ /* TX and RX csum */
+ unsigned int tx_coe;
+ unsigned int rx_coe_type1;
+ unsigned int rx_coe_type2;
+ unsigned int rxfifo_over_2048;
+ /* TX and RX number of channels */
+ unsigned int number_rx_channel;
+ unsigned int number_tx_channel;
+ /* Alternate (enhanced) DESC mode*/
+ unsigned int enh_desc;
+};
+
/* GMAC TX FIFO is 8K, Rx FIFO is 16K */
#define BUF_SIZE_16KiB 16384
#define BUF_SIZE_8KiB 8192
@@ -188,6 +219,8 @@ struct stmmac_dma_ops {
void (*stop_rx) (void __iomem *ioaddr);
int (*dma_interrupt) (void __iomem *ioaddr,
struct stmmac_extra_stats *x);
+ /* If supported then get the optional core features */
+ unsigned int (*get_hw_feature) (void __iomem *ioaddr);
};
struct stmmac_ops {
diff --git a/drivers/net/stmmac/dwmac1000_dma.c b/drivers/net/stmmac/dwmac1000_dma.c
index a89384c..da66ac5 100644
--- a/drivers/net/stmmac/dwmac1000_dma.c
+++ b/drivers/net/stmmac/dwmac1000_dma.c
@@ -132,6 +132,11 @@ static void dwmac1000_dump_dma_regs(void __iomem *ioaddr)
}
}
+static unsigned int dwmac1000_get_hw_feature(void __iomem *ioaddr)
+{
+ return readl(ioaddr + DMA_HW_FEATURE);
+}
+
const struct stmmac_dma_ops dwmac1000_dma_ops = {
.init = dwmac1000_dma_init,
.dump_regs = dwmac1000_dump_dma_regs,
@@ -144,4 +149,5 @@ const struct stmmac_dma_ops dwmac1000_dma_ops = {
.start_rx = dwmac_dma_start_rx,
.stop_rx = dwmac_dma_stop_rx,
.dma_interrupt = dwmac_dma_interrupt,
+ .get_hw_feature = dwmac1000_get_hw_feature,
};
diff --git a/drivers/net/stmmac/dwmac_dma.h b/drivers/net/stmmac/dwmac_dma.h
index da3f5cc..437edac 100644
--- a/drivers/net/stmmac/dwmac_dma.h
+++ b/drivers/net/stmmac/dwmac_dma.h
@@ -34,6 +34,7 @@
#define DMA_MISSED_FRAME_CTR 0x00001020 /* Missed Frame Counter */
#define DMA_CUR_TX_BUF_ADDR 0x00001050 /* Current Host Tx Buffer */
#define DMA_CUR_RX_BUF_ADDR 0x00001054 /* Current Host Rx Buffer */
+#define DMA_HW_FEATURE 0x00001058 /* HW Feature Register */
/* DMA Control register defines */
#define DMA_CONTROL_ST 0x00002000 /* Start/Stop Transmission */
diff --git a/drivers/net/stmmac/stmmac.h b/drivers/net/stmmac/stmmac.h
index ef03796..c3a2da7 100644
--- a/drivers/net/stmmac/stmmac.h
+++ b/drivers/net/stmmac/stmmac.h
@@ -78,6 +78,7 @@ struct stmmac_priv {
#endif
struct plat_stmmacenet_data *plat;
struct stmmac_counters mmc;
+ struct dma_features dma_cap;
};
extern int stmmac_mdio_unregister(struct net_device *ndev);
diff --git a/drivers/net/stmmac/stmmac_main.c b/drivers/net/stmmac/stmmac_main.c
index f9ba0f7..a87d583 100644
--- a/drivers/net/stmmac/stmmac_main.c
+++ b/drivers/net/stmmac/stmmac_main.c
@@ -779,6 +779,49 @@ static u32 stmmac_get_synopsys_id(struct stmmac_priv *priv)
}
return 0;
}
+
+/* New GMAC chips support a new register to indicate the
+ * presence of the optional feature/functions.
+ */
+static int stmmac_get_hw_features(struct stmmac_priv *priv)
+{
+ u32 hw_cap = priv->hw->dma->get_hw_feature(priv->ioaddr);
+
+ if (likely(hw_cap)) {
+ priv->dma_cap.mbps_10_100 = (hw_cap & 0x1);
+ priv->dma_cap.mbps_1000 = (hw_cap & 0x2) >> 1;
+ priv->dma_cap.half_duplex = (hw_cap & 0x4) >> 2;
+ priv->dma_cap.hash_filter = (hw_cap & 0x10) >> 4;
+ priv->dma_cap.multi_addr = (hw_cap & 0x20) >> 5;
+ priv->dma_cap.pcs = (hw_cap & 0x40) >> 6;
+ priv->dma_cap.sma_mdio = (hw_cap & 0x100) >> 8;
+ priv->dma_cap.pmt_remote_wake_up = (hw_cap & 0x200) >> 9;
+ priv->dma_cap.pmt_magic_frame = (hw_cap & 0x400) >> 10;
+ priv->dma_cap.rmon = (hw_cap & 0x800) >> 11; /* MMC */
+ /* IEEE 1588-2002*/
+ priv->dma_cap.time_stamp = (hw_cap & 0x1000) >> 12;
+ /* IEEE 1588-2008*/
+ priv->dma_cap.atime_stamp = (hw_cap & 0x2000) >> 13;
+ /* 802.3az - Energy-Efficient Ethernet (EEE) */
+ priv->dma_cap.eee = (hw_cap & 0x4000) >> 14;
+ priv->dma_cap.av = (hw_cap & 0x8000) >> 15;
+ /* TX and RX csum */
+ priv->dma_cap.tx_coe = (hw_cap & 0x10000) >> 16;
+ priv->dma_cap.rx_coe_type1 = (hw_cap & 0x20000) >> 17;
+ priv->dma_cap.rx_coe_type2 = (hw_cap & 0x40000) >> 18;
+ priv->dma_cap.rxfifo_over_2048 = (hw_cap & 0x80000) >> 19;
+ /* TX and RX number of channels */
+ priv->dma_cap.number_rx_channel = (hw_cap & 0x300000) >> 20;
+ priv->dma_cap.number_tx_channel = (hw_cap & 0xc00000) >> 22;
+ /* Alternate (enhanced) DESC mode*/
+ priv->dma_cap.enh_desc = (hw_cap & 0x1000000) >> 24;
+
+ } else
+ pr_debug("\tNo HW DMA feature register supported");
+
+ return hw_cap;
+}
+
/**
* stmmac_open - open entry point of the driver
* @dev : pointer to the device structure.
@@ -853,6 +896,8 @@ static int stmmac_open(struct net_device *dev)
stmmac_get_synopsys_id(priv);
+ stmmac_get_hw_features(priv);
+
if (priv->rx_coe)
pr_info("stmmac: Rx Checksum Offload Engine supported\n");
if (priv->plat->tx_coe)
@@ -1449,6 +1494,7 @@ static int stmmac_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
#ifdef CONFIG_STMMAC_DEBUG_FS
static struct dentry *stmmac_fs_dir;
static struct dentry *stmmac_rings_status;
+static struct dentry *stmmac_dma_cap;
static int stmmac_sysfs_ring_read(struct seq_file *seq, void *v)
{
@@ -1502,6 +1548,78 @@ static const struct file_operations stmmac_rings_status_fops = {
.release = seq_release,
};
+static int stmmac_sysfs_dma_cap_read(struct seq_file *seq, void *v)
+{
+ struct net_device *dev = seq->private;
+ struct stmmac_priv *priv = netdev_priv(dev);
+
+ if (!stmmac_get_hw_features(priv)) {
+ seq_printf(seq, "DMA HW features not supported\n");
+ return 0;
+ }
+
+ seq_printf(seq, "==============================\n");
+ seq_printf(seq, "\tDMA HW features\n");
+ seq_printf(seq, "==============================\n");
+
+ seq_printf(seq, "\t10/100 Mbps %s\n",
+ (priv->dma_cap.mbps_10_100) ? "Y" : "N");
+ seq_printf(seq, "\t1000 Mbps %s\n",
+ (priv->dma_cap.mbps_1000) ? "Y" : "N");
+ seq_printf(seq, "\tHalf duple %s\n",
+ (priv->dma_cap.half_duplex) ? "Y" : "N");
+ seq_printf(seq, "\tHash Filter: %s\n",
+ (priv->dma_cap.hash_filter) ? "Y" : "N");
+ seq_printf(seq, "\tMultiple MAC address registers: %s\n",
+ (priv->dma_cap.multi_addr) ? "Y" : "N");
+ seq_printf(seq, "\tPCS (TBI/SGMII/RTBI PHY interfatces): %s\n",
+ (priv->dma_cap.pcs) ? "Y" : "N");
+ seq_printf(seq, "\tSMA (MDIO) Interface: %s\n",
+ (priv->dma_cap.sma_mdio) ? "Y" : "N");
+ seq_printf(seq, "\tPMT Remote wake up: %s\n",
+ (priv->dma_cap.pmt_remote_wake_up) ? "Y" : "N");
+ seq_printf(seq, "\tPMT Magic Frame: %s\n",
+ (priv->dma_cap.pmt_magic_frame) ? "Y" : "N");
+ seq_printf(seq, "\tRMON module: %s\n",
+ (priv->dma_cap.rmon) ? "Y" : "N");
+ seq_printf(seq, "\tIEEE 1588-2002 Time Stamp: %s\n",
+ (priv->dma_cap.time_stamp) ? "Y" : "N");
+ seq_printf(seq, "\tIEEE 1588-2008 Advanced Time Stamp:%s\n",
+ (priv->dma_cap.atime_stamp) ? "Y" : "N");
+ seq_printf(seq, "\t802.3az - Energy-Efficient Ethernet (EEE) %s\n",
+ (priv->dma_cap.eee) ? "Y" : "N");
+ seq_printf(seq, "\tAV features: %s\n", (priv->dma_cap.av) ? "Y" : "N");
+ seq_printf(seq, "\tChecksum Offload in TX: %s\n",
+ (priv->dma_cap.tx_coe) ? "Y" : "N");
+ seq_printf(seq, "\tIP Checksum Offload (type1) in RX: %s\n",
+ (priv->dma_cap.rx_coe_type1) ? "Y" : "N");
+ seq_printf(seq, "\tIP Checksum Offload (type2) in RX: %s\n",
+ (priv->dma_cap.rx_coe_type2) ? "Y" : "N");
+ seq_printf(seq, "\tRXFIFO > 2048bytes: %s\n",
+ (priv->dma_cap.rxfifo_over_2048) ? "Y" : "N");
+ seq_printf(seq, "\tNumber of Additional RX channel: %d\n",
+ priv->dma_cap.number_rx_channel);
+ seq_printf(seq, "\tNumber of Additional TX channel: %d\n",
+ priv->dma_cap.number_tx_channel);
+ seq_printf(seq, "\tEnhanced descriptors: %s\n",
+ (priv->dma_cap.enh_desc) ? "Y" : "N");
+
+ return 0;
+}
+
+static int stmmac_sysfs_dma_cap_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, stmmac_sysfs_dma_cap_read, inode->i_private);
+}
+
+static const struct file_operations stmmac_dma_cap_fops = {
+ .owner = THIS_MODULE,
+ .open = stmmac_sysfs_dma_cap_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = seq_release,
+};
+
static int stmmac_init_fs(struct net_device *dev)
{
/* Create debugfs entries */
@@ -1526,12 +1644,25 @@ static int stmmac_init_fs(struct net_device *dev)
return -ENOMEM;
}
+ /* Entry to report the DMA HW features */
+ stmmac_dma_cap = debugfs_create_file("dma_cap", S_IRUGO, stmmac_fs_dir,
+ dev, &stmmac_dma_cap_fops);
+
+ if (!stmmac_dma_cap || IS_ERR(stmmac_dma_cap)) {
+ pr_info("ERROR creating stmmac MMC debugfs file\n");
+ debugfs_remove(stmmac_rings_status);
+ debugfs_remove(stmmac_fs_dir);
+
+ return -ENOMEM;
+ }
+
return 0;
}
static void stmmac_exit_fs(void)
{
debugfs_remove(stmmac_rings_status);
+ debugfs_remove(stmmac_dma_cap);
debugfs_remove(stmmac_fs_dir);
}
#endif /* CONFIG_STMMAC_DEBUG_FS */
--
1.7.4.4
^ permalink raw reply related
* [PATCH 8/9] stmmac: update the doc with new info about the driver's debug (v2)
From: Giuseppe CAVALLARO @ 2011-08-30 14:21 UTC (permalink / raw)
To: netdev; +Cc: Giuseppe Cavallaro
In-Reply-To: <1314714064-29101-1-git-send-email-peppe.cavallaro@st.com>
Signed-off-by: Giuseppe Cavallaro <peppe.cavallaro@st.com>
---
Documentation/networking/stmmac.txt | 33 ++++++++++++++++++++++++++++++++-
1 files changed, 32 insertions(+), 1 deletions(-)
diff --git a/Documentation/networking/stmmac.txt b/Documentation/networking/stmmac.txt
index 57a2410..40ec92c 100644
--- a/Documentation/networking/stmmac.txt
+++ b/Documentation/networking/stmmac.txt
@@ -235,7 +235,38 @@ reset procedure etc).
o enh_desc.c: functions for handling enhanced descriptors
o norm_desc.c: functions for handling normal descriptors
-5) TODO:
+5) Debug Information
+
+The driver exports many information i.e. internal statistics,
+debug information, MAC and DMA registers etc.
+
+These can be read in several ways depending on the
+type of the information actually needed.
+
+For example a user can be use the ethtool support
+to get statistics: e.g. using: ethtool -S ethX
+(that shows the Management counters (MMC) if supported)
+or sees the MAC/DMA registers: e.g. using: ethtool -d ethX
+
+Compiling the Kernel with CONFIG_DEBUG_FS and enabling the
+STMMAC_DEBUG_FS option the driver will export the following
+debugfs entries:
+
+/sys/kernel/debug/stmmaceth/descriptors_status
+ To show the DMA TX/RX descriptor rings
+
+Developer can also use the "debug" module parameter to get
+further debug information.
+
+In the end, there are other macros (that cannot be enabled
+via menuconfig) to turn-on the RX/TX DMA debugging,
+specific MAC core debug printk etc. Others to enable the
+debug in the TX and RX processes.
+All these are only useful during the developing stage
+and should never enabled inside the code for general usage.
+In fact, these can generate an huge amount of debug messages.
+
+6) TODO:
o XGMAC is not supported.
o Review the timer optimisation code to use an embedded device that will be
available in new chip generations.
--
1.7.4.4
^ permalink raw reply related
* [PATCH 9/9] stmmac: update the driver version (Aug_2011) (v2)
From: Giuseppe CAVALLARO @ 2011-08-30 14:21 UTC (permalink / raw)
To: netdev; +Cc: Giuseppe Cavallaro
In-Reply-To: <1314714064-29101-1-git-send-email-peppe.cavallaro@st.com>
Signed-off-by: Giuseppe Cavallaro <peppe.cavallaro@st.com>
---
drivers/net/stmmac/stmmac.h | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/drivers/net/stmmac/stmmac.h b/drivers/net/stmmac/stmmac.h
index c3a2da7..1434bdb 100644
--- a/drivers/net/stmmac/stmmac.h
+++ b/drivers/net/stmmac/stmmac.h
@@ -20,7 +20,7 @@
Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>
*******************************************************************************/
-#define DRV_MODULE_VERSION "July_2011"
+#define DRV_MODULE_VERSION "Aug_2011"
#include <linux/stmmac.h>
#include "common.h"
--
1.7.4.4
^ permalink raw reply related
* Re: 802.1Q VLAN random tag injected when vlan configured on forcedeth interface
From: Ruslan N. Marchenko @ 2011-08-30 14:23 UTC (permalink / raw)
To: Eric Dumazet; +Cc: netdev
In-Reply-To: <20110830134624.GB28341@ruff.mobi>
On Tue, Aug 30, 2011 at 03:46:24PM +0200, Ruslan N. Marchenko wrote:
> On Tue, Aug 30, 2011 at 03:23:48PM +0200, Eric Dumazet wrote:
> >
> > What kernel version are you using ?
> >
> Oh, sorry for missing it, it runs on
> Linux ruff.mobi 2.6.38-11-generic #48-Ubuntu SMP Fri Jul 29 19:05:14 UTC 2011 i686 i686 i386 GNU/Linux
>
> Just fyi - the openwrt box to which it is connected is
> Linux OpenWrt 2.6.39.2 #2 Fri Aug 12 09:36:23 EEST 2011 mips GNU/Linux
> although packet drop happens even if there're no vlans configured on remote side.
>
Here is double-tag sample:
16:20:31.151268 e0:46:9a:4e:88:1d > 00:26:18:40:21:62, ethertype 802.1Q (0x8100), length 106: vlan 2112, p 7, ethertype 802.1Q, vlan 6, p 0, ethertype IPv4, [|ip]
0x0000: 0026 1840 2162 e046 9a4e 881d 8100 e840
0x0010: 8100 0006 0800 4500 0054 abec 0000
Regards,
Ruslan
^ permalink raw reply
* [PATCH 0/7 net-next] bnx2x: cleanups and VLAN stripping toggle
From: Michal Schmidt @ 2011-08-30 14:30 UTC (permalink / raw)
To: netdev; +Cc: vladz, dmitry, eilong, Michal Schmidt
Hello,
patches 1-6 are cleanups.
Patch 7 adds HW VLAN stripping control via ethtool.
Michal Schmidt (7):
bnx2x: remove unused fields in struct bnx2x_func_init_params
bnx2x: remove the 'leading' arguments
bnx2x: decrease indentation in bnx2x_rx_int()
bnx2x: simplify TPA sanity check
bnx2x: do not set TPA flags and features in bnx2x_init_bp
bnx2x: move fp->disable_tpa to ->flags
bnx2x: expose HW RX VLAN stripping toggle
drivers/net/ethernet/broadcom/bnx2x/bnx2x.h | 21 +--
drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c | 242 +++++++++++-----------
drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h | 6 +-
drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | 62 ++----
4 files changed, 148 insertions(+), 183 deletions(-)
--
1.7.6
^ permalink raw reply
* [PATCH 1/7] bnx2x: remove unused fields in struct bnx2x_func_init_params
From: Michal Schmidt @ 2011-08-30 14:30 UTC (permalink / raw)
To: netdev; +Cc: vladz, dmitry, eilong, Michal Schmidt
In-Reply-To: <1314714646-3642-1-git-send-email-mschmidt@redhat.com>
func_flgs is not used for anything. The only flag that's ever checked
(FUNC_FLG_SPQ) is always set. The other flags are never read.
fw_stat_map is not used at all.
Signed-off-by: Michal Schmidt <mschmidt@redhat.com>
---
drivers/net/ethernet/broadcom/bnx2x/bnx2x.h | 15 ++-------------
drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | 18 +++---------------
2 files changed, 5 insertions(+), 28 deletions(-)
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h
index f127768..735e491 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h
@@ -1490,24 +1490,13 @@ extern int num_queues;
#define RSS_IPV6_TCP_CAP_MASK \
TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV6_TCP_CAPABILITY
-/* func init flags */
-#define FUNC_FLG_RSS 0x0001
-#define FUNC_FLG_STATS 0x0002
-/* removed FUNC_FLG_UNMATCHED 0x0004 */
-#define FUNC_FLG_TPA 0x0008
-#define FUNC_FLG_SPQ 0x0010
-#define FUNC_FLG_LEADING 0x0020 /* PF only */
-
-
struct bnx2x_func_init_params {
/* dma */
- dma_addr_t fw_stat_map; /* valid iff FUNC_FLG_STATS */
- dma_addr_t spq_map; /* valid iff FUNC_FLG_SPQ */
+ dma_addr_t spq_map;
- u16 func_flgs;
u16 func_id; /* abs fid */
u16 pf_id;
- u16 spq_prod; /* valid iff FUNC_FLG_SPQ */
+ u16 spq_prod;
};
#define for_each_eth_queue(bp, var) \
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
index 85dd294..e7b584b 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
@@ -2661,11 +2661,9 @@ void bnx2x_func_init(struct bnx2x *bp, struct bnx2x_func_init_params *p)
storm_memset_func_en(bp, p->func_id, 1);
/* spq */
- if (p->func_flgs & FUNC_FLG_SPQ) {
- storm_memset_spq_addr(bp, p->spq_map, p->func_id);
- REG_WR(bp, XSEM_REG_FAST_MEMORY +
- XSTORM_SPQ_PROD_OFFSET(p->func_id), p->spq_prod);
- }
+ storm_memset_spq_addr(bp, p->spq_map, p->func_id);
+ REG_WR(bp, XSEM_REG_FAST_MEMORY +
+ XSTORM_SPQ_PROD_OFFSET(p->func_id), p->spq_prod);
}
/**
@@ -2838,7 +2836,6 @@ static void bnx2x_pf_init(struct bnx2x *bp)
{
struct bnx2x_func_init_params func_init = {0};
struct event_ring_data eq_data = { {0} };
- u16 flags;
if (!CHIP_IS_E1x(bp)) {
/* reset IGU PF statistics: MSIX + ATTN */
@@ -2855,15 +2852,6 @@ static void bnx2x_pf_init(struct bnx2x *bp)
BP_FUNC(bp) : BP_VN(bp))*4, 0);
}
- /* function setup flags */
- flags = (FUNC_FLG_STATS | FUNC_FLG_LEADING | FUNC_FLG_SPQ);
-
- /* This flag is relevant for E1x only.
- * E2 doesn't have a TPA configuration in a function level.
- */
- flags |= (bp->flags & TPA_ENABLE_FLAG) ? FUNC_FLG_TPA : 0;
-
- func_init.func_flgs = flags;
func_init.pf_id = BP_FUNC(bp);
func_init.func_id = BP_FUNC(bp);
func_init.spq_map = bp->spq_mapping;
--
1.7.6
^ permalink raw reply related
* [PATCH 2/7] bnx2x: remove the 'leading' arguments
From: Michal Schmidt @ 2011-08-30 14:30 UTC (permalink / raw)
To: netdev; +Cc: vladz, dmitry, eilong, Michal Schmidt
In-Reply-To: <1314714646-3642-1-git-send-email-mschmidt@redhat.com>
Whether a queue is leading can be deduced from its index.
Signed-off-by: Michal Schmidt <mschmidt@redhat.com>
---
drivers/net/ethernet/broadcom/bnx2x/bnx2x.h | 1 +
drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c | 2 +-
drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h | 4 +---
drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | 21 +++++++++------------
4 files changed, 12 insertions(+), 16 deletions(-)
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h
index 735e491..c0d2d9c 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h
@@ -531,6 +531,7 @@ struct bnx2x_fastpath {
#define IS_ETH_FP(fp) (fp->index < \
BNX2X_NUM_ETH_QUEUES(fp->bp))
+#define IS_LEADING_FP(fp) ((fp)->index == 0)
#ifdef BCM_CNIC
#define IS_FCOE_FP(fp) (fp->index == FCOE_IDX)
#define IS_FCOE_IDX(idx) ((idx) == FCOE_IDX)
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
index 5c3eb17..448e301 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
@@ -1881,7 +1881,7 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode)
#endif
for_each_nondefault_queue(bp, i) {
- rc = bnx2x_setup_queue(bp, &bp->fp[i], 0);
+ rc = bnx2x_setup_queue(bp, &bp->fp[i]);
if (rc)
LOAD_ERROR_EXIT(bp, load_error4);
}
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h
index 5b1f9b5..54d50b7 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h
@@ -109,11 +109,9 @@ void bnx2x__init_func_obj(struct bnx2x *bp);
*
* @bp: driver handle
* @fp: pointer to the fastpath structure
- * @leading: boolean
*
*/
-int bnx2x_setup_queue(struct bnx2x *bp, struct bnx2x_fastpath *fp,
- bool leading);
+int bnx2x_setup_queue(struct bnx2x *bp, struct bnx2x_fastpath *fp);
/**
* bnx2x_setup_leading - bring up a leading eth queue.
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
index e7b584b..64314f7 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
@@ -2697,9 +2697,8 @@ static inline unsigned long bnx2x_get_common_flags(struct bnx2x *bp,
return flags;
}
-static inline unsigned long bnx2x_get_q_flags(struct bnx2x *bp,
- struct bnx2x_fastpath *fp,
- bool leading)
+static unsigned long bnx2x_get_q_flags(struct bnx2x *bp,
+ struct bnx2x_fastpath *fp)
{
unsigned long flags = 0;
@@ -2715,7 +2714,7 @@ static inline unsigned long bnx2x_get_q_flags(struct bnx2x *bp,
__set_bit(BNX2X_Q_FLG_TPA_IPV6, &flags);
}
- if (leading) {
+ if (IS_LEADING_FP(fp)) {
__set_bit(BNX2X_Q_FLG_LEADING_RSS, &flags);
__set_bit(BNX2X_Q_FLG_MCAST, &flags);
}
@@ -6966,7 +6965,7 @@ int bnx2x_set_eth_mac(struct bnx2x *bp, bool set)
int bnx2x_setup_leading(struct bnx2x *bp)
{
- return bnx2x_setup_queue(bp, &bp->fp[0], 1);
+ return bnx2x_setup_queue(bp, &bp->fp[0]);
}
/**
@@ -7177,10 +7176,10 @@ static inline void bnx2x_pf_q_prep_init(struct bnx2x *bp,
&bp->context.vcxt[fp->txdata[cos].cid].eth;
}
-int bnx2x_setup_tx_only(struct bnx2x *bp, struct bnx2x_fastpath *fp,
+static int bnx2x_setup_tx_only(struct bnx2x *bp, struct bnx2x_fastpath *fp,
struct bnx2x_queue_state_params *q_params,
struct bnx2x_queue_setup_tx_only_params *tx_only_params,
- int tx_index, bool leading)
+ int tx_index)
{
memset(tx_only_params, 0, sizeof(*tx_only_params));
@@ -7216,14 +7215,12 @@ int bnx2x_setup_tx_only(struct bnx2x *bp, struct bnx2x_fastpath *fp,
*
* @bp: driver handle
* @fp: pointer to fastpath
- * @leading: is leading
*
* This function performs 2 steps in a Queue state machine
* actually: 1) RESET->INIT 2) INIT->SETUP
*/
-int bnx2x_setup_queue(struct bnx2x *bp, struct bnx2x_fastpath *fp,
- bool leading)
+int bnx2x_setup_queue(struct bnx2x *bp, struct bnx2x_fastpath *fp)
{
struct bnx2x_queue_state_params q_params = {0};
struct bnx2x_queue_setup_params *setup_params =
@@ -7264,7 +7261,7 @@ int bnx2x_setup_queue(struct bnx2x *bp, struct bnx2x_fastpath *fp,
memset(setup_params, 0, sizeof(*setup_params));
/* Set QUEUE flags */
- setup_params->flags = bnx2x_get_q_flags(bp, fp, leading);
+ setup_params->flags = bnx2x_get_q_flags(bp, fp);
/* Set general SETUP parameters */
bnx2x_pf_q_prep_general(bp, fp, &setup_params->gen_params,
@@ -7293,7 +7290,7 @@ int bnx2x_setup_queue(struct bnx2x *bp, struct bnx2x_fastpath *fp,
/* prepare and send tx-only ramrod*/
rc = bnx2x_setup_tx_only(bp, fp, &q_params,
- tx_only_params, tx_index, leading);
+ tx_only_params, tx_index);
if (rc) {
BNX2X_ERR("Queue(%d.%d) TX_ONLY_SETUP failed\n",
fp->index, tx_index);
--
1.7.6
^ permalink raw reply related
* [PATCH 3/7] bnx2x: decrease indentation in bnx2x_rx_int()
From: Michal Schmidt @ 2011-08-30 14:30 UTC (permalink / raw)
To: netdev; +Cc: vladz, dmitry, eilong, Michal Schmidt
In-Reply-To: <1314714646-3642-1-git-send-email-mschmidt@redhat.com>
For better readability decrease the indentation in bnx2x_rx_int().
'else' is unnecessary when the positive branch ends with a 'goto'.
Signed-off-by: Michal Schmidt <mschmidt@redhat.com>
---
drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c | 194 +++++++++++------------
1 files changed, 92 insertions(+), 102 deletions(-)
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
index 448e301..f1fea58 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
@@ -624,135 +624,125 @@ int bnx2x_rx_int(struct bnx2x_fastpath *fp, int budget)
if (unlikely(CQE_TYPE_SLOW(cqe_fp_type))) {
bnx2x_sp_event(fp, cqe);
goto next_cqe;
+ }
/* this is an rx packet */
- } else {
- rx_buf = &fp->rx_buf_ring[bd_cons];
- skb = rx_buf->skb;
- prefetch(skb);
+ rx_buf = &fp->rx_buf_ring[bd_cons];
+ skb = rx_buf->skb;
+ prefetch(skb);
- if (!CQE_TYPE_FAST(cqe_fp_type)) {
+ if (!CQE_TYPE_FAST(cqe_fp_type)) {
#ifdef BNX2X_STOP_ON_ERROR
- /* sanity check */
- if (fp->disable_tpa &&
- (CQE_TYPE_START(cqe_fp_type) ||
- CQE_TYPE_STOP(cqe_fp_type)))
- BNX2X_ERR("START/STOP packet while "
- "disable_tpa type %x\n",
- CQE_TYPE(cqe_fp_type));
+ /* sanity check */
+ if (fp->disable_tpa &&
+ (CQE_TYPE_START(cqe_fp_type) ||
+ CQE_TYPE_STOP(cqe_fp_type)))
+ BNX2X_ERR("START/STOP packet while "
+ "disable_tpa type %x\n",
+ CQE_TYPE(cqe_fp_type));
#endif
- if (CQE_TYPE_START(cqe_fp_type)) {
- u16 queue = cqe_fp->queue_index;
- DP(NETIF_MSG_RX_STATUS,
- "calling tpa_start on queue %d\n",
- queue);
+ if (CQE_TYPE_START(cqe_fp_type)) {
+ u16 queue = cqe_fp->queue_index;
+ DP(NETIF_MSG_RX_STATUS,
+ "calling tpa_start on queue %d\n", queue);
- bnx2x_tpa_start(fp, queue, skb,
- bd_cons, bd_prod,
- cqe_fp);
+ bnx2x_tpa_start(fp, queue, skb,
+ bd_cons, bd_prod, cqe_fp);
- /* Set Toeplitz hash for LRO skb */
- bnx2x_set_skb_rxhash(bp, cqe, skb);
+ /* Set Toeplitz hash for LRO skb */
+ bnx2x_set_skb_rxhash(bp, cqe, skb);
- goto next_rx;
+ goto next_rx;
- } else {
- u16 queue =
- cqe->end_agg_cqe.queue_index;
- DP(NETIF_MSG_RX_STATUS,
- "calling tpa_stop on queue %d\n",
- queue);
+ } else {
+ u16 queue =
+ cqe->end_agg_cqe.queue_index;
+ DP(NETIF_MSG_RX_STATUS,
+ "calling tpa_stop on queue %d\n", queue);
- bnx2x_tpa_stop(bp, fp, queue,
- &cqe->end_agg_cqe,
- comp_ring_cons);
+ bnx2x_tpa_stop(bp, fp, queue, &cqe->end_agg_cqe,
+ comp_ring_cons);
#ifdef BNX2X_STOP_ON_ERROR
- if (bp->panic)
- return 0;
+ if (bp->panic)
+ return 0;
#endif
- bnx2x_update_sge_prod(fp, cqe_fp);
- goto next_cqe;
- }
+ bnx2x_update_sge_prod(fp, cqe_fp);
+ goto next_cqe;
}
- /* non TPA */
- len = le16_to_cpu(cqe_fp->pkt_len);
- pad = cqe_fp->placement_offset;
- dma_sync_single_for_cpu(&bp->pdev->dev,
+ }
+ /* non TPA */
+ len = le16_to_cpu(cqe_fp->pkt_len);
+ pad = cqe_fp->placement_offset;
+ dma_sync_single_for_cpu(&bp->pdev->dev,
dma_unmap_addr(rx_buf, mapping),
- pad + RX_COPY_THRESH,
- DMA_FROM_DEVICE);
- prefetch(((char *)(skb)) + L1_CACHE_BYTES);
+ pad + RX_COPY_THRESH, DMA_FROM_DEVICE);
+ prefetch(((char *)(skb)) + L1_CACHE_BYTES);
- /* is this an error packet? */
- if (unlikely(cqe_fp_flags & ETH_RX_ERROR_FALGS)) {
+ /* is this an error packet? */
+ if (unlikely(cqe_fp_flags & ETH_RX_ERROR_FALGS)) {
+ DP(NETIF_MSG_RX_ERR, "ERROR flags %x rx packet %u\n",
+ cqe_fp_flags, sw_comp_cons);
+ fp->eth_q_stats.rx_err_discard_pkt++;
+ goto reuse_rx;
+ }
+
+ /*
+ * Since we don't have a jumbo ring,
+ * copy small packets if mtu > 1500
+ */
+ if ((bp->dev->mtu > ETH_MAX_PACKET_SIZE) &&
+ (len <= RX_COPY_THRESH)) {
+ struct sk_buff *new_skb;
+
+ new_skb = netdev_alloc_skb(bp->dev, len + pad);
+ if (new_skb == NULL) {
DP(NETIF_MSG_RX_ERR,
- "ERROR flags %x rx packet %u\n",
- cqe_fp_flags, sw_comp_cons);
- fp->eth_q_stats.rx_err_discard_pkt++;
+ "ERROR packet dropped "
+ "because of alloc failure\n");
+ fp->eth_q_stats.rx_skb_alloc_failed++;
goto reuse_rx;
}
- /* Since we don't have a jumbo ring
- * copy small packets if mtu > 1500
- */
- if ((bp->dev->mtu > ETH_MAX_PACKET_SIZE) &&
- (len <= RX_COPY_THRESH)) {
- struct sk_buff *new_skb;
-
- new_skb = netdev_alloc_skb(bp->dev, len + pad);
- if (new_skb == NULL) {
- DP(NETIF_MSG_RX_ERR,
- "ERROR packet dropped "
- "because of alloc failure\n");
- fp->eth_q_stats.rx_skb_alloc_failed++;
- goto reuse_rx;
- }
-
- /* aligned copy */
- skb_copy_from_linear_data_offset(skb, pad,
- new_skb->data + pad, len);
- skb_reserve(new_skb, pad);
- skb_put(new_skb, len);
+ /* aligned copy */
+ skb_copy_from_linear_data_offset(skb, pad,
+ new_skb->data + pad, len);
+ skb_reserve(new_skb, pad);
+ skb_put(new_skb, len);
- bnx2x_reuse_rx_skb(fp, bd_cons, bd_prod);
+ bnx2x_reuse_rx_skb(fp, bd_cons, bd_prod);
- skb = new_skb;
+ skb = new_skb;
- } else
- if (likely(bnx2x_alloc_rx_skb(bp, fp, bd_prod) == 0)) {
- dma_unmap_single(&bp->pdev->dev,
- dma_unmap_addr(rx_buf, mapping),
- fp->rx_buf_size,
- DMA_FROM_DEVICE);
- skb_reserve(skb, pad);
- skb_put(skb, len);
+ } else if (likely(bnx2x_alloc_rx_skb(bp, fp, bd_prod) == 0)) {
+ dma_unmap_single(&bp->pdev->dev,
+ dma_unmap_addr(rx_buf, mapping),
+ fp->rx_buf_size, DMA_FROM_DEVICE);
+ skb_reserve(skb, pad);
+ skb_put(skb, len);
- } else {
- DP(NETIF_MSG_RX_ERR,
- "ERROR packet dropped because "
- "of alloc failure\n");
- fp->eth_q_stats.rx_skb_alloc_failed++;
+ } else {
+ DP(NETIF_MSG_RX_ERR,
+ "ERROR packet dropped because of alloc failure\n");
+ fp->eth_q_stats.rx_skb_alloc_failed++;
reuse_rx:
- bnx2x_reuse_rx_skb(fp, bd_cons, bd_prod);
- goto next_rx;
- }
-
- skb->protocol = eth_type_trans(skb, bp->dev);
+ bnx2x_reuse_rx_skb(fp, bd_cons, bd_prod);
+ goto next_rx;
+ }
- /* Set Toeplitz hash for a none-LRO skb */
- bnx2x_set_skb_rxhash(bp, cqe, skb);
+ skb->protocol = eth_type_trans(skb, bp->dev);
- skb_checksum_none_assert(skb);
+ /* Set Toeplitz hash for a none-LRO skb */
+ bnx2x_set_skb_rxhash(bp, cqe, skb);
- if (bp->dev->features & NETIF_F_RXCSUM) {
+ skb_checksum_none_assert(skb);
- if (likely(BNX2X_RX_CSUM_OK(cqe)))
- skb->ip_summed = CHECKSUM_UNNECESSARY;
- else
- fp->eth_q_stats.hw_csum_err++;
- }
+ if (bp->dev->features & NETIF_F_RXCSUM) {
+ if (likely(BNX2X_RX_CSUM_OK(cqe)))
+ skb->ip_summed = CHECKSUM_UNNECESSARY;
+ else
+ fp->eth_q_stats.hw_csum_err++;
}
skb_record_rx_queue(skb, fp->index);
--
1.7.6
^ permalink raw reply related
* [PATCH 4/7] bnx2x: simplify TPA sanity check
From: Michal Schmidt @ 2011-08-30 14:30 UTC (permalink / raw)
To: netdev; +Cc: vladz, dmitry, eilong, Michal Schmidt
In-Reply-To: <1314714646-3642-1-git-send-email-mschmidt@redhat.com>
In the TPA branch we already know the CQE type is either START or STOP.
No need to test for that. Even if the type were to differ, we wouldn't
want to suppress the error message.
Signed-off-by: Michal Schmidt <mschmidt@redhat.com>
---
drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c | 4 +---
1 files changed, 1 insertions(+), 3 deletions(-)
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
index f1fea58..fe5be0c 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
@@ -634,9 +634,7 @@ int bnx2x_rx_int(struct bnx2x_fastpath *fp, int budget)
if (!CQE_TYPE_FAST(cqe_fp_type)) {
#ifdef BNX2X_STOP_ON_ERROR
/* sanity check */
- if (fp->disable_tpa &&
- (CQE_TYPE_START(cqe_fp_type) ||
- CQE_TYPE_STOP(cqe_fp_type)))
+ if (fp->disable_tpa)
BNX2X_ERR("START/STOP packet while "
"disable_tpa type %x\n",
CQE_TYPE(cqe_fp_type));
--
1.7.6
^ permalink raw reply related
* [PATCH 5/7] bnx2x: do not set TPA flags and features in bnx2x_init_bp
From: Michal Schmidt @ 2011-08-30 14:30 UTC (permalink / raw)
To: netdev; +Cc: vladz, dmitry, eilong, Michal Schmidt
In-Reply-To: <1314714646-3642-1-git-send-email-mschmidt@redhat.com>
The .ndo_{set,fix}_features callbacks are sufficient.
Signed-off-by: Michal Schmidt <mschmidt@redhat.com>
---
drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | 9 ---------
1 files changed, 0 insertions(+), 9 deletions(-)
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
index 64314f7..617a072 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
@@ -9752,15 +9752,6 @@ static int __devinit bnx2x_init_bp(struct bnx2x *bp)
"must load devices in order!\n");
bp->multi_mode = multi_mode;
-
- /* Set TPA flags */
- if (disable_tpa) {
- bp->flags &= ~TPA_ENABLE_FLAG;
- bp->dev->features &= ~NETIF_F_LRO;
- } else {
- bp->flags |= TPA_ENABLE_FLAG;
- bp->dev->features |= NETIF_F_LRO;
- }
bp->disable_tpa = disable_tpa;
if (CHIP_IS_E1(bp))
--
1.7.6
^ permalink raw reply related
* [PATCH 6/7] bnx2x: move fp->disable_tpa to ->flags
From: Michal Schmidt @ 2011-08-30 14:30 UTC (permalink / raw)
To: netdev; +Cc: vladz, dmitry, eilong, Michal Schmidt
In-Reply-To: <1314714646-3642-1-git-send-email-mschmidt@redhat.com>
Store the boolean fp->disable_tpa in a more general 'flags' field.
Later more flags will be added.
Signed-off-by: Michal Schmidt <mschmidt@redhat.com>
---
drivers/net/ethernet/broadcom/bnx2x/bnx2x.h | 3 +-
drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c | 31 ++++++++++------------
drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h | 2 +-
drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | 4 +-
4 files changed, 19 insertions(+), 21 deletions(-)
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h
index c0d2d9c..02fa7a7 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h
@@ -477,6 +477,8 @@ struct bnx2x_fastpath {
u8 cl_qzone_id;
u8 fw_sb_id; /* status block number in FW */
u8 igu_sb_id; /* status block number in HW */
+ u8 flags;
+#define FP_TPA (1 << 0) /* TPA enabled */
u16 rx_bd_prod;
u16 rx_bd_cons;
@@ -491,7 +493,6 @@ struct bnx2x_fastpath {
/* TPA related */
struct bnx2x_agg_info tpa_info[ETH_MAX_AGGREGATION_QUEUES_E1H_E2];
- u8 disable_tpa;
#ifdef BNX2X_STOP_ON_ERROR
u64 tpa_queue_used;
#endif
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
index fe5be0c..d45aaa5 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
@@ -60,15 +60,12 @@ static inline void bnx2x_bz_fp(struct bnx2x *bp, int index)
/*
* set the tpa flag for each queue. The tpa flag determines the queue
- * minimal size so it must be set prior to queue memory allocation
+ * minimal size so it must be set prior to queue memory allocation.
+ *
+ * We don't want TPA on an FCoE L2 ring.
*/
- fp->disable_tpa = ((bp->flags & TPA_ENABLE_FLAG) == 0);
-
-#ifdef BCM_CNIC
- /* We don't want TPA on an FCoE L2 ring */
- if (IS_FCOE_FP(fp))
- fp->disable_tpa = 1;
-#endif
+ if ((bp->flags & TPA_ENABLE_FLAG) && !IS_FCOE_FP(fp))
+ fp->flags = FP_TPA;
}
/**
@@ -634,9 +631,9 @@ int bnx2x_rx_int(struct bnx2x_fastpath *fp, int budget)
if (!CQE_TYPE_FAST(cqe_fp_type)) {
#ifdef BNX2X_STOP_ON_ERROR
/* sanity check */
- if (fp->disable_tpa)
+ if (!(fp->flags & FP_TPA))
BNX2X_ERR("START/STOP packet while "
- "disable_tpa type %x\n",
+ "TPA disabled, type %x\n",
CQE_TYPE(cqe_fp_type));
#endif
@@ -993,7 +990,7 @@ void bnx2x_init_rx_rings(struct bnx2x *bp)
DP(NETIF_MSG_IFUP,
"mtu %d rx_buf_size %d\n", bp->dev->mtu, fp->rx_buf_size);
- if (!fp->disable_tpa) {
+ if (fp->flags & FP_TPA) {
/* Fill the per-aggregtion pool */
for (i = 0; i < max_agg_queues; i++) {
struct bnx2x_agg_info *tpa_info =
@@ -1009,7 +1006,7 @@ void bnx2x_init_rx_rings(struct bnx2x *bp)
"disabling TPA on this "
"queue!\n", j);
bnx2x_free_tpa_pool(bp, fp, i);
- fp->disable_tpa = 1;
+ fp->flags &= ~FP_TPA;
break;
}
dma_unmap_addr_set(first_buf, mapping, 0);
@@ -1036,7 +1033,7 @@ void bnx2x_init_rx_rings(struct bnx2x *bp)
ring_prod);
bnx2x_free_tpa_pool(bp, fp,
max_agg_queues);
- fp->disable_tpa = 1;
+ fp->flags &= ~FP_TPA;
ring_prod = 0;
break;
}
@@ -1130,7 +1127,7 @@ static void bnx2x_free_rx_skbs(struct bnx2x *bp)
bnx2x_free_rx_bds(fp);
- if (!fp->disable_tpa)
+ if (fp->flags & FP_TPA)
bnx2x_free_tpa_pool(bp, fp, CHIP_IS_E1(bp) ?
ETH_MAX_AGGREGATION_QUEUES_E1 :
ETH_MAX_AGGREGATION_QUEUES_E1H_E2);
@@ -1724,7 +1721,7 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode)
/*
* Zero fastpath structures preserving invariants like napi, which are
* allocated only once, fp index, max_cos, bp pointer.
- * Also set fp->disable_tpa.
+ * Also set fp->flags.
*/
for_each_queue(bp, i)
bnx2x_bz_fp(bp, i);
@@ -3182,8 +3179,8 @@ alloc_mem_err:
* In these cases we disable the queue
* Min size is different for OOO, TPA and non-TPA queues
*/
- if (ring_size < (fp->disable_tpa ?
- MIN_RX_SIZE_NONTPA : MIN_RX_SIZE_TPA)) {
+ if (ring_size < ((fp->flags & FP_TPA) ? MIN_RX_SIZE_TPA :
+ MIN_RX_SIZE_NONTPA)) {
/* release memory allocated for this queue */
bnx2x_free_fp_mem_at(bp, index);
return -ENOMEM;
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h
index 54d50b7..14b3658 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h
@@ -1013,7 +1013,7 @@ static inline void bnx2x_free_rx_sge_range(struct bnx2x *bp,
{
int i;
- if (fp->disable_tpa)
+ if (!(fp->flags & FP_TPA))
return;
for (i = 0; i < last; i++)
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
index 617a072..7bc6944 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
@@ -2709,7 +2709,7 @@ static unsigned long bnx2x_get_q_flags(struct bnx2x *bp,
if (IS_FCOE_FP(fp))
__set_bit(BNX2X_Q_FLG_FCOE, &flags);
- if (!fp->disable_tpa) {
+ if (fp->flags & FP_TPA) {
__set_bit(BNX2X_Q_FLG_TPA, &flags);
__set_bit(BNX2X_Q_FLG_TPA_IPV6, &flags);
}
@@ -2750,7 +2750,7 @@ static void bnx2x_pf_rx_q_prep(struct bnx2x *bp,
u16 sge_sz = 0;
u16 tpa_agg_size = 0;
- if (!fp->disable_tpa) {
+ if (fp->flags & FP_TPA) {
pause->sge_th_hi = 250;
pause->sge_th_lo = 150;
tpa_agg_size = min_t(u32,
--
1.7.6
^ permalink raw reply related
* [PATCH 7/7] bnx2x: expose HW RX VLAN stripping toggle
From: Michal Schmidt @ 2011-08-30 14:30 UTC (permalink / raw)
To: netdev; +Cc: vladz, dmitry, eilong, Michal Schmidt
In-Reply-To: <1314714646-3642-1-git-send-email-mschmidt@redhat.com>
Allow disabling of HW RX VLAN stripping with ethtool.
[v2: Store the flag in the fp to ensure that pending packets are
handled correctly during a switch.]
Signed-off-by: Michal Schmidt <mschmidt@redhat.com>
---
drivers/net/ethernet/broadcom/bnx2x/bnx2x.h | 2 +
drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c | 29 ++++++++++++++++------
drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | 10 ++++----
3 files changed, 28 insertions(+), 13 deletions(-)
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h
index 02fa7a7..e70a208 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h
@@ -479,6 +479,7 @@ struct bnx2x_fastpath {
u8 igu_sb_id; /* status block number in HW */
u8 flags;
#define FP_TPA (1 << 0) /* TPA enabled */
+#define FP_VLAN_STRIP (1 << 1) /* RX VLAN headers stripping */
u16 rx_bd_prod;
u16 rx_bd_cons;
@@ -1180,6 +1181,7 @@ struct bnx2x {
#define NO_MCP_FLAG (1 << 9)
#define BP_NOMCP(bp) (bp->flags & NO_MCP_FLAG)
+#define RX_VLAN_STRIP_FLAG (1 << 10)
#define MF_FUNC_DIS (1 << 11)
#define OWN_CNIC_IRQ (1 << 12)
#define NO_ISCSI_OOO_FLAG (1 << 13)
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
index d45aaa5..e39ea23 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
@@ -66,6 +66,9 @@ static inline void bnx2x_bz_fp(struct bnx2x *bp, int index)
*/
if ((bp->flags & TPA_ENABLE_FLAG) && !IS_FCOE_FP(fp))
fp->flags = FP_TPA;
+
+ if (bp->flags & RX_VLAN_STRIP_FLAG)
+ fp->flags |= FP_VLAN_STRIP;
}
/**
@@ -359,7 +362,7 @@ static void bnx2x_tpa_start(struct bnx2x_fastpath *fp, u16 queue,
/**
* bnx2x_set_lro_mss - calculate the approximate value of the MSS
*
- * @bp: driver handle
+ * @fp: fastpath handle
* @parsing_flags: parsing flags from the START CQE
* @len_on_bd: total length of the first packet for the
* aggregation.
@@ -367,8 +370,8 @@ static void bnx2x_tpa_start(struct bnx2x_fastpath *fp, u16 queue,
* Approximate value of the MSS for this aggregation calculated using
* the first packet of it.
*/
-static inline u16 bnx2x_set_lro_mss(struct bnx2x *bp, u16 parsing_flags,
- u16 len_on_bd)
+static u16 bnx2x_set_lro_mss(struct bnx2x_fastpath *fp, u16 parsing_flags,
+ u16 len_on_bd)
{
/*
* TPA arrgregation won't have either IP options or TCP options
@@ -382,6 +385,10 @@ static inline u16 bnx2x_set_lro_mss(struct bnx2x *bp, u16 parsing_flags,
else /* IPv4 */
hdrs_len += sizeof(struct iphdr);
+ /* VLAN header present and not stripped by HW */
+ if ((parsing_flags & PARSING_FLAGS_VLAN) &&
+ !(fp->flags & FP_VLAN_STRIP))
+ hdrs_len += VLAN_HLEN;
/* Check if there was a TCP timestamp, if there is it's will
* always be 12 bytes length: nop nop kind length echo val.
@@ -409,9 +416,9 @@ static int bnx2x_fill_frag_skb(struct bnx2x *bp, struct bnx2x_fastpath *fp,
frag_size = le16_to_cpu(cqe->pkt_len) - len_on_bd;
pages = SGE_PAGE_ALIGN(frag_size) >> SGE_PAGE_SHIFT;
- /* This is needed in order to enable forwarding support */
+ /* Doing LRO, let TCP know the receive MSS */
if (frag_size)
- skb_shinfo(skb)->gso_size = bnx2x_set_lro_mss(bp,
+ skb_shinfo(skb)->gso_size = bnx2x_set_lro_mss(fp,
tpa_info->parsing_flags, len_on_bd);
#ifdef BNX2X_STOP_ON_ERROR
@@ -511,7 +518,8 @@ static void bnx2x_tpa_stop(struct bnx2x *bp, struct bnx2x_fastpath *fp,
skb->ip_summed = CHECKSUM_UNNECESSARY;
if (!bnx2x_fill_frag_skb(bp, fp, queue, skb, cqe, cqe_idx)) {
- if (tpa_info->parsing_flags & PARSING_FLAGS_VLAN)
+ if ((tpa_info->parsing_flags & PARSING_FLAGS_VLAN) &&
+ (fp->flags & FP_VLAN_STRIP))
__vlan_hwaccel_put_tag(skb, tpa_info->vlan_tag);
napi_gro_receive(&fp->napi, skb);
} else {
@@ -742,8 +750,8 @@ reuse_rx:
skb_record_rx_queue(skb, fp->index);
- if (le16_to_cpu(cqe_fp->pars_flags.flags) &
- PARSING_FLAGS_VLAN)
+ if ((le16_to_cpu(cqe_fp->pars_flags.flags) &
+ PARSING_FLAGS_VLAN) && (fp->flags & FP_VLAN_STRIP))
__vlan_hwaccel_put_tag(skb,
le16_to_cpu(cqe_fp->vlan_tag));
napi_gro_receive(&fp->napi, skb);
@@ -3415,6 +3423,11 @@ int bnx2x_set_features(struct net_device *dev, u32 features)
else
flags &= ~TPA_ENABLE_FLAG;
+ if (features & NETIF_F_HW_VLAN_RX)
+ flags |= RX_VLAN_STRIP_FLAG;
+ else
+ flags &= ~RX_VLAN_STRIP_FLAG;
+
if (features & NETIF_F_LOOPBACK) {
if (bp->link_params.loopback_mode != LOOPBACK_BMAC) {
bp->link_params.loopback_mode = LOOPBACK_BMAC;
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
index 7bc6944..15624bc 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
@@ -2719,9 +2719,8 @@ static unsigned long bnx2x_get_q_flags(struct bnx2x *bp,
__set_bit(BNX2X_Q_FLG_MCAST, &flags);
}
- /* Always set HW VLAN stripping */
- __set_bit(BNX2X_Q_FLG_VLAN, &flags);
-
+ if (fp->flags & FP_VLAN_STRIP)
+ __set_bit(BNX2X_Q_FLG_VLAN, &flags);
return flags | bnx2x_get_common_flags(bp, fp, true);
}
@@ -10262,12 +10261,13 @@ static int __devinit bnx2x_init_dev(struct pci_dev *pdev,
dev->hw_features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
NETIF_F_TSO | NETIF_F_TSO_ECN | NETIF_F_TSO6 | NETIF_F_LRO |
- NETIF_F_RXCSUM | NETIF_F_RXHASH | NETIF_F_HW_VLAN_TX;
+ NETIF_F_RXCSUM | NETIF_F_RXHASH |
+ NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
dev->vlan_features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
NETIF_F_TSO | NETIF_F_TSO_ECN | NETIF_F_TSO6 | NETIF_F_HIGHDMA;
- dev->features |= dev->hw_features | NETIF_F_HW_VLAN_RX;
+ dev->features |= dev->hw_features;
if (bp->flags & USING_DAC_FLAG)
dev->features |= NETIF_F_HIGHDMA;
--
1.7.6
^ permalink raw reply related
* Re: [patch 1/3 -next] 6LoWPAN: use kfree_skb() instead of kfree()
From: Eric Dumazet @ 2011-08-30 14:40 UTC (permalink / raw)
To: Dan Carpenter
Cc: Alexander Smirnov, Dmitry Eremin-Solenikov, Sergey Lapin,
David S. Miller, open list:IEEE 802.15.4 SUB...,
open list:NETWORKING [GENERAL], kernel-janitors
In-Reply-To: <20110830134552.GH3705@shale.localdomain>
Le mardi 30 août 2011 à 16:45 +0300, Dan Carpenter a écrit :
> Use kfree_skb() to free sbk_buffs.
>
> Signed-off-by: Dan Carpenter <error27@gmail.com>
>
> diff --git a/net/ieee802154/6lowpan.c b/net/ieee802154/6lowpan.c
> index cf304cc..8a9dbaa 100644
> --- a/net/ieee802154/6lowpan.c
> +++ b/net/ieee802154/6lowpan.c
> @@ -674,7 +674,7 @@ lowpan_process_data(struct sk_buff *skb)
> sizeof(hdr));
> return lowpan_skb_deliver(skb, &hdr);
> drop:
> - kfree(skb);
> + kfree_skb(skb);
> return -EINVAL;
> }
>
Another bug is the skb_copy() done in lowpan_skb_deliver()
1) No check of skb_copy() return
2.1) Use of GFP_KERNEL : Is it safe at this point ? Aren’t we in
softirq ?
2.2) If GFP_KERNEL is safe, why do we later do :
if (in_interrupt())
stat = netif_rx(skb);
else
stat = netif_rx_ni(skb);
^ permalink raw reply
* [PATCH 1/8] netfilter: xt_rateest: fix xt_rateest_mt_checkentry()
From: kaber @ 2011-08-30 14:41 UTC (permalink / raw)
To: davem; +Cc: netfilter-devel, netdev
In-Reply-To: <1314715281-26233-1-git-send-email-kaber@trash.net>
From: Eric Dumazet <eric.dumazet@gmail.com>
commit 4a5a5c73b7cfee (slightly better error reporting) added some
useless code in xt_rateest_mt_checkentry().
Fix this so that different error codes can really be returned.
Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
CC: Jan Engelhardt <jengelh@medozas.de>
Signed-off-by: Patrick McHardy <kaber@trash.net>
---
net/netfilter/xt_rateest.c | 9 ++++-----
1 files changed, 4 insertions(+), 5 deletions(-)
diff --git a/net/netfilter/xt_rateest.c b/net/netfilter/xt_rateest.c
index 76a0831..ed0db15 100644
--- a/net/netfilter/xt_rateest.c
+++ b/net/netfilter/xt_rateest.c
@@ -78,7 +78,7 @@ static int xt_rateest_mt_checkentry(const struct xt_mtchk_param *par)
{
struct xt_rateest_match_info *info = par->matchinfo;
struct xt_rateest *est1, *est2;
- int ret = false;
+ int ret = -EINVAL;
if (hweight32(info->flags & (XT_RATEEST_MATCH_ABS |
XT_RATEEST_MATCH_REL)) != 1)
@@ -101,13 +101,12 @@ static int xt_rateest_mt_checkentry(const struct xt_mtchk_param *par)
if (!est1)
goto err1;
+ est2 = NULL;
if (info->flags & XT_RATEEST_MATCH_REL) {
est2 = xt_rateest_lookup(info->name2);
if (!est2)
goto err2;
- } else
- est2 = NULL;
-
+ }
info->est1 = est1;
info->est2 = est2;
@@ -116,7 +115,7 @@ static int xt_rateest_mt_checkentry(const struct xt_mtchk_param *par)
err2:
xt_rateest_put(est1);
err1:
- return -EINVAL;
+ return ret;
}
static void xt_rateest_mt_destroy(const struct xt_mtdtor_param *par)
--
1.7.2.3
^ permalink raw reply related
* [PATCH 4/8] netfilter: nf_queue: reject NF_STOLEN verdicts from userspace
From: kaber @ 2011-08-30 14:41 UTC (permalink / raw)
To: davem; +Cc: netfilter-devel, netdev
In-Reply-To: <1314715281-26233-1-git-send-email-kaber@trash.net>
From: Florian Westphal <fw@strlen.de>
A userspace listener may send (bogus) NF_STOLEN verdict, which causes skb leak.
This problem was previously fixed via
64507fdbc29c3a622180378210ecea8659b14e40 (netfilter:
nf_queue: fix NF_STOLEN skb leak) but this had to be reverted because
NF_STOLEN can also be returned by a netfilter hook when iterating the
rules in nf_reinject.
Reject userspace NF_STOLEN verdict, as suggested by Michal Miroslaw.
This is complementary to commit fad54440438a7c231a6ae347738423cbabc936d9
(netfilter: avoid double free in nf_reinject).
Cc: Julian Anastasov <ja@ssi.bg>
Cc: Eric Dumazet <eric.dumazet@gmail.com>
Signed-off-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Patrick McHardy <kaber@trash.net>
---
net/ipv4/netfilter/ip_queue.c | 11 ++++-------
net/ipv6/netfilter/ip6_queue.c | 11 ++++-------
net/netfilter/nfnetlink_queue.c | 4 ++--
3 files changed, 10 insertions(+), 16 deletions(-)
diff --git a/net/ipv4/netfilter/ip_queue.c b/net/ipv4/netfilter/ip_queue.c
index 48f7d5b..e59aabd 100644
--- a/net/ipv4/netfilter/ip_queue.c
+++ b/net/ipv4/netfilter/ip_queue.c
@@ -314,7 +314,7 @@ ipq_set_verdict(struct ipq_verdict_msg *vmsg, unsigned int len)
{
struct nf_queue_entry *entry;
- if (vmsg->value > NF_MAX_VERDICT)
+ if (vmsg->value > NF_MAX_VERDICT || vmsg->value == NF_STOLEN)
return -EINVAL;
entry = ipq_find_dequeue_entry(vmsg->id);
@@ -359,12 +359,9 @@ ipq_receive_peer(struct ipq_peer_msg *pmsg,
break;
case IPQM_VERDICT:
- if (pmsg->msg.verdict.value > NF_MAX_VERDICT)
- status = -EINVAL;
- else
- status = ipq_set_verdict(&pmsg->msg.verdict,
- len - sizeof(*pmsg));
- break;
+ status = ipq_set_verdict(&pmsg->msg.verdict,
+ len - sizeof(*pmsg));
+ break;
default:
status = -EINVAL;
}
diff --git a/net/ipv6/netfilter/ip6_queue.c b/net/ipv6/netfilter/ip6_queue.c
index 87b243a..e63c397 100644
--- a/net/ipv6/netfilter/ip6_queue.c
+++ b/net/ipv6/netfilter/ip6_queue.c
@@ -314,7 +314,7 @@ ipq_set_verdict(struct ipq_verdict_msg *vmsg, unsigned int len)
{
struct nf_queue_entry *entry;
- if (vmsg->value > NF_MAX_VERDICT)
+ if (vmsg->value > NF_MAX_VERDICT || vmsg->value == NF_STOLEN)
return -EINVAL;
entry = ipq_find_dequeue_entry(vmsg->id);
@@ -359,12 +359,9 @@ ipq_receive_peer(struct ipq_peer_msg *pmsg,
break;
case IPQM_VERDICT:
- if (pmsg->msg.verdict.value > NF_MAX_VERDICT)
- status = -EINVAL;
- else
- status = ipq_set_verdict(&pmsg->msg.verdict,
- len - sizeof(*pmsg));
- break;
+ status = ipq_set_verdict(&pmsg->msg.verdict,
+ len - sizeof(*pmsg));
+ break;
default:
status = -EINVAL;
}
diff --git a/net/netfilter/nfnetlink_queue.c b/net/netfilter/nfnetlink_queue.c
index 00bd475..a80b0cb 100644
--- a/net/netfilter/nfnetlink_queue.c
+++ b/net/netfilter/nfnetlink_queue.c
@@ -646,8 +646,8 @@ verdicthdr_get(const struct nlattr * const nfqa[])
return NULL;
vhdr = nla_data(nfqa[NFQA_VERDICT_HDR]);
- verdict = ntohl(vhdr->verdict);
- if ((verdict & NF_VERDICT_MASK) > NF_MAX_VERDICT)
+ verdict = ntohl(vhdr->verdict) & NF_VERDICT_MASK;
+ if (verdict > NF_MAX_VERDICT || verdict == NF_STOLEN)
return NULL;
return vhdr;
}
--
1.7.2.3
^ permalink raw reply related
* [PATCH 5/8] netfilter: nf_ct_pptp: fix DNATed PPTP connection address translation
From: kaber @ 2011-08-30 14:41 UTC (permalink / raw)
To: davem; +Cc: netfilter-devel, netdev
In-Reply-To: <1314715281-26233-1-git-send-email-kaber@trash.net>
From: Sanket Shah <sanket.shah@elitecore.com>
When both the server and the client are NATed, the set-link-info control
packet containing the peer's call-id field is not properly translated.
I have verified that it was working in 2.6.16.13 kernel previously but
due to rewrite, this scenario stopped working (Not knowing exact version
when it stopped working).
Signed-off-by: Sanket Shah <sanket.shah@elitecore.com>
Signed-off-by: Patrick McHardy <kaber@trash.net>
---
net/netfilter/nf_conntrack_pptp.c | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/net/netfilter/nf_conntrack_pptp.c b/net/netfilter/nf_conntrack_pptp.c
index 2fd4565..31d56b2 100644
--- a/net/netfilter/nf_conntrack_pptp.c
+++ b/net/netfilter/nf_conntrack_pptp.c
@@ -364,6 +364,7 @@ pptp_inbound_pkt(struct sk_buff *skb,
break;
case PPTP_WAN_ERROR_NOTIFY:
+ case PPTP_SET_LINK_INFO:
case PPTP_ECHO_REQUEST:
case PPTP_ECHO_REPLY:
/* I don't have to explain these ;) */
--
1.7.2.3
^ permalink raw reply related
* [PATCH 7/8] netfilter: nf_ct_tcp: wrong multiplication of TCPOLEN_TSTAMP_ALIGNED in tcp_sack skips fastpath
From: kaber @ 2011-08-30 14:41 UTC (permalink / raw)
To: davem; +Cc: netfilter-devel, netdev
In-Reply-To: <1314715281-26233-1-git-send-email-kaber@trash.net>
From: Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
The wrong multiplication of TCPOLEN_TSTAMP_ALIGNED by 4 skips the fast path
for the timestamp-only option. Bug reported by Michael M. Builov (netfilter
bugzilla #738).
Signed-off-by: Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
Signed-off-by: Patrick McHardy <kaber@trash.net>
---
net/netfilter/nf_conntrack_proto_tcp.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/net/netfilter/nf_conntrack_proto_tcp.c b/net/netfilter/nf_conntrack_proto_tcp.c
index afc4ab7..8235b86 100644
--- a/net/netfilter/nf_conntrack_proto_tcp.c
+++ b/net/netfilter/nf_conntrack_proto_tcp.c
@@ -447,7 +447,7 @@ static void tcp_sack(const struct sk_buff *skb, unsigned int dataoff,
BUG_ON(ptr == NULL);
/* Fast path for timestamp-only option */
- if (length == TCPOLEN_TSTAMP_ALIGNED*4
+ if (length == TCPOLEN_TSTAMP_ALIGNED
&& *(__be32 *)ptr == htonl((TCPOPT_NOP << 24)
| (TCPOPT_NOP << 16)
| (TCPOPT_TIMESTAMP << 8)
--
1.7.2.3
^ permalink raw reply related
* [PATCH 8/8] netfilter: update netfilter git URL
From: kaber @ 2011-08-30 14:41 UTC (permalink / raw)
To: davem; +Cc: netfilter-devel, netdev
In-Reply-To: <1314715281-26233-1-git-send-email-kaber@trash.net>
From: Patrick McHardy <kaber@trash.net>
Netfilter git trees are moving to a directory shared by Pablo and
myself, update git URLs.
Signed-off-by: Patrick McHardy <kaber@trash.net>
---
MAINTAINERS | 3 ++-
1 files changed, 2 insertions(+), 1 deletions(-)
diff --git a/MAINTAINERS b/MAINTAINERS
index 1d2e79d..a6669b2 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -4386,7 +4386,8 @@ L: netfilter@vger.kernel.org
L: coreteam@netfilter.org
W: http://www.netfilter.org/
W: http://www.iptables.org/
-T: git git://git.kernel.org/pub/scm/linux/kernel/git/kaber/nf-2.6.git
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/netfilter/nf-2.6.git
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/netfilter/nf-next-2.6.git
S: Supported
F: include/linux/netfilter*
F: include/linux/netfilter/
--
1.7.2.3
^ permalink raw reply related
* [PATCH 0/8] netfilter: netfilter fixes
From: kaber @ 2011-08-30 14:41 UTC (permalink / raw)
To: davem; +Cc: netfilter-devel, netdev
Hi Dave,
following are a couple of netfilter fixes:
- invalid return values in xt_rateest_mt_checkentry(), from Eric
- a possible memory leak in ip_queue and ip6_queue, from Jesper Juhl
- an incorrect Kconfig dependency for ebtables, from Bart
- handling of (bogus) NF_STOLEN verdicts in userspace queueing, from Florian
- a fix for missing address translation in certain cases for NATed PPTP
connections, from Sanket Shah
- possible out-of-bounds memory access in TCP connection tracking in case
of partial TCP options, from Jozsef
- an incorrect multiplication of TCPOLEN_TSTAMP_ALIGNED in the fast-path
check of TCP connection tracking, from Jozsef
- update of the netfilter git tree URLs to a directory shared by Pablo and
myself (trees will move after patch is applied)
Please apply or pull from:
git://git.kernel.org/pub/scm/linux/kernel/git/kaber/nf-2.6.git master
Thanks!
^ permalink raw reply
* [PATCH 3/8] netfilter: ebtables: fix ebtables build dependency
From: kaber @ 2011-08-30 14:41 UTC (permalink / raw)
To: davem; +Cc: netfilter-devel, netdev
In-Reply-To: <1314715281-26233-1-git-send-email-kaber@trash.net>
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset=UTF-8, Size: 885 bytes --]
From: Bart De Schuymer <bdschuym@pandora.be>
The configuration of ebtables shouldn't depend on
CONFIG_BRIDGE_NETFILTER, only on CONFIG_NETFILTER.
Reported-by: Sébastien Laveze <slaveze@gmail.com>
Signed-off-by: Bart De Schuymer <bdschuym@pandora.be>
Signed-off-by: Patrick McHardy <kaber@trash.net>
---
net/bridge/netfilter/Kconfig | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/net/bridge/netfilter/Kconfig b/net/bridge/netfilter/Kconfig
index ba6f73e..a9aff9c 100644
--- a/net/bridge/netfilter/Kconfig
+++ b/net/bridge/netfilter/Kconfig
@@ -4,7 +4,7 @@
menuconfig BRIDGE_NF_EBTABLES
tristate "Ethernet Bridge tables (ebtables) support"
- depends on BRIDGE && BRIDGE_NETFILTER
+ depends on BRIDGE && NETFILTER
select NETFILTER_XTABLES
help
ebtables is a general, extensible frame/packet identification
--
1.7.2.3
^ permalink raw reply related
* [PATCH 2/8] netfilter: ip_queue: Fix small leak in ipq_build_packet_message()
From: kaber @ 2011-08-30 14:41 UTC (permalink / raw)
To: davem; +Cc: netfilter-devel, netdev
In-Reply-To: <1314715281-26233-1-git-send-email-kaber@trash.net>
From: Jesper Juhl <jj@chaosbits.net>
ipq_build_packet_message() in net/ipv4/netfilter/ip_queue.c and
net/ipv6/netfilter/ip6_queue.c contain a small potential mem leak as
far as I can tell.
We allocate memory for 'skb' with alloc_skb() annd then call
nlh = NLMSG_PUT(skb, 0, 0, IPQM_PACKET, size - sizeof(*nlh));
NLMSG_PUT is a macro
NLMSG_PUT(skb, pid, seq, type, len) \
NLMSG_NEW(skb, pid, seq, type, len, 0)
that expands to NLMSG_NEW, which is also a macro which expands to:
NLMSG_NEW(skb, pid, seq, type, len, flags) \
({ if (unlikely(skb_tailroom(skb) < (int)NLMSG_SPACE(len))) \
goto nlmsg_failure; \
__nlmsg_put(skb, pid, seq, type, len, flags); })
If we take the true branch of the 'if' statement and 'goto
nlmsg_failure', then we'll, at that point, return from
ipq_build_packet_message() without having assigned 'skb' to anything
and we'll leak the memory we allocated for it when it goes out of
scope.
Fix this by placing a 'kfree(skb)' at 'nlmsg_failure'.
I admit that I do not know how likely this to actually happen or even
if there's something that guarantees that it will never happen - I'm
not that familiar with this code, but if that is so, I've not been
able to spot it.
Signed-off-by: Jesper Juhl <jj@chaosbits.net>
Signed-off-by: Patrick McHardy <kaber@trash.net>
---
net/ipv4/netfilter/ip_queue.c | 1 +
net/ipv6/netfilter/ip6_queue.c | 1 +
2 files changed, 2 insertions(+), 0 deletions(-)
diff --git a/net/ipv4/netfilter/ip_queue.c b/net/ipv4/netfilter/ip_queue.c
index 5c9b9d9..48f7d5b 100644
--- a/net/ipv4/netfilter/ip_queue.c
+++ b/net/ipv4/netfilter/ip_queue.c
@@ -218,6 +218,7 @@ ipq_build_packet_message(struct nf_queue_entry *entry, int *errp)
return skb;
nlmsg_failure:
+ kfree_skb(skb);
*errp = -EINVAL;
printk(KERN_ERR "ip_queue: error creating packet message\n");
return NULL;
diff --git a/net/ipv6/netfilter/ip6_queue.c b/net/ipv6/netfilter/ip6_queue.c
index 2493948..87b243a 100644
--- a/net/ipv6/netfilter/ip6_queue.c
+++ b/net/ipv6/netfilter/ip6_queue.c
@@ -218,6 +218,7 @@ ipq_build_packet_message(struct nf_queue_entry *entry, int *errp)
return skb;
nlmsg_failure:
+ kfree_skb(skb);
*errp = -EINVAL;
printk(KERN_ERR "ip6_queue: error creating packet message\n");
return NULL;
--
1.7.2.3
^ permalink raw reply related
* [PATCH 6/8] netfilter: nf_ct_tcp: fix incorrect handling of invalid TCP option
From: kaber @ 2011-08-30 14:41 UTC (permalink / raw)
To: davem; +Cc: netfilter-devel, netdev
In-Reply-To: <1314715281-26233-1-git-send-email-kaber@trash.net>
From: Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
Michael M. Builov reported that in the tcp_options and tcp_sack functions
of netfilter TCP conntrack the incorrect handling of invalid TCP option
with too big opsize may lead to read access beyond tcp-packet or buffer
allocated on stack (netfilter bugzilla #738). The fix is to stop parsing
the options at detecting the broken option.
Signed-off-by: Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
Signed-off-by: Patrick McHardy <kaber@trash.net>
---
net/netfilter/nf_conntrack_proto_tcp.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/net/netfilter/nf_conntrack_proto_tcp.c b/net/netfilter/nf_conntrack_proto_tcp.c
index 37bf943..afc4ab7 100644
--- a/net/netfilter/nf_conntrack_proto_tcp.c
+++ b/net/netfilter/nf_conntrack_proto_tcp.c
@@ -409,7 +409,7 @@ static void tcp_options(const struct sk_buff *skb,
if (opsize < 2) /* "silly options" */
return;
if (opsize > length)
- break; /* don't parse partial options */
+ return; /* don't parse partial options */
if (opcode == TCPOPT_SACK_PERM
&& opsize == TCPOLEN_SACK_PERM)
@@ -469,7 +469,7 @@ static void tcp_sack(const struct sk_buff *skb, unsigned int dataoff,
if (opsize < 2) /* "silly options" */
return;
if (opsize > length)
- break; /* don't parse partial options */
+ return; /* don't parse partial options */
if (opcode == TCPOPT_SACK
&& opsize >= (TCPOLEN_SACK_BASE
--
1.7.2.3
^ permalink raw reply related
* Re: 802.1Q VLAN random tag injected when vlan configured on forcedeth interface
From: Eric Dumazet @ 2011-08-30 14:42 UTC (permalink / raw)
To: Ruslan N. Marchenko; +Cc: netdev
In-Reply-To: <20110830142310.GC28341@ruff.mobi>
Le mardi 30 août 2011 à 16:23 +0200, Ruslan N. Marchenko a écrit :
> On Tue, Aug 30, 2011 at 03:46:24PM +0200, Ruslan N. Marchenko wrote:
> > On Tue, Aug 30, 2011 at 03:23:48PM +0200, Eric Dumazet wrote:
> > >
> > > What kernel version are you using ?
> > >
> > Oh, sorry for missing it, it runs on
> > Linux ruff.mobi 2.6.38-11-generic #48-Ubuntu SMP Fri Jul 29 19:05:14 UTC 2011 i686 i686 i386 GNU/Linux
> >
> > Just fyi - the openwrt box to which it is connected is
> > Linux OpenWrt 2.6.39.2 #2 Fri Aug 12 09:36:23 EEST 2011 mips GNU/Linux
> > although packet drop happens even if there're no vlans configured on remote side.
> >
> Here is double-tag sample:
> 16:20:31.151268 e0:46:9a:4e:88:1d > 00:26:18:40:21:62, ethertype 802.1Q (0x8100), length 106: vlan 2112, p 7, ethertype 802.1Q, vlan 6, p 0, ethertype IPv4, [|ip]
> 0x0000: 0026 1840 2162 e046 9a4e 881d 8100 e840
> 0x0010: 8100 0006 0800 4500 0054 abec 0000
>
>
Latest kernel should be fine. Some patches need to be backported by
Ubuntu team, if you can test them.
commit 9331db4f00cfee8a79d2147ac83723ef436b9759
Author: Jiri Pirko <jpirko@redhat.com>
Date: Wed Aug 17 23:50:37 2011 -0700
forcedeth: call vlan_mode only if hw supports vlans
If hw does not support vlans, dont call nv_vlan_mode because it has no point.
I believe that this should fix issues on older non-vlan supportive
chips (like Ingo has).
Reported-ty: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Jiri Pirko <jpirko@redhat.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
commit 0891b0e08937aaec2c4734acb94c5ff8042313bb
Author: Jiri Pirko <jpirko@redhat.com>
Date: Tue Jul 26 10:19:28 2011 +0000
forcedeth: fix vlans
For some reason, when rxaccel is disabled, NV_RX3_VLAN_TAG_PRESENT is
still set and some pseudorandom vids appear. So check for
NETIF_F_HW_VLAN_RX as well. Also set correctly hw_features and set vlan
mode on probe.
Signed-off-by: Jiri Pirko <jpirko@redhat.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
commit 3326c784c9f492e988617d93f647ae0cfd4c8d09
Author: Jiri Pirko <jpirko@redhat.com>
Date: Wed Jul 20 04:54:38 2011 +0000
forcedeth: do vlan cleanup
- unify vlan and nonvlan rx path
- kill np->vlangrp and nv_vlan_rx_register
- allow to turn on/off rx vlan accel via ethtool (set_features)
Signed-off-by: Jiri Pirko <jpirko@redhat.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
^ permalink raw reply
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