* [PATCH] bridge: netfilter: use PTR_RET instead of IS_ERR + PTR_ERR
From: Silviu-Mihai Popescu @ 2013-03-12 18:11 UTC (permalink / raw)
To: netfilter-devel
Cc: bart.de.schuymer, pablo, kaber, stephen, davem, netfilter,
coreteam, bridge, netdev, linux-kernel, Silviu-Mihai Popescu
This uses PTR_RET instead of IS_ERR and PTR_ERR in order to increase
readability.
Signed-off-by: Silviu-Mihai Popescu <silviupopescu1990@gmail.com>
---
net/bridge/netfilter/ebtable_broute.c | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/net/bridge/netfilter/ebtable_broute.c b/net/bridge/netfilter/ebtable_broute.c
index 40d8258..70f656c 100644
--- a/net/bridge/netfilter/ebtable_broute.c
+++ b/net/bridge/netfilter/ebtable_broute.c
@@ -64,9 +64,7 @@ static int ebt_broute(struct sk_buff *skb)
static int __net_init broute_net_init(struct net *net)
{
net->xt.broute_table = ebt_register_table(net, &broute_table);
- if (IS_ERR(net->xt.broute_table))
- return PTR_ERR(net->xt.broute_table);
- return 0;
+ return PTR_RET(net->xt.broute_table);
}
static void __net_exit broute_net_exit(struct net *net)
--
1.7.9.5
^ permalink raw reply related
* [PATCH] bluetooth: use PTR_RET instead of IS_ERR + PTR_ERR
From: Silviu-Mihai Popescu @ 2013-03-12 18:13 UTC (permalink / raw)
To: linux-bluetooth-u79uwXL29TY76Z2rM5mHXA
Cc: marcel-kz+m5ild9QBg9hUCZPvPmw, gustavo-THi1TnShQwVAfugRpC6u6w,
johan.hedberg-Re5JQEeQqe8AvxtiuMwx3w,
davem-fT/PcQaiUtIeIZ0/mPfg9Q, netdev-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA, Silviu-Mihai Popescu
This uses PTR_RET instead of IS_ERR and PTR_ERR in order to increase
readability.
Signed-off-by: Silviu-Mihai Popescu <silviupopescu1990-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
---
net/bluetooth/hci_sysfs.c | 5 +----
1 file changed, 1 insertion(+), 4 deletions(-)
diff --git a/net/bluetooth/hci_sysfs.c b/net/bluetooth/hci_sysfs.c
index 23b4e24..6fb5065 100644
--- a/net/bluetooth/hci_sysfs.c
+++ b/net/bluetooth/hci_sysfs.c
@@ -590,10 +590,7 @@ int __init bt_sysfs_init(void)
bt_debugfs = debugfs_create_dir("bluetooth", NULL);
bt_class = class_create(THIS_MODULE, "bluetooth");
- if (IS_ERR(bt_class))
- return PTR_ERR(bt_class);
-
- return 0;
+ return PTR_RET(bt_class)
}
void bt_sysfs_cleanup(void)
--
1.7.9.5
^ permalink raw reply related
* [PATCH] ethernet: nxp: use resource_size()
From: Silviu-Mihai Popescu @ 2013-03-12 18:30 UTC (permalink / raw)
To: netdev
Cc: davem, stigge, edumazet, gregkh, jiri, linux-kernel,
Silviu-Mihai Popescu
Use resource_size() instead of explicit calculation. This was found via
make coccicheck.
Signed-off-by: Silviu-Mihai Popescu <silviupopescu1990@gmail.com>
---
drivers/net/ethernet/nxp/lpc_eth.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/nxp/lpc_eth.c b/drivers/net/ethernet/nxp/lpc_eth.c
index c4122c8..bc493c8 100644
--- a/drivers/net/ethernet/nxp/lpc_eth.c
+++ b/drivers/net/ethernet/nxp/lpc_eth.c
@@ -1362,7 +1362,7 @@ static int lpc_eth_drv_probe(struct platform_device *pdev)
__lpc_eth_clock_enable(pldat, true);
/* Map IO space */
- pldat->net_base = ioremap(res->start, res->end - res->start + 1);
+ pldat->net_base = ioremap(res->start, resource_size(res));
if (!pldat->net_base) {
dev_err(&pdev->dev, "failed to map registers\n");
ret = -ENOMEM;
@@ -1421,7 +1421,7 @@ static int lpc_eth_drv_probe(struct platform_device *pdev)
netdev_dbg(ndev, "IO address start :0x%08x\n",
res->start);
netdev_dbg(ndev, "IO address size :%d\n",
- res->end - res->start + 1);
+ resource_size(res));
netdev_dbg(ndev, "IO address (mapped) :0x%p\n",
pldat->net_base);
netdev_dbg(ndev, "IRQ number :%d\n", ndev->irq);
--
1.7.9.5
^ permalink raw reply related
* Re: e1000e failed to check map error
From: Dave Jones @ 2013-03-12 18:51 UTC (permalink / raw)
To: Allan, Bruce W; +Cc: netdev@vger.kernel.org
In-Reply-To: <804857E1F29AAC47BF68C404FC60A1844D022AE1@ORSMSX102.amr.corp.intel.com>
On Fri, Mar 01, 2013 at 05:13:29PM +0000, Allan, Bruce W wrote:
> > -----Original Message-----
> > From: netdev-owner@vger.kernel.org [mailto:netdev-
> > owner@vger.kernel.org] On Behalf Of Dave Jones
> > Sent: Thursday, February 28, 2013 9:30 PM
> > To: netdev@vger.kernel.org
> > Subject: e1000e failed to check map error
> >
> > Linus' current tree shows this shortly after boot for me..
> >
> > WARNING: at lib/dma-debug.c:933 check_unmap+0x407/0x8a0()
>
> Thanks for the report Dave. I'll look into it.
>
> Bruce.
fwiw, I see this also on 3.8.x, albeit with a different size..
e1000e 0000:05:00.0: DMA-API: device driver failed to check map error[device address=0x0000000007130000] [size=24 bytes] [mapped as page]
Same backtrace though.
Dave
^ permalink raw reply
* Re: [PATCH] ethernet: nxp: use resource_size()
From: Joe Perches @ 2013-03-12 19:10 UTC (permalink / raw)
To: Silviu-Mihai Popescu
Cc: netdev, davem, stigge, edumazet, gregkh, jiri, linux-kernel
In-Reply-To: <1363113035-11269-1-git-send-email-silviupopescu1990@gmail.com>
On Tue, 2013-03-12 at 20:30 +0200, Silviu-Mihai Popescu wrote:
> Use resource_size() instead of explicit calculation. This was found via
> make coccicheck.
[]
> diff --git a/drivers/net/ethernet/nxp/lpc_eth.c b/drivers/net/ethernet/nxp/lpc_eth.c
[]
> @@ -1421,7 +1421,7 @@ static int lpc_eth_drv_probe(struct platform_device *pdev)
> netdev_dbg(ndev, "IO address start :0x%08x\n",
> res->start);
> netdev_dbg(ndev, "IO address size :%d\n",
> - res->end - res->start + 1);
> + resource_size(res));
This might be better as
netdev_dbg(ndev, "IO resource :%pR\n", res);
^ permalink raw reply
* [PATCH net-next 1/2] qlcnic: Implement flash sysfs callback for 83xx adapter
From: Shahed Shaikh @ 2013-03-12 19:02 UTC (permalink / raw)
To: davem; +Cc: netdev, Dept_NX_Linux_NIC_Driver, Himanshu Madhani
From: Himanshu Madhani <himanshu.madhani@qlogic.com>
QLogic applications use these callbacks to perform
o NIC Partitioning (NPAR) configuration and management
o Diagnostic tests
o Flash access and updates
Signed-off-by: Himanshu Madhani <himanshu.madhani@qlogic.com>
Signed-off-by: Shahed Shaikh <shahed.shaikh@qlogic.com>
---
.../net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c | 12 +-
.../net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h | 8 +-
drivers/net/ethernet/qlogic/qlcnic/qlcnic_sysfs.c | 253 ++++++++++++++++++++
3 files changed, 265 insertions(+), 8 deletions(-)
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c
index c08fa20..56c3676 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c
@@ -2272,7 +2272,7 @@ static int qlcnic_83xx_poll_flash_status_reg(struct qlcnic_adapter *adapter)
return 0;
}
-static int qlcnic_83xx_enable_flash_write_op(struct qlcnic_adapter *adapter)
+int qlcnic_83xx_enable_flash_write(struct qlcnic_adapter *adapter)
{
int ret;
u32 cmd;
@@ -2290,7 +2290,7 @@ static int qlcnic_83xx_enable_flash_write_op(struct qlcnic_adapter *adapter)
return 0;
}
-static int qlcnic_83xx_disable_flash_write_op(struct qlcnic_adapter *adapter)
+int qlcnic_83xx_disable_flash_write(struct qlcnic_adapter *adapter)
{
int ret;
@@ -2364,7 +2364,7 @@ int qlcnic_83xx_erase_flash_sector(struct qlcnic_adapter *adapter,
return -EIO;
if (adapter->ahw->fdt.mfg_id == adapter->flash_mfg_id) {
- ret = qlcnic_83xx_enable_flash_write_op(adapter);
+ ret = qlcnic_83xx_enable_flash_write(adapter);
if (ret) {
qlcnic_83xx_unlock_flash(adapter);
dev_err(&adapter->pdev->dev,
@@ -2406,7 +2406,7 @@ int qlcnic_83xx_erase_flash_sector(struct qlcnic_adapter *adapter,
}
if (adapter->ahw->fdt.mfg_id == adapter->flash_mfg_id) {
- ret = qlcnic_83xx_disable_flash_write_op(adapter);
+ ret = qlcnic_83xx_disable_flash_write(adapter);
if (ret) {
qlcnic_83xx_unlock_flash(adapter);
dev_err(&adapter->pdev->dev,
@@ -2446,8 +2446,8 @@ int qlcnic_83xx_flash_bulk_write(struct qlcnic_adapter *adapter, u32 addr,
u32 temp;
int ret = -EIO;
- if ((count < QLC_83XX_FLASH_BULK_WRITE_MIN) ||
- (count > QLC_83XX_FLASH_BULK_WRITE_MAX)) {
+ if ((count < QLC_83XX_FLASH_WRITE_MIN) ||
+ (count > QLC_83XX_FLASH_WRITE_MAX)) {
dev_err(&adapter->pdev->dev,
"%s: Invalid word count\n", __func__);
return -EIO;
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h
index 648a73f..fbb3d1d 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h
@@ -12,6 +12,8 @@
#include <linux/etherdevice.h>
#include "qlcnic_hw.h"
+#define QLCNIC_83XX_BAR0_LENGTH 0x4000
+
/* Directly mapped registers */
#define QLC_83XX_CRB_WIN_BASE 0x3800
#define QLC_83XX_CRB_WIN_FUNC(f) (QLC_83XX_CRB_WIN_BASE+((f)*4))
@@ -257,8 +259,8 @@ struct qlc_83xx_idc {
#define QLC_83XX_FLASH_BULK_WRITE_CMD 0xcadcadca
#define QLC_83XX_FLASH_READ_RETRY_COUNT 5000
#define QLC_83XX_FLASH_STATUS_READY 0x6
-#define QLC_83XX_FLASH_BULK_WRITE_MIN 2
-#define QLC_83XX_FLASH_BULK_WRITE_MAX 64
+#define QLC_83XX_FLASH_WRITE_MIN 2
+#define QLC_83XX_FLASH_WRITE_MAX 64
#define QLC_83XX_FLASH_STATUS_REG_POLL_DELAY 1
#define QLC_83XX_ERASE_MODE 1
#define QLC_83XX_WRITE_MODE 2
@@ -451,4 +453,6 @@ int qlcnic_83xx_loopback_test(struct net_device *, u8);
int qlcnic_83xx_interrupt_test(struct net_device *);
int qlcnic_83xx_set_led(struct net_device *, enum ethtool_phys_id_state);
int qlcnic_83xx_flash_test(struct qlcnic_adapter *);
+int qlcnic_83xx_enable_flash_write(struct qlcnic_adapter *);
+int qlcnic_83xx_disable_flash_write(struct qlcnic_adapter *);
#endif
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sysfs.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sysfs.c
index 4e464dc..c77675d 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sysfs.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sysfs.c
@@ -884,6 +884,244 @@ static ssize_t qlcnic_sysfs_read_pci_config(struct file *file,
return size;
}
+static ssize_t qlcnic_83xx_sysfs_flash_read_handler(struct file *filp,
+ struct kobject *kobj,
+ struct bin_attribute *attr,
+ char *buf, loff_t offset,
+ size_t size)
+{
+ unsigned char *p_read_buf;
+ int ret, count;
+ struct device *dev = container_of(kobj, struct device, kobj);
+ struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
+
+ if (!size)
+ return QL_STATUS_INVALID_PARAM;
+ if (!buf)
+ return QL_STATUS_INVALID_PARAM;
+
+ count = size / sizeof(u32);
+
+ if (size % sizeof(u32))
+ count++;
+
+ p_read_buf = kcalloc(size, sizeof(unsigned char), GFP_KERNEL);
+ if (!p_read_buf)
+ return -ENOMEM;
+ if (qlcnic_83xx_lock_flash(adapter) != 0) {
+ kfree(p_read_buf);
+ return -EIO;
+ }
+
+ ret = qlcnic_83xx_lockless_flash_read32(adapter, offset, p_read_buf,
+ count);
+
+ if (ret) {
+ qlcnic_83xx_unlock_flash(adapter);
+ kfree(p_read_buf);
+ return ret;
+ }
+
+ qlcnic_83xx_unlock_flash(adapter);
+ memcpy(buf, p_read_buf, size);
+ kfree(p_read_buf);
+
+ return size;
+}
+
+static int qlcnic_83xx_sysfs_flash_bulk_write(struct qlcnic_adapter *adapter,
+ char *buf, loff_t offset,
+ size_t size)
+{
+ int i, ret, count;
+ unsigned char *p_cache, *p_src;
+
+ p_cache = kcalloc(size, sizeof(unsigned char), GFP_KERNEL);
+ if (!p_cache)
+ return -ENOMEM;
+
+ memcpy(p_cache, buf, size);
+ p_src = p_cache;
+ count = size / sizeof(u32);
+
+ if (qlcnic_83xx_lock_flash(adapter) != 0) {
+ kfree(p_cache);
+ return -EIO;
+ }
+
+ if (adapter->ahw->fdt.mfg_id == adapter->flash_mfg_id) {
+ ret = qlcnic_83xx_enable_flash_write(adapter);
+ if (ret) {
+ kfree(p_cache);
+ qlcnic_83xx_unlock_flash(adapter);
+ return -EIO;
+ }
+ }
+
+ for (i = 0; i < count / QLC_83XX_FLASH_WRITE_MAX; i++) {
+ ret = qlcnic_83xx_flash_bulk_write(adapter, offset,
+ (u32 *)p_src,
+ QLC_83XX_FLASH_WRITE_MAX);
+
+ if (ret) {
+ if (adapter->ahw->fdt.mfg_id == adapter->flash_mfg_id) {
+ ret = qlcnic_83xx_disable_flash_write(adapter);
+ if (ret) {
+ kfree(p_cache);
+ qlcnic_83xx_unlock_flash(adapter);
+ return -EIO;
+ }
+ }
+
+ kfree(p_cache);
+ qlcnic_83xx_unlock_flash(adapter);
+ return -EIO;
+ }
+
+ p_src = p_src + sizeof(u32)*QLC_83XX_FLASH_WRITE_MAX;
+ offset = offset + sizeof(u32)*QLC_83XX_FLASH_WRITE_MAX;
+ }
+
+ if (adapter->ahw->fdt.mfg_id == adapter->flash_mfg_id) {
+ ret = qlcnic_83xx_disable_flash_write(adapter);
+ if (ret) {
+ kfree(p_cache);
+ qlcnic_83xx_unlock_flash(adapter);
+ return -EIO;
+ }
+ }
+
+ kfree(p_cache);
+ qlcnic_83xx_unlock_flash(adapter);
+
+ return 0;
+}
+
+static int qlcnic_83xx_sysfs_flash_write(struct qlcnic_adapter *adapter,
+ char *buf, loff_t offset, size_t size)
+{
+ int i, ret, count;
+ unsigned char *p_cache, *p_src;
+
+ p_cache = kcalloc(size, sizeof(unsigned char), GFP_KERNEL);
+ if (!p_cache)
+ return -ENOMEM;
+
+ memcpy(p_cache, buf, size);
+ p_src = p_cache;
+ count = size / sizeof(u32);
+
+ if (qlcnic_83xx_lock_flash(adapter) != 0) {
+ kfree(p_cache);
+ return -EIO;
+ }
+
+ if (adapter->ahw->fdt.mfg_id == adapter->flash_mfg_id) {
+ ret = qlcnic_83xx_enable_flash_write(adapter);
+ if (ret) {
+ kfree(p_cache);
+ qlcnic_83xx_unlock_flash(adapter);
+ return -EIO;
+ }
+ }
+
+ for (i = 0; i < count; i++) {
+ ret = qlcnic_83xx_flash_write32(adapter, offset, (u32 *)p_src);
+ if (ret) {
+ if (adapter->ahw->fdt.mfg_id == adapter->flash_mfg_id) {
+ ret = qlcnic_83xx_disable_flash_write(adapter);
+ if (ret) {
+ kfree(p_cache);
+ qlcnic_83xx_unlock_flash(adapter);
+ return -EIO;
+ }
+ }
+ kfree(p_cache);
+ qlcnic_83xx_unlock_flash(adapter);
+ return -EIO;
+ }
+
+ p_src = p_src + sizeof(u32);
+ offset = offset + sizeof(u32);
+ }
+
+ if (adapter->ahw->fdt.mfg_id == adapter->flash_mfg_id) {
+ ret = qlcnic_83xx_disable_flash_write(adapter);
+ if (ret) {
+ kfree(p_cache);
+ qlcnic_83xx_unlock_flash(adapter);
+ return -EIO;
+ }
+ }
+
+ kfree(p_cache);
+ qlcnic_83xx_unlock_flash(adapter);
+
+ return 0;
+}
+
+static ssize_t qlcnic_83xx_sysfs_flash_write_handler(struct file *filp,
+ struct kobject *kobj,
+ struct bin_attribute *attr,
+ char *buf, loff_t offset,
+ size_t size)
+{
+ int ret;
+ static int flash_mode;
+ unsigned long data;
+ struct device *dev = container_of(kobj, struct device, kobj);
+ struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
+
+ if (!buf)
+ return QL_STATUS_INVALID_PARAM;
+
+ ret = kstrtoul(buf, 16, &data);
+
+ switch (data) {
+ case QLC_83XX_FLASH_SECTOR_ERASE_CMD:
+ flash_mode = QLC_83XX_ERASE_MODE;
+ ret = qlcnic_83xx_erase_flash_sector(adapter, offset);
+ if (ret) {
+ dev_err(&adapter->pdev->dev,
+ "%s failed at %d\n", __func__, __LINE__);
+ return -EIO;
+ }
+ break;
+
+ case QLC_83XX_FLASH_BULK_WRITE_CMD:
+ flash_mode = QLC_83XX_BULK_WRITE_MODE;
+ break;
+
+ case QLC_83XX_FLASH_WRITE_CMD:
+ flash_mode = QLC_83XX_WRITE_MODE;
+ break;
+ default:
+ if (flash_mode == QLC_83XX_BULK_WRITE_MODE) {
+ ret = qlcnic_83xx_sysfs_flash_bulk_write(adapter, buf,
+ offset, size);
+ if (ret) {
+ dev_err(&adapter->pdev->dev,
+ "%s failed at %d\n",
+ __func__, __LINE__);
+ return -EIO;
+ }
+ }
+
+ if (flash_mode == QLC_83XX_WRITE_MODE) {
+ ret = qlcnic_83xx_sysfs_flash_write(adapter, buf,
+ offset, size);
+ if (ret) {
+ dev_err(&adapter->pdev->dev,
+ "%s failed at %d\n", __func__,
+ __LINE__);
+ return -EIO;
+ }
+ }
+ }
+
+ return size;
+}
+
static struct device_attribute dev_attr_bridged_mode = {
.attr = {.name = "bridged_mode", .mode = (S_IRUGO | S_IWUSR)},
.show = qlcnic_show_bridged_mode,
@@ -958,6 +1196,13 @@ static struct bin_attribute bin_attr_pm_config = {
.write = qlcnic_sysfs_write_pm_config,
};
+static struct bin_attribute bin_attr_flash = {
+ .attr = {.name = "flash", .mode = (S_IRUGO | S_IWUSR)},
+ .size = 0,
+ .read = qlcnic_83xx_sysfs_flash_read_handler,
+ .write = qlcnic_83xx_sysfs_flash_write_handler,
+};
+
void qlcnic_create_sysfs_entries(struct qlcnic_adapter *adapter)
{
struct device *dev = &adapter->pdev->dev;
@@ -1046,10 +1291,18 @@ void qlcnic_82xx_remove_sysfs(struct qlcnic_adapter *adapter)
void qlcnic_83xx_add_sysfs(struct qlcnic_adapter *adapter)
{
+ struct device *dev = &adapter->pdev->dev;
+
qlcnic_create_diag_entries(adapter);
+
+ if (sysfs_create_bin_file(&dev->kobj, &bin_attr_flash))
+ dev_info(dev, "failed to create flash sysfs entry\n");
}
void qlcnic_83xx_remove_sysfs(struct qlcnic_adapter *adapter)
{
+ struct device *dev = &adapter->pdev->dev;
+
qlcnic_remove_diag_entries(adapter);
+ sysfs_remove_bin_file(&dev->kobj, &bin_attr_flash);
}
--
1.5.6
^ permalink raw reply related
* [PATCH net-next 2/2] qlcnic: Bump up the version to 5.1.37
From: Shahed Shaikh @ 2013-03-12 19:02 UTC (permalink / raw)
To: davem; +Cc: netdev, Dept_NX_Linux_NIC_Driver, Shahed Shaikh
In-Reply-To: <1363114937-23283-1-git-send-email-shahed.shaikh@qlogic.com>
From: Shahed Shaikh <shahed.shaikh@qlogic.com>
Signed-off-by: Shahed Shaikh <shahed.shaikh@qlogic.com>
---
drivers/net/ethernet/qlogic/qlcnic/qlcnic.h | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h
index c8b4895..1577799 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h
@@ -38,8 +38,8 @@
#define _QLCNIC_LINUX_MAJOR 5
#define _QLCNIC_LINUX_MINOR 1
-#define _QLCNIC_LINUX_SUBVERSION 36
-#define QLCNIC_LINUX_VERSIONID "5.1.36"
+#define _QLCNIC_LINUX_SUBVERSION 37
+#define QLCNIC_LINUX_VERSIONID "5.1.37"
#define QLCNIC_DRV_IDC_VER 0x01
#define QLCNIC_DRIVER_VERSION ((_QLCNIC_LINUX_MAJOR << 16) |\
(_QLCNIC_LINUX_MINOR << 8) | (_QLCNIC_LINUX_SUBVERSION))
--
1.5.6
^ permalink raw reply related
* [RFC PATCH] qmi_wwan: set correct altsetting for Gobi 1K devices
From: Dan Williams @ 2013-03-12 19:40 UTC (permalink / raw)
To: Bjørn Mork
Cc: linux-usb-u79uwXL29TY76Z2rM5mHXA, netdev-u79uwXL29TY76Z2rM5mHXA
With Gobi 1K devices, USB interface #3's altsetting is 0 by default, but
altsetting 0 only provides one interrupt endpoint and is not sufficent
for QMI. Altsetting 1 provides all 3 endpoints required for qmi_wwan
and works with QMI.
IIRC the altsetting used to be set by qcserial back before we made
qcserial stop touching interfaces that qmi_wwan was going to use. But
now that qcserial only touches the modem interface, we need qmi_wwan to
set the correct altsetting on the QMI interface.
The attached patch works for my Gobi1K (and should work for all other
1Ks too) but seems somewhat ugly. What approach should we take?
Basically, we need to know that a device is Gobi1K at probe time so we
can set the right altsetting on it.
Gobi 1K layout for intf#3 is:
Interface Descriptor: 255/255/255
bInterfaceNumber 3
bAlternateSetting 0
Endpoint Descriptor: Interrupt IN
Interface Descriptor: 255/255/255
bInterfaceNumber 3
bAlternateSetting 1
Endpoint Descriptor: Interrupt IN
Endpoint Descriptor: Bulk IN
Endpoint Descriptor: Bulk OUT
Dan
---
diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c
index efb5c7c..50e1b7c 100644
--- a/drivers/net/usb/qmi_wwan.c
+++ b/drivers/net/usb/qmi_wwan.c
@@ -43,6 +43,9 @@
* commands on a serial interface
*/
+/* Quirks for the usbnet 'struct driver_info' data field */
+#define QUIRK_GOBI_1K (1 << 0) /* QMI interface requires altsetting 1 */
+
/* driver specific data */
struct qmi_wwan_state {
struct usb_driver *subdriver;
@@ -326,6 +329,15 @@ static const struct driver_info qmi_wwan_info = {
.manage_power = qmi_wwan_manage_power,
};
+static const struct driver_info gobi1k_info = {
+ .description = "WWAN/QMI device",
+ .flags = FLAG_WWAN,
+ .bind = qmi_wwan_bind,
+ .unbind = qmi_wwan_unbind,
+ .manage_power = qmi_wwan_manage_power,
+ .data = QUIRK_GOBI_1K,
+};
+
#define HUAWEI_VENDOR_ID 0x12D1
/* map QMI/wwan function by a fixed interface number */
@@ -335,7 +347,8 @@ static const struct driver_info qmi_wwan_info = {
/* Gobi 1000 QMI/wwan interface number is 3 according to qcserial */
#define QMI_GOBI1K_DEVICE(vend, prod) \
- QMI_FIXED_INTF(vend, prod, 3)
+ USB_DEVICE_INTERFACE_NUMBER(vend, prod, 3), \
+ .driver_info = (unsigned long)&gobi1k_info
/* Gobi 2000/3000 QMI/wwan interface number is 0 according to qcserial */
#define QMI_GOBI_DEVICE(vend, prod) \
@@ -541,6 +554,9 @@ MODULE_DEVICE_TABLE(usb, products);
static int qmi_wwan_probe(struct usb_interface *intf, const struct usb_device_id *prod)
{
struct usb_device_id *id = (struct usb_device_id *)prod;
+ struct driver_info *info;
+ u8 intf_num = intf->cur_altsetting->desc.bInterfaceNumber;
+ int retval;
/* Workaround to enable dynamic IDs. This disables usbnet
* blacklisting functionality. Which, if required, can be
@@ -552,6 +568,20 @@ static int qmi_wwan_probe(struct usb_interface *intf, const struct usb_device_id
id->driver_info = (unsigned long)&qmi_wwan_info;
}
+ info = (struct driver_info *) id->driver_info;
+ if (info->data & QUIRK_GOBI_1K) {
+ /* Gobi 1K's QMI interface is always USB interface #3 */
+ BUG_ON(intf_num != 3);
+
+ retval = usb_set_interface(interface_to_usbdev (intf),
+ intf_num, 1);
+ if (retval < 0) {
+ dev_err(&intf->dev, "Failed to set altsetting 1: %d\n",
+ retval);
+ return -ENODEV;
+ }
+ }
+
return usbnet_probe(intf, id);
}
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* [PATCH] VSOCK: Support VM sockets connected to the hypervisor.
From: Reilly Grant @ 2013-03-12 19:40 UTC (permalink / raw)
To: netdev; +Cc: davem, linux-kernel, pv-drivers, Reilly Grant
The resource ID used for VM socket control packets (0) is already
used for the VMCI_GET_CONTEXT_ID hypercall so a new ID (15) must be
used when the guest sends these datagrams to the hypervisor.
The hypervisor context ID must also be removed from the internal
blacklist.
Signed-off-by: Reilly Grant <grantr@vmware.com>
Acked-by: Andy King <acking@vmware.com>
---
net/vmw_vsock/vmci_transport.c | 16 +++++++++++++---
net/vmw_vsock/vmci_transport.h | 3 +++
2 files changed, 16 insertions(+), 3 deletions(-)
diff --git a/net/vmw_vsock/vmci_transport.c b/net/vmw_vsock/vmci_transport.c
index a70ace8..c19ff0e 100644
--- a/net/vmw_vsock/vmci_transport.c
+++ b/net/vmw_vsock/vmci_transport.c
@@ -123,6 +123,14 @@ static s32 vmci_transport_error_to_vsock_error(s32 vmci_error)
return err > 0 ? -err : err;
}
+static u32 vmci_transport_peer_rid(u32 peer_cid)
+{
+ if (VMADDR_HYPERVISOR_ID == peer_cid)
+ return VMCI_TRANSPORT_HYPERVISOR_PACKET_RID;
+
+ return VMCI_TRANSPORT_PACKET_RID;
+}
+
static inline void
vmci_transport_packet_init(struct vmci_transport_packet *pkt,
struct sockaddr_vm *src,
@@ -140,7 +148,7 @@ vmci_transport_packet_init(struct vmci_transport_packet *pkt,
pkt->dg.src = vmci_make_handle(VMADDR_CID_ANY,
VMCI_TRANSPORT_PACKET_RID);
pkt->dg.dst = vmci_make_handle(dst->svm_cid,
- VMCI_TRANSPORT_PACKET_RID);
+ vmci_transport_peer_rid(dst->svm_cid);
pkt->dg.payload_size = sizeof(*pkt) - sizeof(pkt->dg);
pkt->version = VMCI_TRANSPORT_PACKET_VERSION;
pkt->type = type;
@@ -511,6 +519,9 @@ static bool vmci_transport_is_trusted(struct vsock_sock *vsock, u32 peer_cid)
static bool vmci_transport_allow_dgram(struct vsock_sock *vsock, u32 peer_cid)
{
+ if (VMADDR_CID_HYPERVISOR == peer_cid)
+ return true;
+
if (vsock->cached_peer != peer_cid) {
vsock->cached_peer = peer_cid;
if (!vmci_transport_is_trusted(vsock, peer_cid) &&
@@ -631,7 +642,6 @@ static int vmci_transport_recv_dgram_cb(void *data, struct vmci_datagram *dg)
static bool vmci_transport_stream_allow(u32 cid, u32 port)
{
static const u32 non_socket_contexts[] = {
- VMADDR_CID_HYPERVISOR,
VMADDR_CID_RESERVED,
};
int i;
@@ -670,7 +680,7 @@ static int vmci_transport_recv_stream_cb(void *data, struct vmci_datagram *dg)
*/
if (!vmci_transport_stream_allow(dg->src.context, -1)
- || VMCI_TRANSPORT_PACKET_RID != dg->src.resource)
+ || vmci_transport_peer_rid(dg->src.context) != dg->src.resource)
return VMCI_ERROR_NO_ACCESS;
if (VMCI_DG_SIZE(dg) < sizeof(*pkt))
diff --git a/net/vmw_vsock/vmci_transport.h b/net/vmw_vsock/vmci_transport.h
index 1bf9918..fd88ea8 100644
--- a/net/vmw_vsock/vmci_transport.h
+++ b/net/vmw_vsock/vmci_transport.h
@@ -28,6 +28,9 @@
/* The resource ID on which control packets are sent. */
#define VMCI_TRANSPORT_PACKET_RID 1
+/* The resource ID on which control packets are sent to the hypervisor. */
+#define VMCI_TRANSPORT_HYPERVISOR_PACKET_RID 15
+
#define VSOCK_PROTO_INVALID 0
#define VSOCK_PROTO_PKT_ON_NOTIFY (1 << 0)
#define VSOCK_PROTO_ALL_SUPPORTED (VSOCK_PROTO_PKT_ON_NOTIFY)
--
1.8.1.5
^ permalink raw reply related
* Re: [PATCH] net: ethernet: cpsw: fix usage of cpdma_check_free_tx_desc()
From: Mugunthan V N @ 2013-03-12 19:47 UTC (permalink / raw)
To: Daniel Mack; +Cc: netdev, andreas.fenkart, davem, s.neumann, koen
In-Reply-To: <1363105879-26921-1-git-send-email-zonque@gmail.com>
On 3/12/2013 10:01 PM, Daniel Mack wrote:
> Commit fae50823d0 ("net: ethernet: davinci_cpdma: Add boundary for rx
> and tx descriptors") introduced a function to check the current
> allocation state of tx packets. The return value is taken into account
> to stop the netqork queue on the adapter in case there are no free
> slots.
>
> However, cpdma_check_free_tx_desc() returns 'true' if there is room in
> the bitmap, not 'false', so the usage of the function is wrong.
>
> Signed-off-by: Daniel Mack <zonque@gmail.com>
> Cc: Mugunthan V N <mugunthanvnm@ti.com>
> Reported-by: Sven Neumann <s.neumann@raumfeld.com>
> Reported-by: Andreas Fenkart <andreas.fenkart@streamunlimited.com>
> ---
> drivers/net/ethernet/ti/cpsw.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c
> index 01ffbc4..75c4855 100644
> --- a/drivers/net/ethernet/ti/cpsw.c
> +++ b/drivers/net/ethernet/ti/cpsw.c
> @@ -905,7 +905,7 @@ static netdev_tx_t cpsw_ndo_start_xmit(struct sk_buff *skb,
> /* If there is no more tx desc left free then we need to
> * tell the kernel to stop sending us tx frames.
> */
> - if (unlikely(cpdma_check_free_tx_desc(priv->txch)))
> + if (unlikely(!cpdma_check_free_tx_desc(priv->txch)))
> netif_stop_queue(ndev);
>
> return NETDEV_TX_OK;
Tested-by: Mugunthan V N <mugunthanvnm@ti.com>
Acked-by: Mugunthan V N <mugunthanvnm@ti.com>
Regards
Mugunthan V N
^ permalink raw reply
* [PATCH] igb: Fix null pointer dereference
From: Alex Williamson @ 2013-03-12 20:09 UTC (permalink / raw)
To: gregory.v.rose, jeffrey.t.kirsher; +Cc: netdev, ddutile, linux-kernel, sassmann
The max_vfs= option has always been self limiting to the number of VFs
supported by the device. fa44f2f1 added SR-IOV configuration via
sysfs, but in the process broke this self correction factor. The
failing path is:
igb_probe
igb_sw_init
if (max_vfs > 7) {
adapter->vfs_allocated_count = 7;
...
igb_probe_vfs
igb_enable_sriov(, max_vfs)
if (num_vfs > 7) {
err = -EPERM;
...
This leaves vfs_allocated_count = 7 and vf_data = NULL, so we bomb out
when igb_probe finally calls igb_reset. It seems like a really bad
idea, and somewhat pointless, to set vfs_allocated_count separate from
vf_data, but limiting max_vfs is enough to avoid the null pointer.
Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
---
drivers/net/ethernet/intel/igb/igb_main.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c
index ed79a1c..d5b8289 100644
--- a/drivers/net/ethernet/intel/igb/igb_main.c
+++ b/drivers/net/ethernet/intel/igb/igb_main.c
@@ -2656,7 +2656,7 @@ static int igb_sw_init(struct igb_adapter *adapter)
if (max_vfs > 7) {
dev_warn(&pdev->dev,
"Maximum of 7 VFs per PF, using max\n");
- adapter->vfs_allocated_count = 7;
+ max_vfs = adapter->vfs_allocated_count = 7;
} else
adapter->vfs_allocated_count = max_vfs;
if (adapter->vfs_allocated_count)
^ permalink raw reply related
* Re: [PATCH] net: ethernet: cpsw: fix usage of cpdma_check_free_tx_desc()
From: Andreas Fenkart @ 2013-03-12 20:20 UTC (permalink / raw)
To: Mugunthan V N
Cc: Daniel Mack, netdev, andreas.fenkart, davem, s.neumann, koen
In-Reply-To: <513F8660.2010602@ti.com>
On Wed, Mar 13, 2013 at 01:17:44AM +0530, Mugunthan V N wrote:
> On 3/12/2013 10:01 PM, Daniel Mack wrote:
> >Commit fae50823d0 ("net: ethernet: davinci_cpdma: Add boundary for rx
> >and tx descriptors") introduced a function to check the current
> >allocation state of tx packets. The return value is taken into account
> >to stop the netqork queue on the adapter in case there are no free
> >slots.
> >
> >However, cpdma_check_free_tx_desc() returns 'true' if there is room in
> >the bitmap, not 'false', so the usage of the function is wrong.
> >
> >Signed-off-by: Daniel Mack <zonque@gmail.com>
> >Cc: Mugunthan V N <mugunthanvnm@ti.com>
> >Reported-by: Sven Neumann <s.neumann@raumfeld.com>
> >Reported-by: Andreas Fenkart <andreas.fenkart@streamunlimited.com>
> >---
> > drivers/net/ethernet/ti/cpsw.c | 2 +-
> > 1 file changed, 1 insertion(+), 1 deletion(-)
> >
> >diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c
> >index 01ffbc4..75c4855 100644
> >--- a/drivers/net/ethernet/ti/cpsw.c
> >+++ b/drivers/net/ethernet/ti/cpsw.c
> >@@ -905,7 +905,7 @@ static netdev_tx_t cpsw_ndo_start_xmit(struct sk_buff *skb,
> > /* If there is no more tx desc left free then we need to
> > * tell the kernel to stop sending us tx frames.
> > */
> >- if (unlikely(cpdma_check_free_tx_desc(priv->txch)))
> >+ if (unlikely(!cpdma_check_free_tx_desc(priv->txch)))
> > netif_stop_queue(ndev);
> > return NETDEV_TX_OK;
> Tested-by: Mugunthan V N <mugunthanvnm@ti.com>
> Acked-by: Mugunthan V N <mugunthanvnm@ti.com>
>
> Regards
> Mugunthan V N
This restores throughput to the level of 3.7.0
Tested-by: Andreas Fenkart <andreas.fenkart@streamunlimited.com>
^ permalink raw reply
* Re: [PATCH] sctp: optimize searching the active path for tsns
From: Vlad Yasevich @ 2013-03-12 21:01 UTC (permalink / raw)
To: Neil Horman; +Cc: linux-sctp, Xufeng Zhang, davem, netdev
In-Reply-To: <1363109382-753-1-git-send-email-nhorman@tuxdriver.com>
Hi Neil
On 03/12/2013 01:29 PM, Neil Horman wrote:
> SCTP currently attempts to optimize the search for tsns on a transport by first
> checking the active_path, then searching alternate transports. This operation
> however is a bit convoluted, as we explicitly search the active path, then serch
> all other transports, skipping the active path, when its detected. Lets
> optimize this by preforming a move to front on the transport_addr_list every
> time the active_path is changed. The active_path changes occur in relatively
> non-critical paths, and doing so allows us to just search the
> transport_addr_list in order, avoiding an extra conditional check in the
> relatively hot tsn lookup path. This also happens to fix a bug where we break
> out of the for loop early in the tsn lookup.
>
> CC: Xufeng Zhang <xufengzhang.main@gmail.com>
> CC: vyasevich@gmail.com
> CC: davem@davemloft.net
> CC: netdev@vger.kernel.org
> ---
> net/sctp/associola.c | 31 ++++++++++++-------------------
> 1 file changed, 12 insertions(+), 19 deletions(-)
>
> diff --git a/net/sctp/associola.c b/net/sctp/associola.c
> index 43cd0dd..7af96b3 100644
> --- a/net/sctp/associola.c
> +++ b/net/sctp/associola.c
> @@ -513,8 +513,11 @@ void sctp_assoc_set_primary(struct sctp_association *asoc,
> * user wants to use this new path.
> */
> if ((transport->state == SCTP_ACTIVE) ||
> - (transport->state == SCTP_UNKNOWN))
> + (transport->state == SCTP_UNKNOWN)) {
> + list_del_rcu(&transport->transports);
> + list_add_rcu(&transport->transports, &asoc->peer.transport_addr_list);
> asoc->peer.active_path = transport;
> + }
What would happen if at the same time someone is walking the list
through the proc interfaces?
Since you are effectively changing the .next pointer, I think it is
possible to get a duplicate transport output essentially corrupting the
output.
Personally, I don't think that this particular case is worth the
optimization since we are trying to optimize a TSN search that only
happens when ECNE chunk is received. You say that it is a hot path.
Is ECNE really such a common occurrence?
Additionally, I don't think this is really an optimization as the
current and new code do exactly the same thing:
1) look at active path
2) look at the rest of the paths
This just makes cleaner code at the expense of list shuffling.
-vlad
>
> /*
> * SFR-CACC algorithm:
> @@ -964,6 +967,10 @@ void sctp_assoc_control_transport(struct sctp_association *asoc,
> }
>
> /* Set the active and retran transports. */
> + if (asoc->peer.active_path != first) {
> + list_del_rcu(first);
> + list_add_rcu(first, &asoc->peer.transport_addr_list);
> + }
> asoc->peer.active_path = first;
> asoc->peer.retran_path = second;
> }
> @@ -1040,7 +1047,6 @@ struct sctp_chunk *sctp_get_ecne_prepend(struct sctp_association *asoc)
> struct sctp_transport *sctp_assoc_lookup_tsn(struct sctp_association *asoc,
> __u32 tsn)
> {
> - struct sctp_transport *active;
> struct sctp_transport *match;
> struct sctp_transport *transport;
> struct sctp_chunk *chunk;
> @@ -1057,29 +1063,16 @@ struct sctp_transport *sctp_assoc_lookup_tsn(struct sctp_association *asoc,
> * The general strategy is to search each transport's transmitted
> * list. Return which transport this TSN lives on.
> *
> - * Let's be hopeful and check the active_path first.
> - * Another optimization would be to know if there is only one
> - * outbound path and not have to look for the TSN at all.
> + * Note, that sctp_assoc_set_primary does a move to front operation
> + * on the active_path transport, so this code implicitly checks
> + * the active_path first, as we most commonly expect to find our TSN
> + * there.
> *
> */
>
> - active = asoc->peer.active_path;
> -
> - list_for_each_entry(chunk, &active->transmitted,
> - transmitted_list) {
> -
> - if (key == chunk->subh.data_hdr->tsn) {
> - match = active;
> - goto out;
> - }
> - }
> -
> - /* If not found, go search all the other transports. */
> list_for_each_entry(transport, &asoc->peer.transport_addr_list,
> transports) {
>
> - if (transport == active)
> - break;
> list_for_each_entry(chunk, &transport->transmitted,
> transmitted_list) {
> if (key == chunk->subh.data_hdr->tsn) {
>
^ permalink raw reply
* Re: [RFC PATCH] qmi_wwan: set correct altsetting for Gobi 1K devices
From: Bjørn Mork @ 2013-03-12 21:17 UTC (permalink / raw)
To: Dan Williams; +Cc: linux-usb, netdev
In-Reply-To: <1363117205.9644.17.camel@dcbw.foobar.com>
Dan Williams <dcbw@redhat.com> wrote:
>With Gobi 1K devices, USB interface #3's altsetting is 0 by default,
>but
>altsetting 0 only provides one interrupt endpoint and is not sufficent
>for QMI. Altsetting 1 provides all 3 endpoints required for qmi_wwan
>and works with QMI.
>
>IIRC the altsetting used to be set by qcserial back before we made
>qcserial stop touching interfaces that qmi_wwan was going to use. But
>now that qcserial only touches the modem interface, we need qmi_wwan to
>set the correct altsetting on the QMI interface.
No, I broke this when I tried to be smart and merged the 1 and 2 interface probes. That's the second time I break probing of these devices by making too many unfounded assumptions.
This used to work because usbnet_get_endpoints selects the first usable altsetting. It doesn't work anymore because qmi_wwan checks the number of endpoints before calling usbnet_get_endpoints.
>The attached patch works for my Gobi1K (and should work for all other
>1Ks too) but seems somewhat ugly. What approach should we take?
>Basically, we need to know that a device is Gobi1K at probe time so we
>can set the right altsetting on it.
>
>Gobi 1K layout for intf#3 is:
>
> Interface Descriptor: 255/255/255
> bInterfaceNumber 3
> bAlternateSetting 0
> Endpoint Descriptor: Interrupt IN
> Interface Descriptor: 255/255/255
> bInterfaceNumber 3
> bAlternateSetting 1
> Endpoint Descriptor: Interrupt IN
> Endpoint Descriptor: Bulk IN
> Endpoint Descriptor: Bulk OUT
Ouch. I did not know this. I should get one of these devices, I guess. ..
>Dan
>
>---
>diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c
>index efb5c7c..50e1b7c 100644
>--- a/drivers/net/usb/qmi_wwan.c
>+++ b/drivers/net/usb/qmi_wwan.c
>@@ -43,6 +43,9 @@
> * commands on a serial interface
> */
>
>+/* Quirks for the usbnet 'struct driver_info' data field */
>+#define QUIRK_GOBI_1K (1 << 0) /* QMI interface requires altsetting
>1 */
>+
> /* driver specific data */
> struct qmi_wwan_state {
> struct usb_driver *subdriver;
>@@ -326,6 +329,15 @@ static const struct driver_info qmi_wwan_info = {
> .manage_power = qmi_wwan_manage_power,
> };
>
>+static const struct driver_info gobi1k_info = {
>+ .description = "WWAN/QMI device",
>+ .flags = FLAG_WWAN,
>+ .bind = qmi_wwan_bind,
>+ .unbind = qmi_wwan_unbind,
>+ .manage_power = qmi_wwan_manage_power,
>+ .data = QUIRK_GOBI_1K,
>+};
>+
> #define HUAWEI_VENDOR_ID 0x12D1
>
> /* map QMI/wwan function by a fixed interface number */
>@@ -335,7 +347,8 @@ static const struct driver_info qmi_wwan_info = {
>
> /* Gobi 1000 QMI/wwan interface number is 3 according to qcserial */
> #define QMI_GOBI1K_DEVICE(vend, prod) \
>- QMI_FIXED_INTF(vend, prod, 3)
>+ USB_DEVICE_INTERFACE_NUMBER(vend, prod, 3), \
>+ .driver_info = (unsigned long)&gobi1k_info
>
>/* Gobi 2000/3000 QMI/wwan interface number is 0 according to qcserial
>*/
> #define QMI_GOBI_DEVICE(vend, prod) \
>@@ -541,6 +554,9 @@ MODULE_DEVICE_TABLE(usb, products);
>static int qmi_wwan_probe(struct usb_interface *intf, const struct
>usb_device_id *prod)
> {
> struct usb_device_id *id = (struct usb_device_id *)prod;
>+ struct driver_info *info;
>+ u8 intf_num = intf->cur_altsetting->desc.bInterfaceNumber;
>+ int retval;
>
> /* Workaround to enable dynamic IDs. This disables usbnet
> * blacklisting functionality. Which, if required, can be
>@@ -552,6 +568,20 @@ static int qmi_wwan_probe(struct usb_interface
>*intf, const struct usb_device_id
> id->driver_info = (unsigned long)&qmi_wwan_info;
> }
>
>+ info = (struct driver_info *) id->driver_info;
>+ if (info->data & QUIRK_GOBI_1K) {
>+ /* Gobi 1K's QMI interface is always USB interface #3 */
>+ BUG_ON(intf_num != 3);
Definitely not. We return ENODEV if the probe logic fails for whatever reason.
>+ retval = usb_set_interface(interface_to_usbdev (intf),
>+ intf_num, 1);
>+ if (retval < 0) {
>+ dev_err(&intf->dev, "Failed to set altsetting 1: %d\n",
>+ retval);
>+ return -ENODEV;
>+ }
>+ }
Risking that I am trying to be too smart again. .. But I really think we can fix this in a more generic way by making the probe behave more like it did before. How about just letting it continue without erring out until it has called usbnet_get_endpoints? That should work without needing any quirks.
Bjørn
^ permalink raw reply
* [PATCH net-next] ipv6: use ipv6_iface_scope_id in conntrack to return scope id
From: Hannes Frederic Sowa @ 2013-03-12 21:21 UTC (permalink / raw)
To: netfilter-devel; +Cc: yoshfuji, netdev, pablo
Cc: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
Signed-off-by: Hannes Frederic Sowa <hannes@stressinduktion.org>
---
net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c | 8 ++------
1 file changed, 2 insertions(+), 6 deletions(-)
diff --git a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
index 2b6c226..97bcf2b 100644
--- a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
+++ b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
@@ -330,12 +330,8 @@ ipv6_getorigdst(struct sock *sk, int optval, void __user *user, int *len)
sizeof(sin6.sin6_addr));
nf_ct_put(ct);
-
- if (ipv6_addr_type(&sin6.sin6_addr) & IPV6_ADDR_LINKLOCAL)
- sin6.sin6_scope_id = sk->sk_bound_dev_if;
- else
- sin6.sin6_scope_id = 0;
-
+ sin6.sin6_scope_id = ipv6_iface_scope_id(&sin6.sin6_addr,
+ sk->sk_bound_dev_if);
return copy_to_user(user, &sin6, sizeof(sin6)) ? -EFAULT : 0;
}
--
1.8.1.4
^ permalink raw reply related
* [PATCH] igb: SR-IOV init reordering
From: Alex Williamson @ 2013-03-12 21:25 UTC (permalink / raw)
To: gregory.v.rose, jeffrey.t.kirsher; +Cc: netdev, ddutile, linux-kernel, sassmann
igb is ineffective at setting a lower total VFs because:
int pci_sriov_set_totalvfs(struct pci_dev *dev, u16 numvfs)
{
...
/* Shouldn't change if VFs already enabled */
if (dev->sriov->ctrl & PCI_SRIOV_CTRL_VFE)
return -EBUSY;
Swap init ordering.
Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
---
drivers/net/ethernet/intel/igb/igb_main.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c
index d5b8289..ac65c39 100644
--- a/drivers/net/ethernet/intel/igb/igb_main.c
+++ b/drivers/net/ethernet/intel/igb/igb_main.c
@@ -2546,8 +2546,8 @@ static void igb_probe_vfs(struct igb_adapter *adapter)
if ((hw->mac.type == e1000_i210) || (hw->mac.type == e1000_i211))
return;
- igb_enable_sriov(pdev, max_vfs);
pci_sriov_set_totalvfs(pdev, 7);
+ igb_enable_sriov(pdev, max_vfs);
#endif /* CONFIG_PCI_IOV */
}
^ permalink raw reply related
* Re: [PATCH net-next 1/2] qlcnic: Implement flash sysfs callback for 83xx adapter
From: Ben Hutchings @ 2013-03-12 21:30 UTC (permalink / raw)
To: Shahed Shaikh; +Cc: davem, netdev, Dept_NX_Linux_NIC_Driver, Himanshu Madhani
In-Reply-To: <1363114937-23283-1-git-send-email-shahed.shaikh@qlogic.com>
On Tue, 2013-03-12 at 15:02 -0400, Shahed Shaikh wrote:
> From: Himanshu Madhani <himanshu.madhani@qlogic.com>
>
> QLogic applications use these callbacks to perform
>
> o NIC Partitioning (NPAR) configuration and management
> o Diagnostic tests
> o Flash access and updates
>
> Signed-off-by: Himanshu Madhani <himanshu.madhani@qlogic.com>
> Signed-off-by: Shahed Shaikh <shahed.shaikh@qlogic.com>
[...]
MTD is the standard Linux interface for raw flash devices.
Ben.
--
Ben Hutchings, Staff Engineer, Solarflare
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.
^ permalink raw reply
* [PATCH iproute2] Fix -oneline output when alias present
From: roopa @ 2013-03-12 22:03 UTC (permalink / raw)
To: shemminger, roopa; +Cc: netdev, roopa
From: roopa <roopa@cumulusnetworks.com>
This patch removes '\n' in -oneline output when alias
present on interface
Signed-off-by: Roopa Prabhu <roopa@cumulusnetworks.com>
---
ip/ipaddress.c | 6 ++++--
1 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/ip/ipaddress.c b/ip/ipaddress.c
index cff503f..fdd2a74 100644
--- a/ip/ipaddress.c
+++ b/ip/ipaddress.c
@@ -468,9 +468,11 @@ int print_linkinfo(const struct sockaddr_nl *who,
if (do_link && tb[IFLA_LINKINFO] && show_details)
print_linktype(fp, tb[IFLA_LINKINFO]);
- if (do_link && tb[IFLA_IFALIAS])
- fprintf(fp,"\n alias %s",
+ if (do_link && tb[IFLA_IFALIAS]) {
+ fprintf(fp, "%s", _SL_);
+ fprintf(fp," alias %s",
rta_getattr_str(tb[IFLA_IFALIAS]));
+ }
if (do_link && show_stats) {
if (tb[IFLA_STATS64])
--
1.7.2.5
^ permalink raw reply related
* [PATCH] net: lpc_eth: fix coccicheck warnings
From: Silviu-Mihai Popescu @ 2013-03-12 22:33 UTC (permalink / raw)
To: netdev
Cc: davem, stigge, edumazet, gregkh, jiri, linux-kernel,
Silviu-Mihai Popescu
Use resource_size() instead of explicit calculation and change the way
debugging for struct resource is done.
Signed-off-by: Silviu-Mihai Popescu <silviupopescu1990@gmail.com>
---
drivers/net/ethernet/nxp/lpc_eth.c | 7 ++-----
1 file changed, 2 insertions(+), 5 deletions(-)
diff --git a/drivers/net/ethernet/nxp/lpc_eth.c b/drivers/net/ethernet/nxp/lpc_eth.c
index c4122c8..7862f96 100644
--- a/drivers/net/ethernet/nxp/lpc_eth.c
+++ b/drivers/net/ethernet/nxp/lpc_eth.c
@@ -1362,7 +1362,7 @@ static int lpc_eth_drv_probe(struct platform_device *pdev)
__lpc_eth_clock_enable(pldat, true);
/* Map IO space */
- pldat->net_base = ioremap(res->start, res->end - res->start + 1);
+ pldat->net_base = ioremap(res->start, resource_size(res));
if (!pldat->net_base) {
dev_err(&pdev->dev, "failed to map registers\n");
ret = -ENOMEM;
@@ -1418,10 +1418,7 @@ static int lpc_eth_drv_probe(struct platform_device *pdev)
}
pldat->dma_buff_base_p = dma_handle;
- netdev_dbg(ndev, "IO address start :0x%08x\n",
- res->start);
- netdev_dbg(ndev, "IO address size :%d\n",
- res->end - res->start + 1);
+ netdev_dbg(ndev, "IO resource :%pR\n", res);
netdev_dbg(ndev, "IO address (mapped) :0x%p\n",
pldat->net_base);
netdev_dbg(ndev, "IRQ number :%d\n", ndev->irq);
--
1.7.9.5
^ permalink raw reply related
* Re: [PATCH] ethernet: nxp: use resource_size()
From: Silviu Popescu @ 2013-03-12 22:35 UTC (permalink / raw)
To: Joe Perches; +Cc: netdev, davem, stigge, edumazet, gregkh, jiri, linux-kernel
In-Reply-To: <1363115431.2125.13.camel@joe-AO722>
On Tue, Mar 12, 2013 at 9:10 PM, Joe Perches <joe@perches.com> wrote:
> On Tue, 2013-03-12 at 20:30 +0200, Silviu-Mihai Popescu wrote:
>> Use resource_size() instead of explicit calculation. This was found via
>> make coccicheck.
> []
>> diff --git a/drivers/net/ethernet/nxp/lpc_eth.c b/drivers/net/ethernet/nxp/lpc_eth.c
> []
>> @@ -1421,7 +1421,7 @@ static int lpc_eth_drv_probe(struct platform_device *pdev)
>> netdev_dbg(ndev, "IO address start :0x%08x\n",
>> res->start);
>> netdev_dbg(ndev, "IO address size :%d\n",
>> - res->end - res->start + 1);
>> + resource_size(res));
>
> This might be better as
>
> netdev_dbg(ndev, "IO resource :%pR\n", res);
>
>
Thanks for the review. I've refreshed the patch and sent it again.
--
Silviu Popescu
^ permalink raw reply
* Re: [PATCH] sctp: optimize searching the active path for tsns
From: Neil Horman @ 2013-03-13 1:20 UTC (permalink / raw)
To: Vlad Yasevich; +Cc: linux-sctp, Xufeng Zhang, davem, netdev
In-Reply-To: <513F97BE.6040800@gmail.com>
On Tue, Mar 12, 2013 at 05:01:50PM -0400, Vlad Yasevich wrote:
> Hi Neil
>
> On 03/12/2013 01:29 PM, Neil Horman wrote:
> >SCTP currently attempts to optimize the search for tsns on a transport by first
> >checking the active_path, then searching alternate transports. This operation
> >however is a bit convoluted, as we explicitly search the active path, then serch
> >all other transports, skipping the active path, when its detected. Lets
> >optimize this by preforming a move to front on the transport_addr_list every
> >time the active_path is changed. The active_path changes occur in relatively
> >non-critical paths, and doing so allows us to just search the
> >transport_addr_list in order, avoiding an extra conditional check in the
> >relatively hot tsn lookup path. This also happens to fix a bug where we break
> >out of the for loop early in the tsn lookup.
> >
> >CC: Xufeng Zhang <xufengzhang.main@gmail.com>
> >CC: vyasevich@gmail.com
> >CC: davem@davemloft.net
> >CC: netdev@vger.kernel.org
> >---
> > net/sctp/associola.c | 31 ++++++++++++-------------------
> > 1 file changed, 12 insertions(+), 19 deletions(-)
> >
> >diff --git a/net/sctp/associola.c b/net/sctp/associola.c
> >index 43cd0dd..7af96b3 100644
> >--- a/net/sctp/associola.c
> >+++ b/net/sctp/associola.c
> >@@ -513,8 +513,11 @@ void sctp_assoc_set_primary(struct sctp_association *asoc,
> > * user wants to use this new path.
> > */
> > if ((transport->state == SCTP_ACTIVE) ||
> >- (transport->state == SCTP_UNKNOWN))
> >+ (transport->state == SCTP_UNKNOWN)) {
> >+ list_del_rcu(&transport->transports);
> >+ list_add_rcu(&transport->transports, &asoc->peer.transport_addr_list);
> > asoc->peer.active_path = transport;
> >+ }
>
> What would happen if at the same time someone is walking the list
> through the proc interfaces?
>
> Since you are effectively changing the .next pointer, I think it is
> possible to get a duplicate transport output essentially corrupting
> the output.
>
It would be the case, but you're using the rcu variants of the list_add macros
at all the points where we modify the list (some of which we do at call sites
right before we call set_primary, see sctp_assoc_add_peer, where
list_add_tail_rcu also modifies a next pointer). So if this is a problem, its a
problem without this patch. In fact looking at it, our list access to
transport_addr_list is broken, as we use rcu apis to modify the list but non-rcu
apis to traverse the list. I'll need to fix that first.
> Personally, I don't think that this particular case is worth the
> optimization since we are trying to optimize a TSN search that only
> happens when ECNE chunk is received. You say that it is a hot path.
> Is ECNE really such a common occurrence?
>
Not particularly, but I'm guessing its more used than the path that switches the
active path. Plus its just more elegant, modifying the list so we don't have to
have two identical for loops in the lookup_tsn function, plus a check for the
transport that we already checked.
> Additionally, I don't think this is really an optimization as the
> current and new code do exactly the same thing:
> 1) look at active path
> 2) look at the rest of the paths
>
Thats not the optimization, its trading where we do work in the interests of
making the more used path faster (we drop an if condition, and remove some
duplicated code).
> This just makes cleaner code at the expense of list shuffling.
>
Yes, that sounds like a good trade to me. But as noted above, we probably need
to fix the transport_addr_list access first.
Neil
> -vlad
> >
> > /*
> > * SFR-CACC algorithm:
> >@@ -964,6 +967,10 @@ void sctp_assoc_control_transport(struct sctp_association *asoc,
> > }
> >
> > /* Set the active and retran transports. */
> >+ if (asoc->peer.active_path != first) {
> >+ list_del_rcu(first);
> >+ list_add_rcu(first, &asoc->peer.transport_addr_list);
> >+ }
> > asoc->peer.active_path = first;
> > asoc->peer.retran_path = second;
> > }
> >@@ -1040,7 +1047,6 @@ struct sctp_chunk *sctp_get_ecne_prepend(struct sctp_association *asoc)
> > struct sctp_transport *sctp_assoc_lookup_tsn(struct sctp_association *asoc,
> > __u32 tsn)
> > {
> >- struct sctp_transport *active;
> > struct sctp_transport *match;
> > struct sctp_transport *transport;
> > struct sctp_chunk *chunk;
> >@@ -1057,29 +1063,16 @@ struct sctp_transport *sctp_assoc_lookup_tsn(struct sctp_association *asoc,
> > * The general strategy is to search each transport's transmitted
> > * list. Return which transport this TSN lives on.
> > *
> >- * Let's be hopeful and check the active_path first.
> >- * Another optimization would be to know if there is only one
> >- * outbound path and not have to look for the TSN at all.
> >+ * Note, that sctp_assoc_set_primary does a move to front operation
> >+ * on the active_path transport, so this code implicitly checks
> >+ * the active_path first, as we most commonly expect to find our TSN
> >+ * there.
> > *
> > */
> >
> >- active = asoc->peer.active_path;
> >-
> >- list_for_each_entry(chunk, &active->transmitted,
> >- transmitted_list) {
> >-
> >- if (key == chunk->subh.data_hdr->tsn) {
> >- match = active;
> >- goto out;
> >- }
> >- }
> >-
> >- /* If not found, go search all the other transports. */
> > list_for_each_entry(transport, &asoc->peer.transport_addr_list,
> > transports) {
> >
> >- if (transport == active)
> >- break;
> > list_for_each_entry(chunk, &transport->transmitted,
> > transmitted_list) {
> > if (key == chunk->subh.data_hdr->tsn) {
> >
>
>
^ permalink raw reply
* Re: [PATCH RFC] ipv6: use stronger hash for reassembly queue hash table
From: Hannes Frederic Sowa @ 2013-03-13 1:27 UTC (permalink / raw)
To: Eric Dumazet; +Cc: netdev, yoshfuji, brouer
In-Reply-To: <1362756219.15793.240.camel@edumazet-glaptop>
[cc'ing Jesper, too]
On Fri, Mar 08, 2013 at 07:23:39AM -0800, Eric Dumazet wrote:
> On Fri, 2013-03-08 at 16:08 +0100, Hannes Frederic Sowa wrote:
> > On Fri, Mar 08, 2013 at 06:53:06AM -0800, Eric Dumazet wrote:
> > > No matter how you hash, a hacker can easily fill your defrag unit with
> > > not complete datagrams, so what's the point ?
> >
> > I want to harden reassembly logic against all fragments being put in
> > the same hash bucket because of malicious traffic and thus creating
> > long list traversals in the fragment queue hash table.
>
> Note that the long traversal was a real issue with TCP (thats why I
> introduced ipv6_addr_jhash()), as a single ehash slot could contains
> thousand of sockets.
>
> But with fragments, we should just limit the depth of any particular
> slot, and drop above a particular threshold.
[PATCH net-next RFC] inet: add max_depth to limit list length in inet_frags hash
This does implement trivial drop for fragments where the hash queue
is above some limit.
I calculate the limit as follow:
I averaged the folowing formula
max_depth = max_threshold / INETFRAGS_HASHSZ / rounded up (SKB_TRUELEN(0)
sizeof(struct ipq or struct frag_queue))
to
max_threshold >> 15
So we start with a maximum list length of 128. I think we could halve
this value to 64, but because I have no real performance data I left it
at this higher value for now.
This patch does only protect IPv6 (and not netfilter ipv6 defragmentation)
and will switch off limit checking if max_depth is zero. I'll rewrite
the check if we agree that this simple solution is the way to go (simple
drop) and will clamp the minimum value to 1 as soon as I also migrated
ipv4 and netfilter to the new sysctl handler.
When testing this patch:
Disable netfilter defragmenation for ipv6 on your machine if you test
this patch, otherwise you won't see the improvment. Machine now runs
smoothly under fragmentation dos.
Ok if I target this patch for net next time because the hashing changes
are in there already?
Signed-off-by: Hannes Frederic Sowa <hannes@stressinduktion.org>
---
include/net/inet_frag.h | 13 +++++++++++++
net/ipv4/inet_fragment.c | 25 ++++++++++++++++++++++++-
net/ipv6/reassembly.c | 6 +++++-
3 files changed, 42 insertions(+), 2 deletions(-)
diff --git a/include/net/inet_frag.h b/include/net/inet_frag.h
index 76c3fe5..9ba6ada 100644
--- a/include/net/inet_frag.h
+++ b/include/net/inet_frag.h
@@ -17,6 +17,7 @@ struct netns_frags {
int timeout;
int high_thresh;
int low_thresh;
+ int max_depth;
};
struct inet_frag_queue {
@@ -43,6 +44,11 @@ struct inet_frag_queue {
#define INETFRAGS_HASHSZ 64
+/* max_depth = max_threshold / INETFRAGS_HASHSZ / rounded up (SKB_TRUELEN(0) +
+ * sizeof(struct ipq or struct frag_queue))
+ */
+#define INETFRAGS_MAXDEPTH_SHIFT 15
+
struct inet_frags {
struct hlist_head hash[INETFRAGS_HASHSZ];
/* This rwlock is a global lock (seperate per IPv4, IPv6 and
@@ -144,4 +150,11 @@ static inline void inet_frag_lru_add(struct netns_frags *nf,
list_add_tail(&q->lru_list, &nf->lru_list);
spin_unlock(&nf->lru_lock);
}
+
+#ifdef CONFIG_SYSCTL
+int inet_frag_update_high_thresh(struct ctl_table *table, int write,
+ void __user *buffer, size_t *lenp,
+ loff_t *ppos);
+#endif
+
#endif
diff --git a/net/ipv4/inet_fragment.c b/net/ipv4/inet_fragment.c
index 245ae07..92f1fdd 100644
--- a/net/ipv4/inet_fragment.c
+++ b/net/ipv4/inet_fragment.c
@@ -277,6 +277,7 @@ struct inet_frag_queue *inet_frag_find(struct netns_frags *nf,
__releases(&f->lock)
{
struct inet_frag_queue *q;
+ int depth = 0;
hlist_for_each_entry(q, &f->hash[hash], list) {
if (q->net == nf && f->match(q, key)) {
@@ -284,9 +285,31 @@ struct inet_frag_queue *inet_frag_find(struct netns_frags *nf,
read_unlock(&f->lock);
return q;
}
+ depth++;
}
read_unlock(&f->lock);
- return inet_frag_create(nf, f, key);
+ if (!nf->max_depth || depth <= nf->max_depth)
+ return inet_frag_create(nf, f, key);
+ else
+ return NULL;
}
EXPORT_SYMBOL(inet_frag_find);
+
+#ifdef CONFIG_SYSCTL
+int inet_frag_update_high_thresh(struct ctl_table *table, int write,
+ void __user *buffer, size_t *lenp,
+ loff_t *ppos)
+{
+ int ret;
+ ret = proc_dointvec(table, write, buffer, lenp, ppos);
+
+ if (!ret && write && table->extra1) {
+ int *data = table->data;
+ int *max_depth = table->extra1;
+ *max_depth = *data >> INETFRAGS_MAXDEPTH_SHIFT;
+ }
+ return ret;
+}
+EXPORT_SYMBOL(inet_frag_update_high_thresh);
+#endif
diff --git a/net/ipv6/reassembly.c b/net/ipv6/reassembly.c
index 3c6a772..84b35f6 100644
--- a/net/ipv6/reassembly.c
+++ b/net/ipv6/reassembly.c
@@ -558,7 +558,8 @@ static struct ctl_table ip6_frags_ns_ctl_table[] = {
.data = &init_net.ipv6.frags.high_thresh,
.maxlen = sizeof(int),
.mode = 0644,
- .proc_handler = proc_dointvec
+ .proc_handler = inet_frag_update_high_thresh,
+ .extra1 = &init_net.ipv6.frags.max_depth
},
{
.procname = "ip6frag_low_thresh",
@@ -600,6 +601,7 @@ static int __net_init ip6_frags_ns_sysctl_register(struct net *net)
goto err_alloc;
table[0].data = &net->ipv6.frags.high_thresh;
+ table[0].extra1 = &net->ipv6.frags.max_depth;
table[1].data = &net->ipv6.frags.low_thresh;
table[2].data = &net->ipv6.frags.timeout;
@@ -670,6 +672,8 @@ static int __net_init ipv6_frags_init_net(struct net *net)
net->ipv6.frags.high_thresh = IPV6_FRAG_HIGH_THRESH;
net->ipv6.frags.low_thresh = IPV6_FRAG_LOW_THRESH;
net->ipv6.frags.timeout = IPV6_FRAG_TIMEOUT;
+ net->ipv6.frags.max_depth =
+ IPV6_FRAG_HIGH_THRESH >> INETFRAGS_MAXDEPTH_SHIFT;
inet_frags_init_net(&net->ipv6.frags);
--
1.8.1.4
^ permalink raw reply related
* Re: [PATCH RFC] ipv6: use stronger hash for reassembly queue hash table
From: Hannes Frederic Sowa @ 2013-03-13 1:31 UTC (permalink / raw)
To: Eric Dumazet, netdev, yoshfuji, brouer
In-Reply-To: <20130313012715.GE14801@order.stressinduktion.org>
On Wed, Mar 13, 2013 at 02:27:15AM +0100, Hannes Frederic Sowa wrote:
> Disable netfilter defragmenation for ipv6 on your machine if you test
> this patch, otherwise you won't see the improvment. Machine now runs
> smoothly under fragmentation dos.
Just to clarify:
When I wrote dos above, I actually meant a dos where the addresses have a
common ipv6_addr_hash. A simple test tool I wrote for testing is here:
https://gist.github.com/hannes/5116331
^ permalink raw reply
* [PATCH net] tg3: 5715 does not link up when autoneg off
From: Nithin Nayak Sujir @ 2013-03-13 1:32 UTC (permalink / raw)
To: davem; +Cc: netdev, marcinmiotk81, Nithin Sujir, Michael Chan
From: Nithin Sujir <nsujir@broadcom.com>
Commit d13ba512cbba7de5d55d7a3b2aae7d83c8921457 cleaned up the autoneg
advertisement by removing some dead code. One effect of this change was that
the advertisement register would not be updated if autoneg is turned off.
This exposed a bug on the 5715 device w.r.t linking. The 5715 defaults
to advertise only 10Mb Full duplex. But with autoneg disabled, it needs
the configured speed enabled in the advertisement register to link up.
This patch adds the work around to advertise all speeds on the 5715 when
autoneg is disabled.
Reported-by: Marcin Miotk <marcinmiotk81@gmail.com>
Reviewed-by: Benjamin Li <benli@broadcom.com>
Signed-off-by: Nithin Nayak Sujir <nsujir@broadcom.com>
Signed-off-by: Michael Chan <mchan@broadcom.com>
---
drivers/net/ethernet/broadcom/tg3.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c
index 93729f9..67d2663 100644
--- a/drivers/net/ethernet/broadcom/tg3.c
+++ b/drivers/net/ethernet/broadcom/tg3.c
@@ -4130,6 +4130,14 @@ static void tg3_phy_copper_begin(struct tg3 *tp)
tp->link_config.active_speed = tp->link_config.speed;
tp->link_config.active_duplex = tp->link_config.duplex;
+ if (tg3_asic_rev(tp) == ASIC_REV_5714) {
+ /* With autoneg disabled, 5715 only links up when the
+ * advertisement register has the configured speed
+ * enabled.
+ */
+ tg3_writephy(tp, MII_ADVERTISE, ADVERTISE_ALL);
+ }
+
bmcr = 0;
switch (tp->link_config.speed) {
default:
--
1.8.1.4
^ permalink raw reply related
* Re: [PATCH] sctp: optimize searching the active path for tsns
From: Vlad Yasevich @ 2013-03-13 1:43 UTC (permalink / raw)
To: Neil Horman; +Cc: linux-sctp, Xufeng Zhang, davem, netdev
In-Reply-To: <20130313012006.GA6958@hmsreliant.think-freely.org>
On 03/12/2013 09:20 PM, Neil Horman wrote:
> On Tue, Mar 12, 2013 at 05:01:50PM -0400, Vlad Yasevich wrote:
>> Hi Neil
>>
>> On 03/12/2013 01:29 PM, Neil Horman wrote:
>>> SCTP currently attempts to optimize the search for tsns on a transport by first
>>> checking the active_path, then searching alternate transports. This operation
>>> however is a bit convoluted, as we explicitly search the active path, then serch
>>> all other transports, skipping the active path, when its detected. Lets
>>> optimize this by preforming a move to front on the transport_addr_list every
>>> time the active_path is changed. The active_path changes occur in relatively
>>> non-critical paths, and doing so allows us to just search the
>>> transport_addr_list in order, avoiding an extra conditional check in the
>>> relatively hot tsn lookup path. This also happens to fix a bug where we break
>>> out of the for loop early in the tsn lookup.
>>>
>>> CC: Xufeng Zhang <xufengzhang.main@gmail.com>
>>> CC: vyasevich@gmail.com
>>> CC: davem@davemloft.net
>>> CC: netdev@vger.kernel.org
>>> ---
>>> net/sctp/associola.c | 31 ++++++++++++-------------------
>>> 1 file changed, 12 insertions(+), 19 deletions(-)
>>>
>>> diff --git a/net/sctp/associola.c b/net/sctp/associola.c
>>> index 43cd0dd..7af96b3 100644
>>> --- a/net/sctp/associola.c
>>> +++ b/net/sctp/associola.c
>>> @@ -513,8 +513,11 @@ void sctp_assoc_set_primary(struct sctp_association *asoc,
>>> * user wants to use this new path.
>>> */
>>> if ((transport->state == SCTP_ACTIVE) ||
>>> - (transport->state == SCTP_UNKNOWN))
>>> + (transport->state == SCTP_UNKNOWN)) {
>>> + list_del_rcu(&transport->transports);
>>> + list_add_rcu(&transport->transports, &asoc->peer.transport_addr_list);
>>> asoc->peer.active_path = transport;
>>> + }
>>
>> What would happen if at the same time someone is walking the list
>> through the proc interfaces?
>>
>> Since you are effectively changing the .next pointer, I think it is
>> possible to get a duplicate transport output essentially corrupting
>> the output.
>>
> It would be the case, but you're using the rcu variants of the list_add macros
> at all the points where we modify the list (some of which we do at call sites
> right before we call set_primary, see sctp_assoc_add_peer, where
> list_add_tail_rcu also modifies a next pointer). So if this is a problem, its a
> problem without this patch. In fact looking at it, our list access to
> transport_addr_list is broken, as we use rcu apis to modify the list but non-rcu
> apis to traverse the list. I'll need to fix that first.
As long as we are under lock, we don't need rcu variants for traversal.
The traversals done by the sctp_seq_ functions already use correct rcu
variants.
I don't see this as a problem right now since we either delete the
transport, or add it. We don't move it to a new location in the list.
With the move, what could happen is that while sctp_seq_ is printing
a transport, you might move it to another spot, and the when you grab
the .next pointer on the next iteration, it points to a completely
different spot.
-vlad
>
>> Personally, I don't think that this particular case is worth the
>> optimization since we are trying to optimize a TSN search that only
>> happens when ECNE chunk is received. You say that it is a hot path.
>> Is ECNE really such a common occurrence?
>>
> Not particularly, but I'm guessing its more used than the path that switches the
> active path. Plus its just more elegant, modifying the list so we don't have to
> have two identical for loops in the lookup_tsn function, plus a check for the
> transport that we already checked.
>
>> Additionally, I don't think this is really an optimization as the
>> current and new code do exactly the same thing:
>> 1) look at active path
>> 2) look at the rest of the paths
>>
> Thats not the optimization, its trading where we do work in the interests of
> making the more used path faster (we drop an if condition, and remove some
> duplicated code).
>
>> This just makes cleaner code at the expense of list shuffling.
>>
> Yes, that sounds like a good trade to me. But as noted above, we probably need
> to fix the transport_addr_list access first.
> Neil
>
>> -vlad
>>>
>>> /*
>>> * SFR-CACC algorithm:
>>> @@ -964,6 +967,10 @@ void sctp_assoc_control_transport(struct sctp_association *asoc,
>>> }
>>>
>>> /* Set the active and retran transports. */
>>> + if (asoc->peer.active_path != first) {
>>> + list_del_rcu(first);
>>> + list_add_rcu(first, &asoc->peer.transport_addr_list);
>>> + }
>>> asoc->peer.active_path = first;
>>> asoc->peer.retran_path = second;
>>> }
>>> @@ -1040,7 +1047,6 @@ struct sctp_chunk *sctp_get_ecne_prepend(struct sctp_association *asoc)
>>> struct sctp_transport *sctp_assoc_lookup_tsn(struct sctp_association *asoc,
>>> __u32 tsn)
>>> {
>>> - struct sctp_transport *active;
>>> struct sctp_transport *match;
>>> struct sctp_transport *transport;
>>> struct sctp_chunk *chunk;
>>> @@ -1057,29 +1063,16 @@ struct sctp_transport *sctp_assoc_lookup_tsn(struct sctp_association *asoc,
>>> * The general strategy is to search each transport's transmitted
>>> * list. Return which transport this TSN lives on.
>>> *
>>> - * Let's be hopeful and check the active_path first.
>>> - * Another optimization would be to know if there is only one
>>> - * outbound path and not have to look for the TSN at all.
>>> + * Note, that sctp_assoc_set_primary does a move to front operation
>>> + * on the active_path transport, so this code implicitly checks
>>> + * the active_path first, as we most commonly expect to find our TSN
>>> + * there.
>>> *
>>> */
>>>
>>> - active = asoc->peer.active_path;
>>> -
>>> - list_for_each_entry(chunk, &active->transmitted,
>>> - transmitted_list) {
>>> -
>>> - if (key == chunk->subh.data_hdr->tsn) {
>>> - match = active;
>>> - goto out;
>>> - }
>>> - }
>>> -
>>> - /* If not found, go search all the other transports. */
>>> list_for_each_entry(transport, &asoc->peer.transport_addr_list,
>>> transports) {
>>>
>>> - if (transport == active)
>>> - break;
>>> list_for_each_entry(chunk, &transport->transmitted,
>>> transmitted_list) {
>>> if (key == chunk->subh.data_hdr->tsn) {
>>>
>>
>>
^ 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