mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-04-01 12:04:08 +00:00
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6: (108 commits) bridge: ensure to unlock in error path in br_multicast_query(). drivers/net/tulip/eeprom.c: fix bogus "(null)" in tulip init messages sky2: Avoid rtnl_unlock without rtnl_lock ipv6: Send netlink notification when DAD fails drivers/net/tg3.c: change the field used with the TG3_FLAG_10_100_ONLY constant ipconfig: Handle devices which take some time to come up. mac80211: Fix memory leak in ieee80211_if_write() mac80211: Fix (dynamic) power save entry ipw2200: use kmalloc for large local variables ath5k: read eeprom IQ calibration values correctly for G mode ath5k: fix I/Q calibration (for real) ath5k: fix TSF reset ath5k: use fixed antenna for tx descriptors libipw: split ieee->networks into small pieces mac80211: Fix sta_mtx unlocking on insert STA failure path rt2x00: remove KSEG1ADDR define from rt2x00soc.h net: add ColdFire support to the smc91x driver asix: fix setting mac address for AX88772 ipv6 ip6_tunnel: eliminate unused recursion field from ip6_tnl{}. net: Fix dev_mc_add() ...
This commit is contained in:
commit
d89b218b80
114 changed files with 1300 additions and 23812 deletions
21
MAINTAINERS
21
MAINTAINERS
|
@ -1405,20 +1405,30 @@ F: arch/x86/include/asm/calgary.h
|
||||||
F: arch/x86/include/asm/tce.h
|
F: arch/x86/include/asm/tce.h
|
||||||
|
|
||||||
CAN NETWORK LAYER
|
CAN NETWORK LAYER
|
||||||
M: Urs Thuermann <urs.thuermann@volkswagen.de>
|
M: Oliver Hartkopp <socketcan@hartkopp.net>
|
||||||
M: Oliver Hartkopp <oliver.hartkopp@volkswagen.de>
|
M: Oliver Hartkopp <oliver.hartkopp@volkswagen.de>
|
||||||
L: socketcan-core@lists.berlios.de (subscribers-only)
|
M: Urs Thuermann <urs.thuermann@volkswagen.de>
|
||||||
|
L: socketcan-core@lists.berlios.de
|
||||||
|
L: netdev@vger.kernel.org
|
||||||
W: http://developer.berlios.de/projects/socketcan/
|
W: http://developer.berlios.de/projects/socketcan/
|
||||||
S: Maintained
|
S: Maintained
|
||||||
F: drivers/net/can/
|
F: net/can/
|
||||||
F: include/linux/can/
|
|
||||||
F: include/linux/can.h
|
F: include/linux/can.h
|
||||||
|
F: include/linux/can/core.h
|
||||||
|
F: include/linux/can/bcm.h
|
||||||
|
F: include/linux/can/raw.h
|
||||||
|
|
||||||
CAN NETWORK DRIVERS
|
CAN NETWORK DRIVERS
|
||||||
M: Wolfgang Grandegger <wg@grandegger.com>
|
M: Wolfgang Grandegger <wg@grandegger.com>
|
||||||
L: socketcan-core@lists.berlios.de (subscribers-only)
|
L: socketcan-core@lists.berlios.de
|
||||||
|
L: netdev@vger.kernel.org
|
||||||
W: http://developer.berlios.de/projects/socketcan/
|
W: http://developer.berlios.de/projects/socketcan/
|
||||||
S: Maintained
|
S: Maintained
|
||||||
|
F: drivers/net/can/
|
||||||
|
F: include/linux/can/dev.h
|
||||||
|
F: include/linux/can/error.h
|
||||||
|
F: include/linux/can/netlink.h
|
||||||
|
F: include/linux/can/platform/
|
||||||
|
|
||||||
CELL BROADBAND ENGINE ARCHITECTURE
|
CELL BROADBAND ENGINE ARCHITECTURE
|
||||||
M: Arnd Bergmann <arnd@arndb.de>
|
M: Arnd Bergmann <arnd@arndb.de>
|
||||||
|
@ -2130,6 +2140,7 @@ F: drivers/net/eexpress.*
|
||||||
ETHERNET BRIDGE
|
ETHERNET BRIDGE
|
||||||
M: Stephen Hemminger <shemminger@linux-foundation.org>
|
M: Stephen Hemminger <shemminger@linux-foundation.org>
|
||||||
L: bridge@lists.linux-foundation.org
|
L: bridge@lists.linux-foundation.org
|
||||||
|
L: netdev@vger.kernel.org
|
||||||
W: http://www.linux-foundation.org/en/Net:Bridge
|
W: http://www.linux-foundation.org/en/Net:Bridge
|
||||||
S: Maintained
|
S: Maintained
|
||||||
F: include/linux/netfilter_bridge/
|
F: include/linux/netfilter_bridge/
|
||||||
|
|
|
@ -907,7 +907,7 @@ config SMC91X
|
||||||
select CRC32
|
select CRC32
|
||||||
select MII
|
select MII
|
||||||
depends on ARM || REDWOOD_5 || REDWOOD_6 || M32R || SUPERH || \
|
depends on ARM || REDWOOD_5 || REDWOOD_6 || M32R || SUPERH || \
|
||||||
MIPS || BLACKFIN || MN10300
|
MIPS || BLACKFIN || MN10300 || COLDFIRE
|
||||||
help
|
help
|
||||||
This is a driver for SMC's 91x series of Ethernet chipsets,
|
This is a driver for SMC's 91x series of Ethernet chipsets,
|
||||||
including the SMC91C94 and the SMC91C111. Say Y if you want it
|
including the SMC91C94 and the SMC91C111. Say Y if you want it
|
||||||
|
|
|
@ -575,9 +575,9 @@ static int ks8695_poll(struct napi_struct *napi, int budget)
|
||||||
if (work_done < budget) {
|
if (work_done < budget) {
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
spin_lock_irqsave(&ksp->rx_lock, flags);
|
spin_lock_irqsave(&ksp->rx_lock, flags);
|
||||||
|
__napi_complete(napi);
|
||||||
/*enable rx interrupt*/
|
/*enable rx interrupt*/
|
||||||
writel(isr | mask_bit, KS8695_IRQ_VA + KS8695_INTEN);
|
writel(isr | mask_bit, KS8695_IRQ_VA + KS8695_INTEN);
|
||||||
__napi_complete(napi);
|
|
||||||
spin_unlock_irqrestore(&ksp->rx_lock, flags);
|
spin_unlock_irqrestore(&ksp->rx_lock, flags);
|
||||||
}
|
}
|
||||||
return work_done;
|
return work_done;
|
||||||
|
|
|
@ -290,11 +290,6 @@ extern const struct ethtool_ops be_ethtool_ops;
|
||||||
|
|
||||||
#define drvr_stats(adapter) (&adapter->stats.drvr_stats)
|
#define drvr_stats(adapter) (&adapter->stats.drvr_stats)
|
||||||
|
|
||||||
static inline unsigned int be_pci_func(struct be_adapter *adapter)
|
|
||||||
{
|
|
||||||
return PCI_FUNC(adapter->pdev->devfn);
|
|
||||||
}
|
|
||||||
|
|
||||||
#define BE_SET_NETDEV_OPS(netdev, ops) (netdev->netdev_ops = ops)
|
#define BE_SET_NETDEV_OPS(netdev, ops) (netdev->netdev_ops = ops)
|
||||||
|
|
||||||
#define PAGE_SHIFT_4K 12
|
#define PAGE_SHIFT_4K 12
|
||||||
|
|
|
@ -465,8 +465,6 @@ int be_cmd_eq_create(struct be_adapter *adapter,
|
||||||
|
|
||||||
req->num_pages = cpu_to_le16(PAGES_4K_SPANNED(q_mem->va, q_mem->size));
|
req->num_pages = cpu_to_le16(PAGES_4K_SPANNED(q_mem->va, q_mem->size));
|
||||||
|
|
||||||
AMAP_SET_BITS(struct amap_eq_context, func, req->context,
|
|
||||||
be_pci_func(adapter));
|
|
||||||
AMAP_SET_BITS(struct amap_eq_context, valid, req->context, 1);
|
AMAP_SET_BITS(struct amap_eq_context, valid, req->context, 1);
|
||||||
/* 4byte eqe*/
|
/* 4byte eqe*/
|
||||||
AMAP_SET_BITS(struct amap_eq_context, size, req->context, 0);
|
AMAP_SET_BITS(struct amap_eq_context, size, req->context, 0);
|
||||||
|
@ -629,7 +627,6 @@ int be_cmd_cq_create(struct be_adapter *adapter,
|
||||||
AMAP_SET_BITS(struct amap_cq_context, eventable, ctxt, 1);
|
AMAP_SET_BITS(struct amap_cq_context, eventable, ctxt, 1);
|
||||||
AMAP_SET_BITS(struct amap_cq_context, eqid, ctxt, eq->id);
|
AMAP_SET_BITS(struct amap_cq_context, eqid, ctxt, eq->id);
|
||||||
AMAP_SET_BITS(struct amap_cq_context, armed, ctxt, 1);
|
AMAP_SET_BITS(struct amap_cq_context, armed, ctxt, 1);
|
||||||
AMAP_SET_BITS(struct amap_cq_context, func, ctxt, be_pci_func(adapter));
|
|
||||||
be_dws_cpu_to_le(ctxt, sizeof(req->context));
|
be_dws_cpu_to_le(ctxt, sizeof(req->context));
|
||||||
|
|
||||||
be_cmd_page_addrs_prepare(req->pages, ARRAY_SIZE(req->pages), q_mem);
|
be_cmd_page_addrs_prepare(req->pages, ARRAY_SIZE(req->pages), q_mem);
|
||||||
|
@ -678,7 +675,6 @@ int be_cmd_mccq_create(struct be_adapter *adapter,
|
||||||
|
|
||||||
req->num_pages = PAGES_4K_SPANNED(q_mem->va, q_mem->size);
|
req->num_pages = PAGES_4K_SPANNED(q_mem->va, q_mem->size);
|
||||||
|
|
||||||
AMAP_SET_BITS(struct amap_mcc_context, fid, ctxt, be_pci_func(adapter));
|
|
||||||
AMAP_SET_BITS(struct amap_mcc_context, valid, ctxt, 1);
|
AMAP_SET_BITS(struct amap_mcc_context, valid, ctxt, 1);
|
||||||
AMAP_SET_BITS(struct amap_mcc_context, ring_size, ctxt,
|
AMAP_SET_BITS(struct amap_mcc_context, ring_size, ctxt,
|
||||||
be_encoded_q_len(mccq->len));
|
be_encoded_q_len(mccq->len));
|
||||||
|
@ -727,8 +723,6 @@ int be_cmd_txq_create(struct be_adapter *adapter,
|
||||||
|
|
||||||
AMAP_SET_BITS(struct amap_tx_context, tx_ring_size, ctxt,
|
AMAP_SET_BITS(struct amap_tx_context, tx_ring_size, ctxt,
|
||||||
be_encoded_q_len(txq->len));
|
be_encoded_q_len(txq->len));
|
||||||
AMAP_SET_BITS(struct amap_tx_context, pci_func_id, ctxt,
|
|
||||||
be_pci_func(adapter));
|
|
||||||
AMAP_SET_BITS(struct amap_tx_context, ctx_valid, ctxt, 1);
|
AMAP_SET_BITS(struct amap_tx_context, ctx_valid, ctxt, 1);
|
||||||
AMAP_SET_BITS(struct amap_tx_context, cq_id_send, ctxt, cq->id);
|
AMAP_SET_BITS(struct amap_tx_context, cq_id_send, ctxt, cq->id);
|
||||||
|
|
||||||
|
|
|
@ -114,8 +114,7 @@
|
||||||
#define IMG_TYPE_ISCSI_BACKUP 9
|
#define IMG_TYPE_ISCSI_BACKUP 9
|
||||||
#define IMG_TYPE_FCOE_FW_ACTIVE 10
|
#define IMG_TYPE_FCOE_FW_ACTIVE 10
|
||||||
#define IMG_TYPE_FCOE_FW_BACKUP 11
|
#define IMG_TYPE_FCOE_FW_BACKUP 11
|
||||||
#define IMG_TYPE_NCSI_BITFILE 13
|
#define IMG_TYPE_NCSI_FW 13
|
||||||
#define IMG_TYPE_NCSI_8051 14
|
|
||||||
|
|
||||||
#define FLASHROM_OPER_FLASH 1
|
#define FLASHROM_OPER_FLASH 1
|
||||||
#define FLASHROM_OPER_SAVE 2
|
#define FLASHROM_OPER_SAVE 2
|
||||||
|
@ -127,6 +126,7 @@
|
||||||
#define FLASH_IMAGE_MAX_SIZE_g3 (2097152) /* Max fw image size */
|
#define FLASH_IMAGE_MAX_SIZE_g3 (2097152) /* Max fw image size */
|
||||||
#define FLASH_BIOS_IMAGE_MAX_SIZE_g3 (524288) /* Max OPTION ROM img sz */
|
#define FLASH_BIOS_IMAGE_MAX_SIZE_g3 (524288) /* Max OPTION ROM img sz */
|
||||||
#define FLASH_REDBOOT_IMAGE_MAX_SIZE_g3 (1048576) /* Max Redboot image sz */
|
#define FLASH_REDBOOT_IMAGE_MAX_SIZE_g3 (1048576) /* Max Redboot image sz */
|
||||||
|
#define FLASH_NCSI_IMAGE_MAX_SIZE_g3 (262144) /* Max NSCI image sz */
|
||||||
|
|
||||||
#define FLASH_NCSI_MAGIC (0x16032009)
|
#define FLASH_NCSI_MAGIC (0x16032009)
|
||||||
#define FLASH_NCSI_DISABLED (0)
|
#define FLASH_NCSI_DISABLED (0)
|
||||||
|
@ -144,6 +144,7 @@
|
||||||
#define FLASH_FCoE_BIOS_START_g2 (524288)
|
#define FLASH_FCoE_BIOS_START_g2 (524288)
|
||||||
#define FLASH_REDBOOT_START_g2 (0)
|
#define FLASH_REDBOOT_START_g2 (0)
|
||||||
|
|
||||||
|
#define FLASH_NCSI_START_g3 (15990784)
|
||||||
#define FLASH_iSCSI_PRIMARY_IMAGE_START_g3 (2097152)
|
#define FLASH_iSCSI_PRIMARY_IMAGE_START_g3 (2097152)
|
||||||
#define FLASH_iSCSI_BACKUP_IMAGE_START_g3 (4194304)
|
#define FLASH_iSCSI_BACKUP_IMAGE_START_g3 (4194304)
|
||||||
#define FLASH_FCoE_PRIMARY_IMAGE_START_g3 (6291456)
|
#define FLASH_FCoE_PRIMARY_IMAGE_START_g3 (6291456)
|
||||||
|
|
|
@ -1382,7 +1382,7 @@ rx_eq_free:
|
||||||
/* There are 8 evt ids per func. Retruns the evt id's bit number */
|
/* There are 8 evt ids per func. Retruns the evt id's bit number */
|
||||||
static inline int be_evt_bit_get(struct be_adapter *adapter, u32 eq_id)
|
static inline int be_evt_bit_get(struct be_adapter *adapter, u32 eq_id)
|
||||||
{
|
{
|
||||||
return eq_id - 8 * be_pci_func(adapter);
|
return eq_id % 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
static irqreturn_t be_intx(int irq, void *dev)
|
static irqreturn_t be_intx(int irq, void *dev)
|
||||||
|
@ -1880,8 +1880,9 @@ static int be_flash_data(struct be_adapter *adapter,
|
||||||
const u8 *p = fw->data;
|
const u8 *p = fw->data;
|
||||||
struct be_cmd_write_flashrom *req = flash_cmd->va;
|
struct be_cmd_write_flashrom *req = flash_cmd->va;
|
||||||
struct flash_comp *pflashcomp;
|
struct flash_comp *pflashcomp;
|
||||||
|
int num_comp;
|
||||||
|
|
||||||
struct flash_comp gen3_flash_types[8] = {
|
struct flash_comp gen3_flash_types[9] = {
|
||||||
{ FLASH_iSCSI_PRIMARY_IMAGE_START_g3, IMG_TYPE_ISCSI_ACTIVE,
|
{ FLASH_iSCSI_PRIMARY_IMAGE_START_g3, IMG_TYPE_ISCSI_ACTIVE,
|
||||||
FLASH_IMAGE_MAX_SIZE_g3},
|
FLASH_IMAGE_MAX_SIZE_g3},
|
||||||
{ FLASH_REDBOOT_START_g3, IMG_TYPE_REDBOOT,
|
{ FLASH_REDBOOT_START_g3, IMG_TYPE_REDBOOT,
|
||||||
|
@ -1897,7 +1898,9 @@ static int be_flash_data(struct be_adapter *adapter,
|
||||||
{ FLASH_FCoE_PRIMARY_IMAGE_START_g3, IMG_TYPE_FCOE_FW_ACTIVE,
|
{ FLASH_FCoE_PRIMARY_IMAGE_START_g3, IMG_TYPE_FCOE_FW_ACTIVE,
|
||||||
FLASH_IMAGE_MAX_SIZE_g3},
|
FLASH_IMAGE_MAX_SIZE_g3},
|
||||||
{ FLASH_FCoE_BACKUP_IMAGE_START_g3, IMG_TYPE_FCOE_FW_BACKUP,
|
{ FLASH_FCoE_BACKUP_IMAGE_START_g3, IMG_TYPE_FCOE_FW_BACKUP,
|
||||||
FLASH_IMAGE_MAX_SIZE_g3}
|
FLASH_IMAGE_MAX_SIZE_g3},
|
||||||
|
{ FLASH_NCSI_START_g3, IMG_TYPE_NCSI_FW,
|
||||||
|
FLASH_NCSI_IMAGE_MAX_SIZE_g3}
|
||||||
};
|
};
|
||||||
struct flash_comp gen2_flash_types[8] = {
|
struct flash_comp gen2_flash_types[8] = {
|
||||||
{ FLASH_iSCSI_PRIMARY_IMAGE_START_g2, IMG_TYPE_ISCSI_ACTIVE,
|
{ FLASH_iSCSI_PRIMARY_IMAGE_START_g2, IMG_TYPE_ISCSI_ACTIVE,
|
||||||
|
@ -1921,11 +1924,16 @@ static int be_flash_data(struct be_adapter *adapter,
|
||||||
if (adapter->generation == BE_GEN3) {
|
if (adapter->generation == BE_GEN3) {
|
||||||
pflashcomp = gen3_flash_types;
|
pflashcomp = gen3_flash_types;
|
||||||
filehdr_size = sizeof(struct flash_file_hdr_g3);
|
filehdr_size = sizeof(struct flash_file_hdr_g3);
|
||||||
|
num_comp = 9;
|
||||||
} else {
|
} else {
|
||||||
pflashcomp = gen2_flash_types;
|
pflashcomp = gen2_flash_types;
|
||||||
filehdr_size = sizeof(struct flash_file_hdr_g2);
|
filehdr_size = sizeof(struct flash_file_hdr_g2);
|
||||||
|
num_comp = 8;
|
||||||
}
|
}
|
||||||
for (i = 0; i < 8; i++) {
|
for (i = 0; i < num_comp; i++) {
|
||||||
|
if ((pflashcomp[i].optype == IMG_TYPE_NCSI_FW) &&
|
||||||
|
memcmp(adapter->fw_ver, "3.102.148.0", 11) < 0)
|
||||||
|
continue;
|
||||||
if ((pflashcomp[i].optype == IMG_TYPE_REDBOOT) &&
|
if ((pflashcomp[i].optype == IMG_TYPE_REDBOOT) &&
|
||||||
(!be_flash_redboot(adapter, fw->data,
|
(!be_flash_redboot(adapter, fw->data,
|
||||||
pflashcomp[i].offset, pflashcomp[i].size,
|
pflashcomp[i].offset, pflashcomp[i].size,
|
||||||
|
@ -1985,16 +1993,7 @@ int be_load_fw(struct be_adapter *adapter, u8 *func)
|
||||||
struct be_dma_mem flash_cmd;
|
struct be_dma_mem flash_cmd;
|
||||||
int status, i = 0;
|
int status, i = 0;
|
||||||
const u8 *p;
|
const u8 *p;
|
||||||
char fw_ver[FW_VER_LEN];
|
|
||||||
char fw_cfg;
|
|
||||||
|
|
||||||
status = be_cmd_get_fw_ver(adapter, fw_ver);
|
|
||||||
if (status)
|
|
||||||
return status;
|
|
||||||
|
|
||||||
fw_cfg = *(fw_ver + 2);
|
|
||||||
if (fw_cfg == '0')
|
|
||||||
fw_cfg = '1';
|
|
||||||
strcpy(fw_file, func);
|
strcpy(fw_file, func);
|
||||||
|
|
||||||
status = request_firmware(&fw, fw_file, &adapter->pdev->dev);
|
status = request_firmware(&fw, fw_file, &adapter->pdev->dev);
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
|
|
||||||
#define DRV_NAME "bfin_can"
|
#define DRV_NAME "bfin_can"
|
||||||
#define BFIN_CAN_TIMEOUT 100
|
#define BFIN_CAN_TIMEOUT 100
|
||||||
|
#define TX_ECHO_SKB_MAX 1
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* transmit and receive channels
|
* transmit and receive channels
|
||||||
|
@ -593,7 +594,7 @@ struct net_device *alloc_bfin_candev(void)
|
||||||
struct net_device *dev;
|
struct net_device *dev;
|
||||||
struct bfin_can_priv *priv;
|
struct bfin_can_priv *priv;
|
||||||
|
|
||||||
dev = alloc_candev(sizeof(*priv));
|
dev = alloc_candev(sizeof(*priv), TX_ECHO_SKB_MAX);
|
||||||
if (!dev)
|
if (!dev)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
|
|
@ -876,9 +876,7 @@ static netdev_tx_t ems_usb_start_xmit(struct sk_buff *skb, struct net_device *ne
|
||||||
return NETDEV_TX_OK;
|
return NETDEV_TX_OK;
|
||||||
|
|
||||||
nomem:
|
nomem:
|
||||||
if (skb)
|
dev_kfree_skb(skb);
|
||||||
dev_kfree_skb(skb);
|
|
||||||
|
|
||||||
stats->tx_dropped++;
|
stats->tx_dropped++;
|
||||||
|
|
||||||
return NETDEV_TX_OK;
|
return NETDEV_TX_OK;
|
||||||
|
|
|
@ -5072,7 +5072,7 @@ static int __devinit cas_init_one(struct pci_dev *pdev,
|
||||||
INIT_WORK(&cp->reset_task, cas_reset_task);
|
INIT_WORK(&cp->reset_task, cas_reset_task);
|
||||||
|
|
||||||
/* Default link parameters */
|
/* Default link parameters */
|
||||||
if (link_mode >= 0 && link_mode <= 6)
|
if (link_mode >= 0 && link_mode < 6)
|
||||||
cp->link_cntl = link_modes[link_mode];
|
cp->link_cntl = link_modes[link_mode];
|
||||||
else
|
else
|
||||||
cp->link_cntl = BMCR_ANENABLE;
|
cp->link_cntl = BMCR_ANENABLE;
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
#include <linux/delay.h>
|
#include <linux/delay.h>
|
||||||
|
|
||||||
#include <linux/netdevice.h>
|
#include <linux/netdevice.h>
|
||||||
|
#include <linux/if_vlan.h>
|
||||||
#include <linux/etherdevice.h>
|
#include <linux/etherdevice.h>
|
||||||
#include <linux/ethtool.h>
|
#include <linux/ethtool.h>
|
||||||
#include <linux/skbuff.h>
|
#include <linux/skbuff.h>
|
||||||
|
@ -55,9 +56,9 @@ module_param(dumb_switch, int, 0444);
|
||||||
MODULE_PARM_DESC(debug_level, "Number of NETIF_MSG bits to enable");
|
MODULE_PARM_DESC(debug_level, "Number of NETIF_MSG bits to enable");
|
||||||
MODULE_PARM_DESC(dumb_switch, "Assume switch is not connected to MDIO bus");
|
MODULE_PARM_DESC(dumb_switch, "Assume switch is not connected to MDIO bus");
|
||||||
|
|
||||||
#define CPMAC_VERSION "0.5.1"
|
#define CPMAC_VERSION "0.5.2"
|
||||||
/* frame size + 802.1q tag */
|
/* frame size + 802.1q tag + FCS size */
|
||||||
#define CPMAC_SKB_SIZE (ETH_FRAME_LEN + 4)
|
#define CPMAC_SKB_SIZE (ETH_FRAME_LEN + ETH_FCS_LEN + VLAN_HLEN)
|
||||||
#define CPMAC_QUEUES 8
|
#define CPMAC_QUEUES 8
|
||||||
|
|
||||||
/* Ethernet registers */
|
/* Ethernet registers */
|
||||||
|
@ -1136,8 +1137,9 @@ static int __devinit cpmac_probe(struct platform_device *pdev)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (phy_id == PHY_MAX_ADDR) {
|
if (phy_id == PHY_MAX_ADDR) {
|
||||||
dev_err(&pdev->dev, "no PHY present\n");
|
dev_err(&pdev->dev, "no PHY present, falling back to switch on MDIO bus 0\n");
|
||||||
return -ENODEV;
|
strncpy(mdio_bus_id, "0", MII_BUS_ID_SIZE); /* fixed phys bus */
|
||||||
|
phy_id = pdev->id;
|
||||||
}
|
}
|
||||||
|
|
||||||
dev = alloc_etherdev_mq(sizeof(*priv), CPMAC_QUEUES);
|
dev = alloc_etherdev_mq(sizeof(*priv), CPMAC_QUEUES);
|
||||||
|
@ -1290,8 +1292,8 @@ void __devexit cpmac_exit(void)
|
||||||
{
|
{
|
||||||
platform_driver_unregister(&cpmac_driver);
|
platform_driver_unregister(&cpmac_driver);
|
||||||
mdiobus_unregister(cpmac_mii);
|
mdiobus_unregister(cpmac_mii);
|
||||||
mdiobus_free(cpmac_mii);
|
|
||||||
iounmap(cpmac_mii->priv);
|
iounmap(cpmac_mii->priv);
|
||||||
|
mdiobus_free(cpmac_mii);
|
||||||
}
|
}
|
||||||
|
|
||||||
module_init(cpmac_init);
|
module_init(cpmac_init);
|
||||||
|
|
|
@ -1294,6 +1294,7 @@ static void cxgb_down(struct adapter *adapter)
|
||||||
|
|
||||||
free_irq_resources(adapter);
|
free_irq_resources(adapter);
|
||||||
quiesce_rx(adapter);
|
quiesce_rx(adapter);
|
||||||
|
t3_sge_stop(adapter);
|
||||||
flush_workqueue(cxgb3_wq); /* wait for external IRQ handler */
|
flush_workqueue(cxgb3_wq); /* wait for external IRQ handler */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2385,7 +2385,7 @@ static int emac_dev_open(struct net_device *ndev)
|
||||||
struct emac_priv *priv = netdev_priv(ndev);
|
struct emac_priv *priv = netdev_priv(ndev);
|
||||||
|
|
||||||
netif_carrier_off(ndev);
|
netif_carrier_off(ndev);
|
||||||
for (cnt = 0; cnt <= ETH_ALEN; cnt++)
|
for (cnt = 0; cnt < ETH_ALEN; cnt++)
|
||||||
ndev->dev_addr[cnt] = priv->mac_addr[cnt];
|
ndev->dev_addr[cnt] = priv->mac_addr[cnt];
|
||||||
|
|
||||||
/* Configuration items */
|
/* Configuration items */
|
||||||
|
|
|
@ -320,6 +320,8 @@
|
||||||
#define E1000_RXCSUM_IPPCSE 0x00001000 /* IP payload checksum enable */
|
#define E1000_RXCSUM_IPPCSE 0x00001000 /* IP payload checksum enable */
|
||||||
|
|
||||||
/* Header split receive */
|
/* Header split receive */
|
||||||
|
#define E1000_RFCTL_NFSW_DIS 0x00000040
|
||||||
|
#define E1000_RFCTL_NFSR_DIS 0x00000080
|
||||||
#define E1000_RFCTL_ACK_DIS 0x00001000
|
#define E1000_RFCTL_ACK_DIS 0x00001000
|
||||||
#define E1000_RFCTL_EXTEN 0x00008000
|
#define E1000_RFCTL_EXTEN 0x00008000
|
||||||
#define E1000_RFCTL_IPV6_EX_DIS 0x00010000
|
#define E1000_RFCTL_IPV6_EX_DIS 0x00010000
|
||||||
|
|
|
@ -2740,6 +2740,16 @@ static void e1000_initialize_hw_bits_ich8lan(struct e1000_hw *hw)
|
||||||
reg &= ~(1 << 31);
|
reg &= ~(1 << 31);
|
||||||
ew32(STATUS, reg);
|
ew32(STATUS, reg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* work-around descriptor data corruption issue during nfs v2 udp
|
||||||
|
* traffic, just disable the nfs filtering capability
|
||||||
|
*/
|
||||||
|
reg = er32(RFCTL);
|
||||||
|
reg |= (E1000_RFCTL_NFSW_DIS | E1000_RFCTL_NFSR_DIS);
|
||||||
|
ew32(RFCTL, reg);
|
||||||
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -2021,7 +2021,6 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* setup the TxBD length and buffer pointer for the first BD */
|
/* setup the TxBD length and buffer pointer for the first BD */
|
||||||
tx_queue->tx_skbuff[tx_queue->skb_curtx] = skb;
|
|
||||||
txbdp_start->bufPtr = dma_map_single(&priv->ofdev->dev, skb->data,
|
txbdp_start->bufPtr = dma_map_single(&priv->ofdev->dev, skb->data,
|
||||||
skb_headlen(skb), DMA_TO_DEVICE);
|
skb_headlen(skb), DMA_TO_DEVICE);
|
||||||
|
|
||||||
|
@ -2053,6 +2052,10 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev)
|
||||||
|
|
||||||
txbdp_start->lstatus = lstatus;
|
txbdp_start->lstatus = lstatus;
|
||||||
|
|
||||||
|
eieio(); /* force lstatus write before tx_skbuff */
|
||||||
|
|
||||||
|
tx_queue->tx_skbuff[tx_queue->skb_curtx] = skb;
|
||||||
|
|
||||||
/* Update the current skb pointer to the next entry we will use
|
/* Update the current skb pointer to the next entry we will use
|
||||||
* (wrapping if necessary) */
|
* (wrapping if necessary) */
|
||||||
tx_queue->skb_curtx = (tx_queue->skb_curtx + 1) &
|
tx_queue->skb_curtx = (tx_queue->skb_curtx + 1) &
|
||||||
|
|
|
@ -1651,6 +1651,8 @@ static int irda_usb_probe(struct usb_interface *intf,
|
||||||
|
|
||||||
self->rx_urb = kcalloc(self->max_rx_urb, sizeof(struct urb *),
|
self->rx_urb = kcalloc(self->max_rx_urb, sizeof(struct urb *),
|
||||||
GFP_KERNEL);
|
GFP_KERNEL);
|
||||||
|
if (!self->rx_urb)
|
||||||
|
goto err_free_net;
|
||||||
|
|
||||||
for (i = 0; i < self->max_rx_urb; i++) {
|
for (i = 0; i < self->max_rx_urb; i++) {
|
||||||
self->rx_urb[i] = usb_alloc_urb(0, GFP_KERNEL);
|
self->rx_urb[i] = usb_alloc_urb(0, GFP_KERNEL);
|
||||||
|
@ -1783,6 +1785,8 @@ err_out_2:
|
||||||
err_out_1:
|
err_out_1:
|
||||||
for (i = 0; i < self->max_rx_urb; i++)
|
for (i = 0; i < self->max_rx_urb; i++)
|
||||||
usb_free_urb(self->rx_urb[i]);
|
usb_free_urb(self->rx_urb[i]);
|
||||||
|
kfree(self->rx_urb);
|
||||||
|
err_free_net:
|
||||||
free_netdev(net);
|
free_netdev(net);
|
||||||
err_out:
|
err_out:
|
||||||
return ret;
|
return ret;
|
||||||
|
|
|
@ -423,6 +423,11 @@ struct qlcnic_adapter_stats {
|
||||||
u64 lro_pkts;
|
u64 lro_pkts;
|
||||||
u64 rxbytes;
|
u64 rxbytes;
|
||||||
u64 txbytes;
|
u64 txbytes;
|
||||||
|
u64 lrobytes;
|
||||||
|
u64 lso_frames;
|
||||||
|
u64 xmit_on;
|
||||||
|
u64 xmit_off;
|
||||||
|
u64 skb_alloc_failure;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1095,11 +1100,11 @@ struct qlcnic_brdinfo {
|
||||||
|
|
||||||
static const struct qlcnic_brdinfo qlcnic_boards[] = {
|
static const struct qlcnic_brdinfo qlcnic_boards[] = {
|
||||||
{0x1077, 0x8020, 0x1077, 0x203,
|
{0x1077, 0x8020, 0x1077, 0x203,
|
||||||
"8200 Series Single Port 10GbE Converged Network Adapter \
|
"8200 Series Single Port 10GbE Converged Network Adapter "
|
||||||
(TCP/IP Networking)"},
|
"(TCP/IP Networking)"},
|
||||||
{0x1077, 0x8020, 0x1077, 0x207,
|
{0x1077, 0x8020, 0x1077, 0x207,
|
||||||
"8200 Series Dual Port 10GbE Converged Network Adapter \
|
"8200 Series Dual Port 10GbE Converged Network Adapter "
|
||||||
(TCP/IP Networking)"},
|
"(TCP/IP Networking)"},
|
||||||
{0x1077, 0x8020, 0x1077, 0x20b,
|
{0x1077, 0x8020, 0x1077, 0x20b,
|
||||||
"3200 Series Dual Port 10Gb Intelligent Ethernet Adapter"},
|
"3200 Series Dual Port 10Gb Intelligent Ethernet Adapter"},
|
||||||
{0x1077, 0x8020, 0x1077, 0x20c,
|
{0x1077, 0x8020, 0x1077, 0x20c,
|
||||||
|
|
|
@ -59,6 +59,17 @@ static const struct qlcnic_stats qlcnic_gstrings_stats[] = {
|
||||||
QLC_SIZEOF(stats.rxbytes), QLC_OFF(stats.rxbytes)},
|
QLC_SIZEOF(stats.rxbytes), QLC_OFF(stats.rxbytes)},
|
||||||
{"tx_bytes",
|
{"tx_bytes",
|
||||||
QLC_SIZEOF(stats.txbytes), QLC_OFF(stats.txbytes)},
|
QLC_SIZEOF(stats.txbytes), QLC_OFF(stats.txbytes)},
|
||||||
|
{"lrobytes",
|
||||||
|
QLC_SIZEOF(stats.lrobytes), QLC_OFF(stats.lrobytes)},
|
||||||
|
{"lso_frames",
|
||||||
|
QLC_SIZEOF(stats.lso_frames), QLC_OFF(stats.lso_frames)},
|
||||||
|
{"xmit_on",
|
||||||
|
QLC_SIZEOF(stats.xmit_on), QLC_OFF(stats.xmit_on)},
|
||||||
|
{"xmit_off",
|
||||||
|
QLC_SIZEOF(stats.xmit_off), QLC_OFF(stats.xmit_off)},
|
||||||
|
{"skb_alloc_failure", QLC_SIZEOF(stats.skb_alloc_failure),
|
||||||
|
QLC_OFF(stats.skb_alloc_failure)},
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#define QLCNIC_STATS_LEN ARRAY_SIZE(qlcnic_gstrings_stats)
|
#define QLCNIC_STATS_LEN ARRAY_SIZE(qlcnic_gstrings_stats)
|
||||||
|
@ -785,6 +796,11 @@ qlcnic_get_ethtool_stats(struct net_device *dev,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static u32 qlcnic_get_tx_csum(struct net_device *dev)
|
||||||
|
{
|
||||||
|
return dev->features & NETIF_F_IP_CSUM;
|
||||||
|
}
|
||||||
|
|
||||||
static u32 qlcnic_get_rx_csum(struct net_device *dev)
|
static u32 qlcnic_get_rx_csum(struct net_device *dev)
|
||||||
{
|
{
|
||||||
struct qlcnic_adapter *adapter = netdev_priv(dev);
|
struct qlcnic_adapter *adapter = netdev_priv(dev);
|
||||||
|
@ -995,6 +1011,7 @@ const struct ethtool_ops qlcnic_ethtool_ops = {
|
||||||
.set_ringparam = qlcnic_set_ringparam,
|
.set_ringparam = qlcnic_set_ringparam,
|
||||||
.get_pauseparam = qlcnic_get_pauseparam,
|
.get_pauseparam = qlcnic_get_pauseparam,
|
||||||
.set_pauseparam = qlcnic_set_pauseparam,
|
.set_pauseparam = qlcnic_set_pauseparam,
|
||||||
|
.get_tx_csum = qlcnic_get_tx_csum,
|
||||||
.set_tx_csum = ethtool_op_set_tx_csum,
|
.set_tx_csum = ethtool_op_set_tx_csum,
|
||||||
.set_sg = ethtool_op_set_sg,
|
.set_sg = ethtool_op_set_sg,
|
||||||
.get_tso = qlcnic_get_tso,
|
.get_tso = qlcnic_get_tso,
|
||||||
|
|
|
@ -349,6 +349,7 @@ qlcnic_send_cmd_descs(struct qlcnic_adapter *adapter,
|
||||||
if (nr_desc >= qlcnic_tx_avail(tx_ring)) {
|
if (nr_desc >= qlcnic_tx_avail(tx_ring)) {
|
||||||
netif_tx_stop_queue(tx_ring->txq);
|
netif_tx_stop_queue(tx_ring->txq);
|
||||||
__netif_tx_unlock_bh(tx_ring->txq);
|
__netif_tx_unlock_bh(tx_ring->txq);
|
||||||
|
adapter->stats.xmit_off++;
|
||||||
return -EBUSY;
|
return -EBUSY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -397,20 +398,16 @@ qlcnic_sre_macaddr_change(struct qlcnic_adapter *adapter, u8 *addr,
|
||||||
return qlcnic_send_cmd_descs(adapter, (struct cmd_desc_type0 *)&req, 1);
|
return qlcnic_send_cmd_descs(adapter, (struct cmd_desc_type0 *)&req, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int qlcnic_nic_add_mac(struct qlcnic_adapter *adapter,
|
static int qlcnic_nic_add_mac(struct qlcnic_adapter *adapter, u8 *addr)
|
||||||
u8 *addr, struct list_head *del_list)
|
|
||||||
{
|
{
|
||||||
struct list_head *head;
|
struct list_head *head;
|
||||||
struct qlcnic_mac_list_s *cur;
|
struct qlcnic_mac_list_s *cur;
|
||||||
|
|
||||||
/* look up if already exists */
|
/* look up if already exists */
|
||||||
list_for_each(head, del_list) {
|
list_for_each(head, &adapter->mac_list) {
|
||||||
cur = list_entry(head, struct qlcnic_mac_list_s, list);
|
cur = list_entry(head, struct qlcnic_mac_list_s, list);
|
||||||
|
if (memcmp(addr, cur->mac_addr, ETH_ALEN) == 0)
|
||||||
if (memcmp(addr, cur->mac_addr, ETH_ALEN) == 0) {
|
|
||||||
list_move_tail(head, &adapter->mac_list);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cur = kzalloc(sizeof(struct qlcnic_mac_list_s), GFP_ATOMIC);
|
cur = kzalloc(sizeof(struct qlcnic_mac_list_s), GFP_ATOMIC);
|
||||||
|
@ -432,14 +429,9 @@ void qlcnic_set_multi(struct net_device *netdev)
|
||||||
struct dev_mc_list *mc_ptr;
|
struct dev_mc_list *mc_ptr;
|
||||||
u8 bcast_addr[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
|
u8 bcast_addr[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
|
||||||
u32 mode = VPORT_MISS_MODE_DROP;
|
u32 mode = VPORT_MISS_MODE_DROP;
|
||||||
LIST_HEAD(del_list);
|
|
||||||
struct list_head *head;
|
|
||||||
struct qlcnic_mac_list_s *cur;
|
|
||||||
|
|
||||||
list_splice_tail_init(&adapter->mac_list, &del_list);
|
qlcnic_nic_add_mac(adapter, adapter->mac_addr);
|
||||||
|
qlcnic_nic_add_mac(adapter, bcast_addr);
|
||||||
qlcnic_nic_add_mac(adapter, adapter->mac_addr, &del_list);
|
|
||||||
qlcnic_nic_add_mac(adapter, bcast_addr, &del_list);
|
|
||||||
|
|
||||||
if (netdev->flags & IFF_PROMISC) {
|
if (netdev->flags & IFF_PROMISC) {
|
||||||
mode = VPORT_MISS_MODE_ACCEPT_ALL;
|
mode = VPORT_MISS_MODE_ACCEPT_ALL;
|
||||||
|
@ -454,22 +446,12 @@ void qlcnic_set_multi(struct net_device *netdev)
|
||||||
|
|
||||||
if (!netdev_mc_empty(netdev)) {
|
if (!netdev_mc_empty(netdev)) {
|
||||||
netdev_for_each_mc_addr(mc_ptr, netdev) {
|
netdev_for_each_mc_addr(mc_ptr, netdev) {
|
||||||
qlcnic_nic_add_mac(adapter, mc_ptr->dmi_addr,
|
qlcnic_nic_add_mac(adapter, mc_ptr->dmi_addr);
|
||||||
&del_list);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
send_fw_cmd:
|
send_fw_cmd:
|
||||||
qlcnic_nic_set_promisc(adapter, mode);
|
qlcnic_nic_set_promisc(adapter, mode);
|
||||||
head = &del_list;
|
|
||||||
while (!list_empty(head)) {
|
|
||||||
cur = list_entry(head->next, struct qlcnic_mac_list_s, list);
|
|
||||||
|
|
||||||
qlcnic_sre_macaddr_change(adapter,
|
|
||||||
cur->mac_addr, QLCNIC_MAC_DEL);
|
|
||||||
list_del(&cur->list);
|
|
||||||
kfree(cur);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int qlcnic_nic_set_promisc(struct qlcnic_adapter *adapter, u32 mode)
|
int qlcnic_nic_set_promisc(struct qlcnic_adapter *adapter, u32 mode)
|
||||||
|
|
|
@ -568,21 +568,123 @@ struct uni_table_desc *qlcnic_get_table_desc(const u8 *unirom, int section)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define FILEHEADER_SIZE (14 * 4)
|
||||||
|
|
||||||
static int
|
static int
|
||||||
qlcnic_set_product_offs(struct qlcnic_adapter *adapter)
|
qlcnic_validate_header(struct qlcnic_adapter *adapter)
|
||||||
|
{
|
||||||
|
const u8 *unirom = adapter->fw->data;
|
||||||
|
struct uni_table_desc *directory = (struct uni_table_desc *) &unirom[0];
|
||||||
|
__le32 fw_file_size = adapter->fw->size;
|
||||||
|
__le32 entries;
|
||||||
|
__le32 entry_size;
|
||||||
|
__le32 tab_size;
|
||||||
|
|
||||||
|
if (fw_file_size < FILEHEADER_SIZE)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
entries = cpu_to_le32(directory->num_entries);
|
||||||
|
entry_size = cpu_to_le32(directory->entry_size);
|
||||||
|
tab_size = cpu_to_le32(directory->findex) + (entries * entry_size);
|
||||||
|
|
||||||
|
if (fw_file_size < tab_size)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
qlcnic_validate_bootld(struct qlcnic_adapter *adapter)
|
||||||
|
{
|
||||||
|
struct uni_table_desc *tab_desc;
|
||||||
|
struct uni_data_desc *descr;
|
||||||
|
const u8 *unirom = adapter->fw->data;
|
||||||
|
int idx = cpu_to_le32(*((int *)&unirom[adapter->file_prd_off] +
|
||||||
|
QLCNIC_UNI_BOOTLD_IDX_OFF));
|
||||||
|
__le32 offs;
|
||||||
|
__le32 tab_size;
|
||||||
|
__le32 data_size;
|
||||||
|
|
||||||
|
tab_desc = qlcnic_get_table_desc(unirom, QLCNIC_UNI_DIR_SECT_BOOTLD);
|
||||||
|
|
||||||
|
if (!tab_desc)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
tab_size = cpu_to_le32(tab_desc->findex) +
|
||||||
|
(cpu_to_le32(tab_desc->entry_size * (idx + 1)));
|
||||||
|
|
||||||
|
if (adapter->fw->size < tab_size)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
offs = cpu_to_le32(tab_desc->findex) +
|
||||||
|
(cpu_to_le32(tab_desc->entry_size) * (idx));
|
||||||
|
descr = (struct uni_data_desc *)&unirom[offs];
|
||||||
|
|
||||||
|
data_size = descr->findex + cpu_to_le32(descr->size);
|
||||||
|
|
||||||
|
if (adapter->fw->size < data_size)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
qlcnic_validate_fw(struct qlcnic_adapter *adapter)
|
||||||
|
{
|
||||||
|
struct uni_table_desc *tab_desc;
|
||||||
|
struct uni_data_desc *descr;
|
||||||
|
const u8 *unirom = adapter->fw->data;
|
||||||
|
int idx = cpu_to_le32(*((int *)&unirom[adapter->file_prd_off] +
|
||||||
|
QLCNIC_UNI_FIRMWARE_IDX_OFF));
|
||||||
|
__le32 offs;
|
||||||
|
__le32 tab_size;
|
||||||
|
__le32 data_size;
|
||||||
|
|
||||||
|
tab_desc = qlcnic_get_table_desc(unirom, QLCNIC_UNI_DIR_SECT_FW);
|
||||||
|
|
||||||
|
if (!tab_desc)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
tab_size = cpu_to_le32(tab_desc->findex) +
|
||||||
|
(cpu_to_le32(tab_desc->entry_size * (idx + 1)));
|
||||||
|
|
||||||
|
if (adapter->fw->size < tab_size)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
offs = cpu_to_le32(tab_desc->findex) +
|
||||||
|
(cpu_to_le32(tab_desc->entry_size) * (idx));
|
||||||
|
descr = (struct uni_data_desc *)&unirom[offs];
|
||||||
|
data_size = descr->findex + cpu_to_le32(descr->size);
|
||||||
|
|
||||||
|
if (adapter->fw->size < data_size)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
qlcnic_validate_product_offs(struct qlcnic_adapter *adapter)
|
||||||
{
|
{
|
||||||
struct uni_table_desc *ptab_descr;
|
struct uni_table_desc *ptab_descr;
|
||||||
const u8 *unirom = adapter->fw->data;
|
const u8 *unirom = adapter->fw->data;
|
||||||
u32 i;
|
|
||||||
__le32 entries;
|
|
||||||
int mn_present = qlcnic_has_mn(adapter);
|
int mn_present = qlcnic_has_mn(adapter);
|
||||||
|
__le32 entries;
|
||||||
|
__le32 entry_size;
|
||||||
|
__le32 tab_size;
|
||||||
|
u32 i;
|
||||||
|
|
||||||
ptab_descr = qlcnic_get_table_desc(unirom,
|
ptab_descr = qlcnic_get_table_desc(unirom,
|
||||||
QLCNIC_UNI_DIR_SECT_PRODUCT_TBL);
|
QLCNIC_UNI_DIR_SECT_PRODUCT_TBL);
|
||||||
if (ptab_descr == NULL)
|
if (!ptab_descr)
|
||||||
return -1;
|
return -EINVAL;
|
||||||
|
|
||||||
entries = cpu_to_le32(ptab_descr->num_entries);
|
entries = cpu_to_le32(ptab_descr->num_entries);
|
||||||
|
entry_size = cpu_to_le32(ptab_descr->entry_size);
|
||||||
|
tab_size = cpu_to_le32(ptab_descr->findex) + (entries * entry_size);
|
||||||
|
|
||||||
|
if (adapter->fw->size < tab_size)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
nomn:
|
nomn:
|
||||||
for (i = 0; i < entries; i++) {
|
for (i = 0; i < entries; i++) {
|
||||||
|
|
||||||
|
@ -609,7 +711,37 @@ nomn:
|
||||||
mn_present = 0;
|
mn_present = 0;
|
||||||
goto nomn;
|
goto nomn;
|
||||||
}
|
}
|
||||||
return -1;
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
qlcnic_validate_unified_romimage(struct qlcnic_adapter *adapter)
|
||||||
|
{
|
||||||
|
if (qlcnic_validate_header(adapter)) {
|
||||||
|
dev_err(&adapter->pdev->dev,
|
||||||
|
"unified image: header validation failed\n");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (qlcnic_validate_product_offs(adapter)) {
|
||||||
|
dev_err(&adapter->pdev->dev,
|
||||||
|
"unified image: product validation failed\n");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (qlcnic_validate_bootld(adapter)) {
|
||||||
|
dev_err(&adapter->pdev->dev,
|
||||||
|
"unified image: bootld validation failed\n");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (qlcnic_validate_fw(adapter)) {
|
||||||
|
dev_err(&adapter->pdev->dev,
|
||||||
|
"unified image: firmware validation failed\n");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
|
@ -715,7 +847,7 @@ qlcnic_get_bios_version(struct qlcnic_adapter *adapter)
|
||||||
bios_ver = cpu_to_le32(*((u32 *) (&fw->data[prd_off])
|
bios_ver = cpu_to_le32(*((u32 *) (&fw->data[prd_off])
|
||||||
+ QLCNIC_UNI_BIOS_VERSION_OFF));
|
+ QLCNIC_UNI_BIOS_VERSION_OFF));
|
||||||
|
|
||||||
return (bios_ver << 24) + ((bios_ver >> 8) & 0xff00) + (bios_ver >> 24);
|
return (bios_ver << 16) + ((bios_ver >> 8) & 0xff00) + (bios_ver >> 24);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
@ -858,7 +990,7 @@ qlcnic_validate_firmware(struct qlcnic_adapter *adapter)
|
||||||
u8 fw_type = adapter->fw_type;
|
u8 fw_type = adapter->fw_type;
|
||||||
|
|
||||||
if (fw_type == QLCNIC_UNIFIED_ROMIMAGE) {
|
if (fw_type == QLCNIC_UNIFIED_ROMIMAGE) {
|
||||||
if (qlcnic_set_product_offs(adapter))
|
if (qlcnic_validate_unified_romimage(adapter))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
min_size = QLCNIC_UNI_FW_MIN_SIZE;
|
min_size = QLCNIC_UNI_FW_MIN_SIZE;
|
||||||
|
@ -1114,8 +1246,10 @@ qlcnic_alloc_rx_skb(struct qlcnic_adapter *adapter,
|
||||||
struct pci_dev *pdev = adapter->pdev;
|
struct pci_dev *pdev = adapter->pdev;
|
||||||
|
|
||||||
buffer->skb = dev_alloc_skb(rds_ring->skb_size);
|
buffer->skb = dev_alloc_skb(rds_ring->skb_size);
|
||||||
if (!buffer->skb)
|
if (!buffer->skb) {
|
||||||
|
adapter->stats.skb_alloc_failure++;
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
skb = buffer->skb;
|
skb = buffer->skb;
|
||||||
|
|
||||||
|
@ -1289,7 +1423,7 @@ qlcnic_process_lro(struct qlcnic_adapter *adapter,
|
||||||
netif_receive_skb(skb);
|
netif_receive_skb(skb);
|
||||||
|
|
||||||
adapter->stats.lro_pkts++;
|
adapter->stats.lro_pkts++;
|
||||||
adapter->stats.rxbytes += length;
|
adapter->stats.lrobytes += length;
|
||||||
|
|
||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
@ -1505,6 +1639,8 @@ qlcnic_process_rcv_diag(struct qlcnic_adapter *adapter,
|
||||||
adapter->diag_cnt++;
|
adapter->diag_cnt++;
|
||||||
|
|
||||||
dev_kfree_skb_any(skb);
|
dev_kfree_skb_any(skb);
|
||||||
|
adapter->stats.rx_pkts++;
|
||||||
|
adapter->stats.rxbytes += length;
|
||||||
|
|
||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
|
@ -118,6 +118,7 @@ qlcnic_update_cmd_producer(struct qlcnic_adapter *adapter,
|
||||||
if (qlcnic_tx_avail(tx_ring) <= TX_STOP_THRESH) {
|
if (qlcnic_tx_avail(tx_ring) <= TX_STOP_THRESH) {
|
||||||
netif_stop_queue(adapter->netdev);
|
netif_stop_queue(adapter->netdev);
|
||||||
smp_mb();
|
smp_mb();
|
||||||
|
adapter->stats.xmit_off++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1385,6 +1386,7 @@ qlcnic_tso_check(struct net_device *netdev,
|
||||||
int copied, offset, copy_len, hdr_len = 0, tso = 0, vlan_oob = 0;
|
int copied, offset, copy_len, hdr_len = 0, tso = 0, vlan_oob = 0;
|
||||||
struct cmd_desc_type0 *hwdesc;
|
struct cmd_desc_type0 *hwdesc;
|
||||||
struct vlan_ethhdr *vh;
|
struct vlan_ethhdr *vh;
|
||||||
|
struct qlcnic_adapter *adapter = netdev_priv(netdev);
|
||||||
|
|
||||||
if (protocol == cpu_to_be16(ETH_P_8021Q)) {
|
if (protocol == cpu_to_be16(ETH_P_8021Q)) {
|
||||||
|
|
||||||
|
@ -1494,6 +1496,7 @@ qlcnic_tso_check(struct net_device *netdev,
|
||||||
|
|
||||||
tx_ring->producer = producer;
|
tx_ring->producer = producer;
|
||||||
barrier();
|
barrier();
|
||||||
|
adapter->stats.lso_frames++;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
@ -1573,6 +1576,7 @@ qlcnic_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
|
||||||
|
|
||||||
if (unlikely(no_of_desc + 2 > qlcnic_tx_avail(tx_ring))) {
|
if (unlikely(no_of_desc + 2 > qlcnic_tx_avail(tx_ring))) {
|
||||||
netif_stop_queue(netdev);
|
netif_stop_queue(netdev);
|
||||||
|
adapter->stats.xmit_off++;
|
||||||
return NETDEV_TX_BUSY;
|
return NETDEV_TX_BUSY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1880,6 +1884,7 @@ static int qlcnic_process_cmd_ring(struct qlcnic_adapter *adapter)
|
||||||
if (qlcnic_tx_avail(tx_ring) > TX_STOP_THRESH) {
|
if (qlcnic_tx_avail(tx_ring) > TX_STOP_THRESH) {
|
||||||
netif_wake_queue(netdev);
|
netif_wake_queue(netdev);
|
||||||
adapter->tx_timeo_cnt = 0;
|
adapter->tx_timeo_cnt = 0;
|
||||||
|
adapter->stats.xmit_on++;
|
||||||
}
|
}
|
||||||
__netif_tx_unlock(tx_ring->txq);
|
__netif_tx_unlock(tx_ring->txq);
|
||||||
}
|
}
|
||||||
|
|
|
@ -4270,7 +4270,7 @@ static netdev_tx_t rtl8169_start_xmit(struct sk_buff *skb,
|
||||||
|
|
||||||
tp->cur_tx += frags + 1;
|
tp->cur_tx += frags + 1;
|
||||||
|
|
||||||
smp_wmb();
|
wmb();
|
||||||
|
|
||||||
RTL_W8(TxPoll, NPQ); /* set polling bit */
|
RTL_W8(TxPoll, NPQ); /* set polling bit */
|
||||||
|
|
||||||
|
@ -4621,7 +4621,7 @@ static int rtl8169_poll(struct napi_struct *napi, int budget)
|
||||||
* until it does.
|
* until it does.
|
||||||
*/
|
*/
|
||||||
tp->intr_mask = 0xffff;
|
tp->intr_mask = 0xffff;
|
||||||
smp_wmb();
|
wmb();
|
||||||
RTL_W16(IntrMask, tp->intr_event);
|
RTL_W16(IntrMask, tp->intr_event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -923,8 +923,8 @@ static int init_shared_mem(struct s2io_nic *nic)
|
||||||
tmp_v_addr = mac_control->stats_mem;
|
tmp_v_addr = mac_control->stats_mem;
|
||||||
mac_control->stats_info = (struct stat_block *)tmp_v_addr;
|
mac_control->stats_info = (struct stat_block *)tmp_v_addr;
|
||||||
memset(tmp_v_addr, 0, size);
|
memset(tmp_v_addr, 0, size);
|
||||||
DBG_PRINT(INIT_DBG, "%s: Ring Mem PHY: 0x%llx\n", dev->name,
|
DBG_PRINT(INIT_DBG, "%s: Ring Mem PHY: 0x%llx\n",
|
||||||
(unsigned long long)tmp_p_addr);
|
dev_name(&nic->pdev->dev), (unsigned long long)tmp_p_addr);
|
||||||
mac_control->stats_info->sw_stat.mem_allocated += mem_allocated;
|
mac_control->stats_info->sw_stat.mem_allocated += mem_allocated;
|
||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -3480,7 +3480,7 @@ static void s2io_reset(struct s2io_nic *sp)
|
||||||
struct swStat *swstats;
|
struct swStat *swstats;
|
||||||
|
|
||||||
DBG_PRINT(INIT_DBG, "%s: Resetting XFrame card %s\n",
|
DBG_PRINT(INIT_DBG, "%s: Resetting XFrame card %s\n",
|
||||||
__func__, sp->dev->name);
|
__func__, pci_name(sp->pdev));
|
||||||
|
|
||||||
/* Back up the PCI-X CMD reg, dont want to lose MMRBC, OST settings */
|
/* Back up the PCI-X CMD reg, dont want to lose MMRBC, OST settings */
|
||||||
pci_read_config_word(sp->pdev, PCIX_COMMAND_REGISTER, &(pci_cmd));
|
pci_read_config_word(sp->pdev, PCIX_COMMAND_REGISTER, &(pci_cmd));
|
||||||
|
|
|
@ -4863,6 +4863,7 @@ static int sky2_resume(struct pci_dev *pdev)
|
||||||
if (!hw)
|
if (!hw)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
rtnl_lock();
|
||||||
err = pci_set_power_state(pdev, PCI_D0);
|
err = pci_set_power_state(pdev, PCI_D0);
|
||||||
if (err)
|
if (err)
|
||||||
goto out;
|
goto out;
|
||||||
|
@ -4884,7 +4885,6 @@ static int sky2_resume(struct pci_dev *pdev)
|
||||||
sky2_write32(hw, B0_IMSK, Y2_IS_BASE);
|
sky2_write32(hw, B0_IMSK, Y2_IS_BASE);
|
||||||
napi_enable(&hw->napi);
|
napi_enable(&hw->napi);
|
||||||
|
|
||||||
rtnl_lock();
|
|
||||||
for (i = 0; i < hw->ports; i++) {
|
for (i = 0; i < hw->ports; i++) {
|
||||||
err = sky2_reattach(hw->dev[i]);
|
err = sky2_reattach(hw->dev[i]);
|
||||||
if (err)
|
if (err)
|
||||||
|
|
|
@ -330,6 +330,48 @@ static inline void LPD7_SMC_outsw (unsigned char* a, int r,
|
||||||
|
|
||||||
#include <unit/smc91111.h>
|
#include <unit/smc91111.h>
|
||||||
|
|
||||||
|
#elif defined(CONFIG_ARCH_MSM)
|
||||||
|
|
||||||
|
#define SMC_CAN_USE_8BIT 0
|
||||||
|
#define SMC_CAN_USE_16BIT 1
|
||||||
|
#define SMC_CAN_USE_32BIT 0
|
||||||
|
#define SMC_NOWAIT 1
|
||||||
|
|
||||||
|
#define SMC_inw(a, r) readw((a) + (r))
|
||||||
|
#define SMC_outw(v, a, r) writew(v, (a) + (r))
|
||||||
|
#define SMC_insw(a, r, p, l) readsw((a) + (r), p, l)
|
||||||
|
#define SMC_outsw(a, r, p, l) writesw((a) + (r), p, l)
|
||||||
|
|
||||||
|
#define SMC_IRQ_FLAGS IRQF_TRIGGER_HIGH
|
||||||
|
|
||||||
|
#elif defined(CONFIG_COLDFIRE)
|
||||||
|
|
||||||
|
#define SMC_CAN_USE_8BIT 0
|
||||||
|
#define SMC_CAN_USE_16BIT 1
|
||||||
|
#define SMC_CAN_USE_32BIT 0
|
||||||
|
#define SMC_NOWAIT 1
|
||||||
|
|
||||||
|
static inline void mcf_insw(void *a, unsigned char *p, int l)
|
||||||
|
{
|
||||||
|
u16 *wp = (u16 *) p;
|
||||||
|
while (l-- > 0)
|
||||||
|
*wp++ = readw(a);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void mcf_outsw(void *a, unsigned char *p, int l)
|
||||||
|
{
|
||||||
|
u16 *wp = (u16 *) p;
|
||||||
|
while (l-- > 0)
|
||||||
|
writew(*wp++, a);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define SMC_inw(a, r) _swapw(readw((a) + (r)))
|
||||||
|
#define SMC_outw(v, a, r) writew(_swapw(v), (a) + (r))
|
||||||
|
#define SMC_insw(a, r, p, l) mcf_insw(a + r, p, l)
|
||||||
|
#define SMC_outsw(a, r, p, l) mcf_outsw(a + r, p, l)
|
||||||
|
|
||||||
|
#define SMC_IRQ_FLAGS (IRQF_DISABLED)
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -5279,7 +5279,7 @@ static void tg3_poll_controller(struct net_device *dev)
|
||||||
struct tg3 *tp = netdev_priv(dev);
|
struct tg3 *tp = netdev_priv(dev);
|
||||||
|
|
||||||
for (i = 0; i < tp->irq_cnt; i++)
|
for (i = 0; i < tp->irq_cnt; i++)
|
||||||
tg3_interrupt(tp->napi[i].irq_vec, dev);
|
tg3_interrupt(tp->napi[i].irq_vec, &tp->napi[i]);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -9776,7 +9776,7 @@ static int tg3_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
|
||||||
ADVERTISED_Pause |
|
ADVERTISED_Pause |
|
||||||
ADVERTISED_Asym_Pause;
|
ADVERTISED_Asym_Pause;
|
||||||
|
|
||||||
if (!(tp->tg3_flags2 & TG3_FLAG_10_100_ONLY))
|
if (!(tp->tg3_flags & TG3_FLAG_10_100_ONLY))
|
||||||
mask |= ADVERTISED_1000baseT_Half |
|
mask |= ADVERTISED_1000baseT_Half |
|
||||||
ADVERTISED_1000baseT_Full;
|
ADVERTISED_1000baseT_Full;
|
||||||
|
|
||||||
|
|
|
@ -143,6 +143,12 @@ static void __devinit tulip_build_fake_mediatable(struct tulip_private *tp)
|
||||||
|
|
||||||
void __devinit tulip_parse_eeprom(struct net_device *dev)
|
void __devinit tulip_parse_eeprom(struct net_device *dev)
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
|
dev is not registered at this point, so logging messages can't
|
||||||
|
use dev_<level> or netdev_<level> but dev->name is good via a
|
||||||
|
hack in the caller
|
||||||
|
*/
|
||||||
|
|
||||||
/* The last media info list parsed, for multiport boards. */
|
/* The last media info list parsed, for multiport boards. */
|
||||||
static struct mediatable *last_mediatable;
|
static struct mediatable *last_mediatable;
|
||||||
static unsigned char *last_ee_data;
|
static unsigned char *last_ee_data;
|
||||||
|
@ -161,15 +167,14 @@ void __devinit tulip_parse_eeprom(struct net_device *dev)
|
||||||
if (ee_data[0] == 0xff) {
|
if (ee_data[0] == 0xff) {
|
||||||
if (last_mediatable) {
|
if (last_mediatable) {
|
||||||
controller_index++;
|
controller_index++;
|
||||||
dev_info(&dev->dev,
|
pr_info("%s: Controller %d of multiport board\n",
|
||||||
"Controller %d of multiport board\n",
|
dev->name, controller_index);
|
||||||
controller_index);
|
|
||||||
tp->mtable = last_mediatable;
|
tp->mtable = last_mediatable;
|
||||||
ee_data = last_ee_data;
|
ee_data = last_ee_data;
|
||||||
goto subsequent_board;
|
goto subsequent_board;
|
||||||
} else
|
} else
|
||||||
dev_info(&dev->dev,
|
pr_info("%s: Missing EEPROM, this interface may not work correctly!\n",
|
||||||
"Missing EEPROM, this interface may not work correctly!\n");
|
dev->name);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
/* Do a fix-up based on the vendor half of the station address prefix. */
|
/* Do a fix-up based on the vendor half of the station address prefix. */
|
||||||
|
@ -181,15 +186,14 @@ void __devinit tulip_parse_eeprom(struct net_device *dev)
|
||||||
i++; /* An Accton EN1207, not an outlaw Maxtech. */
|
i++; /* An Accton EN1207, not an outlaw Maxtech. */
|
||||||
memcpy(ee_data + 26, eeprom_fixups[i].newtable,
|
memcpy(ee_data + 26, eeprom_fixups[i].newtable,
|
||||||
sizeof(eeprom_fixups[i].newtable));
|
sizeof(eeprom_fixups[i].newtable));
|
||||||
dev_info(&dev->dev,
|
pr_info("%s: Old format EEPROM on '%s' board. Using substitute media control info\n",
|
||||||
"Old format EEPROM on '%s' board. Using substitute media control info\n",
|
dev->name, eeprom_fixups[i].name);
|
||||||
eeprom_fixups[i].name);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (eeprom_fixups[i].name == NULL) { /* No fixup found. */
|
if (eeprom_fixups[i].name == NULL) { /* No fixup found. */
|
||||||
dev_info(&dev->dev,
|
pr_info("%s: Old style EEPROM with no media selection information\n",
|
||||||
"Old style EEPROM with no media selection information\n");
|
dev->name);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -217,8 +221,8 @@ subsequent_board:
|
||||||
/* there is no phy information, don't even try to build mtable */
|
/* there is no phy information, don't even try to build mtable */
|
||||||
if (count == 0) {
|
if (count == 0) {
|
||||||
if (tulip_debug > 0)
|
if (tulip_debug > 0)
|
||||||
dev_warn(&dev->dev,
|
pr_warning("%s: no phy info, aborting mtable build\n",
|
||||||
"no phy info, aborting mtable build\n");
|
dev->name);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -234,8 +238,10 @@ subsequent_board:
|
||||||
mtable->has_nonmii = mtable->has_mii = mtable->has_reset = 0;
|
mtable->has_nonmii = mtable->has_mii = mtable->has_reset = 0;
|
||||||
mtable->csr15dir = mtable->csr15val = 0;
|
mtable->csr15dir = mtable->csr15val = 0;
|
||||||
|
|
||||||
dev_info(&dev->dev, "EEPROM default media type %s\n",
|
pr_info("%s: EEPROM default media type %s\n",
|
||||||
media & 0x0800 ? "Autosense" : medianame[media & MEDIA_MASK]);
|
dev->name,
|
||||||
|
media & 0x0800 ? "Autosense"
|
||||||
|
: medianame[media & MEDIA_MASK]);
|
||||||
for (i = 0; i < count; i++) {
|
for (i = 0; i < count; i++) {
|
||||||
struct medialeaf *leaf = &mtable->mleaf[i];
|
struct medialeaf *leaf = &mtable->mleaf[i];
|
||||||
|
|
||||||
|
@ -298,17 +304,17 @@ subsequent_board:
|
||||||
}
|
}
|
||||||
if (tulip_debug > 1 && leaf->media == 11) {
|
if (tulip_debug > 1 && leaf->media == 11) {
|
||||||
unsigned char *bp = leaf->leafdata;
|
unsigned char *bp = leaf->leafdata;
|
||||||
dev_info(&dev->dev,
|
pr_info("%s: MII interface PHY %d, setup/reset sequences %d/%d long, capabilities %02x %02x\n",
|
||||||
"MII interface PHY %d, setup/reset sequences %d/%d long, capabilities %02x %02x\n",
|
dev->name,
|
||||||
bp[0], bp[1], bp[2 + bp[1]*2],
|
bp[0], bp[1], bp[2 + bp[1]*2],
|
||||||
bp[5 + bp[2 + bp[1]*2]*2],
|
bp[5 + bp[2 + bp[1]*2]*2],
|
||||||
bp[4 + bp[2 + bp[1]*2]*2]);
|
bp[4 + bp[2 + bp[1]*2]*2]);
|
||||||
}
|
}
|
||||||
dev_info(&dev->dev,
|
pr_info("%s: Index #%d - Media %s (#%d) described by a %s (%d) block\n",
|
||||||
"Index #%d - Media %s (#%d) described by a %s (%d) block\n",
|
dev->name,
|
||||||
i, medianame[leaf->media & 15], leaf->media,
|
i, medianame[leaf->media & 15], leaf->media,
|
||||||
leaf->type < ARRAY_SIZE(block_name) ? block_name[leaf->type] : "<unknown>",
|
leaf->type < ARRAY_SIZE(block_name) ? block_name[leaf->type] : "<unknown>",
|
||||||
leaf->type);
|
leaf->type);
|
||||||
}
|
}
|
||||||
if (new_advertise)
|
if (new_advertise)
|
||||||
tp->sym_advertise = new_advertise;
|
tp->sym_advertise = new_advertise;
|
||||||
|
|
|
@ -480,7 +480,7 @@ typhoon_hello(struct typhoon *tp)
|
||||||
typhoon_inc_cmd_index(&ring->lastWrite, 1);
|
typhoon_inc_cmd_index(&ring->lastWrite, 1);
|
||||||
|
|
||||||
INIT_COMMAND_NO_RESPONSE(cmd, TYPHOON_CMD_HELLO_RESP);
|
INIT_COMMAND_NO_RESPONSE(cmd, TYPHOON_CMD_HELLO_RESP);
|
||||||
smp_wmb();
|
wmb();
|
||||||
iowrite32(ring->lastWrite, tp->ioaddr + TYPHOON_REG_CMD_READY);
|
iowrite32(ring->lastWrite, tp->ioaddr + TYPHOON_REG_CMD_READY);
|
||||||
spin_unlock(&tp->command_lock);
|
spin_unlock(&tp->command_lock);
|
||||||
}
|
}
|
||||||
|
@ -1311,13 +1311,15 @@ typhoon_init_interface(struct typhoon *tp)
|
||||||
|
|
||||||
tp->txlo_dma_addr = le32_to_cpu(iface->txLoAddr);
|
tp->txlo_dma_addr = le32_to_cpu(iface->txLoAddr);
|
||||||
tp->card_state = Sleeping;
|
tp->card_state = Sleeping;
|
||||||
smp_wmb();
|
|
||||||
|
|
||||||
tp->offload = TYPHOON_OFFLOAD_IP_CHKSUM | TYPHOON_OFFLOAD_TCP_CHKSUM;
|
tp->offload = TYPHOON_OFFLOAD_IP_CHKSUM | TYPHOON_OFFLOAD_TCP_CHKSUM;
|
||||||
tp->offload |= TYPHOON_OFFLOAD_UDP_CHKSUM | TSO_OFFLOAD_ON;
|
tp->offload |= TYPHOON_OFFLOAD_UDP_CHKSUM | TSO_OFFLOAD_ON;
|
||||||
|
|
||||||
spin_lock_init(&tp->command_lock);
|
spin_lock_init(&tp->command_lock);
|
||||||
spin_lock_init(&tp->state_lock);
|
spin_lock_init(&tp->state_lock);
|
||||||
|
|
||||||
|
/* Force the writes to the shared memory area out before continuing. */
|
||||||
|
wmb();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
|
@ -54,6 +54,7 @@ static const char driver_name [] = "asix";
|
||||||
#define AX_CMD_WRITE_IPG0 0x12
|
#define AX_CMD_WRITE_IPG0 0x12
|
||||||
#define AX_CMD_WRITE_IPG1 0x13
|
#define AX_CMD_WRITE_IPG1 0x13
|
||||||
#define AX_CMD_READ_NODE_ID 0x13
|
#define AX_CMD_READ_NODE_ID 0x13
|
||||||
|
#define AX_CMD_WRITE_NODE_ID 0x14
|
||||||
#define AX_CMD_WRITE_IPG2 0x14
|
#define AX_CMD_WRITE_IPG2 0x14
|
||||||
#define AX_CMD_WRITE_MULTI_FILTER 0x16
|
#define AX_CMD_WRITE_MULTI_FILTER 0x16
|
||||||
#define AX88172_CMD_READ_NODE_ID 0x17
|
#define AX88172_CMD_READ_NODE_ID 0x17
|
||||||
|
@ -165,6 +166,7 @@ static const char driver_name [] = "asix";
|
||||||
/* 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 {
|
||||||
u8 multi_filter[AX_MCAST_FILTER_SIZE];
|
u8 multi_filter[AX_MCAST_FILTER_SIZE];
|
||||||
|
u8 mac_addr[ETH_ALEN];
|
||||||
u8 phymode;
|
u8 phymode;
|
||||||
u8 ledmode;
|
u8 ledmode;
|
||||||
u8 eeprom_len;
|
u8 eeprom_len;
|
||||||
|
@ -732,6 +734,30 @@ static int asix_ioctl (struct net_device *net, struct ifreq *rq, int cmd)
|
||||||
return generic_mii_ioctl(&dev->mii, if_mii(rq), cmd, NULL);
|
return generic_mii_ioctl(&dev->mii, if_mii(rq), cmd, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int asix_set_mac_address(struct net_device *net, void *p)
|
||||||
|
{
|
||||||
|
struct usbnet *dev = netdev_priv(net);
|
||||||
|
struct asix_data *data = (struct asix_data *)&dev->data;
|
||||||
|
struct sockaddr *addr = p;
|
||||||
|
|
||||||
|
if (netif_running(net))
|
||||||
|
return -EBUSY;
|
||||||
|
if (!is_valid_ether_addr(addr->sa_data))
|
||||||
|
return -EADDRNOTAVAIL;
|
||||||
|
|
||||||
|
memcpy(net->dev_addr, addr->sa_data, ETH_ALEN);
|
||||||
|
|
||||||
|
/* We use the 20 byte dev->data
|
||||||
|
* for our 6 byte mac buffer
|
||||||
|
* to avoid allocating memory that
|
||||||
|
* is tricky to free later */
|
||||||
|
memcpy(data->mac_addr, addr->sa_data, ETH_ALEN);
|
||||||
|
asix_write_cmd_async(dev, AX_CMD_WRITE_NODE_ID, 0, 0, ETH_ALEN,
|
||||||
|
data->mac_addr);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* We need to override some ethtool_ops so we require our
|
/* We need to override some ethtool_ops so we require our
|
||||||
own structure so we don't interfere with other usbnet
|
own structure so we don't interfere with other usbnet
|
||||||
devices that may be connected at the same time. */
|
devices that may be connected at the same time. */
|
||||||
|
@ -919,7 +945,7 @@ static const struct net_device_ops ax88772_netdev_ops = {
|
||||||
.ndo_start_xmit = usbnet_start_xmit,
|
.ndo_start_xmit = usbnet_start_xmit,
|
||||||
.ndo_tx_timeout = usbnet_tx_timeout,
|
.ndo_tx_timeout = usbnet_tx_timeout,
|
||||||
.ndo_change_mtu = usbnet_change_mtu,
|
.ndo_change_mtu = usbnet_change_mtu,
|
||||||
.ndo_set_mac_address = eth_mac_addr,
|
.ndo_set_mac_address = asix_set_mac_address,
|
||||||
.ndo_validate_addr = eth_validate_addr,
|
.ndo_validate_addr = eth_validate_addr,
|
||||||
.ndo_do_ioctl = asix_ioctl,
|
.ndo_do_ioctl = asix_ioctl,
|
||||||
.ndo_set_multicast_list = asix_set_multicast,
|
.ndo_set_multicast_list = asix_set_multicast,
|
||||||
|
@ -1213,7 +1239,7 @@ static const struct net_device_ops ax88178_netdev_ops = {
|
||||||
.ndo_stop = usbnet_stop,
|
.ndo_stop = usbnet_stop,
|
||||||
.ndo_start_xmit = usbnet_start_xmit,
|
.ndo_start_xmit = usbnet_start_xmit,
|
||||||
.ndo_tx_timeout = usbnet_tx_timeout,
|
.ndo_tx_timeout = usbnet_tx_timeout,
|
||||||
.ndo_set_mac_address = eth_mac_addr,
|
.ndo_set_mac_address = asix_set_mac_address,
|
||||||
.ndo_validate_addr = eth_validate_addr,
|
.ndo_validate_addr = eth_validate_addr,
|
||||||
.ndo_set_multicast_list = asix_set_multicast,
|
.ndo_set_multicast_list = asix_set_multicast,
|
||||||
.ndo_do_ioctl = asix_ioctl,
|
.ndo_do_ioctl = asix_ioctl,
|
||||||
|
|
|
@ -177,7 +177,7 @@ PEGASUS_DEV( "USB 10/100 Fast Ethernet", VENDOR_ABOCOM, 0x400c,
|
||||||
PEGASUS_DEV( "USB 10/100 Fast Ethernet", VENDOR_ABOCOM, 0xabc1,
|
PEGASUS_DEV( "USB 10/100 Fast Ethernet", VENDOR_ABOCOM, 0xabc1,
|
||||||
DEFAULT_GPIO_RESET )
|
DEFAULT_GPIO_RESET )
|
||||||
PEGASUS_DEV( "USB 10/100 Fast Ethernet", VENDOR_ABOCOM, 0x200c,
|
PEGASUS_DEV( "USB 10/100 Fast Ethernet", VENDOR_ABOCOM, 0x200c,
|
||||||
DEFAULT_GPIO_RESET | PEGASUS_II )
|
DEFAULT_GPIO_RESET | PEGASUS_II )
|
||||||
PEGASUS_DEV( "Accton USB 10/100 Ethernet Adapter", VENDOR_ACCTON, 0x1046,
|
PEGASUS_DEV( "Accton USB 10/100 Ethernet Adapter", VENDOR_ACCTON, 0x1046,
|
||||||
DEFAULT_GPIO_RESET )
|
DEFAULT_GPIO_RESET )
|
||||||
PEGASUS_DEV( "SpeedStream USB 10/100 Ethernet", VENDOR_ACCTON, 0x5046,
|
PEGASUS_DEV( "SpeedStream USB 10/100 Ethernet", VENDOR_ACCTON, 0x5046,
|
||||||
|
@ -208,6 +208,8 @@ PEGASUS_DEV( "Allied Telesyn Int. AT-USB100", VENDOR_ALLIEDTEL, 0xb100,
|
||||||
*/
|
*/
|
||||||
PEGASUS_DEV_CLASS( "Belkin F5D5050 USB Ethernet", VENDOR_BELKIN, 0x0121, 0x00,
|
PEGASUS_DEV_CLASS( "Belkin F5D5050 USB Ethernet", VENDOR_BELKIN, 0x0121, 0x00,
|
||||||
DEFAULT_GPIO_RESET | PEGASUS_II )
|
DEFAULT_GPIO_RESET | PEGASUS_II )
|
||||||
|
PEGASUS_DEV( "Belkin F5U122 10/100 USB Ethernet", VENDOR_BELKIN, 0x0122,
|
||||||
|
DEFAULT_GPIO_RESET | PEGASUS_II )
|
||||||
PEGASUS_DEV( "Billionton USB-100", VENDOR_BILLIONTON, 0x0986,
|
PEGASUS_DEV( "Billionton USB-100", VENDOR_BILLIONTON, 0x0986,
|
||||||
DEFAULT_GPIO_RESET )
|
DEFAULT_GPIO_RESET )
|
||||||
PEGASUS_DEV( "Billionton USBLP-100", VENDOR_BILLIONTON, 0x0987,
|
PEGASUS_DEV( "Billionton USBLP-100", VENDOR_BILLIONTON, 0x0987,
|
||||||
|
@ -249,7 +251,7 @@ PEGASUS_DEV( "GIGABYTE GN-BR402W Wireless Router", VENDOR_GIGABYTE, 0x8002,
|
||||||
PEGASUS_DEV( "Hawking UF100 10/100 Ethernet", VENDOR_HAWKING, 0x400c,
|
PEGASUS_DEV( "Hawking UF100 10/100 Ethernet", VENDOR_HAWKING, 0x400c,
|
||||||
DEFAULT_GPIO_RESET | PEGASUS_II )
|
DEFAULT_GPIO_RESET | PEGASUS_II )
|
||||||
PEGASUS_DEV( "HP hn210c Ethernet USB", VENDOR_HP, 0x811c,
|
PEGASUS_DEV( "HP hn210c Ethernet USB", VENDOR_HP, 0x811c,
|
||||||
DEFAULT_GPIO_RESET | PEGASUS_II )
|
DEFAULT_GPIO_RESET | PEGASUS_II )
|
||||||
PEGASUS_DEV( "IO DATA USB ET/TX", VENDOR_IODATA, 0x0904,
|
PEGASUS_DEV( "IO DATA USB ET/TX", VENDOR_IODATA, 0x0904,
|
||||||
DEFAULT_GPIO_RESET )
|
DEFAULT_GPIO_RESET )
|
||||||
PEGASUS_DEV( "IO DATA USB ET/TX-S", VENDOR_IODATA, 0x0913,
|
PEGASUS_DEV( "IO DATA USB ET/TX-S", VENDOR_IODATA, 0x0913,
|
||||||
|
|
|
@ -5255,7 +5255,8 @@ static int set_wep_key(struct airo_info *ai, u16 index, const char *key,
|
||||||
WepKeyRid wkr;
|
WepKeyRid wkr;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
WARN_ON(keylen == 0);
|
if (WARN_ON(keylen == 0))
|
||||||
|
return -1;
|
||||||
|
|
||||||
memset(&wkr, 0, sizeof(wkr));
|
memset(&wkr, 0, sizeof(wkr));
|
||||||
wkr.len = cpu_to_le16(sizeof(wkr));
|
wkr.len = cpu_to_le16(sizeof(wkr));
|
||||||
|
|
|
@ -166,6 +166,7 @@ struct ar9170 {
|
||||||
struct ath_common common;
|
struct ath_common common;
|
||||||
struct mutex mutex;
|
struct mutex mutex;
|
||||||
enum ar9170_device_state state;
|
enum ar9170_device_state state;
|
||||||
|
bool registered;
|
||||||
unsigned long bad_hw_nagger;
|
unsigned long bad_hw_nagger;
|
||||||
|
|
||||||
int (*open)(struct ar9170 *);
|
int (*open)(struct ar9170 *);
|
||||||
|
|
|
@ -2701,7 +2701,8 @@ int ar9170_register(struct ar9170 *ar, struct device *pdev)
|
||||||
dev_info(pdev, "Atheros AR9170 is registered as '%s'\n",
|
dev_info(pdev, "Atheros AR9170 is registered as '%s'\n",
|
||||||
wiphy_name(ar->hw->wiphy));
|
wiphy_name(ar->hw->wiphy));
|
||||||
|
|
||||||
return err;
|
ar->registered = true;
|
||||||
|
return 0;
|
||||||
|
|
||||||
err_unreg:
|
err_unreg:
|
||||||
ieee80211_unregister_hw(ar->hw);
|
ieee80211_unregister_hw(ar->hw);
|
||||||
|
@ -2712,11 +2713,14 @@ err_out:
|
||||||
|
|
||||||
void ar9170_unregister(struct ar9170 *ar)
|
void ar9170_unregister(struct ar9170 *ar)
|
||||||
{
|
{
|
||||||
|
if (ar->registered) {
|
||||||
#ifdef CONFIG_AR9170_LEDS
|
#ifdef CONFIG_AR9170_LEDS
|
||||||
ar9170_unregister_leds(ar);
|
ar9170_unregister_leds(ar);
|
||||||
#endif /* CONFIG_AR9170_LEDS */
|
#endif /* CONFIG_AR9170_LEDS */
|
||||||
|
|
||||||
kfree_skb(ar->rx_failover);
|
|
||||||
ieee80211_unregister_hw(ar->hw);
|
ieee80211_unregister_hw(ar->hw);
|
||||||
|
}
|
||||||
|
|
||||||
|
kfree_skb(ar->rx_failover);
|
||||||
mutex_destroy(&ar->mutex);
|
mutex_destroy(&ar->mutex);
|
||||||
}
|
}
|
||||||
|
|
|
@ -582,43 +582,6 @@ static int ar9170_usb_upload(struct ar9170_usb *aru, const void *data,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ar9170_usb_request_firmware(struct ar9170_usb *aru)
|
|
||||||
{
|
|
||||||
int err = 0;
|
|
||||||
|
|
||||||
err = request_firmware(&aru->firmware, "ar9170.fw",
|
|
||||||
&aru->udev->dev);
|
|
||||||
if (!err) {
|
|
||||||
aru->init_values = NULL;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (aru->req_one_stage_fw) {
|
|
||||||
dev_err(&aru->udev->dev, "ar9170.fw firmware file "
|
|
||||||
"not found and is required for this device\n");
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
dev_err(&aru->udev->dev, "ar9170.fw firmware file "
|
|
||||||
"not found, trying old firmware...\n");
|
|
||||||
|
|
||||||
err = request_firmware(&aru->init_values, "ar9170-1.fw",
|
|
||||||
&aru->udev->dev);
|
|
||||||
if (err) {
|
|
||||||
dev_err(&aru->udev->dev, "file with init values not found.\n");
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
err = request_firmware(&aru->firmware, "ar9170-2.fw", &aru->udev->dev);
|
|
||||||
if (err) {
|
|
||||||
release_firmware(aru->init_values);
|
|
||||||
dev_err(&aru->udev->dev, "firmware file not found.\n");
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int ar9170_usb_reset(struct ar9170_usb *aru)
|
static int ar9170_usb_reset(struct ar9170_usb *aru)
|
||||||
{
|
{
|
||||||
int ret, lock = (aru->intf->condition != USB_INTERFACE_BINDING);
|
int ret, lock = (aru->intf->condition != USB_INTERFACE_BINDING);
|
||||||
|
@ -757,6 +720,103 @@ err_out:
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void ar9170_usb_firmware_failed(struct ar9170_usb *aru)
|
||||||
|
{
|
||||||
|
struct device *parent = aru->udev->dev.parent;
|
||||||
|
|
||||||
|
/* unbind anything failed */
|
||||||
|
if (parent)
|
||||||
|
down(&parent->sem);
|
||||||
|
device_release_driver(&aru->udev->dev);
|
||||||
|
if (parent)
|
||||||
|
up(&parent->sem);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ar9170_usb_firmware_finish(const struct firmware *fw, void *context)
|
||||||
|
{
|
||||||
|
struct ar9170_usb *aru = context;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
aru->firmware = fw;
|
||||||
|
|
||||||
|
if (!fw) {
|
||||||
|
dev_err(&aru->udev->dev, "firmware file not found.\n");
|
||||||
|
goto err_freefw;
|
||||||
|
}
|
||||||
|
|
||||||
|
err = ar9170_usb_init_device(aru);
|
||||||
|
if (err)
|
||||||
|
goto err_freefw;
|
||||||
|
|
||||||
|
err = ar9170_usb_open(&aru->common);
|
||||||
|
if (err)
|
||||||
|
goto err_unrx;
|
||||||
|
|
||||||
|
err = ar9170_register(&aru->common, &aru->udev->dev);
|
||||||
|
|
||||||
|
ar9170_usb_stop(&aru->common);
|
||||||
|
if (err)
|
||||||
|
goto err_unrx;
|
||||||
|
|
||||||
|
return;
|
||||||
|
|
||||||
|
err_unrx:
|
||||||
|
ar9170_usb_cancel_urbs(aru);
|
||||||
|
|
||||||
|
err_freefw:
|
||||||
|
ar9170_usb_firmware_failed(aru);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ar9170_usb_firmware_inits(const struct firmware *fw,
|
||||||
|
void *context)
|
||||||
|
{
|
||||||
|
struct ar9170_usb *aru = context;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
if (!fw) {
|
||||||
|
dev_err(&aru->udev->dev, "file with init values not found.\n");
|
||||||
|
ar9170_usb_firmware_failed(aru);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
aru->init_values = fw;
|
||||||
|
|
||||||
|
/* ok so we have the init values -- get code for two-stage */
|
||||||
|
|
||||||
|
err = request_firmware_nowait(THIS_MODULE, 1, "ar9170-2.fw",
|
||||||
|
&aru->udev->dev, GFP_KERNEL, aru,
|
||||||
|
ar9170_usb_firmware_finish);
|
||||||
|
if (err)
|
||||||
|
ar9170_usb_firmware_failed(aru);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ar9170_usb_firmware_step2(const struct firmware *fw, void *context)
|
||||||
|
{
|
||||||
|
struct ar9170_usb *aru = context;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
if (fw) {
|
||||||
|
ar9170_usb_firmware_finish(fw, context);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (aru->req_one_stage_fw) {
|
||||||
|
dev_err(&aru->udev->dev, "ar9170.fw firmware file "
|
||||||
|
"not found and is required for this device\n");
|
||||||
|
ar9170_usb_firmware_failed(aru);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
dev_err(&aru->udev->dev, "ar9170.fw firmware file "
|
||||||
|
"not found, trying old firmware...\n");
|
||||||
|
|
||||||
|
err = request_firmware_nowait(THIS_MODULE, 1, "ar9170-1.fw",
|
||||||
|
&aru->udev->dev, GFP_KERNEL, aru,
|
||||||
|
ar9170_usb_firmware_inits);
|
||||||
|
if (err)
|
||||||
|
ar9170_usb_firmware_failed(aru);
|
||||||
|
}
|
||||||
|
|
||||||
static bool ar9170_requires_one_stage(const struct usb_device_id *id)
|
static bool ar9170_requires_one_stage(const struct usb_device_id *id)
|
||||||
{
|
{
|
||||||
if (!id->driver_info)
|
if (!id->driver_info)
|
||||||
|
@ -814,33 +874,9 @@ static int ar9170_usb_probe(struct usb_interface *intf,
|
||||||
if (err)
|
if (err)
|
||||||
goto err_freehw;
|
goto err_freehw;
|
||||||
|
|
||||||
err = ar9170_usb_request_firmware(aru);
|
return request_firmware_nowait(THIS_MODULE, 1, "ar9170.fw",
|
||||||
if (err)
|
&aru->udev->dev, GFP_KERNEL, aru,
|
||||||
goto err_freehw;
|
ar9170_usb_firmware_step2);
|
||||||
|
|
||||||
err = ar9170_usb_init_device(aru);
|
|
||||||
if (err)
|
|
||||||
goto err_freefw;
|
|
||||||
|
|
||||||
err = ar9170_usb_open(ar);
|
|
||||||
if (err)
|
|
||||||
goto err_unrx;
|
|
||||||
|
|
||||||
err = ar9170_register(ar, &udev->dev);
|
|
||||||
|
|
||||||
ar9170_usb_stop(ar);
|
|
||||||
if (err)
|
|
||||||
goto err_unrx;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
err_unrx:
|
|
||||||
ar9170_usb_cancel_urbs(aru);
|
|
||||||
|
|
||||||
err_freefw:
|
|
||||||
release_firmware(aru->init_values);
|
|
||||||
release_firmware(aru->firmware);
|
|
||||||
|
|
||||||
err_freehw:
|
err_freehw:
|
||||||
usb_set_intfdata(intf, NULL);
|
usb_set_intfdata(intf, NULL);
|
||||||
usb_put_dev(udev);
|
usb_put_dev(udev);
|
||||||
|
@ -860,12 +896,12 @@ static void ar9170_usb_disconnect(struct usb_interface *intf)
|
||||||
ar9170_unregister(&aru->common);
|
ar9170_unregister(&aru->common);
|
||||||
ar9170_usb_cancel_urbs(aru);
|
ar9170_usb_cancel_urbs(aru);
|
||||||
|
|
||||||
release_firmware(aru->init_values);
|
|
||||||
release_firmware(aru->firmware);
|
|
||||||
|
|
||||||
usb_put_dev(aru->udev);
|
usb_put_dev(aru->udev);
|
||||||
usb_set_intfdata(intf, NULL);
|
usb_set_intfdata(intf, NULL);
|
||||||
ieee80211_free_hw(aru->common.hw);
|
ieee80211_free_hw(aru->common.hw);
|
||||||
|
|
||||||
|
release_firmware(aru->init_values);
|
||||||
|
release_firmware(aru->firmware);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_PM
|
#ifdef CONFIG_PM
|
||||||
|
|
|
@ -429,8 +429,8 @@ static int ath5k_eeprom_read_modes(struct ath5k_hw *ah, u32 *offset,
|
||||||
ee->ee_margin_tx_rx[mode] = (val >> 8) & 0x3f;
|
ee->ee_margin_tx_rx[mode] = (val >> 8) & 0x3f;
|
||||||
|
|
||||||
AR5K_EEPROM_READ(o++, val);
|
AR5K_EEPROM_READ(o++, val);
|
||||||
ee->ee_i_cal[mode] = (val >> 8) & 0x3f;
|
ee->ee_i_cal[mode] = (val >> 5) & 0x3f;
|
||||||
ee->ee_q_cal[mode] = (val >> 3) & 0x1f;
|
ee->ee_q_cal[mode] = val & 0x1f;
|
||||||
|
|
||||||
if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_2) {
|
if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_2) {
|
||||||
AR5K_EEPROM_READ(o++, val);
|
AR5K_EEPROM_READ(o++, val);
|
||||||
|
|
|
@ -1386,38 +1386,39 @@ static int ath5k_hw_rf511x_calibrate(struct ath5k_hw *ah,
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
/* Calibration has finished, get the results and re-run */
|
/* Calibration has finished, get the results and re-run */
|
||||||
|
|
||||||
|
/* work around empty results which can apparently happen on 5212 */
|
||||||
for (i = 0; i <= 10; i++) {
|
for (i = 0; i <= 10; i++) {
|
||||||
iq_corr = ath5k_hw_reg_read(ah, AR5K_PHY_IQRES_CAL_CORR);
|
iq_corr = ath5k_hw_reg_read(ah, AR5K_PHY_IQRES_CAL_CORR);
|
||||||
i_pwr = ath5k_hw_reg_read(ah, AR5K_PHY_IQRES_CAL_PWR_I);
|
i_pwr = ath5k_hw_reg_read(ah, AR5K_PHY_IQRES_CAL_PWR_I);
|
||||||
q_pwr = ath5k_hw_reg_read(ah, AR5K_PHY_IQRES_CAL_PWR_Q);
|
q_pwr = ath5k_hw_reg_read(ah, AR5K_PHY_IQRES_CAL_PWR_Q);
|
||||||
|
ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_CALIBRATE,
|
||||||
|
"iq_corr:%x i_pwr:%x q_pwr:%x", iq_corr, i_pwr, q_pwr);
|
||||||
|
if (i_pwr && q_pwr)
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
i_coffd = ((i_pwr >> 1) + (q_pwr >> 1)) >> 7;
|
i_coffd = ((i_pwr >> 1) + (q_pwr >> 1)) >> 7;
|
||||||
q_coffd = q_pwr >> 7;
|
q_coffd = q_pwr >> 7;
|
||||||
|
|
||||||
/* No correction */
|
/* protect against divide by 0 and loss of sign bits */
|
||||||
if (i_coffd == 0 || q_coffd == 0)
|
if (i_coffd == 0 || q_coffd < 2)
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
i_coff = ((-iq_corr) / i_coffd);
|
i_coff = (-iq_corr) / i_coffd;
|
||||||
|
i_coff = clamp(i_coff, -32, 31); /* signed 6 bit */
|
||||||
|
|
||||||
/* Boundary check */
|
q_coff = (i_pwr / q_coffd) - 128;
|
||||||
if (i_coff > 31)
|
q_coff = clamp(q_coff, -16, 15); /* signed 5 bit */
|
||||||
i_coff = 31;
|
|
||||||
if (i_coff < -32)
|
|
||||||
i_coff = -32;
|
|
||||||
|
|
||||||
q_coff = (((s32)i_pwr / q_coffd) - 128);
|
ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_CALIBRATE,
|
||||||
|
"new I:%d Q:%d (i_coffd:%x q_coffd:%x)",
|
||||||
|
i_coff, q_coff, i_coffd, q_coffd);
|
||||||
|
|
||||||
/* Boundary check */
|
/* Commit new I/Q values (set enable bit last to match HAL sources) */
|
||||||
if (q_coff > 15)
|
AR5K_REG_WRITE_BITS(ah, AR5K_PHY_IQ, AR5K_PHY_IQ_CORR_Q_I_COFF, i_coff);
|
||||||
q_coff = 15;
|
AR5K_REG_WRITE_BITS(ah, AR5K_PHY_IQ, AR5K_PHY_IQ_CORR_Q_Q_COFF, q_coff);
|
||||||
if (q_coff < -16)
|
AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_IQ, AR5K_PHY_IQ_CORR_ENABLE);
|
||||||
q_coff = -16;
|
|
||||||
|
|
||||||
/* Commit new I/Q value */
|
|
||||||
AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_IQ, AR5K_PHY_IQ_CORR_ENABLE |
|
|
||||||
((u32)q_coff) | ((u32)i_coff << AR5K_PHY_IQ_CORR_Q_I_COFF_S));
|
|
||||||
|
|
||||||
/* Re-enable calibration -if we don't we'll commit
|
/* Re-enable calibration -if we don't we'll commit
|
||||||
* the same values again and again */
|
* the same values again and again */
|
||||||
|
@ -1873,7 +1874,7 @@ ath5k_hw_set_antenna_mode(struct ath5k_hw *ah, u8 ant_mode)
|
||||||
break;
|
break;
|
||||||
case AR5K_ANTMODE_FIXED_A:
|
case AR5K_ANTMODE_FIXED_A:
|
||||||
def_ant = 1;
|
def_ant = 1;
|
||||||
tx_ant = 0;
|
tx_ant = 1;
|
||||||
use_def_for_tx = true;
|
use_def_for_tx = true;
|
||||||
update_def_on_tx = false;
|
update_def_on_tx = false;
|
||||||
use_def_for_rts = true;
|
use_def_for_rts = true;
|
||||||
|
@ -1882,7 +1883,7 @@ ath5k_hw_set_antenna_mode(struct ath5k_hw *ah, u8 ant_mode)
|
||||||
break;
|
break;
|
||||||
case AR5K_ANTMODE_FIXED_B:
|
case AR5K_ANTMODE_FIXED_B:
|
||||||
def_ant = 2;
|
def_ant = 2;
|
||||||
tx_ant = 0;
|
tx_ant = 2;
|
||||||
use_def_for_tx = true;
|
use_def_for_tx = true;
|
||||||
update_def_on_tx = false;
|
update_def_on_tx = false;
|
||||||
use_def_for_rts = true;
|
use_def_for_rts = true;
|
||||||
|
|
|
@ -2187,6 +2187,7 @@
|
||||||
*/
|
*/
|
||||||
#define AR5K_PHY_IQ 0x9920 /* Register Address */
|
#define AR5K_PHY_IQ 0x9920 /* Register Address */
|
||||||
#define AR5K_PHY_IQ_CORR_Q_Q_COFF 0x0000001f /* Mask for q correction info */
|
#define AR5K_PHY_IQ_CORR_Q_Q_COFF 0x0000001f /* Mask for q correction info */
|
||||||
|
#define AR5K_PHY_IQ_CORR_Q_Q_COFF_S 0
|
||||||
#define AR5K_PHY_IQ_CORR_Q_I_COFF 0x000007e0 /* Mask for i correction info */
|
#define AR5K_PHY_IQ_CORR_Q_I_COFF 0x000007e0 /* Mask for i correction info */
|
||||||
#define AR5K_PHY_IQ_CORR_Q_I_COFF_S 5
|
#define AR5K_PHY_IQ_CORR_Q_I_COFF_S 5
|
||||||
#define AR5K_PHY_IQ_CORR_ENABLE 0x00000800 /* Enable i/q correction */
|
#define AR5K_PHY_IQ_CORR_ENABLE 0x00000800 /* Enable i/q correction */
|
||||||
|
|
|
@ -851,12 +851,15 @@ static void ath5k_hw_commit_eeprom_settings(struct ath5k_hw *ah,
|
||||||
AR5K_PHY_OFDM_SELFCORR_CYPWR_THR1,
|
AR5K_PHY_OFDM_SELFCORR_CYPWR_THR1,
|
||||||
AR5K_INIT_CYCRSSI_THR1);
|
AR5K_INIT_CYCRSSI_THR1);
|
||||||
|
|
||||||
/* I/Q correction
|
/* I/Q correction (set enable bit last to match HAL sources) */
|
||||||
* TODO: Per channel i/q infos ? */
|
/* TODO: Per channel i/q infos ? */
|
||||||
AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_IQ,
|
if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_0) {
|
||||||
AR5K_PHY_IQ_CORR_ENABLE |
|
AR5K_REG_WRITE_BITS(ah, AR5K_PHY_IQ, AR5K_PHY_IQ_CORR_Q_I_COFF,
|
||||||
(ee->ee_i_cal[ee_mode] << AR5K_PHY_IQ_CORR_Q_I_COFF_S) |
|
ee->ee_i_cal[ee_mode]);
|
||||||
ee->ee_q_cal[ee_mode]);
|
AR5K_REG_WRITE_BITS(ah, AR5K_PHY_IQ, AR5K_PHY_IQ_CORR_Q_Q_COFF,
|
||||||
|
ee->ee_q_cal[ee_mode]);
|
||||||
|
AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_IQ, AR5K_PHY_IQ_CORR_ENABLE);
|
||||||
|
}
|
||||||
|
|
||||||
/* Heavy clipping -disable for now */
|
/* Heavy clipping -disable for now */
|
||||||
if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_5_1)
|
if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_5_1)
|
||||||
|
@ -1379,11 +1382,10 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
|
||||||
ath5k_hw_set_sleep_clock(ah, true);
|
ath5k_hw_set_sleep_clock(ah, true);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Disable beacons and reset the register
|
* Disable beacons and reset the TSF
|
||||||
*/
|
*/
|
||||||
AR5K_REG_DISABLE_BITS(ah, AR5K_BEACON, AR5K_BEACON_ENABLE |
|
AR5K_REG_DISABLE_BITS(ah, AR5K_BEACON, AR5K_BEACON_ENABLE);
|
||||||
AR5K_BEACON_RESET_TSF);
|
ath5k_hw_reset_tsf(ah);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1323,7 +1323,7 @@ static void ath_rate_init(void *priv, struct ieee80211_supported_band *sband,
|
||||||
|
|
||||||
static void ath_rate_update(void *priv, struct ieee80211_supported_band *sband,
|
static void ath_rate_update(void *priv, struct ieee80211_supported_band *sband,
|
||||||
struct ieee80211_sta *sta, void *priv_sta,
|
struct ieee80211_sta *sta, void *priv_sta,
|
||||||
u32 changed)
|
u32 changed, enum nl80211_channel_type oper_chan_type)
|
||||||
{
|
{
|
||||||
struct ath_softc *sc = priv;
|
struct ath_softc *sc = priv;
|
||||||
struct ath_rate_priv *ath_rc_priv = priv_sta;
|
struct ath_rate_priv *ath_rc_priv = priv_sta;
|
||||||
|
@ -1340,8 +1340,8 @@ static void ath_rate_update(void *priv, struct ieee80211_supported_band *sband,
|
||||||
if (sc->sc_ah->opmode != NL80211_IFTYPE_STATION)
|
if (sc->sc_ah->opmode != NL80211_IFTYPE_STATION)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (sc->hw->conf.channel_type == NL80211_CHAN_HT40MINUS ||
|
if (oper_chan_type == NL80211_CHAN_HT40MINUS ||
|
||||||
sc->hw->conf.channel_type == NL80211_CHAN_HT40PLUS)
|
oper_chan_type == NL80211_CHAN_HT40PLUS)
|
||||||
oper_cw40 = true;
|
oper_cw40 = true;
|
||||||
|
|
||||||
oper_sgi40 = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40) ?
|
oper_sgi40 = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40) ?
|
||||||
|
|
|
@ -2258,7 +2258,7 @@ void ath_tx_node_cleanup(struct ath_softc *sc, struct ath_node *an)
|
||||||
if (ATH_TXQ_SETUP(sc, i)) {
|
if (ATH_TXQ_SETUP(sc, i)) {
|
||||||
txq = &sc->tx.txq[i];
|
txq = &sc->tx.txq[i];
|
||||||
|
|
||||||
spin_lock(&txq->axq_lock);
|
spin_lock_bh(&txq->axq_lock);
|
||||||
|
|
||||||
list_for_each_entry_safe(ac,
|
list_for_each_entry_safe(ac,
|
||||||
ac_tmp, &txq->axq_acq, list) {
|
ac_tmp, &txq->axq_acq, list) {
|
||||||
|
@ -2279,7 +2279,7 @@ void ath_tx_node_cleanup(struct ath_softc *sc, struct ath_node *an)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
spin_unlock(&txq->axq_lock);
|
spin_unlock_bh(&txq->axq_lock);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3177,14 +3177,27 @@ static int ipw_load_firmware(struct ipw_priv *priv, u8 * data, size_t len)
|
||||||
int total_nr = 0;
|
int total_nr = 0;
|
||||||
int i;
|
int i;
|
||||||
struct pci_pool *pool;
|
struct pci_pool *pool;
|
||||||
u32 *virts[CB_NUMBER_OF_ELEMENTS_SMALL];
|
void **virts;
|
||||||
dma_addr_t phys[CB_NUMBER_OF_ELEMENTS_SMALL];
|
dma_addr_t *phys;
|
||||||
|
|
||||||
IPW_DEBUG_TRACE("<< : \n");
|
IPW_DEBUG_TRACE("<< : \n");
|
||||||
|
|
||||||
|
virts = kmalloc(sizeof(void *) * CB_NUMBER_OF_ELEMENTS_SMALL,
|
||||||
|
GFP_KERNEL);
|
||||||
|
if (!virts)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
phys = kmalloc(sizeof(dma_addr_t) * CB_NUMBER_OF_ELEMENTS_SMALL,
|
||||||
|
GFP_KERNEL);
|
||||||
|
if (!phys) {
|
||||||
|
kfree(virts);
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
pool = pci_pool_create("ipw2200", priv->pci_dev, CB_MAX_LENGTH, 0, 0);
|
pool = pci_pool_create("ipw2200", priv->pci_dev, CB_MAX_LENGTH, 0, 0);
|
||||||
if (!pool) {
|
if (!pool) {
|
||||||
IPW_ERROR("pci_pool_create failed\n");
|
IPW_ERROR("pci_pool_create failed\n");
|
||||||
|
kfree(phys);
|
||||||
|
kfree(virts);
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3254,6 +3267,8 @@ static int ipw_load_firmware(struct ipw_priv *priv, u8 * data, size_t len)
|
||||||
pci_pool_free(pool, virts[i], phys[i]);
|
pci_pool_free(pool, virts[i], phys[i]);
|
||||||
|
|
||||||
pci_pool_destroy(pool);
|
pci_pool_destroy(pool);
|
||||||
|
kfree(phys);
|
||||||
|
kfree(virts);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
|
@ -797,7 +797,7 @@ struct libipw_device {
|
||||||
/* Probe / Beacon management */
|
/* Probe / Beacon management */
|
||||||
struct list_head network_free_list;
|
struct list_head network_free_list;
|
||||||
struct list_head network_list;
|
struct list_head network_list;
|
||||||
struct libipw_network *networks;
|
struct libipw_network *networks[MAX_NETWORK_COUNT];
|
||||||
int scans;
|
int scans;
|
||||||
int scan_age;
|
int scan_age;
|
||||||
|
|
||||||
|
|
|
@ -67,16 +67,17 @@ void *libipw_wiphy_privid = &libipw_wiphy_privid;
|
||||||
|
|
||||||
static int libipw_networks_allocate(struct libipw_device *ieee)
|
static int libipw_networks_allocate(struct libipw_device *ieee)
|
||||||
{
|
{
|
||||||
if (ieee->networks)
|
int i, j;
|
||||||
return 0;
|
|
||||||
|
|
||||||
ieee->networks =
|
for (i = 0; i < MAX_NETWORK_COUNT; i++) {
|
||||||
kzalloc(MAX_NETWORK_COUNT * sizeof(struct libipw_network),
|
ieee->networks[i] = kzalloc(sizeof(struct libipw_network),
|
||||||
GFP_KERNEL);
|
GFP_KERNEL);
|
||||||
if (!ieee->networks) {
|
if (!ieee->networks[i]) {
|
||||||
printk(KERN_WARNING "%s: Out of memory allocating beacons\n",
|
LIBIPW_ERROR("Out of memory allocating beacons\n");
|
||||||
ieee->dev->name);
|
for (j = 0; j < i; j++)
|
||||||
return -ENOMEM;
|
kfree(ieee->networks[j]);
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -97,15 +98,11 @@ static inline void libipw_networks_free(struct libipw_device *ieee)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (!ieee->networks)
|
for (i = 0; i < MAX_NETWORK_COUNT; i++) {
|
||||||
return;
|
if (ieee->networks[i]->ibss_dfs)
|
||||||
|
kfree(ieee->networks[i]->ibss_dfs);
|
||||||
for (i = 0; i < MAX_NETWORK_COUNT; i++)
|
kfree(ieee->networks[i]);
|
||||||
if (ieee->networks[i].ibss_dfs)
|
}
|
||||||
kfree(ieee->networks[i].ibss_dfs);
|
|
||||||
|
|
||||||
kfree(ieee->networks);
|
|
||||||
ieee->networks = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void libipw_networks_age(struct libipw_device *ieee,
|
void libipw_networks_age(struct libipw_device *ieee,
|
||||||
|
@ -130,7 +127,7 @@ static void libipw_networks_initialize(struct libipw_device *ieee)
|
||||||
INIT_LIST_HEAD(&ieee->network_free_list);
|
INIT_LIST_HEAD(&ieee->network_free_list);
|
||||||
INIT_LIST_HEAD(&ieee->network_list);
|
INIT_LIST_HEAD(&ieee->network_list);
|
||||||
for (i = 0; i < MAX_NETWORK_COUNT; i++)
|
for (i = 0; i < MAX_NETWORK_COUNT; i++)
|
||||||
list_add_tail(&ieee->networks[i].list,
|
list_add_tail(&ieee->networks[i]->list,
|
||||||
&ieee->network_free_list);
|
&ieee->network_free_list);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -184,7 +184,7 @@ static int iwl3945_hwrate_to_plcp_idx(u8 plcp)
|
||||||
{
|
{
|
||||||
int idx;
|
int idx;
|
||||||
|
|
||||||
for (idx = 0; idx < IWL_RATE_COUNT; idx++)
|
for (idx = 0; idx < IWL_RATE_COUNT_3945; idx++)
|
||||||
if (iwl3945_rates[idx].plcp == plcp)
|
if (iwl3945_rates[idx].plcp == plcp)
|
||||||
return idx;
|
return idx;
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -805,7 +805,7 @@ void iwl3945_hw_build_tx_cmd_rate(struct iwl_priv *priv,
|
||||||
int sta_id, int tx_id)
|
int sta_id, int tx_id)
|
||||||
{
|
{
|
||||||
u16 hw_value = ieee80211_get_tx_rate(priv->hw, info)->hw_value;
|
u16 hw_value = ieee80211_get_tx_rate(priv->hw, info)->hw_value;
|
||||||
u16 rate_index = min(hw_value & 0xffff, IWL_RATE_COUNT - 1);
|
u16 rate_index = min(hw_value & 0xffff, IWL_RATE_COUNT_3945);
|
||||||
u16 rate_mask;
|
u16 rate_mask;
|
||||||
int rate;
|
int rate;
|
||||||
u8 rts_retry_limit;
|
u8 rts_retry_limit;
|
||||||
|
@ -2146,7 +2146,7 @@ static void iwl3945_hw_reg_init_channel_groups(struct iwl_priv *priv)
|
||||||
|
|
||||||
/* fill in channel group's nominal powers for each rate */
|
/* fill in channel group's nominal powers for each rate */
|
||||||
for (rate_index = 0;
|
for (rate_index = 0;
|
||||||
rate_index < IWL_RATE_COUNT; rate_index++, clip_pwrs++) {
|
rate_index < IWL_RATE_COUNT_3945; rate_index++, clip_pwrs++) {
|
||||||
switch (rate_index) {
|
switch (rate_index) {
|
||||||
case IWL_RATE_36M_INDEX_TABLE:
|
case IWL_RATE_36M_INDEX_TABLE:
|
||||||
if (i == 0) /* B/G */
|
if (i == 0) /* B/G */
|
||||||
|
|
|
@ -1463,59 +1463,66 @@ static void iwl_nic_start(struct iwl_priv *priv)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context);
|
||||||
* iwl_read_ucode - Read uCode images from disk file.
|
static int iwl_mac_setup_register(struct iwl_priv *priv);
|
||||||
*
|
|
||||||
* Copy into buffers for card to fetch via bus-mastering
|
static int __must_check iwl_request_firmware(struct iwl_priv *priv, bool first)
|
||||||
*/
|
|
||||||
static int iwl_read_ucode(struct iwl_priv *priv)
|
|
||||||
{
|
{
|
||||||
struct iwl_ucode_header *ucode;
|
|
||||||
int ret = -EINVAL, index;
|
|
||||||
const struct firmware *ucode_raw;
|
|
||||||
const char *name_pre = priv->cfg->fw_name_pre;
|
const char *name_pre = priv->cfg->fw_name_pre;
|
||||||
|
|
||||||
|
if (first)
|
||||||
|
priv->fw_index = priv->cfg->ucode_api_max;
|
||||||
|
else
|
||||||
|
priv->fw_index--;
|
||||||
|
|
||||||
|
if (priv->fw_index < priv->cfg->ucode_api_min) {
|
||||||
|
IWL_ERR(priv, "no suitable firmware found!\n");
|
||||||
|
return -ENOENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
sprintf(priv->firmware_name, "%s%d%s",
|
||||||
|
name_pre, priv->fw_index, ".ucode");
|
||||||
|
|
||||||
|
IWL_DEBUG_INFO(priv, "attempting to load firmware '%s'\n",
|
||||||
|
priv->firmware_name);
|
||||||
|
|
||||||
|
return request_firmware_nowait(THIS_MODULE, 1, priv->firmware_name,
|
||||||
|
&priv->pci_dev->dev, GFP_KERNEL, priv,
|
||||||
|
iwl_ucode_callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* iwl_ucode_callback - callback when firmware was loaded
|
||||||
|
*
|
||||||
|
* If loaded successfully, copies the firmware into buffers
|
||||||
|
* for the card to fetch (via DMA).
|
||||||
|
*/
|
||||||
|
static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context)
|
||||||
|
{
|
||||||
|
struct iwl_priv *priv = context;
|
||||||
|
struct iwl_ucode_header *ucode;
|
||||||
const unsigned int api_max = priv->cfg->ucode_api_max;
|
const unsigned int api_max = priv->cfg->ucode_api_max;
|
||||||
const unsigned int api_min = priv->cfg->ucode_api_min;
|
const unsigned int api_min = priv->cfg->ucode_api_min;
|
||||||
char buf[25];
|
|
||||||
u8 *src;
|
u8 *src;
|
||||||
size_t len;
|
size_t len;
|
||||||
u32 api_ver, build;
|
u32 api_ver, build;
|
||||||
u32 inst_size, data_size, init_size, init_data_size, boot_size;
|
u32 inst_size, data_size, init_size, init_data_size, boot_size;
|
||||||
|
int err;
|
||||||
u16 eeprom_ver;
|
u16 eeprom_ver;
|
||||||
|
|
||||||
/* Ask kernel firmware_class module to get the boot firmware off disk.
|
if (!ucode_raw) {
|
||||||
* request_firmware() is synchronous, file is in memory on return. */
|
IWL_ERR(priv, "request for firmware file '%s' failed.\n",
|
||||||
for (index = api_max; index >= api_min; index--) {
|
priv->firmware_name);
|
||||||
sprintf(buf, "%s%d%s", name_pre, index, ".ucode");
|
goto try_again;
|
||||||
ret = request_firmware(&ucode_raw, buf, &priv->pci_dev->dev);
|
|
||||||
if (ret < 0) {
|
|
||||||
IWL_ERR(priv, "%s firmware file req failed: %d\n",
|
|
||||||
buf, ret);
|
|
||||||
if (ret == -ENOENT)
|
|
||||||
continue;
|
|
||||||
else
|
|
||||||
goto error;
|
|
||||||
} else {
|
|
||||||
if (index < api_max)
|
|
||||||
IWL_ERR(priv, "Loaded firmware %s, "
|
|
||||||
"which is deprecated. "
|
|
||||||
"Please use API v%u instead.\n",
|
|
||||||
buf, api_max);
|
|
||||||
|
|
||||||
IWL_DEBUG_INFO(priv, "Got firmware '%s' file (%zd bytes) from disk\n",
|
|
||||||
buf, ucode_raw->size);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ret < 0)
|
IWL_DEBUG_INFO(priv, "Loaded firmware file '%s' (%zd bytes).\n",
|
||||||
goto error;
|
priv->firmware_name, ucode_raw->size);
|
||||||
|
|
||||||
/* Make sure that we got at least the v1 header! */
|
/* Make sure that we got at least the v1 header! */
|
||||||
if (ucode_raw->size < priv->cfg->ops->ucode->get_header_size(1)) {
|
if (ucode_raw->size < priv->cfg->ops->ucode->get_header_size(1)) {
|
||||||
IWL_ERR(priv, "File size way too small!\n");
|
IWL_ERR(priv, "File size way too small!\n");
|
||||||
ret = -EINVAL;
|
goto try_again;
|
||||||
goto err_release;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Data from ucode file: header followed by uCode images */
|
/* Data from ucode file: header followed by uCode images */
|
||||||
|
@ -1540,10 +1547,9 @@ static int iwl_read_ucode(struct iwl_priv *priv)
|
||||||
IWL_ERR(priv, "Driver unable to support your firmware API. "
|
IWL_ERR(priv, "Driver unable to support your firmware API. "
|
||||||
"Driver supports v%u, firmware is v%u.\n",
|
"Driver supports v%u, firmware is v%u.\n",
|
||||||
api_max, api_ver);
|
api_max, api_ver);
|
||||||
priv->ucode_ver = 0;
|
goto try_again;
|
||||||
ret = -EINVAL;
|
|
||||||
goto err_release;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (api_ver != api_max)
|
if (api_ver != api_max)
|
||||||
IWL_ERR(priv, "Firmware has old API version. Expected v%u, "
|
IWL_ERR(priv, "Firmware has old API version. Expected v%u, "
|
||||||
"got v%u. New firmware can be obtained "
|
"got v%u. New firmware can be obtained "
|
||||||
|
@ -1585,6 +1591,12 @@ static int iwl_read_ucode(struct iwl_priv *priv)
|
||||||
IWL_DEBUG_INFO(priv, "f/w package hdr boot inst size = %u\n",
|
IWL_DEBUG_INFO(priv, "f/w package hdr boot inst size = %u\n",
|
||||||
boot_size);
|
boot_size);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* For any of the failures below (before allocating pci memory)
|
||||||
|
* we will try to load a version with a smaller API -- maybe the
|
||||||
|
* user just got a corrupted version of the latest API.
|
||||||
|
*/
|
||||||
|
|
||||||
/* Verify size of file vs. image size info in file's header */
|
/* Verify size of file vs. image size info in file's header */
|
||||||
if (ucode_raw->size !=
|
if (ucode_raw->size !=
|
||||||
priv->cfg->ops->ucode->get_header_size(api_ver) +
|
priv->cfg->ops->ucode->get_header_size(api_ver) +
|
||||||
|
@ -1594,41 +1606,35 @@ static int iwl_read_ucode(struct iwl_priv *priv)
|
||||||
IWL_DEBUG_INFO(priv,
|
IWL_DEBUG_INFO(priv,
|
||||||
"uCode file size %d does not match expected size\n",
|
"uCode file size %d does not match expected size\n",
|
||||||
(int)ucode_raw->size);
|
(int)ucode_raw->size);
|
||||||
ret = -EINVAL;
|
goto try_again;
|
||||||
goto err_release;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Verify that uCode images will fit in card's SRAM */
|
/* Verify that uCode images will fit in card's SRAM */
|
||||||
if (inst_size > priv->hw_params.max_inst_size) {
|
if (inst_size > priv->hw_params.max_inst_size) {
|
||||||
IWL_DEBUG_INFO(priv, "uCode instr len %d too large to fit in\n",
|
IWL_DEBUG_INFO(priv, "uCode instr len %d too large to fit in\n",
|
||||||
inst_size);
|
inst_size);
|
||||||
ret = -EINVAL;
|
goto try_again;
|
||||||
goto err_release;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data_size > priv->hw_params.max_data_size) {
|
if (data_size > priv->hw_params.max_data_size) {
|
||||||
IWL_DEBUG_INFO(priv, "uCode data len %d too large to fit in\n",
|
IWL_DEBUG_INFO(priv, "uCode data len %d too large to fit in\n",
|
||||||
data_size);
|
data_size);
|
||||||
ret = -EINVAL;
|
goto try_again;
|
||||||
goto err_release;
|
|
||||||
}
|
}
|
||||||
if (init_size > priv->hw_params.max_inst_size) {
|
if (init_size > priv->hw_params.max_inst_size) {
|
||||||
IWL_INFO(priv, "uCode init instr len %d too large to fit in\n",
|
IWL_INFO(priv, "uCode init instr len %d too large to fit in\n",
|
||||||
init_size);
|
init_size);
|
||||||
ret = -EINVAL;
|
goto try_again;
|
||||||
goto err_release;
|
|
||||||
}
|
}
|
||||||
if (init_data_size > priv->hw_params.max_data_size) {
|
if (init_data_size > priv->hw_params.max_data_size) {
|
||||||
IWL_INFO(priv, "uCode init data len %d too large to fit in\n",
|
IWL_INFO(priv, "uCode init data len %d too large to fit in\n",
|
||||||
init_data_size);
|
init_data_size);
|
||||||
ret = -EINVAL;
|
goto try_again;
|
||||||
goto err_release;
|
|
||||||
}
|
}
|
||||||
if (boot_size > priv->hw_params.max_bsm_size) {
|
if (boot_size > priv->hw_params.max_bsm_size) {
|
||||||
IWL_INFO(priv, "uCode boot instr len %d too large to fit in\n",
|
IWL_INFO(priv, "uCode boot instr len %d too large to fit in\n",
|
||||||
boot_size);
|
boot_size);
|
||||||
ret = -EINVAL;
|
goto try_again;
|
||||||
goto err_release;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Allocate ucode buffers for card's bus-master loading ... */
|
/* Allocate ucode buffers for card's bus-master loading ... */
|
||||||
|
@ -1712,20 +1718,36 @@ static int iwl_read_ucode(struct iwl_priv *priv)
|
||||||
IWL_DEBUG_INFO(priv, "Copying (but not loading) boot instr len %Zd\n", len);
|
IWL_DEBUG_INFO(priv, "Copying (but not loading) boot instr len %Zd\n", len);
|
||||||
memcpy(priv->ucode_boot.v_addr, src, len);
|
memcpy(priv->ucode_boot.v_addr, src, len);
|
||||||
|
|
||||||
|
/**************************************************
|
||||||
|
* This is still part of probe() in a sense...
|
||||||
|
*
|
||||||
|
* 9. Setup and register with mac80211 and debugfs
|
||||||
|
**************************************************/
|
||||||
|
err = iwl_mac_setup_register(priv);
|
||||||
|
if (err)
|
||||||
|
goto out_unbind;
|
||||||
|
|
||||||
|
err = iwl_dbgfs_register(priv, DRV_NAME);
|
||||||
|
if (err)
|
||||||
|
IWL_ERR(priv, "failed to create debugfs files. Ignoring error: %d\n", err);
|
||||||
|
|
||||||
/* We have our copies now, allow OS release its copies */
|
/* We have our copies now, allow OS release its copies */
|
||||||
release_firmware(ucode_raw);
|
release_firmware(ucode_raw);
|
||||||
return 0;
|
return;
|
||||||
|
|
||||||
|
try_again:
|
||||||
|
/* try next, if any */
|
||||||
|
if (iwl_request_firmware(priv, false))
|
||||||
|
goto out_unbind;
|
||||||
|
release_firmware(ucode_raw);
|
||||||
|
return;
|
||||||
|
|
||||||
err_pci_alloc:
|
err_pci_alloc:
|
||||||
IWL_ERR(priv, "failed to allocate pci memory\n");
|
IWL_ERR(priv, "failed to allocate pci memory\n");
|
||||||
ret = -ENOMEM;
|
|
||||||
iwl_dealloc_ucode_pci(priv);
|
iwl_dealloc_ucode_pci(priv);
|
||||||
|
out_unbind:
|
||||||
err_release:
|
device_release_driver(&priv->pci_dev->dev);
|
||||||
release_firmware(ucode_raw);
|
release_firmware(ucode_raw);
|
||||||
|
|
||||||
error:
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char *desc_lookup_text[] = {
|
static const char *desc_lookup_text[] = {
|
||||||
|
@ -2631,7 +2653,7 @@ static int iwl_mac_setup_register(struct iwl_priv *priv)
|
||||||
*/
|
*/
|
||||||
hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
|
hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
|
||||||
|
|
||||||
hw->wiphy->max_scan_ssids = PROBE_OPTION_MAX + 1;
|
hw->wiphy->max_scan_ssids = PROBE_OPTION_MAX;
|
||||||
/* we create the 802.11 header and a zero-length SSID element */
|
/* we create the 802.11 header and a zero-length SSID element */
|
||||||
hw->wiphy->max_scan_ie_len = IWL_MAX_PROBE_REQUEST - 24 - 2;
|
hw->wiphy->max_scan_ie_len = IWL_MAX_PROBE_REQUEST - 24 - 2;
|
||||||
|
|
||||||
|
@ -2667,21 +2689,7 @@ static int iwl_mac_start(struct ieee80211_hw *hw)
|
||||||
|
|
||||||
/* we should be verifying the device is ready to be opened */
|
/* we should be verifying the device is ready to be opened */
|
||||||
mutex_lock(&priv->mutex);
|
mutex_lock(&priv->mutex);
|
||||||
|
|
||||||
/* fetch ucode file from disk, alloc and copy to bus-master buffers ...
|
|
||||||
* ucode filename and max sizes are card-specific. */
|
|
||||||
|
|
||||||
if (!priv->ucode_code.len) {
|
|
||||||
ret = iwl_read_ucode(priv);
|
|
||||||
if (ret) {
|
|
||||||
IWL_ERR(priv, "Could not read microcode: %d\n", ret);
|
|
||||||
mutex_unlock(&priv->mutex);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = __iwl_up(priv);
|
ret = __iwl_up(priv);
|
||||||
|
|
||||||
mutex_unlock(&priv->mutex);
|
mutex_unlock(&priv->mutex);
|
||||||
|
|
||||||
if (ret)
|
if (ret)
|
||||||
|
@ -3654,17 +3662,10 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
|
||||||
iwl_power_initialize(priv);
|
iwl_power_initialize(priv);
|
||||||
iwl_tt_initialize(priv);
|
iwl_tt_initialize(priv);
|
||||||
|
|
||||||
/**************************************************
|
err = iwl_request_firmware(priv, true);
|
||||||
* 9. Setup and register with mac80211 and debugfs
|
|
||||||
**************************************************/
|
|
||||||
err = iwl_mac_setup_register(priv);
|
|
||||||
if (err)
|
if (err)
|
||||||
goto out_remove_sysfs;
|
goto out_remove_sysfs;
|
||||||
|
|
||||||
err = iwl_dbgfs_register(priv, DRV_NAME);
|
|
||||||
if (err)
|
|
||||||
IWL_ERR(priv, "failed to create debugfs files. Ignoring error: %d\n", err);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
out_remove_sysfs:
|
out_remove_sysfs:
|
||||||
|
|
|
@ -1132,6 +1132,7 @@ struct iwl_priv {
|
||||||
u8 rev_id;
|
u8 rev_id;
|
||||||
|
|
||||||
/* uCode images, save to reload in case of failure */
|
/* uCode images, save to reload in case of failure */
|
||||||
|
int fw_index; /* firmware we're trying to load */
|
||||||
u32 ucode_ver; /* version of ucode, copy of
|
u32 ucode_ver; /* version of ucode, copy of
|
||||||
iwl_ucode.ver */
|
iwl_ucode.ver */
|
||||||
struct fw_desc ucode_code; /* runtime inst */
|
struct fw_desc ucode_code; /* runtime inst */
|
||||||
|
@ -1142,6 +1143,7 @@ struct iwl_priv {
|
||||||
struct fw_desc ucode_boot; /* bootstrap inst */
|
struct fw_desc ucode_boot; /* bootstrap inst */
|
||||||
enum ucode_type ucode_type;
|
enum ucode_type ucode_type;
|
||||||
u8 ucode_write_complete; /* the image write is complete */
|
u8 ucode_write_complete; /* the image write is complete */
|
||||||
|
char firmware_name[25];
|
||||||
|
|
||||||
|
|
||||||
struct iwl_rxon_time_cmd rxon_timing;
|
struct iwl_rxon_time_cmd rxon_timing;
|
||||||
|
|
|
@ -638,20 +638,9 @@ u16 iwl_fill_probe_req(struct iwl_priv *priv, struct ieee80211_mgmt *frame,
|
||||||
if (left < 0)
|
if (left < 0)
|
||||||
return 0;
|
return 0;
|
||||||
*pos++ = WLAN_EID_SSID;
|
*pos++ = WLAN_EID_SSID;
|
||||||
if (!priv->is_internal_short_scan &&
|
*pos++ = 0;
|
||||||
priv->scan_request->n_ssids) {
|
|
||||||
struct cfg80211_ssid *ssid =
|
|
||||||
priv->scan_request->ssids;
|
|
||||||
|
|
||||||
/* Broadcast if ssid_len is 0 */
|
len += 2;
|
||||||
*pos++ = ssid->ssid_len;
|
|
||||||
memcpy(pos, ssid->ssid, ssid->ssid_len);
|
|
||||||
pos += ssid->ssid_len;
|
|
||||||
len += 2 + ssid->ssid_len;
|
|
||||||
} else {
|
|
||||||
*pos++ = 0;
|
|
||||||
len += 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (WARN_ON(left < ie_len))
|
if (WARN_ON(left < ie_len))
|
||||||
return len;
|
return len;
|
||||||
|
@ -780,26 +769,20 @@ static void iwl_bg_request_scan(struct work_struct *data)
|
||||||
if (priv->is_internal_short_scan) {
|
if (priv->is_internal_short_scan) {
|
||||||
IWL_DEBUG_SCAN(priv, "Start internal passive scan.\n");
|
IWL_DEBUG_SCAN(priv, "Start internal passive scan.\n");
|
||||||
} else if (priv->scan_request->n_ssids) {
|
} else if (priv->scan_request->n_ssids) {
|
||||||
|
int i, p = 0;
|
||||||
IWL_DEBUG_SCAN(priv, "Kicking off active scan\n");
|
IWL_DEBUG_SCAN(priv, "Kicking off active scan\n");
|
||||||
/*
|
for (i = 0; i < priv->scan_request->n_ssids; i++) {
|
||||||
* The first SSID to scan is stuffed into the probe request
|
/* always does wildcard anyway */
|
||||||
* template and the remaining ones are handled through the
|
if (!priv->scan_request->ssids[i].ssid_len)
|
||||||
* direct_scan array.
|
continue;
|
||||||
*/
|
scan->direct_scan[p].id = WLAN_EID_SSID;
|
||||||
if (priv->scan_request->n_ssids > 1) {
|
scan->direct_scan[p].len =
|
||||||
int i, p = 0;
|
priv->scan_request->ssids[i].ssid_len;
|
||||||
for (i = 1; i < priv->scan_request->n_ssids; i++) {
|
memcpy(scan->direct_scan[p].ssid,
|
||||||
if (!priv->scan_request->ssids[i].ssid_len)
|
priv->scan_request->ssids[i].ssid,
|
||||||
continue;
|
priv->scan_request->ssids[i].ssid_len);
|
||||||
scan->direct_scan[p].id = WLAN_EID_SSID;
|
n_probes++;
|
||||||
scan->direct_scan[p].len =
|
p++;
|
||||||
priv->scan_request->ssids[i].ssid_len;
|
|
||||||
memcpy(scan->direct_scan[p].ssid,
|
|
||||||
priv->scan_request->ssids[i].ssid,
|
|
||||||
priv->scan_request->ssids[i].ssid_len);
|
|
||||||
n_probes++;
|
|
||||||
p++;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
is_active = true;
|
is_active = true;
|
||||||
} else
|
} else
|
||||||
|
|
|
@ -1496,51 +1496,67 @@ static void set_multicast_list(struct usbnet *usbdev)
|
||||||
{
|
{
|
||||||
struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
|
struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
|
||||||
struct dev_mc_list *mclist;
|
struct dev_mc_list *mclist;
|
||||||
__le32 filter;
|
__le32 filter, basefilter;
|
||||||
int ret, i, size;
|
int ret;
|
||||||
char *buf;
|
char *mc_addrs = NULL;
|
||||||
|
int mc_count;
|
||||||
|
|
||||||
filter = RNDIS_PACKET_TYPE_DIRECTED | RNDIS_PACKET_TYPE_BROADCAST;
|
basefilter = filter = RNDIS_PACKET_TYPE_DIRECTED |
|
||||||
|
RNDIS_PACKET_TYPE_BROADCAST;
|
||||||
|
|
||||||
netif_addr_lock_bh(usbdev->net);
|
|
||||||
if (usbdev->net->flags & IFF_PROMISC) {
|
if (usbdev->net->flags & IFF_PROMISC) {
|
||||||
filter |= RNDIS_PACKET_TYPE_PROMISCUOUS |
|
filter |= RNDIS_PACKET_TYPE_PROMISCUOUS |
|
||||||
RNDIS_PACKET_TYPE_ALL_LOCAL;
|
RNDIS_PACKET_TYPE_ALL_LOCAL;
|
||||||
} else if (usbdev->net->flags & IFF_ALLMULTI ||
|
} else if (usbdev->net->flags & IFF_ALLMULTI) {
|
||||||
netdev_mc_count(usbdev->net) > priv->multicast_size) {
|
|
||||||
filter |= RNDIS_PACKET_TYPE_ALL_MULTICAST;
|
filter |= RNDIS_PACKET_TYPE_ALL_MULTICAST;
|
||||||
} else if (!netdev_mc_empty(usbdev->net)) {
|
}
|
||||||
size = min(priv->multicast_size, netdev_mc_count(usbdev->net));
|
|
||||||
buf = kmalloc(size * ETH_ALEN, GFP_KERNEL);
|
if (filter != basefilter)
|
||||||
if (!buf) {
|
goto set_filter;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* mc_list should be accessed holding the lock, so copy addresses to
|
||||||
|
* local buffer first.
|
||||||
|
*/
|
||||||
|
netif_addr_lock_bh(usbdev->net);
|
||||||
|
mc_count = netdev_mc_count(usbdev->net);
|
||||||
|
if (mc_count > priv->multicast_size) {
|
||||||
|
filter |= RNDIS_PACKET_TYPE_ALL_MULTICAST;
|
||||||
|
} else if (mc_count) {
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
|
mc_addrs = kmalloc(mc_count * ETH_ALEN, GFP_ATOMIC);
|
||||||
|
if (!mc_addrs) {
|
||||||
netdev_warn(usbdev->net,
|
netdev_warn(usbdev->net,
|
||||||
"couldn't alloc %d bytes of memory\n",
|
"couldn't alloc %d bytes of memory\n",
|
||||||
size * ETH_ALEN);
|
mc_count * ETH_ALEN);
|
||||||
netif_addr_unlock_bh(usbdev->net);
|
netif_addr_unlock_bh(usbdev->net);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
i = 0;
|
netdev_for_each_mc_addr(mclist, usbdev->net)
|
||||||
netdev_for_each_mc_addr(mclist, usbdev->net) {
|
memcpy(mc_addrs + i++ * ETH_ALEN,
|
||||||
if (i == size)
|
mclist->dmi_addr, ETH_ALEN);
|
||||||
break;
|
}
|
||||||
memcpy(buf + i++ * ETH_ALEN, mclist->dmi_addr, ETH_ALEN);
|
netif_addr_unlock_bh(usbdev->net);
|
||||||
}
|
|
||||||
|
|
||||||
ret = rndis_set_oid(usbdev, OID_802_3_MULTICAST_LIST, buf,
|
if (filter != basefilter)
|
||||||
i * ETH_ALEN);
|
goto set_filter;
|
||||||
if (ret == 0 && i > 0)
|
|
||||||
|
if (mc_count) {
|
||||||
|
ret = rndis_set_oid(usbdev, OID_802_3_MULTICAST_LIST, mc_addrs,
|
||||||
|
mc_count * ETH_ALEN);
|
||||||
|
kfree(mc_addrs);
|
||||||
|
if (ret == 0)
|
||||||
filter |= RNDIS_PACKET_TYPE_MULTICAST;
|
filter |= RNDIS_PACKET_TYPE_MULTICAST;
|
||||||
else
|
else
|
||||||
filter |= RNDIS_PACKET_TYPE_ALL_MULTICAST;
|
filter |= RNDIS_PACKET_TYPE_ALL_MULTICAST;
|
||||||
|
|
||||||
netdev_dbg(usbdev->net, "OID_802_3_MULTICAST_LIST(%d, max: %d) -> %d\n",
|
netdev_dbg(usbdev->net, "OID_802_3_MULTICAST_LIST(%d, max: %d) -> %d\n",
|
||||||
i, priv->multicast_size, ret);
|
mc_count, priv->multicast_size, ret);
|
||||||
|
|
||||||
kfree(buf);
|
|
||||||
}
|
}
|
||||||
netif_addr_unlock_bh(usbdev->net);
|
|
||||||
|
|
||||||
|
set_filter:
|
||||||
ret = rndis_set_oid(usbdev, OID_GEN_CURRENT_PACKET_FILTER, &filter,
|
ret = rndis_set_oid(usbdev, OID_GEN_CURRENT_PACKET_FILTER, &filter,
|
||||||
sizeof(filter));
|
sizeof(filter));
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
|
|
|
@ -1225,7 +1225,7 @@ MODULE_LICENSE("GPL");
|
||||||
#ifdef CONFIG_RT2800PCI_SOC
|
#ifdef CONFIG_RT2800PCI_SOC
|
||||||
static int rt2800soc_probe(struct platform_device *pdev)
|
static int rt2800soc_probe(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
return rt2x00soc_probe(pdev, rt2800pci_ops);
|
return rt2x00soc_probe(pdev, &rt2800pci_ops);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct platform_driver rt2800soc_driver = {
|
static struct platform_driver rt2800soc_driver = {
|
||||||
|
|
|
@ -112,6 +112,7 @@ exit_free_device:
|
||||||
|
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(rt2x00soc_probe);
|
||||||
|
|
||||||
int rt2x00soc_remove(struct platform_device *pdev)
|
int rt2x00soc_remove(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
|
|
|
@ -26,8 +26,6 @@
|
||||||
#ifndef RT2X00SOC_H
|
#ifndef RT2X00SOC_H
|
||||||
#define RT2X00SOC_H
|
#define RT2X00SOC_H
|
||||||
|
|
||||||
#define KSEG1ADDR(__ptr) __ptr
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* SoC driver handlers.
|
* SoC driver handlers.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -2352,6 +2352,8 @@ static struct usb_device_id rt73usb_device_table[] = {
|
||||||
{ USB_DEVICE(0x0411, 0x00f4), USB_DEVICE_DATA(&rt73usb_ops) },
|
{ USB_DEVICE(0x0411, 0x00f4), USB_DEVICE_DATA(&rt73usb_ops) },
|
||||||
{ USB_DEVICE(0x0411, 0x0116), USB_DEVICE_DATA(&rt73usb_ops) },
|
{ USB_DEVICE(0x0411, 0x0116), USB_DEVICE_DATA(&rt73usb_ops) },
|
||||||
{ USB_DEVICE(0x0411, 0x0119), USB_DEVICE_DATA(&rt73usb_ops) },
|
{ USB_DEVICE(0x0411, 0x0119), USB_DEVICE_DATA(&rt73usb_ops) },
|
||||||
|
/* CEIVA */
|
||||||
|
{ USB_DEVICE(0x178d, 0x02be), USB_DEVICE_DATA(&rt73usb_ops) },
|
||||||
/* CNet */
|
/* CNet */
|
||||||
{ USB_DEVICE(0x1371, 0x9022), USB_DEVICE_DATA(&rt73usb_ops) },
|
{ USB_DEVICE(0x1371, 0x9022), USB_DEVICE_DATA(&rt73usb_ops) },
|
||||||
{ USB_DEVICE(0x1371, 0x9032), USB_DEVICE_DATA(&rt73usb_ops) },
|
{ USB_DEVICE(0x1371, 0x9032), USB_DEVICE_DATA(&rt73usb_ops) },
|
||||||
|
|
|
@ -350,7 +350,7 @@ static void zd_mac_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb,
|
||||||
first_idx = info->status.rates[0].idx;
|
first_idx = info->status.rates[0].idx;
|
||||||
ZD_ASSERT(0<=first_idx && first_idx<ARRAY_SIZE(zd_retry_rates));
|
ZD_ASSERT(0<=first_idx && first_idx<ARRAY_SIZE(zd_retry_rates));
|
||||||
retries = &zd_retry_rates[first_idx];
|
retries = &zd_retry_rates[first_idx];
|
||||||
ZD_ASSERT(0<=retry && retry<=retries->count);
|
ZD_ASSERT(1 <= retry && retry <= retries->count);
|
||||||
|
|
||||||
info->status.rates[0].idx = retries->rate[0];
|
info->status.rates[0].idx = retries->rate[0];
|
||||||
info->status.rates[0].count = 1; // (retry > 1 ? 2 : 1);
|
info->status.rates[0].count = 1; // (retry > 1 ? 2 : 1);
|
||||||
|
@ -360,7 +360,7 @@ static void zd_mac_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb,
|
||||||
info->status.rates[i].count = 1; // ((i==retry-1) && success ? 1:2);
|
info->status.rates[i].count = 1; // ((i==retry-1) && success ? 1:2);
|
||||||
}
|
}
|
||||||
for (; i<IEEE80211_TX_MAX_RATES && i<retry; i++) {
|
for (; i<IEEE80211_TX_MAX_RATES && i<retry; i++) {
|
||||||
info->status.rates[i].idx = retries->rate[retry-1];
|
info->status.rates[i].idx = retries->rate[retry - 1];
|
||||||
info->status.rates[i].count = 1; // (success ? 1:2);
|
info->status.rates[i].count = 1; // (success ? 1:2);
|
||||||
}
|
}
|
||||||
if (i<IEEE80211_TX_MAX_RATES)
|
if (i<IEEE80211_TX_MAX_RATES)
|
||||||
|
@ -424,12 +424,10 @@ void zd_mac_tx_failed(struct urb *urb)
|
||||||
first_idx = info->status.rates[0].idx;
|
first_idx = info->status.rates[0].idx;
|
||||||
ZD_ASSERT(0<=first_idx && first_idx<ARRAY_SIZE(zd_retry_rates));
|
ZD_ASSERT(0<=first_idx && first_idx<ARRAY_SIZE(zd_retry_rates));
|
||||||
retries = &zd_retry_rates[first_idx];
|
retries = &zd_retry_rates[first_idx];
|
||||||
if (retry < 0 || retry > retries->count) {
|
if (retry <= 0 || retry > retries->count)
|
||||||
continue;
|
continue;
|
||||||
}
|
|
||||||
|
|
||||||
ZD_ASSERT(0<=retry && retry<=retries->count);
|
final_idx = retries->rate[retry - 1];
|
||||||
final_idx = retries->rate[retry-1];
|
|
||||||
final_rate = zd_rates[final_idx].hw_value;
|
final_rate = zd_rates[final_idx].hw_value;
|
||||||
|
|
||||||
if (final_rate != tx_status->rate) {
|
if (final_rate != tx_status->rate) {
|
||||||
|
|
|
@ -763,7 +763,8 @@ static inline int qeth_get_micros(void)
|
||||||
|
|
||||||
static inline int qeth_get_ip_version(struct sk_buff *skb)
|
static inline int qeth_get_ip_version(struct sk_buff *skb)
|
||||||
{
|
{
|
||||||
switch (skb->protocol) {
|
struct ethhdr *ehdr = (struct ethhdr *)skb->data;
|
||||||
|
switch (ehdr->h_proto) {
|
||||||
case ETH_P_IPV6:
|
case ETH_P_IPV6:
|
||||||
return 6;
|
return 6;
|
||||||
case ETH_P_IP:
|
case ETH_P_IP:
|
||||||
|
|
|
@ -537,7 +537,8 @@ static void qeth_send_control_data_cb(struct qeth_channel *channel,
|
||||||
dev_err(&card->gdev->dev,
|
dev_err(&card->gdev->dev,
|
||||||
"The qeth device is not configured "
|
"The qeth device is not configured "
|
||||||
"for the OSI layer required by z/VM\n");
|
"for the OSI layer required by z/VM\n");
|
||||||
qeth_schedule_recovery(card);
|
else
|
||||||
|
qeth_schedule_recovery(card);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1113,8 +1114,6 @@ static int qeth_setup_card(struct qeth_card *card)
|
||||||
card->ipato.enabled = 0;
|
card->ipato.enabled = 0;
|
||||||
card->ipato.invert4 = 0;
|
card->ipato.invert4 = 0;
|
||||||
card->ipato.invert6 = 0;
|
card->ipato.invert6 = 0;
|
||||||
if (card->info.type == QETH_CARD_TYPE_IQD)
|
|
||||||
card->options.checksum_type = NO_CHECKSUMMING;
|
|
||||||
/* init QDIO stuff */
|
/* init QDIO stuff */
|
||||||
qeth_init_qdio_info(card);
|
qeth_init_qdio_info(card);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -8,6 +8,9 @@
|
||||||
* Frank Blaschka <frank.blaschka@de.ibm.com>
|
* Frank Blaschka <frank.blaschka@de.ibm.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#define KMSG_COMPONENT "qeth"
|
||||||
|
#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
|
||||||
|
|
||||||
#include <linux/list.h>
|
#include <linux/list.h>
|
||||||
#include <linux/rwsem.h>
|
#include <linux/rwsem.h>
|
||||||
#include <asm/ebcdic.h>
|
#include <asm/ebcdic.h>
|
||||||
|
|
|
@ -1071,11 +1071,9 @@ static int qeth_l2_recover(void *ptr)
|
||||||
dev_info(&card->gdev->dev,
|
dev_info(&card->gdev->dev,
|
||||||
"Device successfully recovered!\n");
|
"Device successfully recovered!\n");
|
||||||
else {
|
else {
|
||||||
if (card->dev) {
|
rtnl_lock();
|
||||||
rtnl_lock();
|
dev_close(card->dev);
|
||||||
dev_close(card->dev);
|
rtnl_unlock();
|
||||||
rtnl_unlock();
|
|
||||||
}
|
|
||||||
dev_warn(&card->gdev->dev, "The qeth device driver "
|
dev_warn(&card->gdev->dev, "The qeth device driver "
|
||||||
"failed to recover an error on the device\n");
|
"failed to recover an error on the device\n");
|
||||||
}
|
}
|
||||||
|
@ -1129,11 +1127,9 @@ static int qeth_l2_pm_resume(struct ccwgroup_device *gdev)
|
||||||
if (card->state == CARD_STATE_RECOVER) {
|
if (card->state == CARD_STATE_RECOVER) {
|
||||||
rc = __qeth_l2_set_online(card->gdev, 1);
|
rc = __qeth_l2_set_online(card->gdev, 1);
|
||||||
if (rc) {
|
if (rc) {
|
||||||
if (card->dev) {
|
rtnl_lock();
|
||||||
rtnl_lock();
|
dev_close(card->dev);
|
||||||
dev_close(card->dev);
|
rtnl_unlock();
|
||||||
rtnl_unlock();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
rc = __qeth_l2_set_online(card->gdev, 0);
|
rc = __qeth_l2_set_online(card->gdev, 0);
|
||||||
|
|
|
@ -1691,39 +1691,43 @@ qeth_diags_trace_cb(struct qeth_card *card, struct qeth_reply *reply,
|
||||||
|
|
||||||
cmd = (struct qeth_ipa_cmd *)data;
|
cmd = (struct qeth_ipa_cmd *)data;
|
||||||
rc = cmd->hdr.return_code;
|
rc = cmd->hdr.return_code;
|
||||||
if (rc) {
|
if (rc)
|
||||||
QETH_DBF_TEXT_(TRACE, 2, "dxter%x", rc);
|
QETH_DBF_TEXT_(TRACE, 2, "dxter%x", rc);
|
||||||
if (cmd->data.diagass.action == QETH_DIAGS_CMD_TRACE_ENABLE) {
|
|
||||||
switch (rc) {
|
|
||||||
case IPA_RC_HARDWARE_AUTH_ERROR:
|
|
||||||
dev_warn(&card->gdev->dev, "The device is not "
|
|
||||||
"authorized to run as a HiperSockets "
|
|
||||||
"network traffic analyzer\n");
|
|
||||||
break;
|
|
||||||
case IPA_RC_TRACE_ALREADY_ACTIVE:
|
|
||||||
dev_warn(&card->gdev->dev, "A HiperSockets "
|
|
||||||
"network traffic analyzer is already "
|
|
||||||
"active in the HiperSockets LAN\n");
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (cmd->data.diagass.action) {
|
switch (cmd->data.diagass.action) {
|
||||||
case QETH_DIAGS_CMD_TRACE_QUERY:
|
case QETH_DIAGS_CMD_TRACE_QUERY:
|
||||||
break;
|
break;
|
||||||
case QETH_DIAGS_CMD_TRACE_DISABLE:
|
case QETH_DIAGS_CMD_TRACE_DISABLE:
|
||||||
card->info.promisc_mode = SET_PROMISC_MODE_OFF;
|
switch (rc) {
|
||||||
dev_info(&card->gdev->dev, "The HiperSockets network traffic "
|
case 0:
|
||||||
"analyzer is deactivated\n");
|
case IPA_RC_INVALID_SUBCMD:
|
||||||
|
card->info.promisc_mode = SET_PROMISC_MODE_OFF;
|
||||||
|
dev_info(&card->gdev->dev, "The HiperSockets network "
|
||||||
|
"traffic analyzer is deactivated\n");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case QETH_DIAGS_CMD_TRACE_ENABLE:
|
case QETH_DIAGS_CMD_TRACE_ENABLE:
|
||||||
card->info.promisc_mode = SET_PROMISC_MODE_ON;
|
switch (rc) {
|
||||||
dev_info(&card->gdev->dev, "The HiperSockets network traffic "
|
case 0:
|
||||||
"analyzer is activated\n");
|
card->info.promisc_mode = SET_PROMISC_MODE_ON;
|
||||||
|
dev_info(&card->gdev->dev, "The HiperSockets network "
|
||||||
|
"traffic analyzer is activated\n");
|
||||||
|
break;
|
||||||
|
case IPA_RC_HARDWARE_AUTH_ERROR:
|
||||||
|
dev_warn(&card->gdev->dev, "The device is not "
|
||||||
|
"authorized to run as a HiperSockets network "
|
||||||
|
"traffic analyzer\n");
|
||||||
|
break;
|
||||||
|
case IPA_RC_TRACE_ALREADY_ACTIVE:
|
||||||
|
dev_warn(&card->gdev->dev, "A HiperSockets "
|
||||||
|
"network traffic analyzer is already "
|
||||||
|
"active in the HiperSockets LAN\n");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
QETH_DBF_MESSAGE(2, "Unknown sniffer action (0x%04x) on %s\n",
|
QETH_DBF_MESSAGE(2, "Unknown sniffer action (0x%04x) on %s\n",
|
||||||
|
@ -2215,11 +2219,9 @@ static int qeth_l3_stop_card(struct qeth_card *card, int recovery_mode)
|
||||||
if (recovery_mode)
|
if (recovery_mode)
|
||||||
qeth_l3_stop(card->dev);
|
qeth_l3_stop(card->dev);
|
||||||
else {
|
else {
|
||||||
if (card->dev) {
|
rtnl_lock();
|
||||||
rtnl_lock();
|
dev_close(card->dev);
|
||||||
dev_close(card->dev);
|
rtnl_unlock();
|
||||||
rtnl_unlock();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (!card->use_hard_stop) {
|
if (!card->use_hard_stop) {
|
||||||
rc = qeth_send_stoplan(card);
|
rc = qeth_send_stoplan(card);
|
||||||
|
@ -2900,10 +2902,8 @@ static int qeth_l3_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
|
||||||
int data_offset = -1;
|
int data_offset = -1;
|
||||||
int nr_frags;
|
int nr_frags;
|
||||||
|
|
||||||
if ((card->info.type == QETH_CARD_TYPE_IQD) &&
|
if (((card->info.type == QETH_CARD_TYPE_IQD) && (!ipv)) ||
|
||||||
(((skb->protocol != htons(ETH_P_IPV6)) &&
|
card->options.sniffer)
|
||||||
(skb->protocol != htons(ETH_P_IP))) ||
|
|
||||||
card->options.sniffer))
|
|
||||||
goto tx_drop;
|
goto tx_drop;
|
||||||
|
|
||||||
if ((card->state != CARD_STATE_UP) || !card->lan_online) {
|
if ((card->state != CARD_STATE_UP) || !card->lan_online) {
|
||||||
|
@ -2949,14 +2949,14 @@ static int qeth_l3_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
|
||||||
if (data_offset < 0)
|
if (data_offset < 0)
|
||||||
skb_pull(new_skb, ETH_HLEN);
|
skb_pull(new_skb, ETH_HLEN);
|
||||||
} else {
|
} else {
|
||||||
if (new_skb->protocol == htons(ETH_P_IP)) {
|
if (ipv == 4) {
|
||||||
if (card->dev->type == ARPHRD_IEEE802_TR)
|
if (card->dev->type == ARPHRD_IEEE802_TR)
|
||||||
skb_pull(new_skb, TR_HLEN);
|
skb_pull(new_skb, TR_HLEN);
|
||||||
else
|
else
|
||||||
skb_pull(new_skb, ETH_HLEN);
|
skb_pull(new_skb, ETH_HLEN);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (new_skb->protocol == ETH_P_IPV6 && card->vlangrp &&
|
if (ipv == 6 && card->vlangrp &&
|
||||||
vlan_tx_tag_present(new_skb)) {
|
vlan_tx_tag_present(new_skb)) {
|
||||||
skb_push(new_skb, VLAN_HLEN);
|
skb_push(new_skb, VLAN_HLEN);
|
||||||
skb_copy_to_linear_data(new_skb, new_skb->data + 4, 4);
|
skb_copy_to_linear_data(new_skb, new_skb->data + 4, 4);
|
||||||
|
@ -3534,11 +3534,9 @@ static int qeth_l3_pm_resume(struct ccwgroup_device *gdev)
|
||||||
if (card->state == CARD_STATE_RECOVER) {
|
if (card->state == CARD_STATE_RECOVER) {
|
||||||
rc = __qeth_l3_set_online(card->gdev, 1);
|
rc = __qeth_l3_set_online(card->gdev, 1);
|
||||||
if (rc) {
|
if (rc) {
|
||||||
if (card->dev) {
|
rtnl_lock();
|
||||||
rtnl_lock();
|
dev_close(card->dev);
|
||||||
dev_close(card->dev);
|
rtnl_unlock();
|
||||||
rtnl_unlock();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
rc = __qeth_l3_set_online(card->gdev, 0);
|
rc = __qeth_l3_set_online(card->gdev, 0);
|
||||||
|
|
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -61,6 +61,13 @@ struct ethtool_drvinfo {
|
||||||
/* For PCI devices, use pci_name(pci_dev). */
|
/* For PCI devices, use pci_name(pci_dev). */
|
||||||
char reserved1[32];
|
char reserved1[32];
|
||||||
char reserved2[12];
|
char reserved2[12];
|
||||||
|
/*
|
||||||
|
* Some struct members below are filled in
|
||||||
|
* using ops->get_sset_count(). Obtaining
|
||||||
|
* this info from ethtool_drvinfo is now
|
||||||
|
* deprecated; Use ETHTOOL_GSSET_INFO
|
||||||
|
* instead.
|
||||||
|
*/
|
||||||
__u32 n_priv_flags; /* number of flags valid in ETHTOOL_GPFLAGS */
|
__u32 n_priv_flags; /* number of flags valid in ETHTOOL_GPFLAGS */
|
||||||
__u32 n_stats; /* number of u64's from ETHTOOL_GSTATS */
|
__u32 n_stats; /* number of u64's from ETHTOOL_GSTATS */
|
||||||
__u32 testinfo_len;
|
__u32 testinfo_len;
|
||||||
|
@ -253,6 +260,17 @@ struct ethtool_gstrings {
|
||||||
__u8 data[0];
|
__u8 data[0];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct ethtool_sset_info {
|
||||||
|
__u32 cmd; /* ETHTOOL_GSSET_INFO */
|
||||||
|
__u32 reserved;
|
||||||
|
__u64 sset_mask; /* input: each bit selects an sset to query */
|
||||||
|
/* output: each bit a returned sset */
|
||||||
|
__u32 data[0]; /* ETH_SS_xxx count, in order, based on bits
|
||||||
|
in sset_mask. One bit implies one
|
||||||
|
__u32, two bits implies two
|
||||||
|
__u32's, etc. */
|
||||||
|
};
|
||||||
|
|
||||||
enum ethtool_test_flags {
|
enum ethtool_test_flags {
|
||||||
ETH_TEST_FL_OFFLINE = (1 << 0), /* online / offline */
|
ETH_TEST_FL_OFFLINE = (1 << 0), /* online / offline */
|
||||||
ETH_TEST_FL_FAILED = (1 << 1), /* test passed / failed */
|
ETH_TEST_FL_FAILED = (1 << 1), /* test passed / failed */
|
||||||
|
@ -606,9 +624,9 @@ struct ethtool_ops {
|
||||||
#define ETHTOOL_SRXCLSRLINS 0x00000032 /* Insert RX classification rule */
|
#define ETHTOOL_SRXCLSRLINS 0x00000032 /* Insert RX classification rule */
|
||||||
#define ETHTOOL_FLASHDEV 0x00000033 /* Flash firmware to device */
|
#define ETHTOOL_FLASHDEV 0x00000033 /* Flash firmware to device */
|
||||||
#define ETHTOOL_RESET 0x00000034 /* Reset hardware */
|
#define ETHTOOL_RESET 0x00000034 /* Reset hardware */
|
||||||
|
#define ETHTOOL_SRXNTUPLE 0x00000035 /* Add an n-tuple filter to device */
|
||||||
#define ETHTOOL_SRXNTUPLE 0x00000035 /* Add an n-tuple filter to device */
|
#define ETHTOOL_GRXNTUPLE 0x00000036 /* Get n-tuple filters from device */
|
||||||
#define ETHTOOL_GRXNTUPLE 0x00000036 /* Get n-tuple filters from device */
|
#define ETHTOOL_GSSET_INFO 0x00000037 /* Get string set info */
|
||||||
|
|
||||||
/* compatibility with older code */
|
/* compatibility with older code */
|
||||||
#define SPARC_ETH_GSET ETHTOOL_GSET
|
#define SPARC_ETH_GSET ETHTOOL_GSET
|
||||||
|
|
|
@ -29,7 +29,7 @@
|
||||||
/**
|
/**
|
||||||
* enum rfkill_type - type of rfkill switch.
|
* enum rfkill_type - type of rfkill switch.
|
||||||
*
|
*
|
||||||
* @RFKILL_TYPE_ALL: toggles all switches (userspace only)
|
* @RFKILL_TYPE_ALL: toggles all switches (requests only - not a switch type)
|
||||||
* @RFKILL_TYPE_WLAN: switch is on a 802.11 wireless network device.
|
* @RFKILL_TYPE_WLAN: switch is on a 802.11 wireless network device.
|
||||||
* @RFKILL_TYPE_BLUETOOTH: switch is on a bluetooth device.
|
* @RFKILL_TYPE_BLUETOOTH: switch is on a bluetooth device.
|
||||||
* @RFKILL_TYPE_UWB: switch is on a ultra wideband device.
|
* @RFKILL_TYPE_UWB: switch is on a ultra wideband device.
|
||||||
|
|
|
@ -225,6 +225,8 @@ enum
|
||||||
LINUX_MIB_SACKSHIFTED,
|
LINUX_MIB_SACKSHIFTED,
|
||||||
LINUX_MIB_SACKMERGED,
|
LINUX_MIB_SACKMERGED,
|
||||||
LINUX_MIB_SACKSHIFTFALLBACK,
|
LINUX_MIB_SACKSHIFTFALLBACK,
|
||||||
|
LINUX_MIB_TCPBACKLOGDROP,
|
||||||
|
LINUX_MIB_TCPMINTTLDROP, /* RFC 5082 */
|
||||||
__LINUX_MIB_MAX
|
__LINUX_MIB_MAX
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -37,6 +37,24 @@ struct route_info {
|
||||||
#define RT6_LOOKUP_F_SRCPREF_PUBLIC 0x00000010
|
#define RT6_LOOKUP_F_SRCPREF_PUBLIC 0x00000010
|
||||||
#define RT6_LOOKUP_F_SRCPREF_COA 0x00000020
|
#define RT6_LOOKUP_F_SRCPREF_COA 0x00000020
|
||||||
|
|
||||||
|
/*
|
||||||
|
* rt6_srcprefs2flags() and rt6_flags2srcprefs() translate
|
||||||
|
* between IPV6_ADDR_PREFERENCES socket option values
|
||||||
|
* IPV6_PREFER_SRC_TMP = 0x1
|
||||||
|
* IPV6_PREFER_SRC_PUBLIC = 0x2
|
||||||
|
* IPV6_PREFER_SRC_COA = 0x4
|
||||||
|
* and above RT6_LOOKUP_F_SRCPREF_xxx flags.
|
||||||
|
*/
|
||||||
|
static inline int rt6_srcprefs2flags(unsigned int srcprefs)
|
||||||
|
{
|
||||||
|
/* No need to bitmask because srcprefs have only 3 bits. */
|
||||||
|
return srcprefs << 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline unsigned int rt6_flags2srcprefs(int flags)
|
||||||
|
{
|
||||||
|
return (flags >> 3) & 7;
|
||||||
|
}
|
||||||
|
|
||||||
extern void ip6_route_input(struct sk_buff *skb);
|
extern void ip6_route_input(struct sk_buff *skb);
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,6 @@
|
||||||
struct ip6_tnl {
|
struct ip6_tnl {
|
||||||
struct ip6_tnl *next; /* next tunnel in list */
|
struct ip6_tnl *next; /* next tunnel in list */
|
||||||
struct net_device *dev; /* virtual device associated with tunnel */
|
struct net_device *dev; /* virtual device associated with tunnel */
|
||||||
int recursion; /* depth of hard_start_xmit recursion */
|
|
||||||
struct ip6_tnl_parm parms; /* tunnel configuration parameters */
|
struct ip6_tnl_parm parms; /* tunnel configuration parameters */
|
||||||
struct flowi fl; /* flowi template for xmit */
|
struct flowi fl; /* flowi template for xmit */
|
||||||
struct dst_entry *dst_cache; /* cached dst */
|
struct dst_entry *dst_cache; /* cached dst */
|
||||||
|
|
|
@ -2426,7 +2426,8 @@ struct rate_control_ops {
|
||||||
struct ieee80211_sta *sta, void *priv_sta);
|
struct ieee80211_sta *sta, void *priv_sta);
|
||||||
void (*rate_update)(void *priv, struct ieee80211_supported_band *sband,
|
void (*rate_update)(void *priv, struct ieee80211_supported_band *sband,
|
||||||
struct ieee80211_sta *sta,
|
struct ieee80211_sta *sta,
|
||||||
void *priv_sta, u32 changed);
|
void *priv_sta, u32 changed,
|
||||||
|
enum nl80211_channel_type oper_chan_type);
|
||||||
void (*free_sta)(void *priv, struct ieee80211_sta *sta,
|
void (*free_sta)(void *priv, struct ieee80211_sta *sta,
|
||||||
void *priv_sta);
|
void *priv_sta);
|
||||||
|
|
||||||
|
|
|
@ -253,6 +253,8 @@ struct sock {
|
||||||
struct {
|
struct {
|
||||||
struct sk_buff *head;
|
struct sk_buff *head;
|
||||||
struct sk_buff *tail;
|
struct sk_buff *tail;
|
||||||
|
int len;
|
||||||
|
int limit;
|
||||||
} sk_backlog;
|
} sk_backlog;
|
||||||
wait_queue_head_t *sk_sleep;
|
wait_queue_head_t *sk_sleep;
|
||||||
struct dst_entry *sk_dst_cache;
|
struct dst_entry *sk_dst_cache;
|
||||||
|
@ -589,8 +591,8 @@ static inline int sk_stream_memory_free(struct sock *sk)
|
||||||
return sk->sk_wmem_queued < sk->sk_sndbuf;
|
return sk->sk_wmem_queued < sk->sk_sndbuf;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The per-socket spinlock must be held here. */
|
/* OOB backlog add */
|
||||||
static inline void sk_add_backlog(struct sock *sk, struct sk_buff *skb)
|
static inline void __sk_add_backlog(struct sock *sk, struct sk_buff *skb)
|
||||||
{
|
{
|
||||||
if (!sk->sk_backlog.tail) {
|
if (!sk->sk_backlog.tail) {
|
||||||
sk->sk_backlog.head = sk->sk_backlog.tail = skb;
|
sk->sk_backlog.head = sk->sk_backlog.tail = skb;
|
||||||
|
@ -601,6 +603,17 @@ static inline void sk_add_backlog(struct sock *sk, struct sk_buff *skb)
|
||||||
skb->next = NULL;
|
skb->next = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* The per-socket spinlock must be held here. */
|
||||||
|
static inline __must_check int sk_add_backlog(struct sock *sk, struct sk_buff *skb)
|
||||||
|
{
|
||||||
|
if (sk->sk_backlog.len >= max(sk->sk_backlog.limit, sk->sk_rcvbuf << 1))
|
||||||
|
return -ENOBUFS;
|
||||||
|
|
||||||
|
__sk_add_backlog(sk, skb);
|
||||||
|
sk->sk_backlog.len += skb->truesize;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static inline int sk_backlog_rcv(struct sock *sk, struct sk_buff *skb)
|
static inline int sk_backlog_rcv(struct sock *sk, struct sk_buff *skb)
|
||||||
{
|
{
|
||||||
return sk->sk_backlog_rcv(sk, skb);
|
return sk->sk_backlog_rcv(sk, skb);
|
||||||
|
|
|
@ -939,7 +939,7 @@ static inline int tcp_prequeue(struct sock *sk, struct sk_buff *skb)
|
||||||
|
|
||||||
tp->ucopy.memory = 0;
|
tp->ucopy.memory = 0;
|
||||||
} else if (skb_queue_len(&tp->ucopy.prequeue) == 1) {
|
} else if (skb_queue_len(&tp->ucopy.prequeue) == 1) {
|
||||||
wake_up_interruptible_poll(sk->sk_sleep,
|
wake_up_interruptible_sync_poll(sk->sk_sleep,
|
||||||
POLLIN | POLLRDNORM | POLLRDBAND);
|
POLLIN | POLLRDNORM | POLLRDBAND);
|
||||||
if (!inet_csk_ack_scheduled(sk))
|
if (!inet_csk_ack_scheduled(sk))
|
||||||
inet_csk_reset_xmit_timer(sk, ICSK_TIME_DACK,
|
inet_csk_reset_xmit_timer(sk, ICSK_TIME_DACK,
|
||||||
|
|
|
@ -275,7 +275,8 @@ struct xfrm_policy_afinfo {
|
||||||
struct dst_entry *dst,
|
struct dst_entry *dst,
|
||||||
int nfheader_len);
|
int nfheader_len);
|
||||||
int (*fill_dst)(struct xfrm_dst *xdst,
|
int (*fill_dst)(struct xfrm_dst *xdst,
|
||||||
struct net_device *dev);
|
struct net_device *dev,
|
||||||
|
struct flowi *fl);
|
||||||
};
|
};
|
||||||
|
|
||||||
extern int xfrm_policy_register_afinfo(struct xfrm_policy_afinfo *afinfo);
|
extern int xfrm_policy_register_afinfo(struct xfrm_policy_afinfo *afinfo);
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
#include <linux/kernel.h>
|
#include <linux/kernel.h>
|
||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
#include <linux/debugfs.h>
|
#include <linux/debugfs.h>
|
||||||
|
#include <linux/seq_file.h>
|
||||||
|
|
||||||
#include <net/bluetooth/bluetooth.h>
|
#include <net/bluetooth/bluetooth.h>
|
||||||
#include <net/bluetooth/hci_core.h>
|
#include <net/bluetooth/hci_core.h>
|
||||||
|
@ -405,20 +406,11 @@ static struct device_type bt_host = {
|
||||||
.release = bt_host_release,
|
.release = bt_host_release,
|
||||||
};
|
};
|
||||||
|
|
||||||
static int inquiry_cache_open(struct inode *inode, struct file *file)
|
static int inquiry_cache_show(struct seq_file *f, void *p)
|
||||||
{
|
{
|
||||||
file->private_data = inode->i_private;
|
struct hci_dev *hdev = f->private;
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static ssize_t inquiry_cache_read(struct file *file, char __user *userbuf,
|
|
||||||
size_t count, loff_t *ppos)
|
|
||||||
{
|
|
||||||
struct hci_dev *hdev = file->private_data;
|
|
||||||
struct inquiry_cache *cache = &hdev->inq_cache;
|
struct inquiry_cache *cache = &hdev->inq_cache;
|
||||||
struct inquiry_entry *e;
|
struct inquiry_entry *e;
|
||||||
char buf[4096];
|
|
||||||
int n = 0;
|
|
||||||
|
|
||||||
hci_dev_lock_bh(hdev);
|
hci_dev_lock_bh(hdev);
|
||||||
|
|
||||||
|
@ -426,23 +418,30 @@ static ssize_t inquiry_cache_read(struct file *file, char __user *userbuf,
|
||||||
struct inquiry_data *data = &e->data;
|
struct inquiry_data *data = &e->data;
|
||||||
bdaddr_t bdaddr;
|
bdaddr_t bdaddr;
|
||||||
baswap(&bdaddr, &data->bdaddr);
|
baswap(&bdaddr, &data->bdaddr);
|
||||||
n += sprintf(buf + n, "%s %d %d %d 0x%.2x%.2x%.2x 0x%.4x %d %d %u\n",
|
seq_printf(f, "%s %d %d %d 0x%.2x%.2x%.2x 0x%.4x %d %d %u\n",
|
||||||
batostr(&bdaddr),
|
batostr(&bdaddr),
|
||||||
data->pscan_rep_mode, data->pscan_period_mode,
|
data->pscan_rep_mode, data->pscan_period_mode,
|
||||||
data->pscan_mode, data->dev_class[2],
|
data->pscan_mode, data->dev_class[2],
|
||||||
data->dev_class[1], data->dev_class[0],
|
data->dev_class[1], data->dev_class[0],
|
||||||
__le16_to_cpu(data->clock_offset),
|
__le16_to_cpu(data->clock_offset),
|
||||||
data->rssi, data->ssp_mode, e->timestamp);
|
data->rssi, data->ssp_mode, e->timestamp);
|
||||||
}
|
}
|
||||||
|
|
||||||
hci_dev_unlock_bh(hdev);
|
hci_dev_unlock_bh(hdev);
|
||||||
|
|
||||||
return simple_read_from_buffer(userbuf, count, ppos, buf, n);
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int inquiry_cache_open(struct inode *inode, struct file *file)
|
||||||
|
{
|
||||||
|
return single_open(file, inquiry_cache_show, inode->i_private);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct file_operations inquiry_cache_fops = {
|
static const struct file_operations inquiry_cache_fops = {
|
||||||
.open = inquiry_cache_open,
|
.open = inquiry_cache_open,
|
||||||
.read = inquiry_cache_read,
|
.read = seq_read,
|
||||||
|
.llseek = seq_lseek,
|
||||||
|
.release = single_release,
|
||||||
};
|
};
|
||||||
|
|
||||||
int hci_register_sysfs(struct hci_dev *hdev)
|
int hci_register_sysfs(struct hci_dev *hdev)
|
||||||
|
|
|
@ -35,6 +35,7 @@ config BRIDGE
|
||||||
config BRIDGE_IGMP_SNOOPING
|
config BRIDGE_IGMP_SNOOPING
|
||||||
bool "IGMP snooping"
|
bool "IGMP snooping"
|
||||||
depends on BRIDGE
|
depends on BRIDGE
|
||||||
|
depends on INET
|
||||||
default y
|
default y
|
||||||
---help---
|
---help---
|
||||||
If you say Y here, then the Ethernet bridge will be able selectively
|
If you say Y here, then the Ethernet bridge will be able selectively
|
||||||
|
|
|
@ -38,7 +38,7 @@ static struct net_bridge_mdb_entry *__br_mdb_ip_get(
|
||||||
struct net_bridge_mdb_entry *mp;
|
struct net_bridge_mdb_entry *mp;
|
||||||
struct hlist_node *p;
|
struct hlist_node *p;
|
||||||
|
|
||||||
hlist_for_each_entry(mp, p, &mdb->mhash[hash], hlist[mdb->ver]) {
|
hlist_for_each_entry_rcu(mp, p, &mdb->mhash[hash], hlist[mdb->ver]) {
|
||||||
if (dst == mp->addr)
|
if (dst == mp->addr)
|
||||||
return mp;
|
return mp;
|
||||||
}
|
}
|
||||||
|
@ -627,8 +627,8 @@ static void br_multicast_port_query_expired(unsigned long data)
|
||||||
struct net_bridge *br = port->br;
|
struct net_bridge *br = port->br;
|
||||||
|
|
||||||
spin_lock(&br->multicast_lock);
|
spin_lock(&br->multicast_lock);
|
||||||
if (port && (port->state == BR_STATE_DISABLED ||
|
if (port->state == BR_STATE_DISABLED ||
|
||||||
port->state == BR_STATE_BLOCKING))
|
port->state == BR_STATE_BLOCKING)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
if (port->multicast_startup_queries_sent <
|
if (port->multicast_startup_queries_sent <
|
||||||
|
@ -823,6 +823,7 @@ static int br_multicast_query(struct net_bridge *br,
|
||||||
unsigned long max_delay;
|
unsigned long max_delay;
|
||||||
unsigned long now = jiffies;
|
unsigned long now = jiffies;
|
||||||
__be32 group;
|
__be32 group;
|
||||||
|
int err = 0;
|
||||||
|
|
||||||
spin_lock(&br->multicast_lock);
|
spin_lock(&br->multicast_lock);
|
||||||
if (!netif_running(br->dev) ||
|
if (!netif_running(br->dev) ||
|
||||||
|
@ -841,12 +842,14 @@ static int br_multicast_query(struct net_bridge *br,
|
||||||
group = 0;
|
group = 0;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (!pskb_may_pull(skb, sizeof(struct igmpv3_query)))
|
if (!pskb_may_pull(skb, sizeof(struct igmpv3_query))) {
|
||||||
return -EINVAL;
|
err = -EINVAL;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
ih3 = igmpv3_query_hdr(skb);
|
ih3 = igmpv3_query_hdr(skb);
|
||||||
if (ih3->nsrcs)
|
if (ih3->nsrcs)
|
||||||
return 0;
|
goto out;
|
||||||
|
|
||||||
max_delay = ih3->code ? 1 :
|
max_delay = ih3->code ? 1 :
|
||||||
IGMPV3_MRC(ih3->code) * (HZ / IGMP_TIMER_SCALE);
|
IGMPV3_MRC(ih3->code) * (HZ / IGMP_TIMER_SCALE);
|
||||||
|
@ -876,7 +879,7 @@ static int br_multicast_query(struct net_bridge *br,
|
||||||
|
|
||||||
out:
|
out:
|
||||||
spin_unlock(&br->multicast_lock);
|
spin_unlock(&br->multicast_lock);
|
||||||
return 0;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void br_multicast_leave_group(struct net_bridge *br,
|
static void br_multicast_leave_group(struct net_bridge *br,
|
||||||
|
@ -1135,7 +1138,7 @@ void br_multicast_stop(struct net_bridge *br)
|
||||||
|
|
||||||
if (mdb->old) {
|
if (mdb->old) {
|
||||||
spin_unlock_bh(&br->multicast_lock);
|
spin_unlock_bh(&br->multicast_lock);
|
||||||
synchronize_rcu_bh();
|
rcu_barrier_bh();
|
||||||
spin_lock_bh(&br->multicast_lock);
|
spin_lock_bh(&br->multicast_lock);
|
||||||
WARN_ON(mdb->old);
|
WARN_ON(mdb->old);
|
||||||
}
|
}
|
||||||
|
|
|
@ -97,8 +97,9 @@ int dev_mc_add(struct net_device *dev, void *addr, int alen, int glbl)
|
||||||
|
|
||||||
netif_addr_lock_bh(dev);
|
netif_addr_lock_bh(dev);
|
||||||
if (alen != dev->addr_len)
|
if (alen != dev->addr_len)
|
||||||
return -EINVAL;
|
err = -EINVAL;
|
||||||
err = __dev_addr_add(&dev->mc_list, &dev->mc_count, addr, alen, glbl);
|
else
|
||||||
|
err = __dev_addr_add(&dev->mc_list, &dev->mc_count, addr, alen, glbl);
|
||||||
if (!err)
|
if (!err)
|
||||||
__dev_set_rx_mode(dev);
|
__dev_set_rx_mode(dev);
|
||||||
netif_addr_unlock_bh(dev);
|
netif_addr_unlock_bh(dev);
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
#include <linux/errno.h>
|
#include <linux/errno.h>
|
||||||
#include <linux/ethtool.h>
|
#include <linux/ethtool.h>
|
||||||
#include <linux/netdevice.h>
|
#include <linux/netdevice.h>
|
||||||
|
#include <linux/bitops.h>
|
||||||
#include <asm/uaccess.h>
|
#include <asm/uaccess.h>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -199,10 +200,7 @@ static int ethtool_set_settings(struct net_device *dev, void __user *useraddr)
|
||||||
return dev->ethtool_ops->set_settings(dev, &cmd);
|
return dev->ethtool_ops->set_settings(dev, &cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
static noinline_for_stack int ethtool_get_drvinfo(struct net_device *dev, void __user *useraddr)
|
||||||
* noinline attribute so that gcc doesnt use too much stack in dev_ethtool()
|
|
||||||
*/
|
|
||||||
static noinline int ethtool_get_drvinfo(struct net_device *dev, void __user *useraddr)
|
|
||||||
{
|
{
|
||||||
struct ethtool_drvinfo info;
|
struct ethtool_drvinfo info;
|
||||||
const struct ethtool_ops *ops = dev->ethtool_ops;
|
const struct ethtool_ops *ops = dev->ethtool_ops;
|
||||||
|
@ -214,6 +212,10 @@ static noinline int ethtool_get_drvinfo(struct net_device *dev, void __user *use
|
||||||
info.cmd = ETHTOOL_GDRVINFO;
|
info.cmd = ETHTOOL_GDRVINFO;
|
||||||
ops->get_drvinfo(dev, &info);
|
ops->get_drvinfo(dev, &info);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* this method of obtaining string set info is deprecated;
|
||||||
|
* Use ETHTOOL_GSSET_INFO instead.
|
||||||
|
*/
|
||||||
if (ops->get_sset_count) {
|
if (ops->get_sset_count) {
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
|
@ -237,10 +239,67 @@ static noinline int ethtool_get_drvinfo(struct net_device *dev, void __user *use
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
static noinline_for_stack int ethtool_get_sset_info(struct net_device *dev,
|
||||||
* noinline attribute so that gcc doesnt use too much stack in dev_ethtool()
|
void __user *useraddr)
|
||||||
*/
|
{
|
||||||
static noinline int ethtool_set_rxnfc(struct net_device *dev, void __user *useraddr)
|
struct ethtool_sset_info info;
|
||||||
|
const struct ethtool_ops *ops = dev->ethtool_ops;
|
||||||
|
u64 sset_mask;
|
||||||
|
int i, idx = 0, n_bits = 0, ret, rc;
|
||||||
|
u32 *info_buf = NULL;
|
||||||
|
|
||||||
|
if (!ops->get_sset_count)
|
||||||
|
return -EOPNOTSUPP;
|
||||||
|
|
||||||
|
if (copy_from_user(&info, useraddr, sizeof(info)))
|
||||||
|
return -EFAULT;
|
||||||
|
|
||||||
|
/* store copy of mask, because we zero struct later on */
|
||||||
|
sset_mask = info.sset_mask;
|
||||||
|
if (!sset_mask)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* calculate size of return buffer */
|
||||||
|
n_bits = hweight64(sset_mask);
|
||||||
|
|
||||||
|
memset(&info, 0, sizeof(info));
|
||||||
|
info.cmd = ETHTOOL_GSSET_INFO;
|
||||||
|
|
||||||
|
info_buf = kzalloc(n_bits * sizeof(u32), GFP_USER);
|
||||||
|
if (!info_buf)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* fill return buffer based on input bitmask and successful
|
||||||
|
* get_sset_count return
|
||||||
|
*/
|
||||||
|
for (i = 0; i < 64; i++) {
|
||||||
|
if (!(sset_mask & (1ULL << i)))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
rc = ops->get_sset_count(dev, i);
|
||||||
|
if (rc >= 0) {
|
||||||
|
info.sset_mask |= (1ULL << i);
|
||||||
|
info_buf[idx++] = rc;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = -EFAULT;
|
||||||
|
if (copy_to_user(useraddr, &info, sizeof(info)))
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
useraddr += offsetof(struct ethtool_sset_info, data);
|
||||||
|
if (copy_to_user(useraddr, info_buf, idx * sizeof(u32)))
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
ret = 0;
|
||||||
|
|
||||||
|
out:
|
||||||
|
kfree(info_buf);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static noinline_for_stack int ethtool_set_rxnfc(struct net_device *dev, void __user *useraddr)
|
||||||
{
|
{
|
||||||
struct ethtool_rxnfc cmd;
|
struct ethtool_rxnfc cmd;
|
||||||
|
|
||||||
|
@ -253,10 +312,7 @@ static noinline int ethtool_set_rxnfc(struct net_device *dev, void __user *usera
|
||||||
return dev->ethtool_ops->set_rxnfc(dev, &cmd);
|
return dev->ethtool_ops->set_rxnfc(dev, &cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
static noinline_for_stack int ethtool_get_rxnfc(struct net_device *dev, void __user *useraddr)
|
||||||
* noinline attribute so that gcc doesnt use too much stack in dev_ethtool()
|
|
||||||
*/
|
|
||||||
static noinline int ethtool_get_rxnfc(struct net_device *dev, void __user *useraddr)
|
|
||||||
{
|
{
|
||||||
struct ethtool_rxnfc info;
|
struct ethtool_rxnfc info;
|
||||||
const struct ethtool_ops *ops = dev->ethtool_ops;
|
const struct ethtool_ops *ops = dev->ethtool_ops;
|
||||||
|
@ -328,10 +384,7 @@ static void __rx_ntuple_filter_add(struct ethtool_rx_ntuple_list *list,
|
||||||
list->count++;
|
list->count++;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
static noinline_for_stack int ethtool_set_rx_ntuple(struct net_device *dev, void __user *useraddr)
|
||||||
* noinline attribute so that gcc doesnt use too much stack in dev_ethtool()
|
|
||||||
*/
|
|
||||||
static noinline int ethtool_set_rx_ntuple(struct net_device *dev, void __user *useraddr)
|
|
||||||
{
|
{
|
||||||
struct ethtool_rx_ntuple cmd;
|
struct ethtool_rx_ntuple cmd;
|
||||||
const struct ethtool_ops *ops = dev->ethtool_ops;
|
const struct ethtool_ops *ops = dev->ethtool_ops;
|
||||||
|
@ -799,10 +852,7 @@ static int ethtool_set_eeprom(struct net_device *dev, void __user *useraddr)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
static noinline_for_stack int ethtool_get_coalesce(struct net_device *dev, void __user *useraddr)
|
||||||
* noinline attribute so that gcc doesnt use too much stack in dev_ethtool()
|
|
||||||
*/
|
|
||||||
static noinline int ethtool_get_coalesce(struct net_device *dev, void __user *useraddr)
|
|
||||||
{
|
{
|
||||||
struct ethtool_coalesce coalesce = { .cmd = ETHTOOL_GCOALESCE };
|
struct ethtool_coalesce coalesce = { .cmd = ETHTOOL_GCOALESCE };
|
||||||
|
|
||||||
|
@ -816,10 +866,7 @@ static noinline int ethtool_get_coalesce(struct net_device *dev, void __user *us
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
static noinline_for_stack int ethtool_set_coalesce(struct net_device *dev, void __user *useraddr)
|
||||||
* noinline attribute so that gcc doesnt use too much stack in dev_ethtool()
|
|
||||||
*/
|
|
||||||
static noinline int ethtool_set_coalesce(struct net_device *dev, void __user *useraddr)
|
|
||||||
{
|
{
|
||||||
struct ethtool_coalesce coalesce;
|
struct ethtool_coalesce coalesce;
|
||||||
|
|
||||||
|
@ -1229,10 +1276,7 @@ static int ethtool_set_value(struct net_device *dev, char __user *useraddr,
|
||||||
return actor(dev, edata.data);
|
return actor(dev, edata.data);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
static noinline_for_stack int ethtool_flash_device(struct net_device *dev, char __user *useraddr)
|
||||||
* noinline attribute so that gcc doesnt use too much stack in dev_ethtool()
|
|
||||||
*/
|
|
||||||
static noinline int ethtool_flash_device(struct net_device *dev, char __user *useraddr)
|
|
||||||
{
|
{
|
||||||
struct ethtool_flash efl;
|
struct ethtool_flash efl;
|
||||||
|
|
||||||
|
@ -1471,6 +1515,9 @@ int dev_ethtool(struct net *net, struct ifreq *ifr)
|
||||||
case ETHTOOL_GRXNTUPLE:
|
case ETHTOOL_GRXNTUPLE:
|
||||||
rc = ethtool_get_rx_ntuple(dev, useraddr);
|
rc = ethtool_get_rx_ntuple(dev, useraddr);
|
||||||
break;
|
break;
|
||||||
|
case ETHTOOL_GSSET_INFO:
|
||||||
|
rc = ethtool_get_sset_info(dev, useraddr);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
rc = -EOPNOTSUPP;
|
rc = -EOPNOTSUPP;
|
||||||
}
|
}
|
||||||
|
|
|
@ -771,6 +771,8 @@ static __inline__ int neigh_max_probes(struct neighbour *n)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void neigh_invalidate(struct neighbour *neigh)
|
static void neigh_invalidate(struct neighbour *neigh)
|
||||||
|
__releases(neigh->lock)
|
||||||
|
__acquires(neigh->lock)
|
||||||
{
|
{
|
||||||
struct sk_buff *skb;
|
struct sk_buff *skb;
|
||||||
|
|
||||||
|
|
|
@ -340,8 +340,12 @@ int sk_receive_skb(struct sock *sk, struct sk_buff *skb, const int nested)
|
||||||
rc = sk_backlog_rcv(sk, skb);
|
rc = sk_backlog_rcv(sk, skb);
|
||||||
|
|
||||||
mutex_release(&sk->sk_lock.dep_map, 1, _RET_IP_);
|
mutex_release(&sk->sk_lock.dep_map, 1, _RET_IP_);
|
||||||
} else
|
} else if (sk_add_backlog(sk, skb)) {
|
||||||
sk_add_backlog(sk, skb);
|
bh_unlock_sock(sk);
|
||||||
|
atomic_inc(&sk->sk_drops);
|
||||||
|
goto discard_and_relse;
|
||||||
|
}
|
||||||
|
|
||||||
bh_unlock_sock(sk);
|
bh_unlock_sock(sk);
|
||||||
out:
|
out:
|
||||||
sock_put(sk);
|
sock_put(sk);
|
||||||
|
@ -1139,6 +1143,7 @@ struct sock *sk_clone(const struct sock *sk, const gfp_t priority)
|
||||||
sock_lock_init(newsk);
|
sock_lock_init(newsk);
|
||||||
bh_lock_sock(newsk);
|
bh_lock_sock(newsk);
|
||||||
newsk->sk_backlog.head = newsk->sk_backlog.tail = NULL;
|
newsk->sk_backlog.head = newsk->sk_backlog.tail = NULL;
|
||||||
|
newsk->sk_backlog.len = 0;
|
||||||
|
|
||||||
atomic_set(&newsk->sk_rmem_alloc, 0);
|
atomic_set(&newsk->sk_rmem_alloc, 0);
|
||||||
/*
|
/*
|
||||||
|
@ -1542,6 +1547,12 @@ static void __release_sock(struct sock *sk)
|
||||||
|
|
||||||
bh_lock_sock(sk);
|
bh_lock_sock(sk);
|
||||||
} while ((skb = sk->sk_backlog.head) != NULL);
|
} while ((skb = sk->sk_backlog.head) != NULL);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Doing the zeroing here guarantee we can not loop forever
|
||||||
|
* while a wild producer attempts to flood us.
|
||||||
|
*/
|
||||||
|
sk->sk_backlog.len = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1874,6 +1885,7 @@ void sock_init_data(struct socket *sock, struct sock *sk)
|
||||||
sk->sk_allocation = GFP_KERNEL;
|
sk->sk_allocation = GFP_KERNEL;
|
||||||
sk->sk_rcvbuf = sysctl_rmem_default;
|
sk->sk_rcvbuf = sysctl_rmem_default;
|
||||||
sk->sk_sndbuf = sysctl_wmem_default;
|
sk->sk_sndbuf = sysctl_wmem_default;
|
||||||
|
sk->sk_backlog.limit = sk->sk_rcvbuf << 1;
|
||||||
sk->sk_state = TCP_CLOSE;
|
sk->sk_state = TCP_CLOSE;
|
||||||
sk_set_socket(sk, sock);
|
sk_set_socket(sk, sock);
|
||||||
|
|
||||||
|
@ -2276,7 +2288,8 @@ out_free_request_sock_slab:
|
||||||
prot->rsk_prot->slab = NULL;
|
prot->rsk_prot->slab = NULL;
|
||||||
}
|
}
|
||||||
out_free_request_sock_slab_name:
|
out_free_request_sock_slab_name:
|
||||||
kfree(prot->rsk_prot->slab_name);
|
if (prot->rsk_prot)
|
||||||
|
kfree(prot->rsk_prot->slab_name);
|
||||||
out_free_sock_slab:
|
out_free_sock_slab:
|
||||||
kmem_cache_destroy(prot->slab);
|
kmem_cache_destroy(prot->slab);
|
||||||
prot->slab = NULL;
|
prot->slab = NULL;
|
||||||
|
|
|
@ -254,7 +254,7 @@ int dccp_child_process(struct sock *parent, struct sock *child,
|
||||||
* in main socket hash table and lock on listening
|
* in main socket hash table and lock on listening
|
||||||
* socket does not protect us more.
|
* socket does not protect us more.
|
||||||
*/
|
*/
|
||||||
sk_add_backlog(child, skb);
|
__sk_add_backlog(child, skb);
|
||||||
}
|
}
|
||||||
|
|
||||||
bh_unlock_sock(child);
|
bh_unlock_sock(child);
|
||||||
|
|
|
@ -1144,12 +1144,9 @@ static int ipgre_header(struct sk_buff *skb, struct net_device *dev,
|
||||||
|
|
||||||
if (saddr)
|
if (saddr)
|
||||||
memcpy(&iph->saddr, saddr, 4);
|
memcpy(&iph->saddr, saddr, 4);
|
||||||
|
if (daddr)
|
||||||
if (daddr) {
|
|
||||||
memcpy(&iph->daddr, daddr, 4);
|
memcpy(&iph->daddr, daddr, 4);
|
||||||
return t->hlen;
|
if (iph->daddr)
|
||||||
}
|
|
||||||
if (iph->daddr && !ipv4_is_multicast(iph->daddr))
|
|
||||||
return t->hlen;
|
return t->hlen;
|
||||||
|
|
||||||
return -t->hlen;
|
return -t->hlen;
|
||||||
|
|
|
@ -187,6 +187,16 @@ struct ic_device {
|
||||||
static struct ic_device *ic_first_dev __initdata = NULL;/* List of open device */
|
static struct ic_device *ic_first_dev __initdata = NULL;/* List of open device */
|
||||||
static struct net_device *ic_dev __initdata = NULL; /* Selected device */
|
static struct net_device *ic_dev __initdata = NULL; /* Selected device */
|
||||||
|
|
||||||
|
static bool __init ic_device_match(struct net_device *dev)
|
||||||
|
{
|
||||||
|
if (user_dev_name[0] ? !strcmp(dev->name, user_dev_name) :
|
||||||
|
(!(dev->flags & IFF_LOOPBACK) &&
|
||||||
|
(dev->flags & (IFF_POINTOPOINT|IFF_BROADCAST)) &&
|
||||||
|
strncmp(dev->name, "dummy", 5)))
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
static int __init ic_open_devs(void)
|
static int __init ic_open_devs(void)
|
||||||
{
|
{
|
||||||
struct ic_device *d, **last;
|
struct ic_device *d, **last;
|
||||||
|
@ -207,10 +217,7 @@ static int __init ic_open_devs(void)
|
||||||
for_each_netdev(&init_net, dev) {
|
for_each_netdev(&init_net, dev) {
|
||||||
if (dev->flags & IFF_LOOPBACK)
|
if (dev->flags & IFF_LOOPBACK)
|
||||||
continue;
|
continue;
|
||||||
if (user_dev_name[0] ? !strcmp(dev->name, user_dev_name) :
|
if (ic_device_match(dev)) {
|
||||||
(!(dev->flags & IFF_LOOPBACK) &&
|
|
||||||
(dev->flags & (IFF_POINTOPOINT|IFF_BROADCAST)) &&
|
|
||||||
strncmp(dev->name, "dummy", 5))) {
|
|
||||||
int able = 0;
|
int able = 0;
|
||||||
if (dev->mtu >= 364)
|
if (dev->mtu >= 364)
|
||||||
able |= IC_BOOTP;
|
able |= IC_BOOTP;
|
||||||
|
@ -228,7 +235,7 @@ static int __init ic_open_devs(void)
|
||||||
}
|
}
|
||||||
if (!(d = kmalloc(sizeof(struct ic_device), GFP_KERNEL))) {
|
if (!(d = kmalloc(sizeof(struct ic_device), GFP_KERNEL))) {
|
||||||
rtnl_unlock();
|
rtnl_unlock();
|
||||||
return -1;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
d->dev = dev;
|
d->dev = dev;
|
||||||
*last = d;
|
*last = d;
|
||||||
|
@ -253,7 +260,7 @@ static int __init ic_open_devs(void)
|
||||||
printk(KERN_ERR "IP-Config: Device `%s' not found.\n", user_dev_name);
|
printk(KERN_ERR "IP-Config: Device `%s' not found.\n", user_dev_name);
|
||||||
else
|
else
|
||||||
printk(KERN_ERR "IP-Config: No network devices available.\n");
|
printk(KERN_ERR "IP-Config: No network devices available.\n");
|
||||||
return -1;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1303,6 +1310,32 @@ __be32 __init root_nfs_parse_addr(char *name)
|
||||||
return addr;
|
return addr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define DEVICE_WAIT_MAX 12 /* 12 seconds */
|
||||||
|
|
||||||
|
static int __init wait_for_devices(void)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
msleep(CONF_PRE_OPEN);
|
||||||
|
for (i = 0; i < DEVICE_WAIT_MAX; i++) {
|
||||||
|
struct net_device *dev;
|
||||||
|
int found = 0;
|
||||||
|
|
||||||
|
rtnl_lock();
|
||||||
|
for_each_netdev(&init_net, dev) {
|
||||||
|
if (ic_device_match(dev)) {
|
||||||
|
found = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
rtnl_unlock();
|
||||||
|
if (found)
|
||||||
|
return 0;
|
||||||
|
ssleep(1);
|
||||||
|
}
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* IP Autoconfig dispatcher.
|
* IP Autoconfig dispatcher.
|
||||||
*/
|
*/
|
||||||
|
@ -1313,6 +1346,7 @@ static int __init ip_auto_config(void)
|
||||||
#ifdef IPCONFIG_DYNAMIC
|
#ifdef IPCONFIG_DYNAMIC
|
||||||
int retries = CONF_OPEN_RETRIES;
|
int retries = CONF_OPEN_RETRIES;
|
||||||
#endif
|
#endif
|
||||||
|
int err;
|
||||||
|
|
||||||
#ifdef CONFIG_PROC_FS
|
#ifdef CONFIG_PROC_FS
|
||||||
proc_net_fops_create(&init_net, "pnp", S_IRUGO, &pnp_seq_fops);
|
proc_net_fops_create(&init_net, "pnp", S_IRUGO, &pnp_seq_fops);
|
||||||
|
@ -1325,12 +1359,15 @@ static int __init ip_auto_config(void)
|
||||||
#ifdef IPCONFIG_DYNAMIC
|
#ifdef IPCONFIG_DYNAMIC
|
||||||
try_try_again:
|
try_try_again:
|
||||||
#endif
|
#endif
|
||||||
/* Give hardware a chance to settle */
|
/* Wait for devices to appear */
|
||||||
msleep(CONF_PRE_OPEN);
|
err = wait_for_devices();
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
|
||||||
/* Setup all network devices */
|
/* Setup all network devices */
|
||||||
if (ic_open_devs() < 0)
|
err = ic_open_devs();
|
||||||
return -1;
|
if (err)
|
||||||
|
return err;
|
||||||
|
|
||||||
/* Give drivers a chance to settle */
|
/* Give drivers a chance to settle */
|
||||||
ssleep(CONF_POST_OPEN);
|
ssleep(CONF_POST_OPEN);
|
||||||
|
|
|
@ -249,6 +249,8 @@ static const struct snmp_mib snmp4_net_list[] = {
|
||||||
SNMP_MIB_ITEM("TCPSackShifted", LINUX_MIB_SACKSHIFTED),
|
SNMP_MIB_ITEM("TCPSackShifted", LINUX_MIB_SACKSHIFTED),
|
||||||
SNMP_MIB_ITEM("TCPSackMerged", LINUX_MIB_SACKMERGED),
|
SNMP_MIB_ITEM("TCPSackMerged", LINUX_MIB_SACKMERGED),
|
||||||
SNMP_MIB_ITEM("TCPSackShiftFallback", LINUX_MIB_SACKSHIFTFALLBACK),
|
SNMP_MIB_ITEM("TCPSackShiftFallback", LINUX_MIB_SACKSHIFTFALLBACK),
|
||||||
|
SNMP_MIB_ITEM("TCPBacklogDrop", LINUX_MIB_TCPBACKLOGDROP),
|
||||||
|
SNMP_MIB_ITEM("TCPMinTTLDrop", LINUX_MIB_TCPMINTTLDROP),
|
||||||
SNMP_MIB_SENTINEL
|
SNMP_MIB_SENTINEL
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -146,7 +146,6 @@ static struct dst_entry *ipv4_negative_advice(struct dst_entry *dst);
|
||||||
static void ipv4_link_failure(struct sk_buff *skb);
|
static void ipv4_link_failure(struct sk_buff *skb);
|
||||||
static void ip_rt_update_pmtu(struct dst_entry *dst, u32 mtu);
|
static void ip_rt_update_pmtu(struct dst_entry *dst, u32 mtu);
|
||||||
static int rt_garbage_collect(struct dst_ops *ops);
|
static int rt_garbage_collect(struct dst_ops *ops);
|
||||||
static void rt_emergency_hash_rebuild(struct net *net);
|
|
||||||
|
|
||||||
|
|
||||||
static struct dst_ops ipv4_dst_ops = {
|
static struct dst_ops ipv4_dst_ops = {
|
||||||
|
@ -780,11 +779,30 @@ static void rt_do_flush(int process_context)
|
||||||
#define FRACT_BITS 3
|
#define FRACT_BITS 3
|
||||||
#define ONE (1UL << FRACT_BITS)
|
#define ONE (1UL << FRACT_BITS)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Given a hash chain and an item in this hash chain,
|
||||||
|
* find if a previous entry has the same hash_inputs
|
||||||
|
* (but differs on tos, mark or oif)
|
||||||
|
* Returns 0 if an alias is found.
|
||||||
|
* Returns ONE if rth has no alias before itself.
|
||||||
|
*/
|
||||||
|
static int has_noalias(const struct rtable *head, const struct rtable *rth)
|
||||||
|
{
|
||||||
|
const struct rtable *aux = head;
|
||||||
|
|
||||||
|
while (aux != rth) {
|
||||||
|
if (compare_hash_inputs(&aux->fl, &rth->fl))
|
||||||
|
return 0;
|
||||||
|
aux = aux->u.dst.rt_next;
|
||||||
|
}
|
||||||
|
return ONE;
|
||||||
|
}
|
||||||
|
|
||||||
static void rt_check_expire(void)
|
static void rt_check_expire(void)
|
||||||
{
|
{
|
||||||
static unsigned int rover;
|
static unsigned int rover;
|
||||||
unsigned int i = rover, goal;
|
unsigned int i = rover, goal;
|
||||||
struct rtable *rth, *aux, **rthp;
|
struct rtable *rth, **rthp;
|
||||||
unsigned long samples = 0;
|
unsigned long samples = 0;
|
||||||
unsigned long sum = 0, sum2 = 0;
|
unsigned long sum = 0, sum2 = 0;
|
||||||
unsigned long delta;
|
unsigned long delta;
|
||||||
|
@ -835,15 +853,7 @@ nofree:
|
||||||
* attributes don't unfairly skew
|
* attributes don't unfairly skew
|
||||||
* the length computation
|
* the length computation
|
||||||
*/
|
*/
|
||||||
for (aux = rt_hash_table[i].chain;;) {
|
length += has_noalias(rt_hash_table[i].chain, rth);
|
||||||
if (aux == rth) {
|
|
||||||
length += ONE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (compare_hash_inputs(&aux->fl, &rth->fl))
|
|
||||||
break;
|
|
||||||
aux = aux->u.dst.rt_next;
|
|
||||||
}
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
} else if (!rt_may_expire(rth, tmo, ip_rt_gc_timeout))
|
} else if (!rt_may_expire(rth, tmo, ip_rt_gc_timeout))
|
||||||
|
@ -1073,6 +1083,21 @@ work_done:
|
||||||
out: return 0;
|
out: return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns number of entries in a hash chain that have different hash_inputs
|
||||||
|
*/
|
||||||
|
static int slow_chain_length(const struct rtable *head)
|
||||||
|
{
|
||||||
|
int length = 0;
|
||||||
|
const struct rtable *rth = head;
|
||||||
|
|
||||||
|
while (rth) {
|
||||||
|
length += has_noalias(head, rth);
|
||||||
|
rth = rth->u.dst.rt_next;
|
||||||
|
}
|
||||||
|
return length >> FRACT_BITS;
|
||||||
|
}
|
||||||
|
|
||||||
static int rt_intern_hash(unsigned hash, struct rtable *rt,
|
static int rt_intern_hash(unsigned hash, struct rtable *rt,
|
||||||
struct rtable **rp, struct sk_buff *skb)
|
struct rtable **rp, struct sk_buff *skb)
|
||||||
{
|
{
|
||||||
|
@ -1185,7 +1210,8 @@ restart:
|
||||||
rt_free(cand);
|
rt_free(cand);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (chain_length > rt_chain_length_max) {
|
if (chain_length > rt_chain_length_max &&
|
||||||
|
slow_chain_length(rt_hash_table[hash].chain) > rt_chain_length_max) {
|
||||||
struct net *net = dev_net(rt->u.dst.dev);
|
struct net *net = dev_net(rt->u.dst.dev);
|
||||||
int num = ++net->ipv4.current_rt_cache_rebuild_count;
|
int num = ++net->ipv4.current_rt_cache_rebuild_count;
|
||||||
if (!rt_caching(dev_net(rt->u.dst.dev))) {
|
if (!rt_caching(dev_net(rt->u.dst.dev))) {
|
||||||
|
|
|
@ -1651,13 +1651,15 @@ int tcp_v4_rcv(struct sk_buff *skb)
|
||||||
if (!sk)
|
if (!sk)
|
||||||
goto no_tcp_socket;
|
goto no_tcp_socket;
|
||||||
|
|
||||||
if (iph->ttl < inet_sk(sk)->min_ttl)
|
|
||||||
goto discard_and_relse;
|
|
||||||
|
|
||||||
process:
|
process:
|
||||||
if (sk->sk_state == TCP_TIME_WAIT)
|
if (sk->sk_state == TCP_TIME_WAIT)
|
||||||
goto do_time_wait;
|
goto do_time_wait;
|
||||||
|
|
||||||
|
if (unlikely(iph->ttl < inet_sk(sk)->min_ttl)) {
|
||||||
|
NET_INC_STATS_BH(net, LINUX_MIB_TCPMINTTLDROP);
|
||||||
|
goto discard_and_relse;
|
||||||
|
}
|
||||||
|
|
||||||
if (!xfrm4_policy_check(sk, XFRM_POLICY_IN, skb))
|
if (!xfrm4_policy_check(sk, XFRM_POLICY_IN, skb))
|
||||||
goto discard_and_relse;
|
goto discard_and_relse;
|
||||||
nf_reset(skb);
|
nf_reset(skb);
|
||||||
|
@ -1682,8 +1684,11 @@ process:
|
||||||
if (!tcp_prequeue(sk, skb))
|
if (!tcp_prequeue(sk, skb))
|
||||||
ret = tcp_v4_do_rcv(sk, skb);
|
ret = tcp_v4_do_rcv(sk, skb);
|
||||||
}
|
}
|
||||||
} else
|
} else if (unlikely(sk_add_backlog(sk, skb))) {
|
||||||
sk_add_backlog(sk, skb);
|
bh_unlock_sock(sk);
|
||||||
|
NET_INC_STATS_BH(net, LINUX_MIB_TCPBACKLOGDROP);
|
||||||
|
goto discard_and_relse;
|
||||||
|
}
|
||||||
bh_unlock_sock(sk);
|
bh_unlock_sock(sk);
|
||||||
|
|
||||||
sock_put(sk);
|
sock_put(sk);
|
||||||
|
|
|
@ -728,7 +728,7 @@ int tcp_child_process(struct sock *parent, struct sock *child,
|
||||||
* in main socket hash table and lock on listening
|
* in main socket hash table and lock on listening
|
||||||
* socket does not protect us more.
|
* socket does not protect us more.
|
||||||
*/
|
*/
|
||||||
sk_add_backlog(child, skb);
|
__sk_add_backlog(child, skb);
|
||||||
}
|
}
|
||||||
|
|
||||||
bh_unlock_sock(child);
|
bh_unlock_sock(child);
|
||||||
|
|
|
@ -2395,13 +2395,17 @@ struct sk_buff *tcp_make_synack(struct sock *sk, struct dst_entry *dst,
|
||||||
struct tcp_extend_values *xvp = tcp_xv(rvp);
|
struct tcp_extend_values *xvp = tcp_xv(rvp);
|
||||||
struct inet_request_sock *ireq = inet_rsk(req);
|
struct inet_request_sock *ireq = inet_rsk(req);
|
||||||
struct tcp_sock *tp = tcp_sk(sk);
|
struct tcp_sock *tp = tcp_sk(sk);
|
||||||
|
const struct tcp_cookie_values *cvp = tp->cookie_values;
|
||||||
struct tcphdr *th;
|
struct tcphdr *th;
|
||||||
struct sk_buff *skb;
|
struct sk_buff *skb;
|
||||||
struct tcp_md5sig_key *md5;
|
struct tcp_md5sig_key *md5;
|
||||||
int tcp_header_size;
|
int tcp_header_size;
|
||||||
int mss;
|
int mss;
|
||||||
|
int s_data_desired = 0;
|
||||||
|
|
||||||
skb = sock_wmalloc(sk, MAX_TCP_HEADER + 15, 1, GFP_ATOMIC);
|
if (cvp != NULL && cvp->s_data_constant && cvp->s_data_desired)
|
||||||
|
s_data_desired = cvp->s_data_desired;
|
||||||
|
skb = sock_wmalloc(sk, MAX_TCP_HEADER + 15 + s_data_desired, 1, GFP_ATOMIC);
|
||||||
if (skb == NULL)
|
if (skb == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
@ -2457,16 +2461,12 @@ struct sk_buff *tcp_make_synack(struct sock *sk, struct dst_entry *dst,
|
||||||
TCPCB_FLAG_SYN | TCPCB_FLAG_ACK);
|
TCPCB_FLAG_SYN | TCPCB_FLAG_ACK);
|
||||||
|
|
||||||
if (OPTION_COOKIE_EXTENSION & opts.options) {
|
if (OPTION_COOKIE_EXTENSION & opts.options) {
|
||||||
const struct tcp_cookie_values *cvp = tp->cookie_values;
|
if (s_data_desired) {
|
||||||
|
u8 *buf = skb_put(skb, s_data_desired);
|
||||||
if (cvp != NULL &&
|
|
||||||
cvp->s_data_constant &&
|
|
||||||
cvp->s_data_desired > 0) {
|
|
||||||
u8 *buf = skb_put(skb, cvp->s_data_desired);
|
|
||||||
|
|
||||||
/* copy data directly from the listening socket. */
|
/* copy data directly from the listening socket. */
|
||||||
memcpy(buf, cvp->s_data_payload, cvp->s_data_desired);
|
memcpy(buf, cvp->s_data_payload, s_data_desired);
|
||||||
TCP_SKB_CB(skb)->end_seq += cvp->s_data_desired;
|
TCP_SKB_CB(skb)->end_seq += s_data_desired;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (opts.hash_size > 0) {
|
if (opts.hash_size > 0) {
|
||||||
|
|
|
@ -1371,8 +1371,10 @@ int udp_queue_rcv_skb(struct sock *sk, struct sk_buff *skb)
|
||||||
bh_lock_sock(sk);
|
bh_lock_sock(sk);
|
||||||
if (!sock_owned_by_user(sk))
|
if (!sock_owned_by_user(sk))
|
||||||
rc = __udp_queue_rcv_skb(sk, skb);
|
rc = __udp_queue_rcv_skb(sk, skb);
|
||||||
else
|
else if (sk_add_backlog(sk, skb)) {
|
||||||
sk_add_backlog(sk, skb);
|
bh_unlock_sock(sk);
|
||||||
|
goto drop;
|
||||||
|
}
|
||||||
bh_unlock_sock(sk);
|
bh_unlock_sock(sk);
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
|
|
|
@ -91,11 +91,12 @@ static int xfrm4_init_path(struct xfrm_dst *path, struct dst_entry *dst,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int xfrm4_fill_dst(struct xfrm_dst *xdst, struct net_device *dev)
|
static int xfrm4_fill_dst(struct xfrm_dst *xdst, struct net_device *dev,
|
||||||
|
struct flowi *fl)
|
||||||
{
|
{
|
||||||
struct rtable *rt = (struct rtable *)xdst->route;
|
struct rtable *rt = (struct rtable *)xdst->route;
|
||||||
|
|
||||||
xdst->u.rt.fl = rt->fl;
|
xdst->u.rt.fl = *fl;
|
||||||
|
|
||||||
xdst->u.dst.dev = dev;
|
xdst->u.dst.dev = dev;
|
||||||
dev_hold(dev);
|
dev_hold(dev);
|
||||||
|
|
|
@ -1380,6 +1380,8 @@ static void addrconf_dad_stop(struct inet6_ifaddr *ifp, int dad_failed)
|
||||||
if (dad_failed)
|
if (dad_failed)
|
||||||
ifp->flags |= IFA_F_DADFAILED;
|
ifp->flags |= IFA_F_DADFAILED;
|
||||||
spin_unlock_bh(&ifp->lock);
|
spin_unlock_bh(&ifp->lock);
|
||||||
|
if (dad_failed)
|
||||||
|
ipv6_ifa_notify(0, ifp);
|
||||||
in6_ifa_put(ifp);
|
in6_ifa_put(ifp);
|
||||||
#ifdef CONFIG_IPV6_PRIVACY
|
#ifdef CONFIG_IPV6_PRIVACY
|
||||||
} else if (ifp->flags&IFA_F_TEMPORARY) {
|
} else if (ifp->flags&IFA_F_TEMPORARY) {
|
||||||
|
@ -2615,7 +2617,7 @@ static void addrconf_bonding_change(struct net_device *dev, unsigned long event)
|
||||||
static int addrconf_ifdown(struct net_device *dev, int how)
|
static int addrconf_ifdown(struct net_device *dev, int how)
|
||||||
{
|
{
|
||||||
struct inet6_dev *idev;
|
struct inet6_dev *idev;
|
||||||
struct inet6_ifaddr *ifa, **bifa;
|
struct inet6_ifaddr *ifa, *keep_list, **bifa;
|
||||||
struct net *net = dev_net(dev);
|
struct net *net = dev_net(dev);
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
@ -2649,11 +2651,11 @@ static int addrconf_ifdown(struct net_device *dev, int how)
|
||||||
write_lock_bh(&addrconf_hash_lock);
|
write_lock_bh(&addrconf_hash_lock);
|
||||||
while ((ifa = *bifa) != NULL) {
|
while ((ifa = *bifa) != NULL) {
|
||||||
if (ifa->idev == idev &&
|
if (ifa->idev == idev &&
|
||||||
(how || !(ifa->flags&IFA_F_PERMANENT))) {
|
(how || !(ifa->flags&IFA_F_PERMANENT) ||
|
||||||
|
ipv6_addr_type(&ifa->addr) & IPV6_ADDR_LINKLOCAL)) {
|
||||||
*bifa = ifa->lst_next;
|
*bifa = ifa->lst_next;
|
||||||
ifa->lst_next = NULL;
|
ifa->lst_next = NULL;
|
||||||
addrconf_del_timer(ifa);
|
__in6_ifa_put(ifa);
|
||||||
in6_ifa_put(ifa);
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
bifa = &ifa->lst_next;
|
bifa = &ifa->lst_next;
|
||||||
|
@ -2689,31 +2691,51 @@ static int addrconf_ifdown(struct net_device *dev, int how)
|
||||||
write_lock_bh(&idev->lock);
|
write_lock_bh(&idev->lock);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
bifa = &idev->addr_list;
|
keep_list = NULL;
|
||||||
while ((ifa = *bifa) != NULL) {
|
bifa = &keep_list;
|
||||||
if (how == 0 && (ifa->flags&IFA_F_PERMANENT)) {
|
while ((ifa = idev->addr_list) != NULL) {
|
||||||
/* Retain permanent address on admin down */
|
idev->addr_list = ifa->if_next;
|
||||||
|
ifa->if_next = NULL;
|
||||||
|
|
||||||
|
addrconf_del_timer(ifa);
|
||||||
|
|
||||||
|
/* If just doing link down, and address is permanent
|
||||||
|
and not link-local, then retain it. */
|
||||||
|
if (how == 0 &&
|
||||||
|
(ifa->flags&IFA_F_PERMANENT) &&
|
||||||
|
!(ipv6_addr_type(&ifa->addr) & IPV6_ADDR_LINKLOCAL)) {
|
||||||
|
|
||||||
|
/* Move to holding list */
|
||||||
|
*bifa = ifa;
|
||||||
bifa = &ifa->if_next;
|
bifa = &ifa->if_next;
|
||||||
|
|
||||||
/* Restart DAD if needed when link comes back up */
|
/* If not doing DAD on this address, just keep it. */
|
||||||
if ( !((dev->flags&(IFF_NOARP|IFF_LOOPBACK)) ||
|
if ((dev->flags&(IFF_NOARP|IFF_LOOPBACK)) ||
|
||||||
idev->cnf.accept_dad <= 0 ||
|
idev->cnf.accept_dad <= 0 ||
|
||||||
(ifa->flags & IFA_F_NODAD)))
|
(ifa->flags & IFA_F_NODAD))
|
||||||
ifa->flags |= IFA_F_TENTATIVE;
|
continue;
|
||||||
|
|
||||||
|
/* If it was tentative already, no need to notify */
|
||||||
|
if (ifa->flags & IFA_F_TENTATIVE)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* Flag it for later restoration when link comes up */
|
||||||
|
ifa->flags |= IFA_F_TENTATIVE;
|
||||||
|
in6_ifa_hold(ifa);
|
||||||
} else {
|
} else {
|
||||||
*bifa = ifa->if_next;
|
|
||||||
ifa->if_next = NULL;
|
|
||||||
|
|
||||||
ifa->dead = 1;
|
ifa->dead = 1;
|
||||||
write_unlock_bh(&idev->lock);
|
|
||||||
|
|
||||||
__ipv6_ifa_notify(RTM_DELADDR, ifa);
|
|
||||||
atomic_notifier_call_chain(&inet6addr_chain, NETDEV_DOWN, ifa);
|
|
||||||
in6_ifa_put(ifa);
|
|
||||||
|
|
||||||
write_lock_bh(&idev->lock);
|
|
||||||
}
|
}
|
||||||
|
write_unlock_bh(&idev->lock);
|
||||||
|
|
||||||
|
__ipv6_ifa_notify(RTM_DELADDR, ifa);
|
||||||
|
atomic_notifier_call_chain(&inet6addr_chain, NETDEV_DOWN, ifa);
|
||||||
|
in6_ifa_put(ifa);
|
||||||
|
|
||||||
|
write_lock_bh(&idev->lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
idev->addr_list = keep_list;
|
||||||
|
|
||||||
write_unlock_bh(&idev->lock);
|
write_unlock_bh(&idev->lock);
|
||||||
|
|
||||||
/* Step 5: Discard multicast list */
|
/* Step 5: Discard multicast list */
|
||||||
|
@ -2739,28 +2761,29 @@ static int addrconf_ifdown(struct net_device *dev, int how)
|
||||||
static void addrconf_rs_timer(unsigned long data)
|
static void addrconf_rs_timer(unsigned long data)
|
||||||
{
|
{
|
||||||
struct inet6_ifaddr *ifp = (struct inet6_ifaddr *) data;
|
struct inet6_ifaddr *ifp = (struct inet6_ifaddr *) data;
|
||||||
|
struct inet6_dev *idev = ifp->idev;
|
||||||
|
|
||||||
if (ifp->idev->cnf.forwarding)
|
read_lock(&idev->lock);
|
||||||
|
if (idev->dead || !(idev->if_flags & IF_READY))
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
if (ifp->idev->if_flags & IF_RA_RCVD) {
|
if (idev->cnf.forwarding)
|
||||||
/*
|
goto out;
|
||||||
* Announcement received after solicitation
|
|
||||||
* was sent
|
/* Announcement received after solicitation was sent */
|
||||||
*/
|
if (idev->if_flags & IF_RA_RCVD)
|
||||||
goto out;
|
goto out;
|
||||||
}
|
|
||||||
|
|
||||||
spin_lock(&ifp->lock);
|
spin_lock(&ifp->lock);
|
||||||
if (ifp->probes++ < ifp->idev->cnf.rtr_solicits) {
|
if (ifp->probes++ < idev->cnf.rtr_solicits) {
|
||||||
/* The wait after the last probe can be shorter */
|
/* The wait after the last probe can be shorter */
|
||||||
addrconf_mod_timer(ifp, AC_RS,
|
addrconf_mod_timer(ifp, AC_RS,
|
||||||
(ifp->probes == ifp->idev->cnf.rtr_solicits) ?
|
(ifp->probes == idev->cnf.rtr_solicits) ?
|
||||||
ifp->idev->cnf.rtr_solicit_delay :
|
idev->cnf.rtr_solicit_delay :
|
||||||
ifp->idev->cnf.rtr_solicit_interval);
|
idev->cnf.rtr_solicit_interval);
|
||||||
spin_unlock(&ifp->lock);
|
spin_unlock(&ifp->lock);
|
||||||
|
|
||||||
ndisc_send_rs(ifp->idev->dev, &ifp->addr, &in6addr_linklocal_allrouters);
|
ndisc_send_rs(idev->dev, &ifp->addr, &in6addr_linklocal_allrouters);
|
||||||
} else {
|
} else {
|
||||||
spin_unlock(&ifp->lock);
|
spin_unlock(&ifp->lock);
|
||||||
/*
|
/*
|
||||||
|
@ -2768,10 +2791,11 @@ static void addrconf_rs_timer(unsigned long data)
|
||||||
* assumption any longer.
|
* assumption any longer.
|
||||||
*/
|
*/
|
||||||
printk(KERN_DEBUG "%s: no IPv6 routers present\n",
|
printk(KERN_DEBUG "%s: no IPv6 routers present\n",
|
||||||
ifp->idev->dev->name);
|
idev->dev->name);
|
||||||
}
|
}
|
||||||
|
|
||||||
out:
|
out:
|
||||||
|
read_unlock(&idev->lock);
|
||||||
in6_ifa_put(ifp);
|
in6_ifa_put(ifp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2850,9 +2874,9 @@ static void addrconf_dad_timer(unsigned long data)
|
||||||
struct inet6_dev *idev = ifp->idev;
|
struct inet6_dev *idev = ifp->idev;
|
||||||
struct in6_addr mcaddr;
|
struct in6_addr mcaddr;
|
||||||
|
|
||||||
read_lock_bh(&idev->lock);
|
read_lock(&idev->lock);
|
||||||
if (idev->dead) {
|
if (idev->dead || !(idev->if_flags & IF_READY)) {
|
||||||
read_unlock_bh(&idev->lock);
|
read_unlock(&idev->lock);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2864,7 +2888,7 @@ static void addrconf_dad_timer(unsigned long data)
|
||||||
|
|
||||||
ifp->flags &= ~(IFA_F_TENTATIVE|IFA_F_OPTIMISTIC|IFA_F_DADFAILED);
|
ifp->flags &= ~(IFA_F_TENTATIVE|IFA_F_OPTIMISTIC|IFA_F_DADFAILED);
|
||||||
spin_unlock(&ifp->lock);
|
spin_unlock(&ifp->lock);
|
||||||
read_unlock_bh(&idev->lock);
|
read_unlock(&idev->lock);
|
||||||
|
|
||||||
addrconf_dad_completed(ifp);
|
addrconf_dad_completed(ifp);
|
||||||
|
|
||||||
|
@ -2874,7 +2898,7 @@ static void addrconf_dad_timer(unsigned long data)
|
||||||
ifp->probes--;
|
ifp->probes--;
|
||||||
addrconf_mod_timer(ifp, AC_DAD, ifp->idev->nd_parms->retrans_time);
|
addrconf_mod_timer(ifp, AC_DAD, ifp->idev->nd_parms->retrans_time);
|
||||||
spin_unlock(&ifp->lock);
|
spin_unlock(&ifp->lock);
|
||||||
read_unlock_bh(&idev->lock);
|
read_unlock(&idev->lock);
|
||||||
|
|
||||||
/* send a neighbour solicitation for our addr */
|
/* send a neighbour solicitation for our addr */
|
||||||
addrconf_addr_solict_mult(&ifp->addr, &mcaddr);
|
addrconf_addr_solict_mult(&ifp->addr, &mcaddr);
|
||||||
|
|
|
@ -84,18 +84,11 @@ static int fib6_rule_action(struct fib_rule *rule, struct flowi *flp,
|
||||||
if ((rule->flags & FIB_RULE_FIND_SADDR) &&
|
if ((rule->flags & FIB_RULE_FIND_SADDR) &&
|
||||||
r->src.plen && !(flags & RT6_LOOKUP_F_HAS_SADDR)) {
|
r->src.plen && !(flags & RT6_LOOKUP_F_HAS_SADDR)) {
|
||||||
struct in6_addr saddr;
|
struct in6_addr saddr;
|
||||||
unsigned int srcprefs = 0;
|
|
||||||
|
|
||||||
if (flags & RT6_LOOKUP_F_SRCPREF_TMP)
|
|
||||||
srcprefs |= IPV6_PREFER_SRC_TMP;
|
|
||||||
if (flags & RT6_LOOKUP_F_SRCPREF_PUBLIC)
|
|
||||||
srcprefs |= IPV6_PREFER_SRC_PUBLIC;
|
|
||||||
if (flags & RT6_LOOKUP_F_SRCPREF_COA)
|
|
||||||
srcprefs |= IPV6_PREFER_SRC_COA;
|
|
||||||
|
|
||||||
if (ipv6_dev_get_saddr(net,
|
if (ipv6_dev_get_saddr(net,
|
||||||
ip6_dst_idev(&rt->u.dst)->dev,
|
ip6_dst_idev(&rt->u.dst)->dev,
|
||||||
&flp->fl6_dst, srcprefs,
|
&flp->fl6_dst,
|
||||||
|
rt6_flags2srcprefs(flags),
|
||||||
&saddr))
|
&saddr))
|
||||||
goto again;
|
goto again;
|
||||||
if (!ipv6_prefix_equal(&saddr, &r->src.addr,
|
if (!ipv6_prefix_equal(&saddr, &r->src.addr,
|
||||||
|
|
|
@ -819,15 +819,8 @@ struct dst_entry * ip6_route_output(struct net *net, struct sock *sk,
|
||||||
|
|
||||||
if (!ipv6_addr_any(&fl->fl6_src))
|
if (!ipv6_addr_any(&fl->fl6_src))
|
||||||
flags |= RT6_LOOKUP_F_HAS_SADDR;
|
flags |= RT6_LOOKUP_F_HAS_SADDR;
|
||||||
else if (sk) {
|
else if (sk)
|
||||||
unsigned int prefs = inet6_sk(sk)->srcprefs;
|
flags |= rt6_srcprefs2flags(inet6_sk(sk)->srcprefs);
|
||||||
if (prefs & IPV6_PREFER_SRC_TMP)
|
|
||||||
flags |= RT6_LOOKUP_F_SRCPREF_TMP;
|
|
||||||
if (prefs & IPV6_PREFER_SRC_PUBLIC)
|
|
||||||
flags |= RT6_LOOKUP_F_SRCPREF_PUBLIC;
|
|
||||||
if (prefs & IPV6_PREFER_SRC_COA)
|
|
||||||
flags |= RT6_LOOKUP_F_SRCPREF_COA;
|
|
||||||
}
|
|
||||||
|
|
||||||
return fib6_rule_lookup(net, fl, flags, ip6_pol_route_output);
|
return fib6_rule_lookup(net, fl, flags, ip6_pol_route_output);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1740,8 +1740,11 @@ process:
|
||||||
if (!tcp_prequeue(sk, skb))
|
if (!tcp_prequeue(sk, skb))
|
||||||
ret = tcp_v6_do_rcv(sk, skb);
|
ret = tcp_v6_do_rcv(sk, skb);
|
||||||
}
|
}
|
||||||
} else
|
} else if (unlikely(sk_add_backlog(sk, skb))) {
|
||||||
sk_add_backlog(sk, skb);
|
bh_unlock_sock(sk);
|
||||||
|
NET_INC_STATS_BH(net, LINUX_MIB_TCPBACKLOGDROP);
|
||||||
|
goto discard_and_relse;
|
||||||
|
}
|
||||||
bh_unlock_sock(sk);
|
bh_unlock_sock(sk);
|
||||||
|
|
||||||
sock_put(sk);
|
sock_put(sk);
|
||||||
|
|
|
@ -583,16 +583,20 @@ static void flush_stack(struct sock **stack, unsigned int count,
|
||||||
bh_lock_sock(sk);
|
bh_lock_sock(sk);
|
||||||
if (!sock_owned_by_user(sk))
|
if (!sock_owned_by_user(sk))
|
||||||
udpv6_queue_rcv_skb(sk, skb1);
|
udpv6_queue_rcv_skb(sk, skb1);
|
||||||
else
|
else if (sk_add_backlog(sk, skb1)) {
|
||||||
sk_add_backlog(sk, skb1);
|
kfree_skb(skb1);
|
||||||
|
bh_unlock_sock(sk);
|
||||||
|
goto drop;
|
||||||
|
}
|
||||||
bh_unlock_sock(sk);
|
bh_unlock_sock(sk);
|
||||||
} else {
|
continue;
|
||||||
atomic_inc(&sk->sk_drops);
|
|
||||||
UDP6_INC_STATS_BH(sock_net(sk),
|
|
||||||
UDP_MIB_RCVBUFERRORS, IS_UDPLITE(sk));
|
|
||||||
UDP6_INC_STATS_BH(sock_net(sk),
|
|
||||||
UDP_MIB_INERRORS, IS_UDPLITE(sk));
|
|
||||||
}
|
}
|
||||||
|
drop:
|
||||||
|
atomic_inc(&sk->sk_drops);
|
||||||
|
UDP6_INC_STATS_BH(sock_net(sk),
|
||||||
|
UDP_MIB_RCVBUFERRORS, IS_UDPLITE(sk));
|
||||||
|
UDP6_INC_STATS_BH(sock_net(sk),
|
||||||
|
UDP_MIB_INERRORS, IS_UDPLITE(sk));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
|
@ -754,8 +758,12 @@ int __udp6_lib_rcv(struct sk_buff *skb, struct udp_table *udptable,
|
||||||
bh_lock_sock(sk);
|
bh_lock_sock(sk);
|
||||||
if (!sock_owned_by_user(sk))
|
if (!sock_owned_by_user(sk))
|
||||||
udpv6_queue_rcv_skb(sk, skb);
|
udpv6_queue_rcv_skb(sk, skb);
|
||||||
else
|
else if (sk_add_backlog(sk, skb)) {
|
||||||
sk_add_backlog(sk, skb);
|
atomic_inc(&sk->sk_drops);
|
||||||
|
bh_unlock_sock(sk);
|
||||||
|
sock_put(sk);
|
||||||
|
goto discard;
|
||||||
|
}
|
||||||
bh_unlock_sock(sk);
|
bh_unlock_sock(sk);
|
||||||
sock_put(sk);
|
sock_put(sk);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -116,7 +116,8 @@ static int xfrm6_init_path(struct xfrm_dst *path, struct dst_entry *dst,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int xfrm6_fill_dst(struct xfrm_dst *xdst, struct net_device *dev)
|
static int xfrm6_fill_dst(struct xfrm_dst *xdst, struct net_device *dev,
|
||||||
|
struct flowi *fl)
|
||||||
{
|
{
|
||||||
struct rt6_info *rt = (struct rt6_info*)xdst->route;
|
struct rt6_info *rt = (struct rt6_info*)xdst->route;
|
||||||
|
|
||||||
|
|
|
@ -1437,7 +1437,7 @@ static void llc_process_tmr_ev(struct sock *sk, struct sk_buff *skb)
|
||||||
llc_conn_state_process(sk, skb);
|
llc_conn_state_process(sk, skb);
|
||||||
else {
|
else {
|
||||||
llc_set_backlog_type(skb, LLC_EVENT);
|
llc_set_backlog_type(skb, LLC_EVENT);
|
||||||
sk_add_backlog(sk, skb);
|
__sk_add_backlog(sk, skb);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -827,7 +827,8 @@ void llc_conn_handler(struct llc_sap *sap, struct sk_buff *skb)
|
||||||
else {
|
else {
|
||||||
dprintk("%s: adding to backlog...\n", __func__);
|
dprintk("%s: adding to backlog...\n", __func__);
|
||||||
llc_set_backlog_type(skb, LLC_PACKET);
|
llc_set_backlog_type(skb, LLC_PACKET);
|
||||||
sk_add_backlog(sk, skb);
|
if (sk_add_backlog(sk, skb))
|
||||||
|
goto drop_unlock;
|
||||||
}
|
}
|
||||||
out:
|
out:
|
||||||
bh_unlock_sock(sk);
|
bh_unlock_sock(sk);
|
||||||
|
|
|
@ -48,20 +48,24 @@ static ssize_t ieee80211_if_write(
|
||||||
ssize_t (*write)(struct ieee80211_sub_if_data *, const char *, int))
|
ssize_t (*write)(struct ieee80211_sub_if_data *, const char *, int))
|
||||||
{
|
{
|
||||||
u8 *buf;
|
u8 *buf;
|
||||||
ssize_t ret = -ENODEV;
|
ssize_t ret;
|
||||||
|
|
||||||
buf = kzalloc(count, GFP_KERNEL);
|
buf = kmalloc(count, GFP_KERNEL);
|
||||||
if (!buf)
|
if (!buf)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
|
ret = -EFAULT;
|
||||||
if (copy_from_user(buf, userbuf, count))
|
if (copy_from_user(buf, userbuf, count))
|
||||||
return -EFAULT;
|
goto freebuf;
|
||||||
|
|
||||||
|
ret = -ENODEV;
|
||||||
rtnl_lock();
|
rtnl_lock();
|
||||||
if (sdata->dev->reg_state == NETREG_REGISTERED)
|
if (sdata->dev->reg_state == NETREG_REGISTERED)
|
||||||
ret = (*write)(sdata, buf, count);
|
ret = (*write)(sdata, buf, count);
|
||||||
rtnl_unlock();
|
rtnl_unlock();
|
||||||
|
|
||||||
|
freebuf:
|
||||||
|
kfree(buf);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -177,7 +177,8 @@ static u32 ieee80211_enable_ht(struct ieee80211_sub_if_data *sdata,
|
||||||
sta = sta_info_get(sdata, bssid);
|
sta = sta_info_get(sdata, bssid);
|
||||||
if (sta)
|
if (sta)
|
||||||
rate_control_rate_update(local, sband, sta,
|
rate_control_rate_update(local, sband, sta,
|
||||||
IEEE80211_RC_HT_CHANGED);
|
IEEE80211_RC_HT_CHANGED,
|
||||||
|
local->oper_channel_type);
|
||||||
rcu_read_unlock();
|
rcu_read_unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -435,10 +436,12 @@ static void ieee80211_enable_ps(struct ieee80211_local *local,
|
||||||
if (local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK)
|
if (local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK)
|
||||||
ieee80211_send_nullfunc(local, sdata, 1);
|
ieee80211_send_nullfunc(local, sdata, 1);
|
||||||
|
|
||||||
if (!(local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS)) {
|
if ((local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK) &&
|
||||||
conf->flags |= IEEE80211_CONF_PS;
|
(local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS))
|
||||||
ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS);
|
return;
|
||||||
}
|
|
||||||
|
conf->flags |= IEEE80211_CONF_PS;
|
||||||
|
ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -557,7 +560,8 @@ void ieee80211_dynamic_ps_enable_work(struct work_struct *work)
|
||||||
(!(ifmgd->flags & IEEE80211_STA_NULLFUNC_ACKED)))
|
(!(ifmgd->flags & IEEE80211_STA_NULLFUNC_ACKED)))
|
||||||
ieee80211_send_nullfunc(local, sdata, 1);
|
ieee80211_send_nullfunc(local, sdata, 1);
|
||||||
|
|
||||||
if (!(local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS) ||
|
if (!((local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS) &&
|
||||||
|
(local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK)) ||
|
||||||
(ifmgd->flags & IEEE80211_STA_NULLFUNC_ACKED)) {
|
(ifmgd->flags & IEEE80211_STA_NULLFUNC_ACKED)) {
|
||||||
ifmgd->flags &= ~IEEE80211_STA_NULLFUNC_ACKED;
|
ifmgd->flags &= ~IEEE80211_STA_NULLFUNC_ACKED;
|
||||||
local->hw.conf.flags |= IEEE80211_CONF_PS;
|
local->hw.conf.flags |= IEEE80211_CONF_PS;
|
||||||
|
@ -1893,8 +1897,20 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
|
||||||
|
|
||||||
mutex_lock(&ifmgd->mtx);
|
mutex_lock(&ifmgd->mtx);
|
||||||
if (ifmgd->associated) {
|
if (ifmgd->associated) {
|
||||||
mutex_unlock(&ifmgd->mtx);
|
if (!req->prev_bssid ||
|
||||||
return -EALREADY;
|
memcmp(req->prev_bssid, ifmgd->associated->bssid,
|
||||||
|
ETH_ALEN)) {
|
||||||
|
/*
|
||||||
|
* We are already associated and the request was not a
|
||||||
|
* reassociation request from the current BSS, so
|
||||||
|
* reject it.
|
||||||
|
*/
|
||||||
|
mutex_unlock(&ifmgd->mtx);
|
||||||
|
return -EALREADY;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Trying to reassociate - clear previous association state */
|
||||||
|
ieee80211_set_disassoc(sdata);
|
||||||
}
|
}
|
||||||
mutex_unlock(&ifmgd->mtx);
|
mutex_unlock(&ifmgd->mtx);
|
||||||
|
|
||||||
|
|
|
@ -66,7 +66,8 @@ static inline void rate_control_rate_init(struct sta_info *sta)
|
||||||
|
|
||||||
static inline void rate_control_rate_update(struct ieee80211_local *local,
|
static inline void rate_control_rate_update(struct ieee80211_local *local,
|
||||||
struct ieee80211_supported_band *sband,
|
struct ieee80211_supported_band *sband,
|
||||||
struct sta_info *sta, u32 changed)
|
struct sta_info *sta, u32 changed,
|
||||||
|
enum nl80211_channel_type oper_chan_type)
|
||||||
{
|
{
|
||||||
struct rate_control_ref *ref = local->rate_ctrl;
|
struct rate_control_ref *ref = local->rate_ctrl;
|
||||||
struct ieee80211_sta *ista = &sta->sta;
|
struct ieee80211_sta *ista = &sta->sta;
|
||||||
|
@ -74,7 +75,7 @@ static inline void rate_control_rate_update(struct ieee80211_local *local,
|
||||||
|
|
||||||
if (ref && ref->ops->rate_update)
|
if (ref && ref->ops->rate_update)
|
||||||
ref->ops->rate_update(ref->priv, sband, ista,
|
ref->ops->rate_update(ref->priv, sband, ista,
|
||||||
priv_sta, changed);
|
priv_sta, changed, oper_chan_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void *rate_control_alloc_sta(struct rate_control_ref *ref,
|
static inline void *rate_control_alloc_sta(struct rate_control_ref *ref,
|
||||||
|
|
|
@ -434,6 +434,7 @@ int sta_info_insert_rcu(struct sta_info *sta) __acquires(RCU)
|
||||||
/* check if STA exists already */
|
/* check if STA exists already */
|
||||||
if (sta_info_get_bss(sdata, sta->sta.addr)) {
|
if (sta_info_get_bss(sdata, sta->sta.addr)) {
|
||||||
spin_unlock_irqrestore(&local->sta_lock, flags);
|
spin_unlock_irqrestore(&local->sta_lock, flags);
|
||||||
|
mutex_unlock(&local->sta_mtx);
|
||||||
rcu_read_lock();
|
rcu_read_lock();
|
||||||
err = -EEXIST;
|
err = -EEXIST;
|
||||||
goto out_free;
|
goto out_free;
|
||||||
|
|
|
@ -1688,6 +1688,8 @@ static int packet_dev_mc(struct net_device *dev, struct packet_mclist *i,
|
||||||
{
|
{
|
||||||
switch (i->type) {
|
switch (i->type) {
|
||||||
case PACKET_MR_MULTICAST:
|
case PACKET_MR_MULTICAST:
|
||||||
|
if (i->alen != dev->addr_len)
|
||||||
|
return -EINVAL;
|
||||||
if (what > 0)
|
if (what > 0)
|
||||||
return dev_mc_add(dev, i->addr, i->alen, 0);
|
return dev_mc_add(dev, i->addr, i->alen, 0);
|
||||||
else
|
else
|
||||||
|
@ -1700,6 +1702,8 @@ static int packet_dev_mc(struct net_device *dev, struct packet_mclist *i,
|
||||||
return dev_set_allmulti(dev, what);
|
return dev_set_allmulti(dev, what);
|
||||||
break;
|
break;
|
||||||
case PACKET_MR_UNICAST:
|
case PACKET_MR_UNICAST:
|
||||||
|
if (i->alen != dev->addr_len)
|
||||||
|
return -EINVAL;
|
||||||
if (what > 0)
|
if (what > 0)
|
||||||
return dev_unicast_add(dev, i->addr);
|
return dev_unicast_add(dev, i->addr);
|
||||||
else
|
else
|
||||||
|
@ -1734,7 +1738,7 @@ static int packet_mc_add(struct sock *sk, struct packet_mreq_max *mreq)
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
err = -EINVAL;
|
err = -EINVAL;
|
||||||
if (mreq->mr_alen != dev->addr_len)
|
if (mreq->mr_alen > dev->addr_len)
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
err = -ENOBUFS;
|
err = -ENOBUFS;
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue