Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net: (86 commits) ipv4: fix redirect handling ping: dont increment ICMP_MIB_INERRORS sky2: fix hang in napi_disable sky2: enforce minimum ring size bonding: Don't allow mode change via sysfs with slaves present f_phonet: fix page offset of first received fragment stmmac: fix pm functions avoiding sleep on spinlock stmmac: remove spin_lock in stmmac_ioctl. stmmac: parameters auto-tuning through HW cap reg stmmac: fix advertising 1000Base capabilties for non GMII iface stmmac: use mdelay on timeout of sw reset sky2: version 1.30 sky2: used fixed RSS key sky2: reduce default Tx ring size sky2: rename up/down functions sky2: pci posting issues sky2: fix hang on shutdown (and other irq issues) r6040: fix check against MCRO_HASHEN bit in r6040_multicast_list MAINTAINERS: change email address for shemminger pch_gbe: Move #include of module.h ...
This commit is contained in:
commit
6fe4c6d466
|
@ -20,7 +20,7 @@ ip_no_pmtu_disc - BOOLEAN
|
||||||
default FALSE
|
default FALSE
|
||||||
|
|
||||||
min_pmtu - INTEGER
|
min_pmtu - INTEGER
|
||||||
default 562 - minimum discovered Path MTU
|
default 552 - minimum discovered Path MTU
|
||||||
|
|
||||||
route/max_size - INTEGER
|
route/max_size - INTEGER
|
||||||
Maximum number of routes allowed in the kernel. Increase
|
Maximum number of routes allowed in the kernel. Increase
|
||||||
|
|
|
@ -2586,7 +2586,7 @@ S: Maintained
|
||||||
F: drivers/net/ethernet/i825xx/eexpress.*
|
F: drivers/net/ethernet/i825xx/eexpress.*
|
||||||
|
|
||||||
ETHERNET BRIDGE
|
ETHERNET BRIDGE
|
||||||
M: Stephen Hemminger <shemminger@linux-foundation.org>
|
M: Stephen Hemminger <shemminger@vyatta.com>
|
||||||
L: bridge@lists.linux-foundation.org
|
L: bridge@lists.linux-foundation.org
|
||||||
L: netdev@vger.kernel.org
|
L: netdev@vger.kernel.org
|
||||||
W: http://www.linuxfoundation.org/en/Net:Bridge
|
W: http://www.linuxfoundation.org/en/Net:Bridge
|
||||||
|
@ -4473,7 +4473,7 @@ S: Supported
|
||||||
F: drivers/infiniband/hw/nes/
|
F: drivers/infiniband/hw/nes/
|
||||||
|
|
||||||
NETEM NETWORK EMULATOR
|
NETEM NETWORK EMULATOR
|
||||||
M: Stephen Hemminger <shemminger@linux-foundation.org>
|
M: Stephen Hemminger <shemminger@vyatta.com>
|
||||||
L: netem@lists.linux-foundation.org
|
L: netem@lists.linux-foundation.org
|
||||||
S: Maintained
|
S: Maintained
|
||||||
F: net/sched/sch_netem.c
|
F: net/sched/sch_netem.c
|
||||||
|
@ -5988,7 +5988,7 @@ S: Maintained
|
||||||
F: drivers/usb/misc/sisusbvga/
|
F: drivers/usb/misc/sisusbvga/
|
||||||
|
|
||||||
SKGE, SKY2 10/100/1000 GIGABIT ETHERNET DRIVERS
|
SKGE, SKY2 10/100/1000 GIGABIT ETHERNET DRIVERS
|
||||||
M: Stephen Hemminger <shemminger@linux-foundation.org>
|
M: Stephen Hemminger <shemminger@vyatta.com>
|
||||||
L: netdev@vger.kernel.org
|
L: netdev@vger.kernel.org
|
||||||
S: Maintained
|
S: Maintained
|
||||||
F: drivers/net/ethernet/marvell/sk*
|
F: drivers/net/ethernet/marvell/sk*
|
||||||
|
|
|
@ -3,7 +3,7 @@ if ETRAX_ARCH_V10
|
||||||
config ETRAX_ETHERNET
|
config ETRAX_ETHERNET
|
||||||
bool "Ethernet support"
|
bool "Ethernet support"
|
||||||
depends on ETRAX_ARCH_V10
|
depends on ETRAX_ARCH_V10
|
||||||
select NET_ETHERNET
|
select ETHERNET
|
||||||
select NET_CORE
|
select NET_CORE
|
||||||
select MII
|
select MII
|
||||||
help
|
help
|
||||||
|
|
|
@ -3,7 +3,7 @@ if ETRAX_ARCH_V32
|
||||||
config ETRAX_ETHERNET
|
config ETRAX_ETHERNET
|
||||||
bool "Ethernet support"
|
bool "Ethernet support"
|
||||||
depends on ETRAX_ARCH_V32
|
depends on ETRAX_ARCH_V32
|
||||||
select NET_ETHERNET
|
select ETHERNET
|
||||||
select NET_CORE
|
select NET_CORE
|
||||||
select MII
|
select MII
|
||||||
help
|
help
|
||||||
|
|
|
@ -100,6 +100,9 @@ static struct usb_device_id btusb_table[] = {
|
||||||
/* Canyon CN-BTU1 with HID interfaces */
|
/* Canyon CN-BTU1 with HID interfaces */
|
||||||
{ USB_DEVICE(0x0c10, 0x0000) },
|
{ USB_DEVICE(0x0c10, 0x0000) },
|
||||||
|
|
||||||
|
/* Broadcom BCM20702A0 */
|
||||||
|
{ USB_DEVICE(0x413c, 0x8197) },
|
||||||
|
|
||||||
{ } /* Terminating entry */
|
{ } /* Terminating entry */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -245,6 +245,8 @@ source "drivers/net/ethernet/Kconfig"
|
||||||
|
|
||||||
source "drivers/net/fddi/Kconfig"
|
source "drivers/net/fddi/Kconfig"
|
||||||
|
|
||||||
|
source "drivers/net/hippi/Kconfig"
|
||||||
|
|
||||||
config NET_SB1000
|
config NET_SB1000
|
||||||
tristate "General Instruments Surfboard 1000"
|
tristate "General Instruments Surfboard 1000"
|
||||||
depends on PNP
|
depends on PNP
|
||||||
|
|
|
@ -319,6 +319,13 @@ static ssize_t bonding_store_mode(struct device *d,
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (bond->slave_cnt > 0) {
|
||||||
|
pr_err("unable to update mode of %s because it has slaves.\n",
|
||||||
|
bond->dev->name);
|
||||||
|
ret = -EPERM;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
new_value = bond_parse_parm(buf, bond_mode_tbl);
|
new_value = bond_parse_parm(buf, bond_mode_tbl);
|
||||||
if (new_value < 0) {
|
if (new_value < 0) {
|
||||||
pr_err("%s: Ignoring invalid mode value %.*s.\n",
|
pr_err("%s: Ignoring invalid mode value %.*s.\n",
|
||||||
|
|
|
@ -10548,10 +10548,13 @@ do { \
|
||||||
|
|
||||||
int bnx2x_init_firmware(struct bnx2x *bp)
|
int bnx2x_init_firmware(struct bnx2x *bp)
|
||||||
{
|
{
|
||||||
const char *fw_file_name;
|
|
||||||
struct bnx2x_fw_file_hdr *fw_hdr;
|
struct bnx2x_fw_file_hdr *fw_hdr;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
|
|
||||||
|
if (!bp->firmware) {
|
||||||
|
const char *fw_file_name;
|
||||||
|
|
||||||
if (CHIP_IS_E1(bp))
|
if (CHIP_IS_E1(bp))
|
||||||
fw_file_name = FW_FILE_NAME_E1;
|
fw_file_name = FW_FILE_NAME_E1;
|
||||||
else if (CHIP_IS_E1H(bp))
|
else if (CHIP_IS_E1H(bp))
|
||||||
|
@ -10562,12 +10565,13 @@ int bnx2x_init_firmware(struct bnx2x *bp)
|
||||||
BNX2X_ERR("Unsupported chip revision\n");
|
BNX2X_ERR("Unsupported chip revision\n");
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
BNX2X_DEV_INFO("Loading %s\n", fw_file_name);
|
BNX2X_DEV_INFO("Loading %s\n", fw_file_name);
|
||||||
|
|
||||||
rc = request_firmware(&bp->firmware, fw_file_name, &bp->pdev->dev);
|
rc = request_firmware(&bp->firmware, fw_file_name,
|
||||||
|
&bp->pdev->dev);
|
||||||
if (rc) {
|
if (rc) {
|
||||||
BNX2X_ERR("Can't load firmware file %s\n", fw_file_name);
|
BNX2X_ERR("Can't load firmware file %s\n",
|
||||||
|
fw_file_name);
|
||||||
goto request_firmware_exit;
|
goto request_firmware_exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10576,6 +10580,7 @@ int bnx2x_init_firmware(struct bnx2x *bp)
|
||||||
BNX2X_ERR("Corrupt firmware file %s\n", fw_file_name);
|
BNX2X_ERR("Corrupt firmware file %s\n", fw_file_name);
|
||||||
goto request_firmware_exit;
|
goto request_firmware_exit;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fw_hdr = (struct bnx2x_fw_file_hdr *)bp->firmware->data;
|
fw_hdr = (struct bnx2x_fw_file_hdr *)bp->firmware->data;
|
||||||
|
|
||||||
|
@ -10630,6 +10635,7 @@ static void bnx2x_release_firmware(struct bnx2x *bp)
|
||||||
kfree(bp->init_ops);
|
kfree(bp->init_ops);
|
||||||
kfree(bp->init_data);
|
kfree(bp->init_data);
|
||||||
release_firmware(bp->firmware);
|
release_firmware(bp->firmware);
|
||||||
|
bp->firmware = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -10925,6 +10931,8 @@ static void __devexit bnx2x_remove_one(struct pci_dev *pdev)
|
||||||
if (bp->doorbells)
|
if (bp->doorbells)
|
||||||
iounmap(bp->doorbells);
|
iounmap(bp->doorbells);
|
||||||
|
|
||||||
|
bnx2x_release_firmware(bp);
|
||||||
|
|
||||||
bnx2x_free_mem_bp(bp);
|
bnx2x_free_mem_bp(bp);
|
||||||
|
|
||||||
free_netdev(dev);
|
free_netdev(dev);
|
||||||
|
|
|
@ -5380,7 +5380,7 @@ static int bnx2x_func_hw_init(struct bnx2x *bp,
|
||||||
rc = drv->init_fw(bp);
|
rc = drv->init_fw(bp);
|
||||||
if (rc) {
|
if (rc) {
|
||||||
BNX2X_ERR("Error loading firmware\n");
|
BNX2X_ERR("Error loading firmware\n");
|
||||||
goto fw_init_err;
|
goto init_err;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Handle the beginning of COMMON_XXX pases separatelly... */
|
/* Handle the beginning of COMMON_XXX pases separatelly... */
|
||||||
|
@ -5388,25 +5388,25 @@ static int bnx2x_func_hw_init(struct bnx2x *bp,
|
||||||
case FW_MSG_CODE_DRV_LOAD_COMMON_CHIP:
|
case FW_MSG_CODE_DRV_LOAD_COMMON_CHIP:
|
||||||
rc = bnx2x_func_init_cmn_chip(bp, drv);
|
rc = bnx2x_func_init_cmn_chip(bp, drv);
|
||||||
if (rc)
|
if (rc)
|
||||||
goto init_hw_err;
|
goto init_err;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case FW_MSG_CODE_DRV_LOAD_COMMON:
|
case FW_MSG_CODE_DRV_LOAD_COMMON:
|
||||||
rc = bnx2x_func_init_cmn(bp, drv);
|
rc = bnx2x_func_init_cmn(bp, drv);
|
||||||
if (rc)
|
if (rc)
|
||||||
goto init_hw_err;
|
goto init_err;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case FW_MSG_CODE_DRV_LOAD_PORT:
|
case FW_MSG_CODE_DRV_LOAD_PORT:
|
||||||
rc = bnx2x_func_init_port(bp, drv);
|
rc = bnx2x_func_init_port(bp, drv);
|
||||||
if (rc)
|
if (rc)
|
||||||
goto init_hw_err;
|
goto init_err;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case FW_MSG_CODE_DRV_LOAD_FUNCTION:
|
case FW_MSG_CODE_DRV_LOAD_FUNCTION:
|
||||||
rc = bnx2x_func_init_func(bp, drv);
|
rc = bnx2x_func_init_func(bp, drv);
|
||||||
if (rc)
|
if (rc)
|
||||||
goto init_hw_err;
|
goto init_err;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -5414,10 +5414,7 @@ static int bnx2x_func_hw_init(struct bnx2x *bp,
|
||||||
rc = -EINVAL;
|
rc = -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
init_hw_err:
|
init_err:
|
||||||
drv->release_fw(bp);
|
|
||||||
|
|
||||||
fw_init_err:
|
|
||||||
drv->gunzip_end(bp);
|
drv->gunzip_end(bp);
|
||||||
|
|
||||||
/* In case of success, complete the comand immediatelly: no ramrods
|
/* In case of success, complete the comand immediatelly: no ramrods
|
||||||
|
|
|
@ -7,6 +7,7 @@ config HAVE_NET_MACB
|
||||||
|
|
||||||
config NET_ATMEL
|
config NET_ATMEL
|
||||||
bool "Atmel devices"
|
bool "Atmel devices"
|
||||||
|
default y
|
||||||
depends on HAVE_NET_MACB || (ARM && ARCH_AT91RM9200)
|
depends on HAVE_NET_MACB || (ARM && ARCH_AT91RM9200)
|
||||||
---help---
|
---help---
|
||||||
If you have a network (Ethernet) card belonging to this class, say Y.
|
If you have a network (Ethernet) card belonging to this class, say Y.
|
||||||
|
|
|
@ -34,6 +34,8 @@
|
||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
#include <linux/delay.h>
|
#include <linux/delay.h>
|
||||||
#include <linux/io.h>
|
#include <linux/io.h>
|
||||||
|
#include <linux/dma-mapping.h>
|
||||||
|
#include <linux/module.h>
|
||||||
|
|
||||||
#include <asm/checksum.h>
|
#include <asm/checksum.h>
|
||||||
|
|
||||||
|
|
|
@ -50,7 +50,7 @@
|
||||||
#include "sky2.h"
|
#include "sky2.h"
|
||||||
|
|
||||||
#define DRV_NAME "sky2"
|
#define DRV_NAME "sky2"
|
||||||
#define DRV_VERSION "1.29"
|
#define DRV_VERSION "1.30"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The Yukon II chipset takes 64 bit command blocks (called list elements)
|
* The Yukon II chipset takes 64 bit command blocks (called list elements)
|
||||||
|
@ -68,7 +68,7 @@
|
||||||
#define MAX_SKB_TX_LE (2 + (sizeof(dma_addr_t)/sizeof(u32))*(MAX_SKB_FRAGS+1))
|
#define MAX_SKB_TX_LE (2 + (sizeof(dma_addr_t)/sizeof(u32))*(MAX_SKB_FRAGS+1))
|
||||||
#define TX_MIN_PENDING (MAX_SKB_TX_LE+1)
|
#define TX_MIN_PENDING (MAX_SKB_TX_LE+1)
|
||||||
#define TX_MAX_PENDING 1024
|
#define TX_MAX_PENDING 1024
|
||||||
#define TX_DEF_PENDING 127
|
#define TX_DEF_PENDING 63
|
||||||
|
|
||||||
#define TX_WATCHDOG (5 * HZ)
|
#define TX_WATCHDOG (5 * HZ)
|
||||||
#define NAPI_WEIGHT 64
|
#define NAPI_WEIGHT 64
|
||||||
|
@ -869,6 +869,7 @@ static void sky2_wol_init(struct sky2_port *sky2)
|
||||||
|
|
||||||
/* block receiver */
|
/* block receiver */
|
||||||
sky2_write8(hw, SK_REG(port, RX_GMF_CTRL_T), GMF_RST_SET);
|
sky2_write8(hw, SK_REG(port, RX_GMF_CTRL_T), GMF_RST_SET);
|
||||||
|
sky2_read32(hw, B0_CTST);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void sky2_set_tx_stfwd(struct sky2_hw *hw, unsigned port)
|
static void sky2_set_tx_stfwd(struct sky2_hw *hw, unsigned port)
|
||||||
|
@ -1274,6 +1275,14 @@ static void rx_set_checksum(struct sky2_port *sky2)
|
||||||
? BMU_ENA_RX_CHKSUM : BMU_DIS_RX_CHKSUM);
|
? BMU_ENA_RX_CHKSUM : BMU_DIS_RX_CHKSUM);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Fixed initial key as seed to RSS.
|
||||||
|
*/
|
||||||
|
static const uint32_t rss_init_key[10] = {
|
||||||
|
0x7c3351da, 0x51c5cf4e, 0x44adbdd1, 0xe8d38d18, 0x48897c43,
|
||||||
|
0xb1d60e7e, 0x6a3dd760, 0x01a2e453, 0x16f46f13, 0x1a0e7b30
|
||||||
|
};
|
||||||
|
|
||||||
/* Enable/disable receive hash calculation (RSS) */
|
/* Enable/disable receive hash calculation (RSS) */
|
||||||
static void rx_set_rss(struct net_device *dev, u32 features)
|
static void rx_set_rss(struct net_device *dev, u32 features)
|
||||||
{
|
{
|
||||||
|
@ -1289,12 +1298,9 @@ static void rx_set_rss(struct net_device *dev, u32 features)
|
||||||
|
|
||||||
/* Program RSS initial values */
|
/* Program RSS initial values */
|
||||||
if (features & NETIF_F_RXHASH) {
|
if (features & NETIF_F_RXHASH) {
|
||||||
u32 key[nkeys];
|
|
||||||
|
|
||||||
get_random_bytes(key, nkeys * sizeof(u32));
|
|
||||||
for (i = 0; i < nkeys; i++)
|
for (i = 0; i < nkeys; i++)
|
||||||
sky2_write32(hw, SK_REG(sky2->port, RSS_KEY + i * 4),
|
sky2_write32(hw, SK_REG(sky2->port, RSS_KEY + i * 4),
|
||||||
key[i]);
|
rss_init_key[i]);
|
||||||
|
|
||||||
/* Need to turn on (undocumented) flag to make hashing work */
|
/* Need to turn on (undocumented) flag to make hashing work */
|
||||||
sky2_write32(hw, SK_REG(sky2->port, RX_GMF_CTRL_T),
|
sky2_write32(hw, SK_REG(sky2->port, RX_GMF_CTRL_T),
|
||||||
|
@ -1717,6 +1723,8 @@ static int sky2_setup_irq(struct sky2_hw *hw, const char *name)
|
||||||
if (err)
|
if (err)
|
||||||
dev_err(&pdev->dev, "cannot assign irq %d\n", pdev->irq);
|
dev_err(&pdev->dev, "cannot assign irq %d\n", pdev->irq);
|
||||||
else {
|
else {
|
||||||
|
hw->flags |= SKY2_HW_IRQ_SETUP;
|
||||||
|
|
||||||
napi_enable(&hw->napi);
|
napi_enable(&hw->napi);
|
||||||
sky2_write32(hw, B0_IMSK, Y2_IS_BASE);
|
sky2_write32(hw, B0_IMSK, Y2_IS_BASE);
|
||||||
sky2_read32(hw, B0_IMSK);
|
sky2_read32(hw, B0_IMSK);
|
||||||
|
@ -1727,7 +1735,7 @@ static int sky2_setup_irq(struct sky2_hw *hw, const char *name)
|
||||||
|
|
||||||
|
|
||||||
/* Bring up network interface. */
|
/* Bring up network interface. */
|
||||||
static int sky2_up(struct net_device *dev)
|
static int sky2_open(struct net_device *dev)
|
||||||
{
|
{
|
||||||
struct sky2_port *sky2 = netdev_priv(dev);
|
struct sky2_port *sky2 = netdev_priv(dev);
|
||||||
struct sky2_hw *hw = sky2->hw;
|
struct sky2_hw *hw = sky2->hw;
|
||||||
|
@ -1747,6 +1755,11 @@ static int sky2_up(struct net_device *dev)
|
||||||
|
|
||||||
sky2_hw_up(sky2);
|
sky2_hw_up(sky2);
|
||||||
|
|
||||||
|
if (hw->chip_id == CHIP_ID_YUKON_OPT ||
|
||||||
|
hw->chip_id == CHIP_ID_YUKON_PRM ||
|
||||||
|
hw->chip_id == CHIP_ID_YUKON_OP_2)
|
||||||
|
imask |= Y2_IS_PHY_QLNK; /* enable PHY Quick Link */
|
||||||
|
|
||||||
/* Enable interrupts from phy/mac for port */
|
/* Enable interrupts from phy/mac for port */
|
||||||
imask = sky2_read32(hw, B0_IMSK);
|
imask = sky2_read32(hw, B0_IMSK);
|
||||||
imask |= portirq_msk[port];
|
imask |= portirq_msk[port];
|
||||||
|
@ -2040,6 +2053,8 @@ static void sky2_tx_reset(struct sky2_hw *hw, unsigned port)
|
||||||
|
|
||||||
sky2_write32(hw, RB_ADDR(txqaddr[port], RB_CTRL), RB_RST_SET);
|
sky2_write32(hw, RB_ADDR(txqaddr[port], RB_CTRL), RB_RST_SET);
|
||||||
sky2_write8(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_RST_SET);
|
sky2_write8(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_RST_SET);
|
||||||
|
|
||||||
|
sky2_read32(hw, B0_CTST);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void sky2_hw_down(struct sky2_port *sky2)
|
static void sky2_hw_down(struct sky2_port *sky2)
|
||||||
|
@ -2090,7 +2105,7 @@ static void sky2_hw_down(struct sky2_port *sky2)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Network shutdown */
|
/* Network shutdown */
|
||||||
static int sky2_down(struct net_device *dev)
|
static int sky2_close(struct net_device *dev)
|
||||||
{
|
{
|
||||||
struct sky2_port *sky2 = netdev_priv(dev);
|
struct sky2_port *sky2 = netdev_priv(dev);
|
||||||
struct sky2_hw *hw = sky2->hw;
|
struct sky2_hw *hw = sky2->hw;
|
||||||
|
@ -2101,15 +2116,22 @@ static int sky2_down(struct net_device *dev)
|
||||||
|
|
||||||
netif_info(sky2, ifdown, dev, "disabling interface\n");
|
netif_info(sky2, ifdown, dev, "disabling interface\n");
|
||||||
|
|
||||||
/* Disable port IRQ */
|
if (hw->ports == 1) {
|
||||||
sky2_write32(hw, B0_IMSK,
|
sky2_write32(hw, B0_IMSK, 0);
|
||||||
sky2_read32(hw, B0_IMSK) & ~portirq_msk[sky2->port]);
|
|
||||||
sky2_read32(hw, B0_IMSK);
|
sky2_read32(hw, B0_IMSK);
|
||||||
|
|
||||||
if (hw->ports == 1) {
|
|
||||||
napi_disable(&hw->napi);
|
napi_disable(&hw->napi);
|
||||||
free_irq(hw->pdev->irq, hw);
|
free_irq(hw->pdev->irq, hw);
|
||||||
|
hw->flags &= ~SKY2_HW_IRQ_SETUP;
|
||||||
} else {
|
} else {
|
||||||
|
u32 imask;
|
||||||
|
|
||||||
|
/* Disable port IRQ */
|
||||||
|
imask = sky2_read32(hw, B0_IMSK);
|
||||||
|
imask &= ~portirq_msk[sky2->port];
|
||||||
|
sky2_write32(hw, B0_IMSK, imask);
|
||||||
|
sky2_read32(hw, B0_IMSK);
|
||||||
|
|
||||||
synchronize_irq(hw->pdev->irq);
|
synchronize_irq(hw->pdev->irq);
|
||||||
napi_synchronize(&hw->napi);
|
napi_synchronize(&hw->napi);
|
||||||
}
|
}
|
||||||
|
@ -2587,7 +2609,7 @@ static inline void sky2_tx_done(struct net_device *dev, u16 last)
|
||||||
if (netif_running(dev)) {
|
if (netif_running(dev)) {
|
||||||
sky2_tx_complete(sky2, last);
|
sky2_tx_complete(sky2, last);
|
||||||
|
|
||||||
/* Wake unless it's detached, and called e.g. from sky2_down() */
|
/* Wake unless it's detached, and called e.g. from sky2_close() */
|
||||||
if (tx_avail(sky2) > MAX_SKB_TX_LE + 4)
|
if (tx_avail(sky2) > MAX_SKB_TX_LE + 4)
|
||||||
netif_wake_queue(dev);
|
netif_wake_queue(dev);
|
||||||
}
|
}
|
||||||
|
@ -3258,7 +3280,6 @@ static void sky2_reset(struct sky2_hw *hw)
|
||||||
hw->chip_id == CHIP_ID_YUKON_PRM ||
|
hw->chip_id == CHIP_ID_YUKON_PRM ||
|
||||||
hw->chip_id == CHIP_ID_YUKON_OP_2) {
|
hw->chip_id == CHIP_ID_YUKON_OP_2) {
|
||||||
u16 reg;
|
u16 reg;
|
||||||
u32 msk;
|
|
||||||
|
|
||||||
if (hw->chip_id == CHIP_ID_YUKON_OPT && hw->chip_rev == 0) {
|
if (hw->chip_id == CHIP_ID_YUKON_OPT && hw->chip_rev == 0) {
|
||||||
/* disable PCI-E PHY power down (set PHY reg 0x80, bit 7 */
|
/* disable PCI-E PHY power down (set PHY reg 0x80, bit 7 */
|
||||||
|
@ -3281,11 +3302,6 @@ static void sky2_reset(struct sky2_hw *hw)
|
||||||
sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON);
|
sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON);
|
||||||
sky2_pci_write16(hw, PSM_CONFIG_REG4, reg);
|
sky2_pci_write16(hw, PSM_CONFIG_REG4, reg);
|
||||||
|
|
||||||
/* enable PHY Quick Link */
|
|
||||||
msk = sky2_read32(hw, B0_IMSK);
|
|
||||||
msk |= Y2_IS_PHY_QLNK;
|
|
||||||
sky2_write32(hw, B0_IMSK, msk);
|
|
||||||
|
|
||||||
/* check if PSMv2 was running before */
|
/* check if PSMv2 was running before */
|
||||||
reg = sky2_pci_read16(hw, PSM_CONFIG_REG3);
|
reg = sky2_pci_read16(hw, PSM_CONFIG_REG3);
|
||||||
if (reg & PCI_EXP_LNKCTL_ASPMC)
|
if (reg & PCI_EXP_LNKCTL_ASPMC)
|
||||||
|
@ -3383,7 +3399,7 @@ static void sky2_detach(struct net_device *dev)
|
||||||
netif_tx_lock(dev);
|
netif_tx_lock(dev);
|
||||||
netif_device_detach(dev); /* stop txq */
|
netif_device_detach(dev); /* stop txq */
|
||||||
netif_tx_unlock(dev);
|
netif_tx_unlock(dev);
|
||||||
sky2_down(dev);
|
sky2_close(dev);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3393,7 +3409,7 @@ static int sky2_reattach(struct net_device *dev)
|
||||||
int err = 0;
|
int err = 0;
|
||||||
|
|
||||||
if (netif_running(dev)) {
|
if (netif_running(dev)) {
|
||||||
err = sky2_up(dev);
|
err = sky2_open(dev);
|
||||||
if (err) {
|
if (err) {
|
||||||
netdev_info(dev, "could not restart %d\n", err);
|
netdev_info(dev, "could not restart %d\n", err);
|
||||||
dev_close(dev);
|
dev_close(dev);
|
||||||
|
@ -3410,10 +3426,13 @@ static void sky2_all_down(struct sky2_hw *hw)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
if (hw->flags & SKY2_HW_IRQ_SETUP) {
|
||||||
sky2_read32(hw, B0_IMSK);
|
sky2_read32(hw, B0_IMSK);
|
||||||
sky2_write32(hw, B0_IMSK, 0);
|
sky2_write32(hw, B0_IMSK, 0);
|
||||||
|
|
||||||
synchronize_irq(hw->pdev->irq);
|
synchronize_irq(hw->pdev->irq);
|
||||||
napi_disable(&hw->napi);
|
napi_disable(&hw->napi);
|
||||||
|
}
|
||||||
|
|
||||||
for (i = 0; i < hw->ports; i++) {
|
for (i = 0; i < hw->ports; i++) {
|
||||||
struct net_device *dev = hw->dev[i];
|
struct net_device *dev = hw->dev[i];
|
||||||
|
@ -3446,12 +3465,13 @@ static void sky2_all_up(struct sky2_hw *hw)
|
||||||
netif_wake_queue(dev);
|
netif_wake_queue(dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (hw->flags & SKY2_HW_IRQ_SETUP) {
|
||||||
sky2_write32(hw, B0_IMSK, imask);
|
sky2_write32(hw, B0_IMSK, imask);
|
||||||
sky2_read32(hw, B0_IMSK);
|
sky2_read32(hw, B0_IMSK);
|
||||||
|
|
||||||
sky2_read32(hw, B0_Y2_SP_LISR);
|
sky2_read32(hw, B0_Y2_SP_LISR);
|
||||||
napi_enable(&hw->napi);
|
napi_enable(&hw->napi);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void sky2_restart(struct work_struct *work)
|
static void sky2_restart(struct work_struct *work)
|
||||||
{
|
{
|
||||||
|
@ -4071,6 +4091,16 @@ static int sky2_set_coalesce(struct net_device *dev,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Hardware is limited to min of 128 and max of 2048 for ring size
|
||||||
|
* and rounded up to next power of two
|
||||||
|
* to avoid division in modulus calclation
|
||||||
|
*/
|
||||||
|
static unsigned long roundup_ring_size(unsigned long pending)
|
||||||
|
{
|
||||||
|
return max(128ul, roundup_pow_of_two(pending+1));
|
||||||
|
}
|
||||||
|
|
||||||
static void sky2_get_ringparam(struct net_device *dev,
|
static void sky2_get_ringparam(struct net_device *dev,
|
||||||
struct ethtool_ringparam *ering)
|
struct ethtool_ringparam *ering)
|
||||||
{
|
{
|
||||||
|
@ -4098,7 +4128,7 @@ static int sky2_set_ringparam(struct net_device *dev,
|
||||||
|
|
||||||
sky2->rx_pending = ering->rx_pending;
|
sky2->rx_pending = ering->rx_pending;
|
||||||
sky2->tx_pending = ering->tx_pending;
|
sky2->tx_pending = ering->tx_pending;
|
||||||
sky2->tx_ring_size = roundup_pow_of_two(sky2->tx_pending+1);
|
sky2->tx_ring_size = roundup_ring_size(sky2->tx_pending);
|
||||||
|
|
||||||
return sky2_reattach(dev);
|
return sky2_reattach(dev);
|
||||||
}
|
}
|
||||||
|
@ -4556,7 +4586,7 @@ static int sky2_device_event(struct notifier_block *unused,
|
||||||
struct net_device *dev = ptr;
|
struct net_device *dev = ptr;
|
||||||
struct sky2_port *sky2 = netdev_priv(dev);
|
struct sky2_port *sky2 = netdev_priv(dev);
|
||||||
|
|
||||||
if (dev->netdev_ops->ndo_open != sky2_up || !sky2_debug)
|
if (dev->netdev_ops->ndo_open != sky2_open || !sky2_debug)
|
||||||
return NOTIFY_DONE;
|
return NOTIFY_DONE;
|
||||||
|
|
||||||
switch (event) {
|
switch (event) {
|
||||||
|
@ -4621,8 +4651,8 @@ static __exit void sky2_debug_cleanup(void)
|
||||||
not allowing netpoll on second port */
|
not allowing netpoll on second port */
|
||||||
static const struct net_device_ops sky2_netdev_ops[2] = {
|
static const struct net_device_ops sky2_netdev_ops[2] = {
|
||||||
{
|
{
|
||||||
.ndo_open = sky2_up,
|
.ndo_open = sky2_open,
|
||||||
.ndo_stop = sky2_down,
|
.ndo_stop = sky2_close,
|
||||||
.ndo_start_xmit = sky2_xmit_frame,
|
.ndo_start_xmit = sky2_xmit_frame,
|
||||||
.ndo_do_ioctl = sky2_ioctl,
|
.ndo_do_ioctl = sky2_ioctl,
|
||||||
.ndo_validate_addr = eth_validate_addr,
|
.ndo_validate_addr = eth_validate_addr,
|
||||||
|
@ -4638,8 +4668,8 @@ static const struct net_device_ops sky2_netdev_ops[2] = {
|
||||||
#endif
|
#endif
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.ndo_open = sky2_up,
|
.ndo_open = sky2_open,
|
||||||
.ndo_stop = sky2_down,
|
.ndo_stop = sky2_close,
|
||||||
.ndo_start_xmit = sky2_xmit_frame,
|
.ndo_start_xmit = sky2_xmit_frame,
|
||||||
.ndo_do_ioctl = sky2_ioctl,
|
.ndo_do_ioctl = sky2_ioctl,
|
||||||
.ndo_validate_addr = eth_validate_addr,
|
.ndo_validate_addr = eth_validate_addr,
|
||||||
|
@ -4692,7 +4722,7 @@ static __devinit struct net_device *sky2_init_netdev(struct sky2_hw *hw,
|
||||||
spin_lock_init(&sky2->phy_lock);
|
spin_lock_init(&sky2->phy_lock);
|
||||||
|
|
||||||
sky2->tx_pending = TX_DEF_PENDING;
|
sky2->tx_pending = TX_DEF_PENDING;
|
||||||
sky2->tx_ring_size = roundup_pow_of_two(TX_DEF_PENDING+1);
|
sky2->tx_ring_size = roundup_ring_size(TX_DEF_PENDING);
|
||||||
sky2->rx_pending = RX_DEF_PENDING;
|
sky2->rx_pending = RX_DEF_PENDING;
|
||||||
|
|
||||||
hw->dev[port] = dev;
|
hw->dev[port] = dev;
|
||||||
|
|
|
@ -2287,6 +2287,7 @@ struct sky2_hw {
|
||||||
#define SKY2_HW_RSS_BROKEN 0x00000100
|
#define SKY2_HW_RSS_BROKEN 0x00000100
|
||||||
#define SKY2_HW_VLAN_BROKEN 0x00000200
|
#define SKY2_HW_VLAN_BROKEN 0x00000200
|
||||||
#define SKY2_HW_RSS_CHKSUM 0x00000400 /* RSS requires chksum */
|
#define SKY2_HW_RSS_CHKSUM 0x00000400 /* RSS requires chksum */
|
||||||
|
#define SKY2_HW_IRQ_SETUP 0x00000800
|
||||||
|
|
||||||
u8 chip_id;
|
u8 chip_id;
|
||||||
u8 chip_rev;
|
u8 chip_rev;
|
||||||
|
|
|
@ -581,6 +581,7 @@ int mlx4_en_process_rx_cq(struct net_device *dev, struct mlx4_en_cq *cq, int bud
|
||||||
* Packet is OK - process it.
|
* Packet is OK - process it.
|
||||||
*/
|
*/
|
||||||
length = be32_to_cpu(cqe->byte_cnt);
|
length = be32_to_cpu(cqe->byte_cnt);
|
||||||
|
length -= ring->fcs_del;
|
||||||
ring->bytes += length;
|
ring->bytes += length;
|
||||||
ring->packets++;
|
ring->packets++;
|
||||||
|
|
||||||
|
@ -813,8 +814,11 @@ static int mlx4_en_config_rss_qp(struct mlx4_en_priv *priv, int qpn,
|
||||||
context->db_rec_addr = cpu_to_be64(ring->wqres.db.dma);
|
context->db_rec_addr = cpu_to_be64(ring->wqres.db.dma);
|
||||||
|
|
||||||
/* Cancel FCS removal if FW allows */
|
/* Cancel FCS removal if FW allows */
|
||||||
if (mdev->dev->caps.flags & MLX4_DEV_CAP_FLAG_FCS_KEEP)
|
if (mdev->dev->caps.flags & MLX4_DEV_CAP_FLAG_FCS_KEEP) {
|
||||||
context->param3 |= cpu_to_be32(1 << 29);
|
context->param3 |= cpu_to_be32(1 << 29);
|
||||||
|
ring->fcs_del = ETH_FCS_LEN;
|
||||||
|
} else
|
||||||
|
ring->fcs_del = 0;
|
||||||
|
|
||||||
err = mlx4_qp_to_ready(mdev->dev, &ring->wqres.mtt, context, qp, state);
|
err = mlx4_qp_to_ready(mdev->dev, &ring->wqres.mtt, context, qp, state);
|
||||||
if (err) {
|
if (err) {
|
||||||
|
|
|
@ -272,6 +272,7 @@ struct mlx4_en_rx_ring {
|
||||||
u32 prod;
|
u32 prod;
|
||||||
u32 cons;
|
u32 cons;
|
||||||
u32 buf_size;
|
u32 buf_size;
|
||||||
|
u8 fcs_del;
|
||||||
void *buf;
|
void *buf;
|
||||||
void *rx_info;
|
void *rx_info;
|
||||||
unsigned long bytes;
|
unsigned long bytes;
|
||||||
|
|
|
@ -609,7 +609,7 @@ struct nv_ethtool_str {
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct nv_ethtool_str nv_estats_str[] = {
|
static const struct nv_ethtool_str nv_estats_str[] = {
|
||||||
{ "tx_bytes" },
|
{ "tx_bytes" }, /* includes Ethernet FCS CRC */
|
||||||
{ "tx_zero_rexmt" },
|
{ "tx_zero_rexmt" },
|
||||||
{ "tx_one_rexmt" },
|
{ "tx_one_rexmt" },
|
||||||
{ "tx_many_rexmt" },
|
{ "tx_many_rexmt" },
|
||||||
|
@ -637,7 +637,7 @@ static const struct nv_ethtool_str nv_estats_str[] = {
|
||||||
/* version 2 stats */
|
/* version 2 stats */
|
||||||
{ "tx_deferral" },
|
{ "tx_deferral" },
|
||||||
{ "tx_packets" },
|
{ "tx_packets" },
|
||||||
{ "rx_bytes" },
|
{ "rx_bytes" }, /* includes Ethernet FCS CRC */
|
||||||
{ "tx_pause" },
|
{ "tx_pause" },
|
||||||
{ "rx_pause" },
|
{ "rx_pause" },
|
||||||
{ "rx_drop_frame" },
|
{ "rx_drop_frame" },
|
||||||
|
@ -649,7 +649,7 @@ static const struct nv_ethtool_str nv_estats_str[] = {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct nv_ethtool_stats {
|
struct nv_ethtool_stats {
|
||||||
u64 tx_bytes;
|
u64 tx_bytes; /* should be ifconfig->tx_bytes + 4*tx_packets */
|
||||||
u64 tx_zero_rexmt;
|
u64 tx_zero_rexmt;
|
||||||
u64 tx_one_rexmt;
|
u64 tx_one_rexmt;
|
||||||
u64 tx_many_rexmt;
|
u64 tx_many_rexmt;
|
||||||
|
@ -670,14 +670,14 @@ struct nv_ethtool_stats {
|
||||||
u64 rx_unicast;
|
u64 rx_unicast;
|
||||||
u64 rx_multicast;
|
u64 rx_multicast;
|
||||||
u64 rx_broadcast;
|
u64 rx_broadcast;
|
||||||
u64 rx_packets;
|
u64 rx_packets; /* should be ifconfig->rx_packets */
|
||||||
u64 rx_errors_total;
|
u64 rx_errors_total;
|
||||||
u64 tx_errors_total;
|
u64 tx_errors_total;
|
||||||
|
|
||||||
/* version 2 stats */
|
/* version 2 stats */
|
||||||
u64 tx_deferral;
|
u64 tx_deferral;
|
||||||
u64 tx_packets;
|
u64 tx_packets; /* should be ifconfig->tx_packets */
|
||||||
u64 rx_bytes;
|
u64 rx_bytes; /* should be ifconfig->rx_bytes + 4*rx_packets */
|
||||||
u64 tx_pause;
|
u64 tx_pause;
|
||||||
u64 rx_pause;
|
u64 rx_pause;
|
||||||
u64 rx_drop_frame;
|
u64 rx_drop_frame;
|
||||||
|
@ -1706,10 +1706,17 @@ static struct net_device_stats *nv_get_stats(struct net_device *dev)
|
||||||
if (np->driver_data & (DEV_HAS_STATISTICS_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_STATISTICS_V3)) {
|
if (np->driver_data & (DEV_HAS_STATISTICS_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_STATISTICS_V3)) {
|
||||||
nv_get_hw_stats(dev);
|
nv_get_hw_stats(dev);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Note: because HW stats are not always available and
|
||||||
|
* for consistency reasons, the following ifconfig
|
||||||
|
* stats are managed by software: rx_bytes, tx_bytes,
|
||||||
|
* rx_packets and tx_packets. The related hardware
|
||||||
|
* stats reported by ethtool should be equivalent to
|
||||||
|
* these ifconfig stats, with 4 additional bytes per
|
||||||
|
* packet (Ethernet FCS CRC).
|
||||||
|
*/
|
||||||
|
|
||||||
/* copy to net_device stats */
|
/* copy to net_device stats */
|
||||||
dev->stats.tx_packets = np->estats.tx_packets;
|
|
||||||
dev->stats.rx_bytes = np->estats.rx_bytes;
|
|
||||||
dev->stats.tx_bytes = np->estats.tx_bytes;
|
|
||||||
dev->stats.tx_fifo_errors = np->estats.tx_fifo_errors;
|
dev->stats.tx_fifo_errors = np->estats.tx_fifo_errors;
|
||||||
dev->stats.tx_carrier_errors = np->estats.tx_carrier_errors;
|
dev->stats.tx_carrier_errors = np->estats.tx_carrier_errors;
|
||||||
dev->stats.rx_crc_errors = np->estats.rx_crc_errors;
|
dev->stats.rx_crc_errors = np->estats.rx_crc_errors;
|
||||||
|
@ -2380,6 +2387,9 @@ static int nv_tx_done(struct net_device *dev, int limit)
|
||||||
if (flags & NV_TX_ERROR) {
|
if (flags & NV_TX_ERROR) {
|
||||||
if ((flags & NV_TX_RETRYERROR) && !(flags & NV_TX_RETRYCOUNT_MASK))
|
if ((flags & NV_TX_RETRYERROR) && !(flags & NV_TX_RETRYCOUNT_MASK))
|
||||||
nv_legacybackoff_reseed(dev);
|
nv_legacybackoff_reseed(dev);
|
||||||
|
} else {
|
||||||
|
dev->stats.tx_packets++;
|
||||||
|
dev->stats.tx_bytes += np->get_tx_ctx->skb->len;
|
||||||
}
|
}
|
||||||
dev_kfree_skb_any(np->get_tx_ctx->skb);
|
dev_kfree_skb_any(np->get_tx_ctx->skb);
|
||||||
np->get_tx_ctx->skb = NULL;
|
np->get_tx_ctx->skb = NULL;
|
||||||
|
@ -2390,6 +2400,9 @@ static int nv_tx_done(struct net_device *dev, int limit)
|
||||||
if (flags & NV_TX2_ERROR) {
|
if (flags & NV_TX2_ERROR) {
|
||||||
if ((flags & NV_TX2_RETRYERROR) && !(flags & NV_TX2_RETRYCOUNT_MASK))
|
if ((flags & NV_TX2_RETRYERROR) && !(flags & NV_TX2_RETRYCOUNT_MASK))
|
||||||
nv_legacybackoff_reseed(dev);
|
nv_legacybackoff_reseed(dev);
|
||||||
|
} else {
|
||||||
|
dev->stats.tx_packets++;
|
||||||
|
dev->stats.tx_bytes += np->get_tx_ctx->skb->len;
|
||||||
}
|
}
|
||||||
dev_kfree_skb_any(np->get_tx_ctx->skb);
|
dev_kfree_skb_any(np->get_tx_ctx->skb);
|
||||||
np->get_tx_ctx->skb = NULL;
|
np->get_tx_ctx->skb = NULL;
|
||||||
|
@ -2429,6 +2442,9 @@ static int nv_tx_done_optimized(struct net_device *dev, int limit)
|
||||||
else
|
else
|
||||||
nv_legacybackoff_reseed(dev);
|
nv_legacybackoff_reseed(dev);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
dev->stats.tx_packets++;
|
||||||
|
dev->stats.tx_bytes += np->get_tx_ctx->skb->len;
|
||||||
}
|
}
|
||||||
|
|
||||||
dev_kfree_skb_any(np->get_tx_ctx->skb);
|
dev_kfree_skb_any(np->get_tx_ctx->skb);
|
||||||
|
@ -2678,6 +2694,7 @@ static int nv_rx_process(struct net_device *dev, int limit)
|
||||||
skb->protocol = eth_type_trans(skb, dev);
|
skb->protocol = eth_type_trans(skb, dev);
|
||||||
napi_gro_receive(&np->napi, skb);
|
napi_gro_receive(&np->napi, skb);
|
||||||
dev->stats.rx_packets++;
|
dev->stats.rx_packets++;
|
||||||
|
dev->stats.rx_bytes += len;
|
||||||
next_pkt:
|
next_pkt:
|
||||||
if (unlikely(np->get_rx.orig++ == np->last_rx.orig))
|
if (unlikely(np->get_rx.orig++ == np->last_rx.orig))
|
||||||
np->get_rx.orig = np->first_rx.orig;
|
np->get_rx.orig = np->first_rx.orig;
|
||||||
|
@ -2761,6 +2778,7 @@ static int nv_rx_process_optimized(struct net_device *dev, int limit)
|
||||||
}
|
}
|
||||||
napi_gro_receive(&np->napi, skb);
|
napi_gro_receive(&np->napi, skb);
|
||||||
dev->stats.rx_packets++;
|
dev->stats.rx_packets++;
|
||||||
|
dev->stats.rx_bytes += len;
|
||||||
} else {
|
} else {
|
||||||
dev_kfree_skb(skb);
|
dev_kfree_skb(skb);
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,8 +18,8 @@
|
||||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <linux/module.h> /* for __MODULE_STRING */
|
|
||||||
#include "pch_gbe.h"
|
#include "pch_gbe.h"
|
||||||
|
#include <linux/module.h> /* for __MODULE_STRING */
|
||||||
|
|
||||||
#define OPTION_UNSET -1
|
#define OPTION_UNSET -1
|
||||||
#define OPTION_DISABLED 0
|
#define OPTION_DISABLED 0
|
||||||
|
|
|
@ -940,7 +940,7 @@ static void r6040_multicast_list(struct net_device *dev)
|
||||||
iowrite16(lp->mcr0, ioaddr + MCR0);
|
iowrite16(lp->mcr0, ioaddr + MCR0);
|
||||||
|
|
||||||
/* Fill the MAC hash tables with their values */
|
/* Fill the MAC hash tables with their values */
|
||||||
if (lp->mcr0 && MCR0_HASH_EN) {
|
if (lp->mcr0 & MCR0_HASH_EN) {
|
||||||
iowrite16(hash_table[0], ioaddr + MAR0);
|
iowrite16(hash_table[0], ioaddr + MAR0);
|
||||||
iowrite16(hash_table[1], ioaddr + MAR1);
|
iowrite16(hash_table[1], ioaddr + MAR1);
|
||||||
iowrite16(hash_table[2], ioaddr + MAR2);
|
iowrite16(hash_table[2], ioaddr + MAR2);
|
||||||
|
|
|
@ -1292,7 +1292,7 @@ static void __rtl8169_check_link_status(struct net_device *dev,
|
||||||
netif_carrier_off(dev);
|
netif_carrier_off(dev);
|
||||||
netif_info(tp, ifdown, dev, "link down\n");
|
netif_info(tp, ifdown, dev, "link down\n");
|
||||||
if (pm)
|
if (pm)
|
||||||
pm_schedule_suspend(&tp->pci_dev->dev, 100);
|
pm_schedule_suspend(&tp->pci_dev->dev, 5000);
|
||||||
}
|
}
|
||||||
spin_unlock_irqrestore(&tp->lock, flags);
|
spin_unlock_irqrestore(&tp->lock, flags);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1937,6 +1937,7 @@ static int __devinit smsc911x_init(struct net_device *dev)
|
||||||
{
|
{
|
||||||
struct smsc911x_data *pdata = netdev_priv(dev);
|
struct smsc911x_data *pdata = netdev_priv(dev);
|
||||||
unsigned int byte_test;
|
unsigned int byte_test;
|
||||||
|
unsigned int to = 100;
|
||||||
|
|
||||||
SMSC_TRACE(pdata, probe, "Driver Parameters:");
|
SMSC_TRACE(pdata, probe, "Driver Parameters:");
|
||||||
SMSC_TRACE(pdata, probe, "LAN base: 0x%08lX",
|
SMSC_TRACE(pdata, probe, "LAN base: 0x%08lX",
|
||||||
|
@ -1952,6 +1953,17 @@ static int __devinit smsc911x_init(struct net_device *dev)
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* poll the READY bit in PMT_CTRL. Any other access to the device is
|
||||||
|
* forbidden while this bit isn't set. Try for 100ms
|
||||||
|
*/
|
||||||
|
while (!(smsc911x_reg_read(pdata, PMT_CTRL) & PMT_CTRL_READY_) && --to)
|
||||||
|
udelay(1000);
|
||||||
|
if (to == 0) {
|
||||||
|
pr_err("Device not READY in 100ms aborting\n");
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
|
||||||
/* Check byte ordering */
|
/* Check byte ordering */
|
||||||
byte_test = smsc911x_reg_read(pdata, BYTE_TEST);
|
byte_test = smsc911x_reg_read(pdata, BYTE_TEST);
|
||||||
SMSC_TRACE(pdata, probe, "BYTE_TEST: 0x%08X", byte_test);
|
SMSC_TRACE(pdata, probe, "BYTE_TEST: 0x%08X", byte_test);
|
||||||
|
|
|
@ -39,10 +39,11 @@ static int dwmac1000_dma_init(void __iomem *ioaddr, int pbl, u32 dma_tx,
|
||||||
/* DMA SW reset */
|
/* DMA SW reset */
|
||||||
value |= DMA_BUS_MODE_SFT_RESET;
|
value |= DMA_BUS_MODE_SFT_RESET;
|
||||||
writel(value, ioaddr + DMA_BUS_MODE);
|
writel(value, ioaddr + DMA_BUS_MODE);
|
||||||
limit = 15000;
|
limit = 10;
|
||||||
while (limit--) {
|
while (limit--) {
|
||||||
if (!(readl(ioaddr + DMA_BUS_MODE) & DMA_BUS_MODE_SFT_RESET))
|
if (!(readl(ioaddr + DMA_BUS_MODE) & DMA_BUS_MODE_SFT_RESET))
|
||||||
break;
|
break;
|
||||||
|
mdelay(10);
|
||||||
}
|
}
|
||||||
if (limit < 0)
|
if (limit < 0)
|
||||||
return -EBUSY;
|
return -EBUSY;
|
||||||
|
|
|
@ -41,10 +41,11 @@ static int dwmac100_dma_init(void __iomem *ioaddr, int pbl, u32 dma_tx,
|
||||||
/* DMA SW reset */
|
/* DMA SW reset */
|
||||||
value |= DMA_BUS_MODE_SFT_RESET;
|
value |= DMA_BUS_MODE_SFT_RESET;
|
||||||
writel(value, ioaddr + DMA_BUS_MODE);
|
writel(value, ioaddr + DMA_BUS_MODE);
|
||||||
limit = 15000;
|
limit = 10;
|
||||||
while (limit--) {
|
while (limit--) {
|
||||||
if (!(readl(ioaddr + DMA_BUS_MODE) & DMA_BUS_MODE_SFT_RESET))
|
if (!(readl(ioaddr + DMA_BUS_MODE) & DMA_BUS_MODE_SFT_RESET))
|
||||||
break;
|
break;
|
||||||
|
mdelay(10);
|
||||||
}
|
}
|
||||||
if (limit < 0)
|
if (limit < 0)
|
||||||
return -EBUSY;
|
return -EBUSY;
|
||||||
|
|
|
@ -72,7 +72,6 @@ struct stmmac_priv {
|
||||||
spinlock_t lock;
|
spinlock_t lock;
|
||||||
spinlock_t tx_lock;
|
spinlock_t tx_lock;
|
||||||
int wolopts;
|
int wolopts;
|
||||||
int wolenabled;
|
|
||||||
int wol_irq;
|
int wol_irq;
|
||||||
#ifdef CONFIG_STMMAC_TIMER
|
#ifdef CONFIG_STMMAC_TIMER
|
||||||
struct stmmac_timer *tm;
|
struct stmmac_timer *tm;
|
||||||
|
@ -80,6 +79,7 @@ struct stmmac_priv {
|
||||||
struct plat_stmmacenet_data *plat;
|
struct plat_stmmacenet_data *plat;
|
||||||
struct stmmac_counters mmc;
|
struct stmmac_counters mmc;
|
||||||
struct dma_features dma_cap;
|
struct dma_features dma_cap;
|
||||||
|
int hw_cap_support;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern int stmmac_mdio_unregister(struct net_device *ndev);
|
extern int stmmac_mdio_unregister(struct net_device *ndev);
|
||||||
|
|
|
@ -430,6 +430,12 @@ static int stmmac_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
|
||||||
struct stmmac_priv *priv = netdev_priv(dev);
|
struct stmmac_priv *priv = netdev_priv(dev);
|
||||||
u32 support = WAKE_MAGIC | WAKE_UCAST;
|
u32 support = WAKE_MAGIC | WAKE_UCAST;
|
||||||
|
|
||||||
|
/* By default almost all GMAC devices support the WoL via
|
||||||
|
* magic frame but we can disable it if the HW capability
|
||||||
|
* register shows no support for pmt_magic_frame. */
|
||||||
|
if ((priv->hw_cap_support) && (!priv->dma_cap.pmt_magic_frame))
|
||||||
|
wol->wolopts &= ~WAKE_MAGIC;
|
||||||
|
|
||||||
if (!device_can_wakeup(priv->device))
|
if (!device_can_wakeup(priv->device))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
|
|
|
@ -321,12 +321,10 @@ static int stmmac_init_phy(struct net_device *dev)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Stop Advertising 1000BASE Capability if interface is not GMII */
|
/* Stop Advertising 1000BASE Capability if interface is not GMII */
|
||||||
if ((interface) && ((interface == PHY_INTERFACE_MODE_MII) ||
|
if ((interface == PHY_INTERFACE_MODE_MII) ||
|
||||||
(interface == PHY_INTERFACE_MODE_RMII))) {
|
(interface == PHY_INTERFACE_MODE_RMII))
|
||||||
phydev->supported &= (PHY_BASIC_FEATURES | SUPPORTED_Pause |
|
phydev->advertising &= ~(SUPPORTED_1000baseT_Half |
|
||||||
SUPPORTED_Asym_Pause);
|
SUPPORTED_1000baseT_Full);
|
||||||
phydev->advertising = phydev->supported;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Broken HW is sometimes missing the pull-up resistor on the
|
* Broken HW is sometimes missing the pull-up resistor on the
|
||||||
|
@ -807,8 +805,29 @@ static u32 stmmac_get_synopsys_id(struct stmmac_priv *priv)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* New GMAC chips support a new register to indicate the
|
/**
|
||||||
|
* stmmac_selec_desc_mode
|
||||||
|
* @dev : device pointer
|
||||||
|
* Description: select the Enhanced/Alternate or Normal descriptors */
|
||||||
|
static void stmmac_selec_desc_mode(struct stmmac_priv *priv)
|
||||||
|
{
|
||||||
|
if (priv->plat->enh_desc) {
|
||||||
|
pr_info(" Enhanced/Alternate descriptors\n");
|
||||||
|
priv->hw->desc = &enh_desc_ops;
|
||||||
|
} else {
|
||||||
|
pr_info(" Normal descriptors\n");
|
||||||
|
priv->hw->desc = &ndesc_ops;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* stmmac_get_hw_features
|
||||||
|
* @priv : private device pointer
|
||||||
|
* Description:
|
||||||
|
* new GMAC chip generations have a new register to indicate the
|
||||||
* presence of the optional feature/functions.
|
* presence of the optional feature/functions.
|
||||||
|
* This can be also used to override the value passed through the
|
||||||
|
* platform and necessary for old MAC10/100 and GMAC chips.
|
||||||
*/
|
*/
|
||||||
static int stmmac_get_hw_features(struct stmmac_priv *priv)
|
static int stmmac_get_hw_features(struct stmmac_priv *priv)
|
||||||
{
|
{
|
||||||
|
@ -857,8 +876,7 @@ static int stmmac_get_hw_features(struct stmmac_priv *priv)
|
||||||
priv->dma_cap.enh_desc =
|
priv->dma_cap.enh_desc =
|
||||||
(hw_cap & DMA_HW_FEAT_ENHDESSEL) >> 24;
|
(hw_cap & DMA_HW_FEAT_ENHDESSEL) >> 24;
|
||||||
|
|
||||||
} else
|
}
|
||||||
pr_debug("\tNo HW DMA feature register supported");
|
|
||||||
|
|
||||||
return hw_cap;
|
return hw_cap;
|
||||||
}
|
}
|
||||||
|
@ -913,6 +931,44 @@ static int stmmac_open(struct net_device *dev)
|
||||||
goto open_error;
|
goto open_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
stmmac_get_synopsys_id(priv);
|
||||||
|
|
||||||
|
priv->hw_cap_support = stmmac_get_hw_features(priv);
|
||||||
|
|
||||||
|
if (priv->hw_cap_support) {
|
||||||
|
pr_info(" Support DMA HW capability register");
|
||||||
|
|
||||||
|
/* We can override some gmac/dma configuration fields: e.g.
|
||||||
|
* enh_desc, tx_coe (e.g. that are passed through the
|
||||||
|
* platform) with the values from the HW capability
|
||||||
|
* register (if supported).
|
||||||
|
*/
|
||||||
|
priv->plat->enh_desc = priv->dma_cap.enh_desc;
|
||||||
|
priv->plat->tx_coe = priv->dma_cap.tx_coe;
|
||||||
|
priv->plat->pmt = priv->dma_cap.pmt_remote_wake_up;
|
||||||
|
|
||||||
|
/* By default disable wol on magic frame if not supported */
|
||||||
|
if (!priv->dma_cap.pmt_magic_frame)
|
||||||
|
priv->wolopts &= ~WAKE_MAGIC;
|
||||||
|
|
||||||
|
} else
|
||||||
|
pr_info(" No HW DMA feature register supported");
|
||||||
|
|
||||||
|
/* Select the enhnaced/normal descriptor structures */
|
||||||
|
stmmac_selec_desc_mode(priv);
|
||||||
|
|
||||||
|
/* PMT module is not integrated in all the MAC devices. */
|
||||||
|
if (priv->plat->pmt) {
|
||||||
|
pr_info(" Remote wake-up capable\n");
|
||||||
|
device_set_wakeup_capable(priv->device, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
priv->rx_coe = priv->hw->mac->rx_coe(priv->ioaddr);
|
||||||
|
if (priv->rx_coe)
|
||||||
|
pr_info(" Checksum Offload Engine supported\n");
|
||||||
|
if (priv->plat->tx_coe)
|
||||||
|
pr_info(" Checksum insertion supported\n");
|
||||||
|
|
||||||
/* Create and initialize the TX/RX descriptors chains. */
|
/* Create and initialize the TX/RX descriptors chains. */
|
||||||
priv->dma_tx_size = STMMAC_ALIGN(dma_txsize);
|
priv->dma_tx_size = STMMAC_ALIGN(dma_txsize);
|
||||||
priv->dma_rx_size = STMMAC_ALIGN(dma_rxsize);
|
priv->dma_rx_size = STMMAC_ALIGN(dma_rxsize);
|
||||||
|
@ -935,15 +991,6 @@ static int stmmac_open(struct net_device *dev)
|
||||||
/* Initialize the MAC Core */
|
/* Initialize the MAC Core */
|
||||||
priv->hw->mac->core_init(priv->ioaddr);
|
priv->hw->mac->core_init(priv->ioaddr);
|
||||||
|
|
||||||
stmmac_get_synopsys_id(priv);
|
|
||||||
|
|
||||||
stmmac_get_hw_features(priv);
|
|
||||||
|
|
||||||
priv->rx_coe = priv->hw->mac->rx_coe(priv->ioaddr);
|
|
||||||
if (priv->rx_coe)
|
|
||||||
pr_info("stmmac: Rx Checksum Offload Engine supported\n");
|
|
||||||
if (priv->plat->tx_coe)
|
|
||||||
pr_info("\tTX Checksum insertion supported\n");
|
|
||||||
netdev_update_features(dev);
|
netdev_update_features(dev);
|
||||||
|
|
||||||
/* Request the IRQ lines */
|
/* Request the IRQ lines */
|
||||||
|
@ -1489,9 +1536,7 @@ static int stmmac_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
|
||||||
if (!priv->phydev)
|
if (!priv->phydev)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
spin_lock(&priv->lock);
|
|
||||||
ret = phy_mii_ioctl(priv->phydev, rq, cmd);
|
ret = phy_mii_ioctl(priv->phydev, rq, cmd);
|
||||||
spin_unlock(&priv->lock);
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -1558,7 +1603,7 @@ static int stmmac_sysfs_dma_cap_read(struct seq_file *seq, void *v)
|
||||||
struct net_device *dev = seq->private;
|
struct net_device *dev = seq->private;
|
||||||
struct stmmac_priv *priv = netdev_priv(dev);
|
struct stmmac_priv *priv = netdev_priv(dev);
|
||||||
|
|
||||||
if (!stmmac_get_hw_features(priv)) {
|
if (!priv->hw_cap_support) {
|
||||||
seq_printf(seq, "DMA HW features not supported\n");
|
seq_printf(seq, "DMA HW features not supported\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1766,12 +1811,6 @@ static int stmmac_mac_device_setup(struct net_device *dev)
|
||||||
if (!device)
|
if (!device)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
if (priv->plat->enh_desc) {
|
|
||||||
device->desc = &enh_desc_ops;
|
|
||||||
pr_info("\tEnhanced descriptor structure\n");
|
|
||||||
} else
|
|
||||||
device->desc = &ndesc_ops;
|
|
||||||
|
|
||||||
priv->hw = device;
|
priv->hw = device;
|
||||||
priv->hw->ring = &ring_mode_ops;
|
priv->hw->ring = &ring_mode_ops;
|
||||||
|
|
||||||
|
@ -1845,11 +1884,6 @@ static int stmmac_dvr_probe(struct platform_device *pdev)
|
||||||
|
|
||||||
priv->ioaddr = addr;
|
priv->ioaddr = addr;
|
||||||
|
|
||||||
/* PMT module is not integrated in all the MAC devices. */
|
|
||||||
if (plat_dat->pmt) {
|
|
||||||
pr_info("\tPMT module supported\n");
|
|
||||||
device_set_wakeup_capable(&pdev->dev, 1);
|
|
||||||
}
|
|
||||||
/*
|
/*
|
||||||
* On some platforms e.g. SPEAr the wake up irq differs from the mac irq
|
* On some platforms e.g. SPEAr the wake up irq differs from the mac irq
|
||||||
* The external wake up irq can be passed through the platform code
|
* The external wake up irq can be passed through the platform code
|
||||||
|
@ -1862,7 +1896,6 @@ static int stmmac_dvr_probe(struct platform_device *pdev)
|
||||||
if (priv->wol_irq == -ENXIO)
|
if (priv->wol_irq == -ENXIO)
|
||||||
priv->wol_irq = ndev->irq;
|
priv->wol_irq = ndev->irq;
|
||||||
|
|
||||||
|
|
||||||
platform_set_drvdata(pdev, ndev);
|
platform_set_drvdata(pdev, ndev);
|
||||||
|
|
||||||
/* Set the I/O base addr */
|
/* Set the I/O base addr */
|
||||||
|
@ -1875,7 +1908,7 @@ static int stmmac_dvr_probe(struct platform_device *pdev)
|
||||||
goto out_free_ndev;
|
goto out_free_ndev;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* MAC HW revice detection */
|
/* MAC HW device detection */
|
||||||
ret = stmmac_mac_device_setup(ndev);
|
ret = stmmac_mac_device_setup(ndev);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto out_plat_exit;
|
goto out_plat_exit;
|
||||||
|
@ -1978,12 +2011,13 @@ static int stmmac_suspend(struct device *dev)
|
||||||
if (!ndev || !netif_running(ndev))
|
if (!ndev || !netif_running(ndev))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
if (priv->phydev)
|
||||||
|
phy_stop(priv->phydev);
|
||||||
|
|
||||||
spin_lock(&priv->lock);
|
spin_lock(&priv->lock);
|
||||||
|
|
||||||
netif_device_detach(ndev);
|
netif_device_detach(ndev);
|
||||||
netif_stop_queue(ndev);
|
netif_stop_queue(ndev);
|
||||||
if (priv->phydev)
|
|
||||||
phy_stop(priv->phydev);
|
|
||||||
|
|
||||||
#ifdef CONFIG_STMMAC_TIMER
|
#ifdef CONFIG_STMMAC_TIMER
|
||||||
priv->tm->timer_stop();
|
priv->tm->timer_stop();
|
||||||
|
@ -2041,12 +2075,13 @@ static int stmmac_resume(struct device *dev)
|
||||||
#endif
|
#endif
|
||||||
napi_enable(&priv->napi);
|
napi_enable(&priv->napi);
|
||||||
|
|
||||||
if (priv->phydev)
|
|
||||||
phy_start(priv->phydev);
|
|
||||||
|
|
||||||
netif_start_queue(ndev);
|
netif_start_queue(ndev);
|
||||||
|
|
||||||
spin_unlock(&priv->lock);
|
spin_unlock(&priv->lock);
|
||||||
|
|
||||||
|
if (priv->phydev)
|
||||||
|
phy_start(priv->phydev);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2637,7 +2637,7 @@ static int __devinit happy_meal_sbus_probe_one(struct platform_device *op, int i
|
||||||
sbus_dp = op->dev.parent->of_node;
|
sbus_dp = op->dev.parent->of_node;
|
||||||
|
|
||||||
/* We can match PCI devices too, do not accept those here. */
|
/* We can match PCI devices too, do not accept those here. */
|
||||||
if (strcmp(sbus_dp->name, "sbus"))
|
if (strcmp(sbus_dp->name, "sbus") && strcmp(sbus_dp->name, "sbi"))
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
if (is_qfe) {
|
if (is_qfe) {
|
||||||
|
|
|
@ -114,6 +114,7 @@ void temac_indirect_out32(struct temac_local *lp, int reg, u32 value)
|
||||||
return;
|
return;
|
||||||
temac_iow(lp, XTE_LSW0_OFFSET, value);
|
temac_iow(lp, XTE_LSW0_OFFSET, value);
|
||||||
temac_iow(lp, XTE_CTL0_OFFSET, CNTLREG_WRITE_ENABLE_MASK | reg);
|
temac_iow(lp, XTE_CTL0_OFFSET, CNTLREG_WRITE_ENABLE_MASK | reg);
|
||||||
|
temac_indirect_busywait(lp);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -203,6 +204,9 @@ static void temac_dma_bd_release(struct net_device *ndev)
|
||||||
struct temac_local *lp = netdev_priv(ndev);
|
struct temac_local *lp = netdev_priv(ndev);
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
/* Reset Local Link (DMA) */
|
||||||
|
lp->dma_out(lp, DMA_CONTROL_REG, DMA_CONTROL_RST);
|
||||||
|
|
||||||
for (i = 0; i < RX_BD_NUM; i++) {
|
for (i = 0; i < RX_BD_NUM; i++) {
|
||||||
if (!lp->rx_skb[i])
|
if (!lp->rx_skb[i])
|
||||||
break;
|
break;
|
||||||
|
@ -860,6 +864,8 @@ static int temac_open(struct net_device *ndev)
|
||||||
phy_start(lp->phy_dev);
|
phy_start(lp->phy_dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
temac_device_reset(ndev);
|
||||||
|
|
||||||
rc = request_irq(lp->tx_irq, ll_temac_tx_irq, 0, ndev->name, ndev);
|
rc = request_irq(lp->tx_irq, ll_temac_tx_irq, 0, ndev->name, ndev);
|
||||||
if (rc)
|
if (rc)
|
||||||
goto err_tx_irq;
|
goto err_tx_irq;
|
||||||
|
@ -867,7 +873,6 @@ static int temac_open(struct net_device *ndev)
|
||||||
if (rc)
|
if (rc)
|
||||||
goto err_rx_irq;
|
goto err_rx_irq;
|
||||||
|
|
||||||
temac_device_reset(ndev);
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
err_rx_irq:
|
err_rx_irq:
|
||||||
|
|
|
@ -36,4 +36,4 @@ config ROADRUNNER_LARGE_RINGS
|
||||||
kernel code or by user space programs. Say Y here only if you have
|
kernel code or by user space programs. Say Y here only if you have
|
||||||
the memory.
|
the memory.
|
||||||
|
|
||||||
endif /* HIPPI */
|
endif # HIPPI
|
||||||
|
|
|
@ -36,7 +36,7 @@
|
||||||
#include <linux/usb/usbnet.h>
|
#include <linux/usb/usbnet.h>
|
||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
|
|
||||||
#define DRIVER_VERSION "26-Sep-2011"
|
#define DRIVER_VERSION "08-Nov-2011"
|
||||||
#define DRIVER_NAME "asix"
|
#define DRIVER_NAME "asix"
|
||||||
|
|
||||||
/* ASIX AX8817X based USB 2.0 Ethernet Devices */
|
/* ASIX AX8817X based USB 2.0 Ethernet Devices */
|
||||||
|
@ -163,7 +163,7 @@
|
||||||
#define MARVELL_CTRL_TXDELAY 0x0002
|
#define MARVELL_CTRL_TXDELAY 0x0002
|
||||||
#define MARVELL_CTRL_RXDELAY 0x0080
|
#define MARVELL_CTRL_RXDELAY 0x0080
|
||||||
|
|
||||||
#define PHY_MODE_RTL8211CL 0x0004
|
#define PHY_MODE_RTL8211CL 0x000C
|
||||||
|
|
||||||
/* This structure cannot exceed sizeof(unsigned long [5]) AKA 20 bytes */
|
/* This structure cannot exceed sizeof(unsigned long [5]) AKA 20 bytes */
|
||||||
struct asix_data {
|
struct asix_data {
|
||||||
|
@ -652,9 +652,17 @@ static u32 asix_get_phyid(struct usbnet *dev)
|
||||||
{
|
{
|
||||||
int phy_reg;
|
int phy_reg;
|
||||||
u32 phy_id;
|
u32 phy_id;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
/* Poll for the rare case the FW or phy isn't ready yet. */
|
||||||
|
for (i = 0; i < 100; i++) {
|
||||||
phy_reg = asix_mdio_read(dev->net, dev->mii.phy_id, MII_PHYSID1);
|
phy_reg = asix_mdio_read(dev->net, dev->mii.phy_id, MII_PHYSID1);
|
||||||
if (phy_reg < 0)
|
if (phy_reg != 0 && phy_reg != 0xFFFF)
|
||||||
|
break;
|
||||||
|
mdelay(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (phy_reg <= 0 || phy_reg == 0xFFFF)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
phy_id = (phy_reg & 0xffff) << 16;
|
phy_id = (phy_reg & 0xffff) << 16;
|
||||||
|
@ -1075,7 +1083,7 @@ static const struct net_device_ops ax88772_netdev_ops = {
|
||||||
|
|
||||||
static int ax88772_bind(struct usbnet *dev, struct usb_interface *intf)
|
static int ax88772_bind(struct usbnet *dev, struct usb_interface *intf)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret, embd_phy;
|
||||||
struct asix_data *data = (struct asix_data *)&dev->data;
|
struct asix_data *data = (struct asix_data *)&dev->data;
|
||||||
u8 buf[ETH_ALEN];
|
u8 buf[ETH_ALEN];
|
||||||
u32 phyid;
|
u32 phyid;
|
||||||
|
@ -1100,16 +1108,36 @@ static int ax88772_bind(struct usbnet *dev, struct usb_interface *intf)
|
||||||
dev->mii.reg_num_mask = 0x1f;
|
dev->mii.reg_num_mask = 0x1f;
|
||||||
dev->mii.phy_id = asix_get_phy_addr(dev);
|
dev->mii.phy_id = asix_get_phy_addr(dev);
|
||||||
|
|
||||||
phyid = asix_get_phyid(dev);
|
|
||||||
dbg("PHYID=0x%08x", phyid);
|
|
||||||
|
|
||||||
dev->net->netdev_ops = &ax88772_netdev_ops;
|
dev->net->netdev_ops = &ax88772_netdev_ops;
|
||||||
dev->net->ethtool_ops = &ax88772_ethtool_ops;
|
dev->net->ethtool_ops = &ax88772_ethtool_ops;
|
||||||
|
|
||||||
ret = ax88772_reset(dev);
|
embd_phy = ((dev->mii.phy_id & 0x1f) == 0x10 ? 1 : 0);
|
||||||
|
|
||||||
|
/* Reset the PHY to normal operation mode */
|
||||||
|
ret = asix_write_cmd(dev, AX_CMD_SW_PHY_SELECT, embd_phy, 0, 0, NULL);
|
||||||
|
if (ret < 0) {
|
||||||
|
dbg("Select PHY #1 failed: %d", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = asix_sw_reset(dev, AX_SWRESET_IPPD | AX_SWRESET_PRL);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
|
msleep(150);
|
||||||
|
|
||||||
|
ret = asix_sw_reset(dev, AX_SWRESET_CLEAR);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
msleep(150);
|
||||||
|
|
||||||
|
ret = asix_sw_reset(dev, embd_phy ? AX_SWRESET_IPRL : AX_SWRESET_PRTE);
|
||||||
|
|
||||||
|
/* Read PHYID register *AFTER* the PHY was reset properly */
|
||||||
|
phyid = asix_get_phyid(dev);
|
||||||
|
dbg("PHYID=0x%08x", phyid);
|
||||||
|
|
||||||
/* Asix framing packs multiple eth frames into a 2K usb bulk transfer */
|
/* Asix framing packs multiple eth frames into a 2K usb bulk transfer */
|
||||||
if (dev->driver_info->flags & FLAG_FRAMING_AX) {
|
if (dev->driver_info->flags & FLAG_FRAMING_AX) {
|
||||||
/* hard_mtu is still the default - the device does not support
|
/* hard_mtu is still the default - the device does not support
|
||||||
|
@ -1220,6 +1248,7 @@ static int ax88178_reset(struct usbnet *dev)
|
||||||
__le16 eeprom;
|
__le16 eeprom;
|
||||||
u8 status;
|
u8 status;
|
||||||
int gpio0 = 0;
|
int gpio0 = 0;
|
||||||
|
u32 phyid;
|
||||||
|
|
||||||
asix_read_cmd(dev, AX_CMD_READ_GPIOS, 0, 0, 1, &status);
|
asix_read_cmd(dev, AX_CMD_READ_GPIOS, 0, 0, 1, &status);
|
||||||
dbg("GPIO Status: 0x%04x", status);
|
dbg("GPIO Status: 0x%04x", status);
|
||||||
|
@ -1235,12 +1264,13 @@ static int ax88178_reset(struct usbnet *dev)
|
||||||
data->ledmode = 0;
|
data->ledmode = 0;
|
||||||
gpio0 = 1;
|
gpio0 = 1;
|
||||||
} else {
|
} else {
|
||||||
data->phymode = le16_to_cpu(eeprom) & 7;
|
data->phymode = le16_to_cpu(eeprom) & 0x7F;
|
||||||
data->ledmode = le16_to_cpu(eeprom) >> 8;
|
data->ledmode = le16_to_cpu(eeprom) >> 8;
|
||||||
gpio0 = (le16_to_cpu(eeprom) & 0x80) ? 0 : 1;
|
gpio0 = (le16_to_cpu(eeprom) & 0x80) ? 0 : 1;
|
||||||
}
|
}
|
||||||
dbg("GPIO0: %d, PhyMode: %d", gpio0, data->phymode);
|
dbg("GPIO0: %d, PhyMode: %d", gpio0, data->phymode);
|
||||||
|
|
||||||
|
/* Power up external GigaPHY through AX88178 GPIO pin */
|
||||||
asix_write_gpio(dev, AX_GPIO_RSE | AX_GPIO_GPO_1 | AX_GPIO_GPO1EN, 40);
|
asix_write_gpio(dev, AX_GPIO_RSE | AX_GPIO_GPO_1 | AX_GPIO_GPO1EN, 40);
|
||||||
if ((le16_to_cpu(eeprom) >> 8) != 1) {
|
if ((le16_to_cpu(eeprom) >> 8) != 1) {
|
||||||
asix_write_gpio(dev, 0x003c, 30);
|
asix_write_gpio(dev, 0x003c, 30);
|
||||||
|
@ -1252,6 +1282,13 @@ static int ax88178_reset(struct usbnet *dev)
|
||||||
asix_write_gpio(dev, AX_GPIO_GPO1EN | AX_GPIO_GPO_1, 30);
|
asix_write_gpio(dev, AX_GPIO_GPO1EN | AX_GPIO_GPO_1, 30);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Read PHYID register *AFTER* powering up PHY */
|
||||||
|
phyid = asix_get_phyid(dev);
|
||||||
|
dbg("PHYID=0x%08x", phyid);
|
||||||
|
|
||||||
|
/* Set AX88178 to enable MII/GMII/RGMII interface for external PHY */
|
||||||
|
asix_write_cmd(dev, AX_CMD_SW_PHY_SELECT, 0, 0, 0, NULL);
|
||||||
|
|
||||||
asix_sw_reset(dev, 0);
|
asix_sw_reset(dev, 0);
|
||||||
msleep(150);
|
msleep(150);
|
||||||
|
|
||||||
|
@ -1396,7 +1433,6 @@ static int ax88178_bind(struct usbnet *dev, struct usb_interface *intf)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
u8 buf[ETH_ALEN];
|
u8 buf[ETH_ALEN];
|
||||||
u32 phyid;
|
|
||||||
struct asix_data *data = (struct asix_data *)&dev->data;
|
struct asix_data *data = (struct asix_data *)&dev->data;
|
||||||
|
|
||||||
data->eeprom_len = AX88772_EEPROM_LEN;
|
data->eeprom_len = AX88772_EEPROM_LEN;
|
||||||
|
@ -1423,12 +1459,12 @@ static int ax88178_bind(struct usbnet *dev, struct usb_interface *intf)
|
||||||
dev->net->netdev_ops = &ax88178_netdev_ops;
|
dev->net->netdev_ops = &ax88178_netdev_ops;
|
||||||
dev->net->ethtool_ops = &ax88178_ethtool_ops;
|
dev->net->ethtool_ops = &ax88178_ethtool_ops;
|
||||||
|
|
||||||
phyid = asix_get_phyid(dev);
|
/* Blink LEDS so users know driver saw dongle */
|
||||||
dbg("PHYID=0x%08x", phyid);
|
asix_sw_reset(dev, 0);
|
||||||
|
msleep(150);
|
||||||
|
|
||||||
ret = ax88178_reset(dev);
|
asix_sw_reset(dev, AX_SWRESET_PRL | AX_SWRESET_IPPD);
|
||||||
if (ret < 0)
|
msleep(150);
|
||||||
return ret;
|
|
||||||
|
|
||||||
/* Asix framing packs multiple eth frames into a 2K usb bulk transfer */
|
/* Asix framing packs multiple eth frames into a 2K usb bulk transfer */
|
||||||
if (dev->driver_info->flags & FLAG_FRAMING_AX) {
|
if (dev->driver_info->flags & FLAG_FRAMING_AX) {
|
||||||
|
|
|
@ -567,7 +567,7 @@ static const struct usb_device_id products [] = {
|
||||||
{
|
{
|
||||||
USB_DEVICE_AND_INTERFACE_INFO(0x1004, 0x61aa, USB_CLASS_COMM,
|
USB_DEVICE_AND_INTERFACE_INFO(0x1004, 0x61aa, USB_CLASS_COMM,
|
||||||
USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE),
|
USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE),
|
||||||
.driver_info = (unsigned long)&wwan_info,
|
.driver_info = 0,
|
||||||
},
|
},
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -144,10 +144,11 @@ static int vl600_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
|
||||||
}
|
}
|
||||||
|
|
||||||
frame = (struct vl600_frame_hdr *) buf->data;
|
frame = (struct vl600_frame_hdr *) buf->data;
|
||||||
/* NOTE: Should check that frame->magic == 0x53544448?
|
/* Yes, check that frame->magic == 0x53544448 (or 0x44544d48),
|
||||||
* Otherwise if we receive garbage at the beginning of the frame
|
* otherwise we may run out of memory w/a bad packet */
|
||||||
* we may end up allocating a huge buffer and saving all the
|
if (ntohl(frame->magic) != 0x53544448 &&
|
||||||
* future incoming data into it. */
|
ntohl(frame->magic) != 0x44544d48)
|
||||||
|
goto error;
|
||||||
|
|
||||||
if (buf->len < sizeof(*frame) ||
|
if (buf->len < sizeof(*frame) ||
|
||||||
buf->len != le32_to_cpup(&frame->len)) {
|
buf->len != le32_to_cpup(&frame->len)) {
|
||||||
|
@ -296,6 +297,11 @@ encapsulate:
|
||||||
* overwrite the remaining fields.
|
* overwrite the remaining fields.
|
||||||
*/
|
*/
|
||||||
packet = (struct vl600_pkt_hdr *) skb->data;
|
packet = (struct vl600_pkt_hdr *) skb->data;
|
||||||
|
/* The VL600 wants IPv6 packets to have an IPv4 ethertype
|
||||||
|
* Since this modem only supports IPv4 and IPv6, just set all
|
||||||
|
* frames to 0x0800 (ETH_P_IP)
|
||||||
|
*/
|
||||||
|
packet->h_proto = htons(ETH_P_IP);
|
||||||
memset(&packet->dummy, 0, sizeof(packet->dummy));
|
memset(&packet->dummy, 0, sizeof(packet->dummy));
|
||||||
packet->len = cpu_to_le32(orig_len);
|
packet->len = cpu_to_le32(orig_len);
|
||||||
|
|
||||||
|
@ -308,21 +314,12 @@ encapsulate:
|
||||||
if (skb->len < full_len) /* Pad */
|
if (skb->len < full_len) /* Pad */
|
||||||
skb_put(skb, full_len - skb->len);
|
skb_put(skb, full_len - skb->len);
|
||||||
|
|
||||||
/* The VL600 wants IPv6 packets to have an IPv4 ethertype
|
|
||||||
* Check if this is an IPv6 packet, and set the ethertype
|
|
||||||
* to 0x800
|
|
||||||
*/
|
|
||||||
if ((skb->data[sizeof(struct vl600_pkt_hdr *) + 0x22] & 0xf0) == 0x60) {
|
|
||||||
skb->data[sizeof(struct vl600_pkt_hdr *) + 0x20] = 0x08;
|
|
||||||
skb->data[sizeof(struct vl600_pkt_hdr *) + 0x21] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return skb;
|
return skb;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct driver_info vl600_info = {
|
static const struct driver_info vl600_info = {
|
||||||
.description = "LG VL600 modem",
|
.description = "LG VL600 modem",
|
||||||
.flags = FLAG_ETHER | FLAG_RX_ASSEMBLE,
|
.flags = FLAG_RX_ASSEMBLE | FLAG_WWAN,
|
||||||
.bind = vl600_bind,
|
.bind = vl600_bind,
|
||||||
.unbind = vl600_unbind,
|
.unbind = vl600_unbind,
|
||||||
.status = usbnet_cdc_status,
|
.status = usbnet_cdc_status,
|
||||||
|
|
|
@ -51,6 +51,7 @@
|
||||||
#define USB_VENDOR_ID_SMSC (0x0424)
|
#define USB_VENDOR_ID_SMSC (0x0424)
|
||||||
#define USB_PRODUCT_ID_LAN7500 (0x7500)
|
#define USB_PRODUCT_ID_LAN7500 (0x7500)
|
||||||
#define USB_PRODUCT_ID_LAN7505 (0x7505)
|
#define USB_PRODUCT_ID_LAN7505 (0x7505)
|
||||||
|
#define RXW_PADDING 2
|
||||||
|
|
||||||
#define check_warn(ret, fmt, args...) \
|
#define check_warn(ret, fmt, args...) \
|
||||||
({ if (ret < 0) netdev_warn(dev->net, fmt, ##args); })
|
({ if (ret < 0) netdev_warn(dev->net, fmt, ##args); })
|
||||||
|
@ -1088,13 +1089,13 @@ static int smsc75xx_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
|
||||||
|
|
||||||
memcpy(&rx_cmd_b, skb->data, sizeof(rx_cmd_b));
|
memcpy(&rx_cmd_b, skb->data, sizeof(rx_cmd_b));
|
||||||
le32_to_cpus(&rx_cmd_b);
|
le32_to_cpus(&rx_cmd_b);
|
||||||
skb_pull(skb, 4 + NET_IP_ALIGN);
|
skb_pull(skb, 4 + RXW_PADDING);
|
||||||
|
|
||||||
packet = skb->data;
|
packet = skb->data;
|
||||||
|
|
||||||
/* get the packet length */
|
/* get the packet length */
|
||||||
size = (rx_cmd_a & RX_CMD_A_LEN) - NET_IP_ALIGN;
|
size = (rx_cmd_a & RX_CMD_A_LEN) - RXW_PADDING;
|
||||||
align_count = (4 - ((size + NET_IP_ALIGN) % 4)) % 4;
|
align_count = (4 - ((size + RXW_PADDING) % 4)) % 4;
|
||||||
|
|
||||||
if (unlikely(rx_cmd_a & RX_CMD_A_RED)) {
|
if (unlikely(rx_cmd_a & RX_CMD_A_RED)) {
|
||||||
netif_dbg(dev, rx_err, dev->net,
|
netif_dbg(dev, rx_err, dev->net,
|
||||||
|
|
|
@ -254,6 +254,8 @@ ath_reg_apply_active_scan_flags(struct wiphy *wiphy,
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
sband = wiphy->bands[IEEE80211_BAND_2GHZ];
|
sband = wiphy->bands[IEEE80211_BAND_2GHZ];
|
||||||
|
if (!sband)
|
||||||
|
return;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If no country IE has been received always enable active scan
|
* If no country IE has been received always enable active scan
|
||||||
|
|
|
@ -175,6 +175,7 @@ void b43_generate_plcp_hdr(struct b43_plcp_hdr4 *plcp,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* TODO: verify if needed for SSLPN or LCN */
|
||||||
static u16 b43_generate_tx_phy_ctl1(struct b43_wldev *dev, u8 bitrate)
|
static u16 b43_generate_tx_phy_ctl1(struct b43_wldev *dev, u8 bitrate)
|
||||||
{
|
{
|
||||||
const struct b43_phy *phy = &dev->phy;
|
const struct b43_phy *phy = &dev->phy;
|
||||||
|
@ -256,6 +257,9 @@ int b43_generate_txhdr(struct b43_wldev *dev,
|
||||||
unsigned int plcp_fragment_len;
|
unsigned int plcp_fragment_len;
|
||||||
u32 mac_ctl = 0;
|
u32 mac_ctl = 0;
|
||||||
u16 phy_ctl = 0;
|
u16 phy_ctl = 0;
|
||||||
|
bool fill_phy_ctl1 = (phy->type == B43_PHYTYPE_LP ||
|
||||||
|
phy->type == B43_PHYTYPE_N ||
|
||||||
|
phy->type == B43_PHYTYPE_HT);
|
||||||
u8 extra_ft = 0;
|
u8 extra_ft = 0;
|
||||||
struct ieee80211_rate *txrate;
|
struct ieee80211_rate *txrate;
|
||||||
struct ieee80211_tx_rate *rates;
|
struct ieee80211_tx_rate *rates;
|
||||||
|
@ -531,7 +535,7 @@ int b43_generate_txhdr(struct b43_wldev *dev,
|
||||||
extra_ft |= B43_TXH_EFT_RTSFB_CCK;
|
extra_ft |= B43_TXH_EFT_RTSFB_CCK;
|
||||||
|
|
||||||
if (rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS &&
|
if (rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS &&
|
||||||
phy->type == B43_PHYTYPE_N) {
|
fill_phy_ctl1) {
|
||||||
txhdr->phy_ctl1_rts = cpu_to_le16(
|
txhdr->phy_ctl1_rts = cpu_to_le16(
|
||||||
b43_generate_tx_phy_ctl1(dev, rts_rate));
|
b43_generate_tx_phy_ctl1(dev, rts_rate));
|
||||||
txhdr->phy_ctl1_rts_fb = cpu_to_le16(
|
txhdr->phy_ctl1_rts_fb = cpu_to_le16(
|
||||||
|
@ -552,7 +556,7 @@ int b43_generate_txhdr(struct b43_wldev *dev,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (phy->type == B43_PHYTYPE_N) {
|
if (fill_phy_ctl1) {
|
||||||
txhdr->phy_ctl1 =
|
txhdr->phy_ctl1 =
|
||||||
cpu_to_le16(b43_generate_tx_phy_ctl1(dev, rate));
|
cpu_to_le16(b43_generate_tx_phy_ctl1(dev, rate));
|
||||||
txhdr->phy_ctl1_fb =
|
txhdr->phy_ctl1_fb =
|
||||||
|
@ -736,7 +740,14 @@ void b43_rx(struct b43_wldev *dev, struct sk_buff *skb, const void *_rxhdr)
|
||||||
|
|
||||||
/* Link quality statistics */
|
/* Link quality statistics */
|
||||||
switch (chanstat & B43_RX_CHAN_PHYTYPE) {
|
switch (chanstat & B43_RX_CHAN_PHYTYPE) {
|
||||||
|
case B43_PHYTYPE_HT:
|
||||||
|
/* TODO: is max the right choice? */
|
||||||
|
status.signal = max_t(__s8,
|
||||||
|
max(rxhdr->phy_ht_power0, rxhdr->phy_ht_power1),
|
||||||
|
rxhdr->phy_ht_power2);
|
||||||
|
break;
|
||||||
case B43_PHYTYPE_N:
|
case B43_PHYTYPE_N:
|
||||||
|
/* Broadcom has code for min and avg, but always uses max */
|
||||||
if (rxhdr->power0 == 16 || rxhdr->power0 == 32)
|
if (rxhdr->power0 == 16 || rxhdr->power0 == 32)
|
||||||
status.signal = max(rxhdr->power1, rxhdr->power2);
|
status.signal = max(rxhdr->power1, rxhdr->power2);
|
||||||
else
|
else
|
||||||
|
|
|
@ -249,6 +249,12 @@ struct b43_rxhdr_fw4 {
|
||||||
} __packed;
|
} __packed;
|
||||||
} __packed;
|
} __packed;
|
||||||
union {
|
union {
|
||||||
|
/* HT-PHY */
|
||||||
|
struct {
|
||||||
|
PAD_BYTES(1);
|
||||||
|
__s8 phy_ht_power0;
|
||||||
|
} __packed;
|
||||||
|
|
||||||
/* RSSI for N-PHYs */
|
/* RSSI for N-PHYs */
|
||||||
struct {
|
struct {
|
||||||
__s8 power2;
|
__s8 power2;
|
||||||
|
@ -257,7 +263,15 @@ struct b43_rxhdr_fw4 {
|
||||||
|
|
||||||
__le16 phy_status2; /* PHY RX Status 2 */
|
__le16 phy_status2; /* PHY RX Status 2 */
|
||||||
} __packed;
|
} __packed;
|
||||||
|
union {
|
||||||
|
/* HT-PHY */
|
||||||
|
struct {
|
||||||
|
__s8 phy_ht_power1;
|
||||||
|
__s8 phy_ht_power2;
|
||||||
|
} __packed;
|
||||||
|
|
||||||
__le16 phy_status3; /* PHY RX Status 3 */
|
__le16 phy_status3; /* PHY RX Status 3 */
|
||||||
|
} __packed;
|
||||||
union {
|
union {
|
||||||
/* Tested with 598.314, 644.1001 and 666.2 */
|
/* Tested with 598.314, 644.1001 and 666.2 */
|
||||||
struct {
|
struct {
|
||||||
|
|
|
@ -358,13 +358,14 @@ static uint nrxdactive(struct dma_info *di, uint h, uint t)
|
||||||
|
|
||||||
static uint _dma_ctrlflags(struct dma_info *di, uint mask, uint flags)
|
static uint _dma_ctrlflags(struct dma_info *di, uint mask, uint flags)
|
||||||
{
|
{
|
||||||
uint dmactrlflags = di->dma.dmactrlflags;
|
uint dmactrlflags;
|
||||||
|
|
||||||
if (di == NULL) {
|
if (di == NULL) {
|
||||||
DMA_ERROR(("%s: _dma_ctrlflags: NULL dma handle\n", di->name));
|
DMA_ERROR(("_dma_ctrlflags: NULL dma handle\n"));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dmactrlflags = di->dma.dmactrlflags;
|
||||||
dmactrlflags &= ~mask;
|
dmactrlflags &= ~mask;
|
||||||
dmactrlflags |= flags;
|
dmactrlflags |= flags;
|
||||||
|
|
||||||
|
|
|
@ -990,29 +990,16 @@ static int iwl_trans_tx_stop(struct iwl_trans *trans)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void iwl_trans_pcie_disable_sync_irq(struct iwl_trans *trans)
|
static void iwl_trans_pcie_stop_device(struct iwl_trans *trans)
|
||||||
{
|
{
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
struct iwl_trans_pcie *trans_pcie =
|
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
|
||||||
IWL_TRANS_GET_PCIE_TRANS(trans);
|
|
||||||
|
|
||||||
|
/* tell the device to stop sending interrupts */
|
||||||
spin_lock_irqsave(&trans->shrd->lock, flags);
|
spin_lock_irqsave(&trans->shrd->lock, flags);
|
||||||
iwl_disable_interrupts(trans);
|
iwl_disable_interrupts(trans);
|
||||||
spin_unlock_irqrestore(&trans->shrd->lock, flags);
|
spin_unlock_irqrestore(&trans->shrd->lock, flags);
|
||||||
|
|
||||||
/* wait to make sure we flush pending tasklet*/
|
|
||||||
synchronize_irq(bus(trans)->irq);
|
|
||||||
tasklet_kill(&trans_pcie->irq_tasklet);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void iwl_trans_pcie_stop_device(struct iwl_trans *trans)
|
|
||||||
{
|
|
||||||
/* stop and reset the on-board processor */
|
|
||||||
iwl_write32(bus(trans), CSR_RESET, CSR_RESET_REG_FLAG_NEVO_RESET);
|
|
||||||
|
|
||||||
/* tell the device to stop sending interrupts */
|
|
||||||
iwl_trans_pcie_disable_sync_irq(trans);
|
|
||||||
|
|
||||||
/* device going down, Stop using ICT table */
|
/* device going down, Stop using ICT table */
|
||||||
iwl_disable_ict(trans);
|
iwl_disable_ict(trans);
|
||||||
|
|
||||||
|
@ -1039,6 +1026,20 @@ static void iwl_trans_pcie_stop_device(struct iwl_trans *trans)
|
||||||
|
|
||||||
/* Stop the device, and put it in low power state */
|
/* Stop the device, and put it in low power state */
|
||||||
iwl_apm_stop(priv(trans));
|
iwl_apm_stop(priv(trans));
|
||||||
|
|
||||||
|
/* Upon stop, the APM issues an interrupt if HW RF kill is set.
|
||||||
|
* Clean again the interrupt here
|
||||||
|
*/
|
||||||
|
spin_lock_irqsave(&trans->shrd->lock, flags);
|
||||||
|
iwl_disable_interrupts(trans);
|
||||||
|
spin_unlock_irqrestore(&trans->shrd->lock, flags);
|
||||||
|
|
||||||
|
/* wait to make sure we flush pending tasklet*/
|
||||||
|
synchronize_irq(bus(trans)->irq);
|
||||||
|
tasklet_kill(&trans_pcie->irq_tasklet);
|
||||||
|
|
||||||
|
/* stop and reset the on-board processor */
|
||||||
|
iwl_write32(bus(trans), CSR_RESET, CSR_RESET_REG_FLAG_NEVO_RESET);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb,
|
static int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb,
|
||||||
|
|
|
@ -634,7 +634,7 @@ static int lbs_ret_scan(struct lbs_private *priv, unsigned long dummy,
|
||||||
if (channel &&
|
if (channel &&
|
||||||
!(channel->flags & IEEE80211_CHAN_DISABLED))
|
!(channel->flags & IEEE80211_CHAN_DISABLED))
|
||||||
cfg80211_inform_bss(wiphy, channel,
|
cfg80211_inform_bss(wiphy, channel,
|
||||||
bssid, le64_to_cpu(*(__le64 *)tsfdesc),
|
bssid, get_unaligned_le64(tsfdesc),
|
||||||
capa, intvl, ie, ielen,
|
capa, intvl, ie, ielen,
|
||||||
LBS_SCAN_RSSI_TO_MBM(rssi),
|
LBS_SCAN_RSSI_TO_MBM(rssi),
|
||||||
GFP_KERNEL);
|
GFP_KERNEL);
|
||||||
|
|
|
@ -995,6 +995,7 @@ static int if_spi_host_to_card(struct lbs_private *priv,
|
||||||
spin_unlock_irqrestore(&card->buffer_lock, flags);
|
spin_unlock_irqrestore(&card->buffer_lock, flags);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
kfree(packet);
|
||||||
netdev_err(priv->dev, "can't transfer buffer of type %d\n",
|
netdev_err(priv->dev, "can't transfer buffer of type %d\n",
|
||||||
type);
|
type);
|
||||||
err = -EINVAL;
|
err = -EINVAL;
|
||||||
|
|
|
@ -819,8 +819,10 @@ mwifiex_scan_setup_scan_config(struct mwifiex_private *priv,
|
||||||
wildcard_ssid_tlv->header.len = cpu_to_le16(
|
wildcard_ssid_tlv->header.len = cpu_to_le16(
|
||||||
(u16) (ssid_len + sizeof(wildcard_ssid_tlv->
|
(u16) (ssid_len + sizeof(wildcard_ssid_tlv->
|
||||||
max_ssid_length)));
|
max_ssid_length)));
|
||||||
wildcard_ssid_tlv->max_ssid_length =
|
|
||||||
user_scan_in->ssid_list[ssid_idx].max_len;
|
/* max_ssid_length = 0 tells firmware to perform
|
||||||
|
specific scan for the SSID filled */
|
||||||
|
wildcard_ssid_tlv->max_ssid_length = 0;
|
||||||
|
|
||||||
memcpy(wildcard_ssid_tlv->ssid,
|
memcpy(wildcard_ssid_tlv->ssid,
|
||||||
user_scan_in->ssid_list[ssid_idx].ssid,
|
user_scan_in->ssid_list[ssid_idx].ssid,
|
||||||
|
@ -1469,7 +1471,7 @@ mwifiex_update_curr_bss_params(struct mwifiex_private *priv, u8 *bssid,
|
||||||
s32 rssi, const u8 *ie_buf, size_t ie_len,
|
s32 rssi, const u8 *ie_buf, size_t ie_len,
|
||||||
u16 beacon_period, u16 cap_info_bitmap, u8 band)
|
u16 beacon_period, u16 cap_info_bitmap, u8 band)
|
||||||
{
|
{
|
||||||
struct mwifiex_bssdescriptor *bss_desc = NULL;
|
struct mwifiex_bssdescriptor *bss_desc;
|
||||||
int ret;
|
int ret;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
u8 *beacon_ie;
|
u8 *beacon_ie;
|
||||||
|
@ -1484,6 +1486,7 @@ mwifiex_update_curr_bss_params(struct mwifiex_private *priv, u8 *bssid,
|
||||||
|
|
||||||
beacon_ie = kmemdup(ie_buf, ie_len, GFP_KERNEL);
|
beacon_ie = kmemdup(ie_buf, ie_len, GFP_KERNEL);
|
||||||
if (!beacon_ie) {
|
if (!beacon_ie) {
|
||||||
|
kfree(bss_desc);
|
||||||
dev_err(priv->adapter->dev, " failed to alloc beacon_ie\n");
|
dev_err(priv->adapter->dev, " failed to alloc beacon_ie\n");
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
|
@ -919,6 +919,7 @@ static struct usb_device_id rt2800usb_device_table[] = {
|
||||||
{ USB_DEVICE(0x050d, 0x935b) },
|
{ USB_DEVICE(0x050d, 0x935b) },
|
||||||
/* Buffalo */
|
/* Buffalo */
|
||||||
{ USB_DEVICE(0x0411, 0x00e8) },
|
{ USB_DEVICE(0x0411, 0x00e8) },
|
||||||
|
{ USB_DEVICE(0x0411, 0x0158) },
|
||||||
{ USB_DEVICE(0x0411, 0x016f) },
|
{ USB_DEVICE(0x0411, 0x016f) },
|
||||||
{ USB_DEVICE(0x0411, 0x01a2) },
|
{ USB_DEVICE(0x0411, 0x01a2) },
|
||||||
/* Corega */
|
/* Corega */
|
||||||
|
|
|
@ -943,6 +943,7 @@ struct rt2x00_dev {
|
||||||
* Powersaving work
|
* Powersaving work
|
||||||
*/
|
*/
|
||||||
struct delayed_work autowakeup_work;
|
struct delayed_work autowakeup_work;
|
||||||
|
struct work_struct sleep_work;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Data queue arrays for RX, TX, Beacon and ATIM.
|
* Data queue arrays for RX, TX, Beacon and ATIM.
|
||||||
|
|
|
@ -465,6 +465,23 @@ static u8 *rt2x00lib_find_ie(u8 *data, unsigned int len, u8 ie)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void rt2x00lib_sleep(struct work_struct *work)
|
||||||
|
{
|
||||||
|
struct rt2x00_dev *rt2x00dev =
|
||||||
|
container_of(work, struct rt2x00_dev, sleep_work);
|
||||||
|
|
||||||
|
if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags))
|
||||||
|
return;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check again is powersaving is enabled, to prevent races from delayed
|
||||||
|
* work execution.
|
||||||
|
*/
|
||||||
|
if (!test_bit(CONFIG_POWERSAVING, &rt2x00dev->flags))
|
||||||
|
rt2x00lib_config(rt2x00dev, &rt2x00dev->hw->conf,
|
||||||
|
IEEE80211_CONF_CHANGE_PS);
|
||||||
|
}
|
||||||
|
|
||||||
static void rt2x00lib_rxdone_check_ps(struct rt2x00_dev *rt2x00dev,
|
static void rt2x00lib_rxdone_check_ps(struct rt2x00_dev *rt2x00dev,
|
||||||
struct sk_buff *skb,
|
struct sk_buff *skb,
|
||||||
struct rxdone_entry_desc *rxdesc)
|
struct rxdone_entry_desc *rxdesc)
|
||||||
|
@ -512,8 +529,7 @@ static void rt2x00lib_rxdone_check_ps(struct rt2x00_dev *rt2x00dev,
|
||||||
cam |= (tim_ie->bitmap_ctrl & 0x01);
|
cam |= (tim_ie->bitmap_ctrl & 0x01);
|
||||||
|
|
||||||
if (!cam && !test_bit(CONFIG_POWERSAVING, &rt2x00dev->flags))
|
if (!cam && !test_bit(CONFIG_POWERSAVING, &rt2x00dev->flags))
|
||||||
rt2x00lib_config(rt2x00dev, &rt2x00dev->hw->conf,
|
queue_work(rt2x00dev->workqueue, &rt2x00dev->sleep_work);
|
||||||
IEEE80211_CONF_CHANGE_PS);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int rt2x00lib_rxdone_read_signal(struct rt2x00_dev *rt2x00dev,
|
static int rt2x00lib_rxdone_read_signal(struct rt2x00_dev *rt2x00dev,
|
||||||
|
@ -1141,6 +1157,7 @@ int rt2x00lib_probe_dev(struct rt2x00_dev *rt2x00dev)
|
||||||
|
|
||||||
INIT_WORK(&rt2x00dev->intf_work, rt2x00lib_intf_scheduled);
|
INIT_WORK(&rt2x00dev->intf_work, rt2x00lib_intf_scheduled);
|
||||||
INIT_DELAYED_WORK(&rt2x00dev->autowakeup_work, rt2x00lib_autowakeup);
|
INIT_DELAYED_WORK(&rt2x00dev->autowakeup_work, rt2x00lib_autowakeup);
|
||||||
|
INIT_WORK(&rt2x00dev->sleep_work, rt2x00lib_sleep);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Let the driver probe the device to detect the capabilities.
|
* Let the driver probe the device to detect the capabilities.
|
||||||
|
@ -1197,6 +1214,7 @@ void rt2x00lib_remove_dev(struct rt2x00_dev *rt2x00dev)
|
||||||
*/
|
*/
|
||||||
cancel_work_sync(&rt2x00dev->intf_work);
|
cancel_work_sync(&rt2x00dev->intf_work);
|
||||||
cancel_delayed_work_sync(&rt2x00dev->autowakeup_work);
|
cancel_delayed_work_sync(&rt2x00dev->autowakeup_work);
|
||||||
|
cancel_work_sync(&rt2x00dev->sleep_work);
|
||||||
if (rt2x00_is_usb(rt2x00dev)) {
|
if (rt2x00_is_usb(rt2x00dev)) {
|
||||||
del_timer_sync(&rt2x00dev->txstatus_timer);
|
del_timer_sync(&rt2x00dev->txstatus_timer);
|
||||||
cancel_work_sync(&rt2x00dev->rxdone_work);
|
cancel_work_sync(&rt2x00dev->rxdone_work);
|
||||||
|
|
|
@ -559,7 +559,7 @@ wl12xx_scan_sched_scan_ssid_list(struct wl1271 *wl,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
/* Fail if SSID isn't present in the filters */
|
/* Fail if SSID isn't present in the filters */
|
||||||
if (j == req->n_ssids) {
|
if (j == cmd->n_ssids) {
|
||||||
ret = -EINVAL;
|
ret = -EINVAL;
|
||||||
goto out_free;
|
goto out_free;
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@ menu "S/390 network device drivers"
|
||||||
config LCS
|
config LCS
|
||||||
def_tristate m
|
def_tristate m
|
||||||
prompt "Lan Channel Station Interface"
|
prompt "Lan Channel Station Interface"
|
||||||
depends on CCW && NETDEVICES && (NET_ETHERNET || TR || FDDI)
|
depends on CCW && NETDEVICES && (ETHERNET || TR || FDDI)
|
||||||
help
|
help
|
||||||
Select this option if you want to use LCS networking on IBM System z.
|
Select this option if you want to use LCS networking on IBM System z.
|
||||||
This device driver supports Token Ring (IEEE 802.5),
|
This device driver supports Token Ring (IEEE 802.5),
|
||||||
|
|
|
@ -50,7 +50,7 @@
|
||||||
#include "lcs.h"
|
#include "lcs.h"
|
||||||
|
|
||||||
|
|
||||||
#if !defined(CONFIG_NET_ETHERNET) && \
|
#if !defined(CONFIG_ETHERNET) && \
|
||||||
!defined(CONFIG_TR) && !defined(CONFIG_FDDI)
|
!defined(CONFIG_TR) && !defined(CONFIG_FDDI)
|
||||||
#error Cannot compile lcs.c without some net devices switched on.
|
#error Cannot compile lcs.c without some net devices switched on.
|
||||||
#endif
|
#endif
|
||||||
|
@ -1634,7 +1634,7 @@ lcs_startlan_auto(struct lcs_card *card)
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
LCS_DBF_TEXT(2, trace, "strtauto");
|
LCS_DBF_TEXT(2, trace, "strtauto");
|
||||||
#ifdef CONFIG_NET_ETHERNET
|
#ifdef CONFIG_ETHERNET
|
||||||
card->lan_type = LCS_FRAME_TYPE_ENET;
|
card->lan_type = LCS_FRAME_TYPE_ENET;
|
||||||
rc = lcs_send_startlan(card, LCS_INITIATOR_TCPIP);
|
rc = lcs_send_startlan(card, LCS_INITIATOR_TCPIP);
|
||||||
if (rc == 0)
|
if (rc == 0)
|
||||||
|
@ -2166,7 +2166,7 @@ lcs_new_device(struct ccwgroup_device *ccwgdev)
|
||||||
goto netdev_out;
|
goto netdev_out;
|
||||||
}
|
}
|
||||||
switch (card->lan_type) {
|
switch (card->lan_type) {
|
||||||
#ifdef CONFIG_NET_ETHERNET
|
#ifdef CONFIG_ETHERNET
|
||||||
case LCS_FRAME_TYPE_ENET:
|
case LCS_FRAME_TYPE_ENET:
|
||||||
card->lan_type_trans = eth_type_trans;
|
card->lan_type_trans = eth_type_trans;
|
||||||
dev = alloc_etherdev(0);
|
dev = alloc_etherdev(0);
|
||||||
|
|
|
@ -1994,6 +1994,8 @@ static struct net_device *netiucv_init_netdevice(char *username)
|
||||||
netiucv_setup_netdevice);
|
netiucv_setup_netdevice);
|
||||||
if (!dev)
|
if (!dev)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
if (dev_alloc_name(dev, dev->name) < 0)
|
||||||
|
goto out_netdev;
|
||||||
|
|
||||||
privptr = netdev_priv(dev);
|
privptr = netdev_priv(dev);
|
||||||
privptr->fsm = init_fsm("netiucvdev", dev_state_names,
|
privptr->fsm = init_fsm("netiucvdev", dev_state_names,
|
||||||
|
|
|
@ -236,8 +236,7 @@ static inline int qeth_is_ipa_enabled(struct qeth_ipa_info *ipa,
|
||||||
#define QETH_IN_BUF_COUNT_MAX 128
|
#define QETH_IN_BUF_COUNT_MAX 128
|
||||||
#define QETH_MAX_BUFFER_ELEMENTS(card) ((card)->qdio.in_buf_size >> 12)
|
#define QETH_MAX_BUFFER_ELEMENTS(card) ((card)->qdio.in_buf_size >> 12)
|
||||||
#define QETH_IN_BUF_REQUEUE_THRESHOLD(card) \
|
#define QETH_IN_BUF_REQUEUE_THRESHOLD(card) \
|
||||||
((card)->ssqd.qdioac1 & AC1_SIGA_INPUT_NEEDED ? 1 : \
|
((card)->qdio.in_buf_pool.buf_count / 2)
|
||||||
((card)->qdio.in_buf_pool.buf_count / 2))
|
|
||||||
|
|
||||||
/* buffers we have to be behind before we get a PCI */
|
/* buffers we have to be behind before we get a PCI */
|
||||||
#define QETH_PCI_THRESHOLD_A(card) ((card)->qdio.in_buf_pool.buf_count+1)
|
#define QETH_PCI_THRESHOLD_A(card) ((card)->qdio.in_buf_pool.buf_count+1)
|
||||||
|
|
|
@ -881,7 +881,6 @@ EXPORT_SYMBOL_GPL(qeth_do_run_thread);
|
||||||
void qeth_schedule_recovery(struct qeth_card *card)
|
void qeth_schedule_recovery(struct qeth_card *card)
|
||||||
{
|
{
|
||||||
QETH_CARD_TEXT(card, 2, "startrec");
|
QETH_CARD_TEXT(card, 2, "startrec");
|
||||||
WARN_ON(1);
|
|
||||||
if (qeth_set_thread_start_bit(card, QETH_RECOVER_THREAD) == 0)
|
if (qeth_set_thread_start_bit(card, QETH_RECOVER_THREAD) == 0)
|
||||||
schedule_work(&card->kernel_thread_starter);
|
schedule_work(&card->kernel_thread_starter);
|
||||||
}
|
}
|
||||||
|
|
|
@ -2756,11 +2756,13 @@ int inline qeth_l3_get_cast_type(struct qeth_card *card, struct sk_buff *skb)
|
||||||
struct neighbour *n = NULL;
|
struct neighbour *n = NULL;
|
||||||
struct dst_entry *dst;
|
struct dst_entry *dst;
|
||||||
|
|
||||||
|
rcu_read_lock();
|
||||||
dst = skb_dst(skb);
|
dst = skb_dst(skb);
|
||||||
if (dst)
|
if (dst)
|
||||||
n = dst_get_neighbour(dst);
|
n = dst_get_neighbour(dst);
|
||||||
if (n) {
|
if (n) {
|
||||||
cast_type = n->type;
|
cast_type = n->type;
|
||||||
|
rcu_read_unlock();
|
||||||
if ((cast_type == RTN_BROADCAST) ||
|
if ((cast_type == RTN_BROADCAST) ||
|
||||||
(cast_type == RTN_MULTICAST) ||
|
(cast_type == RTN_MULTICAST) ||
|
||||||
(cast_type == RTN_ANYCAST))
|
(cast_type == RTN_ANYCAST))
|
||||||
|
@ -2768,6 +2770,8 @@ int inline qeth_l3_get_cast_type(struct qeth_card *card, struct sk_buff *skb)
|
||||||
else
|
else
|
||||||
return RTN_UNSPEC;
|
return RTN_UNSPEC;
|
||||||
}
|
}
|
||||||
|
rcu_read_unlock();
|
||||||
|
|
||||||
/* try something else */
|
/* try something else */
|
||||||
if (skb->protocol == ETH_P_IPV6)
|
if (skb->protocol == ETH_P_IPV6)
|
||||||
return (skb_network_header(skb)[24] == 0xff) ?
|
return (skb_network_header(skb)[24] == 0xff) ?
|
||||||
|
@ -2847,6 +2851,8 @@ static void qeth_l3_fill_header(struct qeth_card *card, struct qeth_hdr *hdr,
|
||||||
}
|
}
|
||||||
|
|
||||||
hdr->hdr.l3.length = skb->len - sizeof(struct qeth_hdr);
|
hdr->hdr.l3.length = skb->len - sizeof(struct qeth_hdr);
|
||||||
|
|
||||||
|
rcu_read_lock();
|
||||||
dst = skb_dst(skb);
|
dst = skb_dst(skb);
|
||||||
if (dst)
|
if (dst)
|
||||||
n = dst_get_neighbour(dst);
|
n = dst_get_neighbour(dst);
|
||||||
|
@ -2893,6 +2899,7 @@ static void qeth_l3_fill_header(struct qeth_card *card, struct qeth_hdr *hdr,
|
||||||
QETH_CAST_UNICAST | QETH_HDR_PASSTHRU;
|
QETH_CAST_UNICAST | QETH_HDR_PASSTHRU;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
rcu_read_unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void qeth_l3_hdr_csum(struct qeth_card *card,
|
static inline void qeth_l3_hdr_csum(struct qeth_card *card,
|
||||||
|
|
|
@ -335,10 +335,10 @@ static ssize_t qeth_l3_dev_sniffer_store(struct device *dev,
|
||||||
QETH_IN_BUF_COUNT_MAX)
|
QETH_IN_BUF_COUNT_MAX)
|
||||||
qeth_realloc_buffer_pool(card,
|
qeth_realloc_buffer_pool(card,
|
||||||
QETH_IN_BUF_COUNT_MAX);
|
QETH_IN_BUF_COUNT_MAX);
|
||||||
break;
|
|
||||||
} else
|
} else
|
||||||
rc = -EPERM;
|
rc = -EPERM;
|
||||||
default: /* fall through */
|
break;
|
||||||
|
default:
|
||||||
rc = -EINVAL;
|
rc = -EINVAL;
|
||||||
}
|
}
|
||||||
out:
|
out:
|
||||||
|
|
|
@ -346,7 +346,7 @@ static void pn_rx_complete(struct usb_ep *ep, struct usb_request *req)
|
||||||
}
|
}
|
||||||
|
|
||||||
skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags, page,
|
skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags, page,
|
||||||
skb->len == 0, req->actual);
|
skb->len <= 1, req->actual);
|
||||||
page = NULL;
|
page = NULL;
|
||||||
|
|
||||||
if (req->actual < req->length) { /* Last fragment */
|
if (req->actual < req->length) { /* Last fragment */
|
||||||
|
|
|
@ -98,9 +98,10 @@ enum {
|
||||||
INET_DIAG_VEGASINFO,
|
INET_DIAG_VEGASINFO,
|
||||||
INET_DIAG_CONG,
|
INET_DIAG_CONG,
|
||||||
INET_DIAG_TOS,
|
INET_DIAG_TOS,
|
||||||
|
INET_DIAG_TCLASS,
|
||||||
};
|
};
|
||||||
|
|
||||||
#define INET_DIAG_MAX INET_DIAG_TOS
|
#define INET_DIAG_MAX INET_DIAG_TCLASS
|
||||||
|
|
||||||
|
|
||||||
/* INET_DIAG_MEM */
|
/* INET_DIAG_MEM */
|
||||||
|
|
|
@ -39,6 +39,9 @@
|
||||||
#define L2CAP_DEFAULT_ACK_TO 200
|
#define L2CAP_DEFAULT_ACK_TO 200
|
||||||
#define L2CAP_LE_DEFAULT_MTU 23
|
#define L2CAP_LE_DEFAULT_MTU 23
|
||||||
|
|
||||||
|
#define L2CAP_DISC_TIMEOUT (100)
|
||||||
|
#define L2CAP_DISC_REJ_TIMEOUT (5000) /* 5 seconds */
|
||||||
|
#define L2CAP_ENC_TIMEOUT (5000) /* 5 seconds */
|
||||||
#define L2CAP_CONN_TIMEOUT (40000) /* 40 seconds */
|
#define L2CAP_CONN_TIMEOUT (40000) /* 40 seconds */
|
||||||
#define L2CAP_INFO_TIMEOUT (4000) /* 4 seconds */
|
#define L2CAP_INFO_TIMEOUT (4000) /* 4 seconds */
|
||||||
|
|
||||||
|
|
|
@ -456,6 +456,9 @@ enum station_parameters_apply_mask {
|
||||||
* as the AC bitmap in the QoS info field
|
* as the AC bitmap in the QoS info field
|
||||||
* @max_sp: max Service Period. same format as the MAX_SP in the
|
* @max_sp: max Service Period. same format as the MAX_SP in the
|
||||||
* QoS info field (but already shifted down)
|
* QoS info field (but already shifted down)
|
||||||
|
* @sta_modify_mask: bitmap indicating which parameters changed
|
||||||
|
* (for those that don't have a natural "no change" value),
|
||||||
|
* see &enum station_parameters_apply_mask
|
||||||
*/
|
*/
|
||||||
struct station_parameters {
|
struct station_parameters {
|
||||||
u8 *supported_rates;
|
u8 *supported_rates;
|
||||||
|
@ -615,6 +618,7 @@ struct sta_bss_parameters {
|
||||||
* user space MLME/SME implementation. The information is provided for
|
* user space MLME/SME implementation. The information is provided for
|
||||||
* the cfg80211_new_sta() calls to notify user space of the IEs.
|
* the cfg80211_new_sta() calls to notify user space of the IEs.
|
||||||
* @assoc_req_ies_len: Length of assoc_req_ies buffer in octets.
|
* @assoc_req_ies_len: Length of assoc_req_ies buffer in octets.
|
||||||
|
* @sta_flags: station flags mask & values
|
||||||
*/
|
*/
|
||||||
struct station_info {
|
struct station_info {
|
||||||
u32 filled;
|
u32 filled;
|
||||||
|
|
|
@ -673,7 +673,7 @@ int hci_conn_security(struct hci_conn *conn, __u8 sec_level, __u8 auth_type)
|
||||||
goto encrypt;
|
goto encrypt;
|
||||||
|
|
||||||
auth:
|
auth:
|
||||||
if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend))
|
if (test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (!hci_conn_auth(conn, sec_level, auth_type))
|
if (!hci_conn_auth(conn, sec_level, auth_type))
|
||||||
|
|
|
@ -251,7 +251,7 @@ static void l2cap_chan_timeout(unsigned long arg)
|
||||||
|
|
||||||
if (sock_owned_by_user(sk)) {
|
if (sock_owned_by_user(sk)) {
|
||||||
/* sk is owned by user. Try again later */
|
/* sk is owned by user. Try again later */
|
||||||
__set_chan_timer(chan, HZ / 5);
|
__set_chan_timer(chan, L2CAP_DISC_TIMEOUT);
|
||||||
bh_unlock_sock(sk);
|
bh_unlock_sock(sk);
|
||||||
chan_put(chan);
|
chan_put(chan);
|
||||||
return;
|
return;
|
||||||
|
@ -2488,7 +2488,7 @@ static inline int l2cap_connect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hd
|
||||||
if (sock_owned_by_user(sk)) {
|
if (sock_owned_by_user(sk)) {
|
||||||
l2cap_state_change(chan, BT_DISCONN);
|
l2cap_state_change(chan, BT_DISCONN);
|
||||||
__clear_chan_timer(chan);
|
__clear_chan_timer(chan);
|
||||||
__set_chan_timer(chan, HZ / 5);
|
__set_chan_timer(chan, L2CAP_DISC_TIMEOUT);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2661,7 +2661,7 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr
|
||||||
|
|
||||||
default:
|
default:
|
||||||
sk->sk_err = ECONNRESET;
|
sk->sk_err = ECONNRESET;
|
||||||
__set_chan_timer(chan, HZ * 5);
|
__set_chan_timer(chan, L2CAP_DISC_REJ_TIMEOUT);
|
||||||
l2cap_send_disconn_req(conn, chan, ECONNRESET);
|
l2cap_send_disconn_req(conn, chan, ECONNRESET);
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
@ -2718,7 +2718,7 @@ static inline int l2cap_disconnect_req(struct l2cap_conn *conn, struct l2cap_cmd
|
||||||
if (sock_owned_by_user(sk)) {
|
if (sock_owned_by_user(sk)) {
|
||||||
l2cap_state_change(chan, BT_DISCONN);
|
l2cap_state_change(chan, BT_DISCONN);
|
||||||
__clear_chan_timer(chan);
|
__clear_chan_timer(chan);
|
||||||
__set_chan_timer(chan, HZ / 5);
|
__set_chan_timer(chan, L2CAP_DISC_TIMEOUT);
|
||||||
bh_unlock_sock(sk);
|
bh_unlock_sock(sk);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -2752,7 +2752,7 @@ static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn, struct l2cap_cmd
|
||||||
if (sock_owned_by_user(sk)) {
|
if (sock_owned_by_user(sk)) {
|
||||||
l2cap_state_change(chan,BT_DISCONN);
|
l2cap_state_change(chan,BT_DISCONN);
|
||||||
__clear_chan_timer(chan);
|
__clear_chan_timer(chan);
|
||||||
__set_chan_timer(chan, HZ / 5);
|
__set_chan_timer(chan, L2CAP_DISC_TIMEOUT);
|
||||||
bh_unlock_sock(sk);
|
bh_unlock_sock(sk);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -3998,7 +3998,7 @@ static inline void l2cap_check_encryption(struct l2cap_chan *chan, u8 encrypt)
|
||||||
if (encrypt == 0x00) {
|
if (encrypt == 0x00) {
|
||||||
if (chan->sec_level == BT_SECURITY_MEDIUM) {
|
if (chan->sec_level == BT_SECURITY_MEDIUM) {
|
||||||
__clear_chan_timer(chan);
|
__clear_chan_timer(chan);
|
||||||
__set_chan_timer(chan, HZ * 5);
|
__set_chan_timer(chan, L2CAP_ENC_TIMEOUT);
|
||||||
} else if (chan->sec_level == BT_SECURITY_HIGH)
|
} else if (chan->sec_level == BT_SECURITY_HIGH)
|
||||||
l2cap_chan_close(chan, ECONNREFUSED);
|
l2cap_chan_close(chan, ECONNREFUSED);
|
||||||
} else {
|
} else {
|
||||||
|
@ -4066,7 +4066,7 @@ static int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
|
||||||
L2CAP_CONN_REQ, sizeof(req), &req);
|
L2CAP_CONN_REQ, sizeof(req), &req);
|
||||||
} else {
|
} else {
|
||||||
__clear_chan_timer(chan);
|
__clear_chan_timer(chan);
|
||||||
__set_chan_timer(chan, HZ / 10);
|
__set_chan_timer(chan, L2CAP_DISC_TIMEOUT);
|
||||||
}
|
}
|
||||||
} else if (chan->state == BT_CONNECT2) {
|
} else if (chan->state == BT_CONNECT2) {
|
||||||
struct l2cap_conn_rsp rsp;
|
struct l2cap_conn_rsp rsp;
|
||||||
|
@ -4086,7 +4086,7 @@ static int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
l2cap_state_change(chan, BT_DISCONN);
|
l2cap_state_change(chan, BT_DISCONN);
|
||||||
__set_chan_timer(chan, HZ / 10);
|
__set_chan_timer(chan, L2CAP_DISC_TIMEOUT);
|
||||||
res = L2CAP_CR_SEC_BLOCK;
|
res = L2CAP_CR_SEC_BLOCK;
|
||||||
stat = L2CAP_CS_NO_INFO;
|
stat = L2CAP_CS_NO_INFO;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1501,6 +1501,8 @@ static int br_multicast_ipv6_rcv(struct net_bridge *br,
|
||||||
|
|
||||||
__skb_pull(skb2, offset);
|
__skb_pull(skb2, offset);
|
||||||
skb_reset_transport_header(skb2);
|
skb_reset_transport_header(skb2);
|
||||||
|
skb_postpull_rcsum(skb2, skb_network_header(skb2),
|
||||||
|
skb_network_header_len(skb2));
|
||||||
|
|
||||||
icmp6_type = icmp6_hdr(skb2)->icmp6_type;
|
icmp6_type = icmp6_hdr(skb2)->icmp6_type;
|
||||||
|
|
||||||
|
@ -1770,7 +1772,7 @@ int br_multicast_toggle(struct net_bridge *br, unsigned long val)
|
||||||
int err = 0;
|
int err = 0;
|
||||||
struct net_bridge_mdb_htable *mdb;
|
struct net_bridge_mdb_htable *mdb;
|
||||||
|
|
||||||
spin_lock(&br->multicast_lock);
|
spin_lock_bh(&br->multicast_lock);
|
||||||
if (br->multicast_disabled == !val)
|
if (br->multicast_disabled == !val)
|
||||||
goto unlock;
|
goto unlock;
|
||||||
|
|
||||||
|
@ -1806,7 +1808,7 @@ rollback:
|
||||||
}
|
}
|
||||||
|
|
||||||
unlock:
|
unlock:
|
||||||
spin_unlock(&br->multicast_lock);
|
spin_unlock_bh(&br->multicast_lock);
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
|
@ -136,8 +136,6 @@ static void ah_output_done(struct crypto_async_request *base, int err)
|
||||||
memcpy(top_iph+1, iph+1, top_iph->ihl*4 - sizeof(struct iphdr));
|
memcpy(top_iph+1, iph+1, top_iph->ihl*4 - sizeof(struct iphdr));
|
||||||
}
|
}
|
||||||
|
|
||||||
err = ah->nexthdr;
|
|
||||||
|
|
||||||
kfree(AH_SKB_CB(skb)->tmp);
|
kfree(AH_SKB_CB(skb)->tmp);
|
||||||
xfrm_output_resume(skb, err);
|
xfrm_output_resume(skb, err);
|
||||||
}
|
}
|
||||||
|
@ -264,12 +262,12 @@ static void ah_input_done(struct crypto_async_request *base, int err)
|
||||||
if (err)
|
if (err)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
|
err = ah->nexthdr;
|
||||||
|
|
||||||
skb->network_header += ah_hlen;
|
skb->network_header += ah_hlen;
|
||||||
memcpy(skb_network_header(skb), work_iph, ihl);
|
memcpy(skb_network_header(skb), work_iph, ihl);
|
||||||
__skb_pull(skb, ah_hlen + ihl);
|
__skb_pull(skb, ah_hlen + ihl);
|
||||||
skb_set_transport_header(skb, -ihl);
|
skb_set_transport_header(skb, -ihl);
|
||||||
|
|
||||||
err = ah->nexthdr;
|
|
||||||
out:
|
out:
|
||||||
kfree(AH_SKB_CB(skb)->tmp);
|
kfree(AH_SKB_CB(skb)->tmp);
|
||||||
xfrm_input_resume(skb, err);
|
xfrm_input_resume(skb, err);
|
||||||
|
@ -371,8 +369,6 @@ static int ah_input(struct xfrm_state *x, struct sk_buff *skb)
|
||||||
if (err == -EINPROGRESS)
|
if (err == -EINPROGRESS)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
if (err == -EBUSY)
|
|
||||||
err = NET_XMIT_DROP;
|
|
||||||
goto out_free;
|
goto out_free;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -133,8 +133,8 @@ static int inet_csk_diag_fill(struct sock *sk,
|
||||||
&np->rcv_saddr);
|
&np->rcv_saddr);
|
||||||
ipv6_addr_copy((struct in6_addr *)r->id.idiag_dst,
|
ipv6_addr_copy((struct in6_addr *)r->id.idiag_dst,
|
||||||
&np->daddr);
|
&np->daddr);
|
||||||
if (ext & (1 << (INET_DIAG_TOS - 1)))
|
if (ext & (1 << (INET_DIAG_TCLASS - 1)))
|
||||||
RTA_PUT_U8(skb, INET_DIAG_TOS, np->tclass);
|
RTA_PUT_U8(skb, INET_DIAG_TCLASS, np->tclass);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -640,6 +640,7 @@ int ip_options_rcv_srr(struct sk_buff *skb)
|
||||||
}
|
}
|
||||||
if (srrptr <= srrspace) {
|
if (srrptr <= srrspace) {
|
||||||
opt->srr_is_hit = 1;
|
opt->srr_is_hit = 1;
|
||||||
|
iph->daddr = nexthop;
|
||||||
opt->is_changed = 1;
|
opt->is_changed = 1;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -339,7 +339,6 @@ void ping_err(struct sk_buff *skb, u32 info)
|
||||||
sk = ping_v4_lookup(net, iph->daddr, iph->saddr,
|
sk = ping_v4_lookup(net, iph->daddr, iph->saddr,
|
||||||
ntohs(icmph->un.echo.id), skb->dev->ifindex);
|
ntohs(icmph->un.echo.id), skb->dev->ifindex);
|
||||||
if (sk == NULL) {
|
if (sk == NULL) {
|
||||||
ICMP_INC_STATS_BH(net, ICMP_MIB_INERRORS);
|
|
||||||
pr_debug("no socket, dropping\n");
|
pr_debug("no socket, dropping\n");
|
||||||
return; /* No socket for error */
|
return; /* No socket for error */
|
||||||
}
|
}
|
||||||
|
@ -679,7 +678,6 @@ static int ping_queue_rcv_skb(struct sock *sk, struct sk_buff *skb)
|
||||||
pr_debug("ping_queue_rcv_skb(sk=%p,sk->num=%d,skb=%p)\n",
|
pr_debug("ping_queue_rcv_skb(sk=%p,sk->num=%d,skb=%p)\n",
|
||||||
inet_sk(sk), inet_sk(sk)->inet_num, skb);
|
inet_sk(sk), inet_sk(sk)->inet_num, skb);
|
||||||
if (sock_queue_rcv_skb(sk, skb) < 0) {
|
if (sock_queue_rcv_skb(sk, skb) < 0) {
|
||||||
ICMP_INC_STATS_BH(sock_net(sk), ICMP_MIB_INERRORS);
|
|
||||||
kfree_skb(skb);
|
kfree_skb(skb);
|
||||||
pr_debug("ping_queue_rcv_skb -> failed\n");
|
pr_debug("ping_queue_rcv_skb -> failed\n");
|
||||||
return -1;
|
return -1;
|
||||||
|
|
102
net/ipv4/route.c
102
net/ipv4/route.c
|
@ -1304,16 +1304,42 @@ static void rt_del(unsigned hash, struct rtable *rt)
|
||||||
spin_unlock_bh(rt_hash_lock_addr(hash));
|
spin_unlock_bh(rt_hash_lock_addr(hash));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int check_peer_redir(struct dst_entry *dst, struct inet_peer *peer)
|
||||||
|
{
|
||||||
|
struct rtable *rt = (struct rtable *) dst;
|
||||||
|
__be32 orig_gw = rt->rt_gateway;
|
||||||
|
struct neighbour *n, *old_n;
|
||||||
|
|
||||||
|
dst_confirm(&rt->dst);
|
||||||
|
|
||||||
|
rt->rt_gateway = peer->redirect_learned.a4;
|
||||||
|
|
||||||
|
n = ipv4_neigh_lookup(&rt->dst, &rt->rt_gateway);
|
||||||
|
if (IS_ERR(n))
|
||||||
|
return PTR_ERR(n);
|
||||||
|
old_n = xchg(&rt->dst._neighbour, n);
|
||||||
|
if (old_n)
|
||||||
|
neigh_release(old_n);
|
||||||
|
if (!n || !(n->nud_state & NUD_VALID)) {
|
||||||
|
if (n)
|
||||||
|
neigh_event_send(n, NULL);
|
||||||
|
rt->rt_gateway = orig_gw;
|
||||||
|
return -EAGAIN;
|
||||||
|
} else {
|
||||||
|
rt->rt_flags |= RTCF_REDIRECTED;
|
||||||
|
call_netevent_notifiers(NETEVENT_NEIGH_UPDATE, n);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* called in rcu_read_lock() section */
|
/* called in rcu_read_lock() section */
|
||||||
void ip_rt_redirect(__be32 old_gw, __be32 daddr, __be32 new_gw,
|
void ip_rt_redirect(__be32 old_gw, __be32 daddr, __be32 new_gw,
|
||||||
__be32 saddr, struct net_device *dev)
|
__be32 saddr, struct net_device *dev)
|
||||||
{
|
{
|
||||||
int s, i;
|
int s, i;
|
||||||
struct in_device *in_dev = __in_dev_get_rcu(dev);
|
struct in_device *in_dev = __in_dev_get_rcu(dev);
|
||||||
struct rtable *rt;
|
|
||||||
__be32 skeys[2] = { saddr, 0 };
|
__be32 skeys[2] = { saddr, 0 };
|
||||||
int ikeys[2] = { dev->ifindex, 0 };
|
int ikeys[2] = { dev->ifindex, 0 };
|
||||||
struct flowi4 fl4;
|
|
||||||
struct inet_peer *peer;
|
struct inet_peer *peer;
|
||||||
struct net *net;
|
struct net *net;
|
||||||
|
|
||||||
|
@ -1336,33 +1362,42 @@ void ip_rt_redirect(__be32 old_gw, __be32 daddr, __be32 new_gw,
|
||||||
goto reject_redirect;
|
goto reject_redirect;
|
||||||
}
|
}
|
||||||
|
|
||||||
memset(&fl4, 0, sizeof(fl4));
|
|
||||||
fl4.daddr = daddr;
|
|
||||||
for (s = 0; s < 2; s++) {
|
for (s = 0; s < 2; s++) {
|
||||||
for (i = 0; i < 2; i++) {
|
for (i = 0; i < 2; i++) {
|
||||||
fl4.flowi4_oif = ikeys[i];
|
unsigned int hash;
|
||||||
fl4.saddr = skeys[s];
|
struct rtable __rcu **rthp;
|
||||||
rt = __ip_route_output_key(net, &fl4);
|
struct rtable *rt;
|
||||||
if (IS_ERR(rt))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (rt->dst.error || rt->dst.dev != dev ||
|
hash = rt_hash(daddr, skeys[s], ikeys[i], rt_genid(net));
|
||||||
rt->rt_gateway != old_gw) {
|
|
||||||
ip_rt_put(rt);
|
rthp = &rt_hash_table[hash].chain;
|
||||||
|
|
||||||
|
while ((rt = rcu_dereference(*rthp)) != NULL) {
|
||||||
|
rthp = &rt->dst.rt_next;
|
||||||
|
|
||||||
|
if (rt->rt_key_dst != daddr ||
|
||||||
|
rt->rt_key_src != skeys[s] ||
|
||||||
|
rt->rt_oif != ikeys[i] ||
|
||||||
|
rt_is_input_route(rt) ||
|
||||||
|
rt_is_expired(rt) ||
|
||||||
|
!net_eq(dev_net(rt->dst.dev), net) ||
|
||||||
|
rt->dst.error ||
|
||||||
|
rt->dst.dev != dev ||
|
||||||
|
rt->rt_gateway != old_gw)
|
||||||
continue;
|
continue;
|
||||||
}
|
|
||||||
|
|
||||||
if (!rt->peer)
|
if (!rt->peer)
|
||||||
rt_bind_peer(rt, rt->rt_dst, 1);
|
rt_bind_peer(rt, rt->rt_dst, 1);
|
||||||
|
|
||||||
peer = rt->peer;
|
peer = rt->peer;
|
||||||
if (peer) {
|
if (peer) {
|
||||||
|
if (peer->redirect_learned.a4 != new_gw) {
|
||||||
peer->redirect_learned.a4 = new_gw;
|
peer->redirect_learned.a4 = new_gw;
|
||||||
atomic_inc(&__rt_peer_genid);
|
atomic_inc(&__rt_peer_genid);
|
||||||
}
|
}
|
||||||
|
check_peer_redir(&rt->dst, peer);
|
||||||
ip_rt_put(rt);
|
}
|
||||||
return;
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
@ -1649,33 +1684,6 @@ static void ip_rt_update_pmtu(struct dst_entry *dst, u32 mtu)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int check_peer_redir(struct dst_entry *dst, struct inet_peer *peer)
|
|
||||||
{
|
|
||||||
struct rtable *rt = (struct rtable *) dst;
|
|
||||||
__be32 orig_gw = rt->rt_gateway;
|
|
||||||
struct neighbour *n, *old_n;
|
|
||||||
|
|
||||||
dst_confirm(&rt->dst);
|
|
||||||
|
|
||||||
rt->rt_gateway = peer->redirect_learned.a4;
|
|
||||||
|
|
||||||
n = ipv4_neigh_lookup(&rt->dst, &rt->rt_gateway);
|
|
||||||
if (IS_ERR(n))
|
|
||||||
return PTR_ERR(n);
|
|
||||||
old_n = xchg(&rt->dst._neighbour, n);
|
|
||||||
if (old_n)
|
|
||||||
neigh_release(old_n);
|
|
||||||
if (!n || !(n->nud_state & NUD_VALID)) {
|
|
||||||
if (n)
|
|
||||||
neigh_event_send(n, NULL);
|
|
||||||
rt->rt_gateway = orig_gw;
|
|
||||||
return -EAGAIN;
|
|
||||||
} else {
|
|
||||||
rt->rt_flags |= RTCF_REDIRECTED;
|
|
||||||
call_netevent_notifiers(NETEVENT_NEIGH_UPDATE, n);
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct dst_entry *ipv4_dst_check(struct dst_entry *dst, u32 cookie)
|
static struct dst_entry *ipv4_dst_check(struct dst_entry *dst, u32 cookie)
|
||||||
{
|
{
|
||||||
|
@ -2845,7 +2853,7 @@ static int rt_fill_info(struct net *net,
|
||||||
struct rtable *rt = skb_rtable(skb);
|
struct rtable *rt = skb_rtable(skb);
|
||||||
struct rtmsg *r;
|
struct rtmsg *r;
|
||||||
struct nlmsghdr *nlh;
|
struct nlmsghdr *nlh;
|
||||||
long expires = 0;
|
unsigned long expires = 0;
|
||||||
const struct inet_peer *peer = rt->peer;
|
const struct inet_peer *peer = rt->peer;
|
||||||
u32 id = 0, ts = 0, tsage = 0, error;
|
u32 id = 0, ts = 0, tsage = 0, error;
|
||||||
|
|
||||||
|
@ -2902,8 +2910,12 @@ static int rt_fill_info(struct net *net,
|
||||||
tsage = get_seconds() - peer->tcp_ts_stamp;
|
tsage = get_seconds() - peer->tcp_ts_stamp;
|
||||||
}
|
}
|
||||||
expires = ACCESS_ONCE(peer->pmtu_expires);
|
expires = ACCESS_ONCE(peer->pmtu_expires);
|
||||||
if (expires)
|
if (expires) {
|
||||||
|
if (time_before(jiffies, expires))
|
||||||
expires -= jiffies;
|
expires -= jiffies;
|
||||||
|
else
|
||||||
|
expires = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rt_is_input_route(rt)) {
|
if (rt_is_input_route(rt)) {
|
||||||
|
|
|
@ -1510,6 +1510,7 @@ exit:
|
||||||
NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_LISTENDROPS);
|
NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_LISTENDROPS);
|
||||||
return NULL;
|
return NULL;
|
||||||
put_and_exit:
|
put_and_exit:
|
||||||
|
tcp_clear_xmit_timers(newsk);
|
||||||
bh_unlock_sock(newsk);
|
bh_unlock_sock(newsk);
|
||||||
sock_put(newsk);
|
sock_put(newsk);
|
||||||
goto exit;
|
goto exit;
|
||||||
|
|
|
@ -1382,7 +1382,7 @@ static inline int tcp_minshall_check(const struct tcp_sock *tp)
|
||||||
/* Return 0, if packet can be sent now without violation Nagle's rules:
|
/* Return 0, if packet can be sent now without violation Nagle's rules:
|
||||||
* 1. It is full sized.
|
* 1. It is full sized.
|
||||||
* 2. Or it contains FIN. (already checked by caller)
|
* 2. Or it contains FIN. (already checked by caller)
|
||||||
* 3. Or TCP_NODELAY was set.
|
* 3. Or TCP_CORK is not set, and TCP_NODELAY is set.
|
||||||
* 4. Or TCP_CORK is not set, and all sent packets are ACKed.
|
* 4. Or TCP_CORK is not set, and all sent packets are ACKed.
|
||||||
* With Minshall's modification: all sent small packets are ACKed.
|
* With Minshall's modification: all sent small packets are ACKed.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -324,8 +324,6 @@ static void ah6_output_done(struct crypto_async_request *base, int err)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
err = ah->nexthdr;
|
|
||||||
|
|
||||||
kfree(AH_SKB_CB(skb)->tmp);
|
kfree(AH_SKB_CB(skb)->tmp);
|
||||||
xfrm_output_resume(skb, err);
|
xfrm_output_resume(skb, err);
|
||||||
}
|
}
|
||||||
|
@ -466,12 +464,12 @@ static void ah6_input_done(struct crypto_async_request *base, int err)
|
||||||
if (err)
|
if (err)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
|
err = ah->nexthdr;
|
||||||
|
|
||||||
skb->network_header += ah_hlen;
|
skb->network_header += ah_hlen;
|
||||||
memcpy(skb_network_header(skb), work_iph, hdr_len);
|
memcpy(skb_network_header(skb), work_iph, hdr_len);
|
||||||
__skb_pull(skb, ah_hlen + hdr_len);
|
__skb_pull(skb, ah_hlen + hdr_len);
|
||||||
skb_set_transport_header(skb, -hdr_len);
|
skb_set_transport_header(skb, -hdr_len);
|
||||||
|
|
||||||
err = ah->nexthdr;
|
|
||||||
out:
|
out:
|
||||||
kfree(AH_SKB_CB(skb)->tmp);
|
kfree(AH_SKB_CB(skb)->tmp);
|
||||||
xfrm_input_resume(skb, err);
|
xfrm_input_resume(skb, err);
|
||||||
|
@ -583,8 +581,6 @@ static int ah6_input(struct xfrm_state *x, struct sk_buff *skb)
|
||||||
if (err == -EINPROGRESS)
|
if (err == -EINPROGRESS)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
if (err == -EBUSY)
|
|
||||||
err = NET_XMIT_DROP;
|
|
||||||
goto out_free;
|
goto out_free;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -111,6 +111,14 @@ int ipv6_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt
|
||||||
ipv6_addr_loopback(&hdr->daddr))
|
ipv6_addr_loopback(&hdr->daddr))
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* RFC4291 2.7
|
||||||
|
* Multicast addresses must not be used as source addresses in IPv6
|
||||||
|
* packets or appear in any Routing header.
|
||||||
|
*/
|
||||||
|
if (ipv6_addr_is_multicast(&hdr->saddr))
|
||||||
|
goto err;
|
||||||
|
|
||||||
skb->transport_header = skb->network_header + sizeof(*hdr);
|
skb->transport_header = skb->network_header + sizeof(*hdr);
|
||||||
IP6CB(skb)->nhoff = offsetof(struct ipv6hdr, nexthdr);
|
IP6CB(skb)->nhoff = offsetof(struct ipv6hdr, nexthdr);
|
||||||
|
|
||||||
|
|
|
@ -289,6 +289,8 @@ static struct ip6_tnl *ip6_tnl_create(struct net *net, struct ip6_tnl_parm *p)
|
||||||
if ((err = register_netdevice(dev)) < 0)
|
if ((err = register_netdevice(dev)) < 0)
|
||||||
goto failed_free;
|
goto failed_free;
|
||||||
|
|
||||||
|
strcpy(t->parms.name, dev->name);
|
||||||
|
|
||||||
dev_hold(dev);
|
dev_hold(dev);
|
||||||
ip6_tnl_link(ip6n, t);
|
ip6_tnl_link(ip6n, t);
|
||||||
return t;
|
return t;
|
||||||
|
@ -1407,7 +1409,6 @@ ip6_tnl_dev_init_gen(struct net_device *dev)
|
||||||
struct ip6_tnl *t = netdev_priv(dev);
|
struct ip6_tnl *t = netdev_priv(dev);
|
||||||
|
|
||||||
t->dev = dev;
|
t->dev = dev;
|
||||||
strcpy(t->parms.name, dev->name);
|
|
||||||
dev->tstats = alloc_percpu(struct pcpu_tstats);
|
dev->tstats = alloc_percpu(struct pcpu_tstats);
|
||||||
if (!dev->tstats)
|
if (!dev->tstats)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
@ -1487,6 +1488,7 @@ static void __net_exit ip6_tnl_destroy_tunnels(struct ip6_tnl_net *ip6n)
|
||||||
static int __net_init ip6_tnl_init_net(struct net *net)
|
static int __net_init ip6_tnl_init_net(struct net *net)
|
||||||
{
|
{
|
||||||
struct ip6_tnl_net *ip6n = net_generic(net, ip6_tnl_net_id);
|
struct ip6_tnl_net *ip6n = net_generic(net, ip6_tnl_net_id);
|
||||||
|
struct ip6_tnl *t = NULL;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
ip6n->tnls[0] = ip6n->tnls_wc;
|
ip6n->tnls[0] = ip6n->tnls_wc;
|
||||||
|
@ -1507,6 +1509,10 @@ static int __net_init ip6_tnl_init_net(struct net *net)
|
||||||
err = register_netdev(ip6n->fb_tnl_dev);
|
err = register_netdev(ip6n->fb_tnl_dev);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
goto err_register;
|
goto err_register;
|
||||||
|
|
||||||
|
t = netdev_priv(ip6n->fb_tnl_dev);
|
||||||
|
|
||||||
|
strcpy(t->parms.name, ip6n->fb_tnl_dev->name);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
err_register:
|
err_register:
|
||||||
|
|
|
@ -756,9 +756,6 @@ static int l2tp_udp_recv_core(struct l2tp_tunnel *tunnel, struct sk_buff *skb,
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Point to L2TP header */
|
|
||||||
optr = ptr = skb->data;
|
|
||||||
|
|
||||||
/* Trace packet contents, if enabled */
|
/* Trace packet contents, if enabled */
|
||||||
if (tunnel->debug & L2TP_MSG_DATA) {
|
if (tunnel->debug & L2TP_MSG_DATA) {
|
||||||
length = min(32u, skb->len);
|
length = min(32u, skb->len);
|
||||||
|
@ -769,12 +766,15 @@ static int l2tp_udp_recv_core(struct l2tp_tunnel *tunnel, struct sk_buff *skb,
|
||||||
|
|
||||||
offset = 0;
|
offset = 0;
|
||||||
do {
|
do {
|
||||||
printk(" %02X", ptr[offset]);
|
printk(" %02X", skb->data[offset]);
|
||||||
} while (++offset < length);
|
} while (++offset < length);
|
||||||
|
|
||||||
printk("\n");
|
printk("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Point to L2TP header */
|
||||||
|
optr = ptr = skb->data;
|
||||||
|
|
||||||
/* Get L2TP header flags */
|
/* Get L2TP header flags */
|
||||||
hdrflags = ntohs(*(__be16 *) ptr);
|
hdrflags = ntohs(*(__be16 *) ptr);
|
||||||
|
|
||||||
|
|
|
@ -1487,6 +1487,7 @@ static bool ieee80211_assoc_success(struct ieee80211_work *wk,
|
||||||
int i, j, err;
|
int i, j, err;
|
||||||
bool have_higher_than_11mbit = false;
|
bool have_higher_than_11mbit = false;
|
||||||
u16 ap_ht_cap_flags;
|
u16 ap_ht_cap_flags;
|
||||||
|
int min_rate = INT_MAX, min_rate_index = -1;
|
||||||
|
|
||||||
/* AssocResp and ReassocResp have identical structure */
|
/* AssocResp and ReassocResp have identical structure */
|
||||||
|
|
||||||
|
@ -1553,6 +1554,10 @@ static bool ieee80211_assoc_success(struct ieee80211_work *wk,
|
||||||
rates |= BIT(j);
|
rates |= BIT(j);
|
||||||
if (is_basic)
|
if (is_basic)
|
||||||
basic_rates |= BIT(j);
|
basic_rates |= BIT(j);
|
||||||
|
if (rate < min_rate) {
|
||||||
|
min_rate = rate;
|
||||||
|
min_rate_index = j;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1570,11 +1575,25 @@ static bool ieee80211_assoc_success(struct ieee80211_work *wk,
|
||||||
rates |= BIT(j);
|
rates |= BIT(j);
|
||||||
if (is_basic)
|
if (is_basic)
|
||||||
basic_rates |= BIT(j);
|
basic_rates |= BIT(j);
|
||||||
|
if (rate < min_rate) {
|
||||||
|
min_rate = rate;
|
||||||
|
min_rate_index = j;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* some buggy APs don't advertise basic_rates. use the lowest
|
||||||
|
* supported rate instead.
|
||||||
|
*/
|
||||||
|
if (unlikely(!basic_rates) && min_rate_index >= 0) {
|
||||||
|
printk(KERN_DEBUG "%s: No basic rates in AssocResp. "
|
||||||
|
"Using min supported rate instead.\n", sdata->name);
|
||||||
|
basic_rates = BIT(min_rate_index);
|
||||||
|
}
|
||||||
|
|
||||||
sta->sta.supp_rates[wk->chan->band] = rates;
|
sta->sta.supp_rates[wk->chan->band] = rates;
|
||||||
sdata->vif.bss_conf.basic_rates = basic_rates;
|
sdata->vif.bss_conf.basic_rates = basic_rates;
|
||||||
|
|
||||||
|
@ -2269,6 +2288,7 @@ void ieee80211_sta_quiesce(struct ieee80211_sub_if_data *sdata)
|
||||||
|
|
||||||
cancel_work_sync(&ifmgd->request_smps_work);
|
cancel_work_sync(&ifmgd->request_smps_work);
|
||||||
|
|
||||||
|
cancel_work_sync(&ifmgd->monitor_work);
|
||||||
cancel_work_sync(&ifmgd->beacon_connection_loss_work);
|
cancel_work_sync(&ifmgd->beacon_connection_loss_work);
|
||||||
if (del_timer_sync(&ifmgd->timer))
|
if (del_timer_sync(&ifmgd->timer))
|
||||||
set_bit(TMR_RUNNING_TIMER, &ifmgd->timers_running);
|
set_bit(TMR_RUNNING_TIMER, &ifmgd->timers_running);
|
||||||
|
@ -2277,7 +2297,6 @@ void ieee80211_sta_quiesce(struct ieee80211_sub_if_data *sdata)
|
||||||
if (del_timer_sync(&ifmgd->chswitch_timer))
|
if (del_timer_sync(&ifmgd->chswitch_timer))
|
||||||
set_bit(TMR_RUNNING_CHANSW, &ifmgd->timers_running);
|
set_bit(TMR_RUNNING_CHANSW, &ifmgd->timers_running);
|
||||||
|
|
||||||
cancel_work_sync(&ifmgd->monitor_work);
|
|
||||||
/* these will just be re-established on connection */
|
/* these will just be re-established on connection */
|
||||||
del_timer_sync(&ifmgd->conn_mon_timer);
|
del_timer_sync(&ifmgd->conn_mon_timer);
|
||||||
del_timer_sync(&ifmgd->bcn_mon_timer);
|
del_timer_sync(&ifmgd->bcn_mon_timer);
|
||||||
|
|
|
@ -141,8 +141,9 @@ ieee80211_add_rx_radiotap_header(struct ieee80211_local *local,
|
||||||
pos++;
|
pos++;
|
||||||
|
|
||||||
/* IEEE80211_RADIOTAP_RATE */
|
/* IEEE80211_RADIOTAP_RATE */
|
||||||
if (status->flag & RX_FLAG_HT) {
|
if (!rate || status->flag & RX_FLAG_HT) {
|
||||||
/*
|
/*
|
||||||
|
* Without rate information don't add it. If we have,
|
||||||
* MCS information is a separate field in radiotap,
|
* MCS information is a separate field in radiotap,
|
||||||
* added below. The byte here is needed as padding
|
* added below. The byte here is needed as padding
|
||||||
* for the channel though, so initialise it to 0.
|
* for the channel though, so initialise it to 0.
|
||||||
|
@ -163,12 +164,14 @@ ieee80211_add_rx_radiotap_header(struct ieee80211_local *local,
|
||||||
else if (status->flag & RX_FLAG_HT)
|
else if (status->flag & RX_FLAG_HT)
|
||||||
put_unaligned_le16(IEEE80211_CHAN_DYN | IEEE80211_CHAN_2GHZ,
|
put_unaligned_le16(IEEE80211_CHAN_DYN | IEEE80211_CHAN_2GHZ,
|
||||||
pos);
|
pos);
|
||||||
else if (rate->flags & IEEE80211_RATE_ERP_G)
|
else if (rate && rate->flags & IEEE80211_RATE_ERP_G)
|
||||||
put_unaligned_le16(IEEE80211_CHAN_OFDM | IEEE80211_CHAN_2GHZ,
|
put_unaligned_le16(IEEE80211_CHAN_OFDM | IEEE80211_CHAN_2GHZ,
|
||||||
pos);
|
pos);
|
||||||
else
|
else if (rate)
|
||||||
put_unaligned_le16(IEEE80211_CHAN_CCK | IEEE80211_CHAN_2GHZ,
|
put_unaligned_le16(IEEE80211_CHAN_CCK | IEEE80211_CHAN_2GHZ,
|
||||||
pos);
|
pos);
|
||||||
|
else
|
||||||
|
put_unaligned_le16(IEEE80211_CHAN_2GHZ, pos);
|
||||||
pos += 2;
|
pos += 2;
|
||||||
|
|
||||||
/* IEEE80211_RADIOTAP_DBM_ANTSIGNAL */
|
/* IEEE80211_RADIOTAP_DBM_ANTSIGNAL */
|
||||||
|
|
|
@ -1354,12 +1354,12 @@ ieee80211_sta_ps_deliver_response(struct sta_info *sta,
|
||||||
* Use MoreData flag to indicate whether there are
|
* Use MoreData flag to indicate whether there are
|
||||||
* more buffered frames for this STA
|
* more buffered frames for this STA
|
||||||
*/
|
*/
|
||||||
if (!more_data)
|
if (more_data || !skb_queue_empty(&frames))
|
||||||
hdr->frame_control &=
|
|
||||||
cpu_to_le16(~IEEE80211_FCTL_MOREDATA);
|
|
||||||
else
|
|
||||||
hdr->frame_control |=
|
hdr->frame_control |=
|
||||||
cpu_to_le16(IEEE80211_FCTL_MOREDATA);
|
cpu_to_le16(IEEE80211_FCTL_MOREDATA);
|
||||||
|
else
|
||||||
|
hdr->frame_control &=
|
||||||
|
cpu_to_le16(~IEEE80211_FCTL_MOREDATA);
|
||||||
|
|
||||||
if (ieee80211_is_data_qos(hdr->frame_control) ||
|
if (ieee80211_is_data_qos(hdr->frame_control) ||
|
||||||
ieee80211_is_qos_nullfunc(hdr->frame_control))
|
ieee80211_is_qos_nullfunc(hdr->frame_control))
|
||||||
|
|
|
@ -881,6 +881,8 @@ struct sk_buff *ieee80211_build_probe_req(struct ieee80211_sub_if_data *sdata,
|
||||||
skb = ieee80211_probereq_get(&local->hw, &sdata->vif,
|
skb = ieee80211_probereq_get(&local->hw, &sdata->vif,
|
||||||
ssid, ssid_len,
|
ssid, ssid_len,
|
||||||
buf, buf_len);
|
buf, buf_len);
|
||||||
|
if (!skb)
|
||||||
|
goto out;
|
||||||
|
|
||||||
if (dst) {
|
if (dst) {
|
||||||
mgmt = (struct ieee80211_mgmt *) skb->data;
|
mgmt = (struct ieee80211_mgmt *) skb->data;
|
||||||
|
@ -889,6 +891,8 @@ struct sk_buff *ieee80211_build_probe_req(struct ieee80211_sub_if_data *sdata,
|
||||||
}
|
}
|
||||||
|
|
||||||
IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT;
|
IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT;
|
||||||
|
|
||||||
|
out:
|
||||||
kfree(buf);
|
kfree(buf);
|
||||||
|
|
||||||
return skb;
|
return skb;
|
||||||
|
|
|
@ -9,7 +9,6 @@ config RDS
|
||||||
|
|
||||||
config RDS_RDMA
|
config RDS_RDMA
|
||||||
tristate "RDS over Infiniband and iWARP"
|
tristate "RDS over Infiniband and iWARP"
|
||||||
select LLIST
|
|
||||||
depends on RDS && INFINIBAND && INFINIBAND_ADDR_TRANS
|
depends on RDS && INFINIBAND && INFINIBAND_ADDR_TRANS
|
||||||
---help---
|
---help---
|
||||||
Allow RDS to use Infiniband and iWARP as a transport.
|
Allow RDS to use Infiniband and iWARP as a transport.
|
||||||
|
|
|
@ -132,8 +132,7 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = {
|
||||||
[NL80211_ATTR_MESH_CONFIG] = { .type = NLA_NESTED },
|
[NL80211_ATTR_MESH_CONFIG] = { .type = NLA_NESTED },
|
||||||
[NL80211_ATTR_SUPPORT_MESH_AUTH] = { .type = NLA_FLAG },
|
[NL80211_ATTR_SUPPORT_MESH_AUTH] = { .type = NLA_FLAG },
|
||||||
|
|
||||||
[NL80211_ATTR_HT_CAPABILITY] = { .type = NLA_BINARY,
|
[NL80211_ATTR_HT_CAPABILITY] = { .len = NL80211_HT_CAPABILITY_LEN },
|
||||||
.len = NL80211_HT_CAPABILITY_LEN },
|
|
||||||
|
|
||||||
[NL80211_ATTR_MGMT_SUBTYPE] = { .type = NLA_U8 },
|
[NL80211_ATTR_MGMT_SUBTYPE] = { .type = NLA_U8 },
|
||||||
[NL80211_ATTR_IE] = { .type = NLA_BINARY,
|
[NL80211_ATTR_IE] = { .type = NLA_BINARY,
|
||||||
|
@ -1253,6 +1252,12 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
|
||||||
goto bad_res;
|
goto bad_res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (netdev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
|
||||||
|
netdev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO) {
|
||||||
|
result = -EINVAL;
|
||||||
|
goto bad_res;
|
||||||
|
}
|
||||||
|
|
||||||
nla_for_each_nested(nl_txq_params,
|
nla_for_each_nested(nl_txq_params,
|
||||||
info->attrs[NL80211_ATTR_WIPHY_TXQ_PARAMS],
|
info->attrs[NL80211_ATTR_WIPHY_TXQ_PARAMS],
|
||||||
rem_txq_params) {
|
rem_txq_params) {
|
||||||
|
|
|
@ -2265,6 +2265,9 @@ void /* __init_or_exit */ regulatory_exit(void)
|
||||||
|
|
||||||
kfree(last_request);
|
kfree(last_request);
|
||||||
|
|
||||||
|
last_request = NULL;
|
||||||
|
dev_set_uevent_suppress(®_pdev->dev, true);
|
||||||
|
|
||||||
platform_device_unregister(reg_pdev);
|
platform_device_unregister(reg_pdev);
|
||||||
|
|
||||||
spin_lock_bh(®_pending_beacons_lock);
|
spin_lock_bh(®_pending_beacons_lock);
|
||||||
|
|
|
@ -259,17 +259,20 @@ static int cmp_ies(u8 num, u8 *ies1, size_t len1, u8 *ies2, size_t len2)
|
||||||
{
|
{
|
||||||
const u8 *ie1 = cfg80211_find_ie(num, ies1, len1);
|
const u8 *ie1 = cfg80211_find_ie(num, ies1, len1);
|
||||||
const u8 *ie2 = cfg80211_find_ie(num, ies2, len2);
|
const u8 *ie2 = cfg80211_find_ie(num, ies2, len2);
|
||||||
int r;
|
|
||||||
|
|
||||||
|
/* equal if both missing */
|
||||||
if (!ie1 && !ie2)
|
if (!ie1 && !ie2)
|
||||||
return 0;
|
return 0;
|
||||||
if (!ie1 || !ie2)
|
/* sort missing IE before (left of) present IE */
|
||||||
|
if (!ie1)
|
||||||
return -1;
|
return -1;
|
||||||
|
if (!ie2)
|
||||||
|
return 1;
|
||||||
|
|
||||||
r = memcmp(ie1 + 2, ie2 + 2, min(ie1[1], ie2[1]));
|
/* sort by length first, then by contents */
|
||||||
if (r == 0 && ie1[1] != ie2[1])
|
if (ie1[1] != ie2[1])
|
||||||
return ie2[1] - ie1[1];
|
return ie2[1] - ie1[1];
|
||||||
return r;
|
return memcmp(ie1 + 2, ie2 + 2, ie1[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool is_bss(struct cfg80211_bss *a,
|
static bool is_bss(struct cfg80211_bss *a,
|
||||||
|
|
Loading…
Reference in New Issue