summaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorJohn W. Linville <linville@tuxdriver.com>2010-04-08 13:34:54 -0400
committerJohn W. Linville <linville@tuxdriver.com>2010-04-08 13:34:54 -0400
commit0f2df9eac70423838a1f8d410fd3899ddd88317b (patch)
tree0617f723320d83eca5cef9c964c001014e74213f /drivers/net
parent8c11e4ab09ffb975a89802dde0e9aa52a53b8aa5 (diff)
parent1144601118507f8b3b676a9a392584d216d3f2cc (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-2.6 into merge
Conflicts: Documentation/feature-removal-schedule.txt drivers/net/wireless/ath/ath5k/phy.c drivers/net/wireless/iwlwifi/iwl-4965.c drivers/net/wireless/iwlwifi/iwl-agn.c drivers/net/wireless/iwlwifi/iwl-core.c drivers/net/wireless/iwlwifi/iwl-core.h drivers/net/wireless/iwlwifi/iwl-tx.c
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/Kconfig2
-rw-r--r--drivers/net/arm/ks8695net.c2
-rw-r--r--drivers/net/benet/be.h5
-rw-r--r--drivers/net/benet/be_cmds.c6
-rw-r--r--drivers/net/benet/be_hw.h5
-rw-r--r--drivers/net/benet/be_main.c25
-rw-r--r--drivers/net/can/bfin_can.c3
-rw-r--r--drivers/net/can/usb/ems_usb.c4
-rw-r--r--drivers/net/cassini.c2
-rw-r--r--drivers/net/cpmac.c14
-rw-r--r--drivers/net/cxgb3/cxgb3_main.c1
-rw-r--r--drivers/net/davinci_emac.c57
-rw-r--r--drivers/net/e1000e/defines.h2
-rw-r--r--drivers/net/e1000e/ich8lan.c10
-rw-r--r--drivers/net/gianfar.c5
-rw-r--r--drivers/net/irda/irda-usb.c4
-rw-r--r--drivers/net/qlcnic/qlcnic.h13
-rw-r--r--drivers/net/qlcnic/qlcnic_ethtool.c17
-rw-r--r--drivers/net/qlcnic/qlcnic_hw.c32
-rw-r--r--drivers/net/qlcnic/qlcnic_init.c156
-rw-r--r--drivers/net/qlcnic/qlcnic_main.c5
-rw-r--r--drivers/net/r8169.c4
-rw-r--r--drivers/net/s2io.c6
-rw-r--r--drivers/net/smc911x.h4
-rw-r--r--drivers/net/smc91x.h14
-rw-r--r--drivers/net/typhoon.c6
-rw-r--r--drivers/net/usb/pegasus.h6
-rw-r--r--drivers/net/wireless/ath/ar9170/usb.c4
-rw-r--r--drivers/net/wireless/ath/ath5k/eeprom.c4
-rw-r--r--drivers/net/wireless/ath/ath5k/phy.c44
-rw-r--r--drivers/net/wireless/ath/ath5k/reg.h1
-rw-r--r--drivers/net/wireless/ath/ath5k/reset.c22
-rw-r--r--drivers/net/wireless/ath/ath9k/main.c3
-rw-r--r--drivers/net/wireless/ath/ath9k/xmit.c21
-rw-r--r--drivers/net/wireless/ipw2x00/ipw2200.c19
-rw-r--r--drivers/net/wireless/ipw2x00/libipw.h2
-rw-r--r--drivers/net/wireless/ipw2x00/libipw_module.c37
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945.c6
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-4965.c6
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-rs.c55
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.c14
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-scan.c49
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-tx.c50
-rw-r--r--drivers/net/wireless/iwlwifi/iwl3945-base.c4
-rw-r--r--drivers/net/wireless/libertas/cfg.c8
-rw-r--r--drivers/net/wireless/libertas/dev.h1
-rw-r--r--drivers/net/wireless/mwl8k.c1
-rw-r--r--drivers/net/wireless/p54/p54usb.c1
-rw-r--r--drivers/net/wireless/rndis_wlan.c66
-rw-r--r--drivers/net/wireless/rt2x00/rt2500usb.c5
-rw-r--r--drivers/net/wireless/rt2x00/rt2800lib.c4
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00soc.h2
-rw-r--r--drivers/net/wireless/wl12xx/wl1251_debugfs.c3
54 files changed, 541 insertions, 303 deletions
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 46af867af85..7029cd50c45 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -932,7 +932,7 @@ config NET_NETX
config TI_DAVINCI_EMAC
tristate "TI DaVinci EMAC Support"
- depends on ARM && ARCH_DAVINCI
+ depends on ARM && ( ARCH_DAVINCI || ARCH_OMAP3 )
select PHYLIB
help
This driver supports TI's DaVinci Ethernet .
diff --git a/drivers/net/arm/ks8695net.c b/drivers/net/arm/ks8695net.c
index 8ca639127db..a1d4188c430 100644
--- a/drivers/net/arm/ks8695net.c
+++ b/drivers/net/arm/ks8695net.c
@@ -575,9 +575,9 @@ static int ks8695_poll(struct napi_struct *napi, int budget)
if (work_done < budget) {
unsigned long flags;
spin_lock_irqsave(&ksp->rx_lock, flags);
+ __napi_complete(napi);
/*enable rx interrupt*/
writel(isr | mask_bit, KS8695_IRQ_VA + KS8695_INTEN);
- __napi_complete(napi);
spin_unlock_irqrestore(&ksp->rx_lock, flags);
}
return work_done;
diff --git a/drivers/net/benet/be.h b/drivers/net/benet/be.h
index be81fb2d10f..8f075255368 100644
--- a/drivers/net/benet/be.h
+++ b/drivers/net/benet/be.h
@@ -290,11 +290,6 @@ extern const struct ethtool_ops be_ethtool_ops;
#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 PAGE_SHIFT_4K 12
diff --git a/drivers/net/benet/be_cmds.c b/drivers/net/benet/be_cmds.c
index 4b1f80519ca..c59215361f4 100644
--- a/drivers/net/benet/be_cmds.c
+++ b/drivers/net/benet/be_cmds.c
@@ -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));
- 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);
/* 4byte eqe*/
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, eqid, ctxt, eq->id);
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_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);
- 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, ring_size, ctxt,
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,
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, cq_id_send, ctxt, cq->id);
diff --git a/drivers/net/benet/be_hw.h b/drivers/net/benet/be_hw.h
index 5ffb149181a..2d4a4b82763 100644
--- a/drivers/net/benet/be_hw.h
+++ b/drivers/net/benet/be_hw.h
@@ -114,8 +114,7 @@
#define IMG_TYPE_ISCSI_BACKUP 9
#define IMG_TYPE_FCOE_FW_ACTIVE 10
#define IMG_TYPE_FCOE_FW_BACKUP 11
-#define IMG_TYPE_NCSI_BITFILE 13
-#define IMG_TYPE_NCSI_8051 14
+#define IMG_TYPE_NCSI_FW 13
#define FLASHROM_OPER_FLASH 1
#define FLASHROM_OPER_SAVE 2
@@ -127,6 +126,7 @@
#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_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_DISABLED (0)
@@ -144,6 +144,7 @@
#define FLASH_FCoE_BIOS_START_g2 (524288)
#define FLASH_REDBOOT_START_g2 (0)
+#define FLASH_NCSI_START_g3 (15990784)
#define FLASH_iSCSI_PRIMARY_IMAGE_START_g3 (2097152)
#define FLASH_iSCSI_BACKUP_IMAGE_START_g3 (4194304)
#define FLASH_FCoE_PRIMARY_IMAGE_START_g3 (6291456)
diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c
index a703ed8e24f..43e8032f923 100644
--- a/drivers/net/benet/be_main.c
+++ b/drivers/net/benet/be_main.c
@@ -1382,7 +1382,7 @@ rx_eq_free:
/* 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)
{
- return eq_id - 8 * be_pci_func(adapter);
+ return eq_id % 8;
}
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;
struct be_cmd_write_flashrom *req = flash_cmd->va;
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_IMAGE_MAX_SIZE_g3},
{ 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_IMAGE_MAX_SIZE_g3},
{ 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] = {
{ 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) {
pflashcomp = gen3_flash_types;
filehdr_size = sizeof(struct flash_file_hdr_g3);
+ num_comp = 9;
} else {
pflashcomp = gen2_flash_types;
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) &&
(!be_flash_redboot(adapter, fw->data,
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;
int status, i = 0;
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);
status = request_firmware(&fw, fw_file, &adapter->pdev->dev);
diff --git a/drivers/net/can/bfin_can.c b/drivers/net/can/bfin_can.c
index bf7f9ba2d90..866905fa411 100644
--- a/drivers/net/can/bfin_can.c
+++ b/drivers/net/can/bfin_can.c
@@ -26,6 +26,7 @@
#define DRV_NAME "bfin_can"
#define BFIN_CAN_TIMEOUT 100
+#define TX_ECHO_SKB_MAX 1
/*
* transmit and receive channels
@@ -593,7 +594,7 @@ struct net_device *alloc_bfin_candev(void)
struct net_device *dev;
struct bfin_can_priv *priv;
- dev = alloc_candev(sizeof(*priv));
+ dev = alloc_candev(sizeof(*priv), TX_ECHO_SKB_MAX);
if (!dev)
return NULL;
diff --git a/drivers/net/can/usb/ems_usb.c b/drivers/net/can/usb/ems_usb.c
index 11c87840cc0..33451092b8e 100644
--- a/drivers/net/can/usb/ems_usb.c
+++ b/drivers/net/can/usb/ems_usb.c
@@ -876,9 +876,7 @@ static netdev_tx_t ems_usb_start_xmit(struct sk_buff *skb, struct net_device *ne
return NETDEV_TX_OK;
nomem:
- if (skb)
- dev_kfree_skb(skb);
-
+ dev_kfree_skb(skb);
stats->tx_dropped++;
return NETDEV_TX_OK;
diff --git a/drivers/net/cassini.c b/drivers/net/cassini.c
index 7cbcfb0ade1..9bd155e4111 100644
--- a/drivers/net/cassini.c
+++ b/drivers/net/cassini.c
@@ -5072,7 +5072,7 @@ static int __devinit cas_init_one(struct pci_dev *pdev,
INIT_WORK(&cp->reset_task, cas_reset_task);
/* Default link parameters */
- if (link_mode >= 0 && link_mode <= 6)
+ if (link_mode >= 0 && link_mode < 6)
cp->link_cntl = link_modes[link_mode];
else
cp->link_cntl = BMCR_ANENABLE;
diff --git a/drivers/net/cpmac.c b/drivers/net/cpmac.c
index b85c81f60d1..60777fd90b3 100644
--- a/drivers/net/cpmac.c
+++ b/drivers/net/cpmac.c
@@ -28,6 +28,7 @@
#include <linux/delay.h>
#include <linux/netdevice.h>
+#include <linux/if_vlan.h>
#include <linux/etherdevice.h>
#include <linux/ethtool.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(dumb_switch, "Assume switch is not connected to MDIO bus");
-#define CPMAC_VERSION "0.5.1"
-/* frame size + 802.1q tag */
-#define CPMAC_SKB_SIZE (ETH_FRAME_LEN + 4)
+#define CPMAC_VERSION "0.5.2"
+/* frame size + 802.1q tag + FCS size */
+#define CPMAC_SKB_SIZE (ETH_FRAME_LEN + ETH_FCS_LEN + VLAN_HLEN)
#define CPMAC_QUEUES 8
/* Ethernet registers */
@@ -1136,8 +1137,9 @@ static int __devinit cpmac_probe(struct platform_device *pdev)
}
if (phy_id == PHY_MAX_ADDR) {
- dev_err(&pdev->dev, "no PHY present\n");
- return -ENODEV;
+ dev_err(&pdev->dev, "no PHY present, falling back to switch on MDIO bus 0\n");
+ strncpy(mdio_bus_id, "0", MII_BUS_ID_SIZE); /* fixed phys bus */
+ phy_id = pdev->id;
}
dev = alloc_etherdev_mq(sizeof(*priv), CPMAC_QUEUES);
@@ -1290,8 +1292,8 @@ void __devexit cpmac_exit(void)
{
platform_driver_unregister(&cpmac_driver);
mdiobus_unregister(cpmac_mii);
- mdiobus_free(cpmac_mii);
iounmap(cpmac_mii->priv);
+ mdiobus_free(cpmac_mii);
}
module_init(cpmac_init);
diff --git a/drivers/net/cxgb3/cxgb3_main.c b/drivers/net/cxgb3/cxgb3_main.c
index 6fd968abb07..cecdec1551d 100644
--- a/drivers/net/cxgb3/cxgb3_main.c
+++ b/drivers/net/cxgb3/cxgb3_main.c
@@ -1280,6 +1280,7 @@ static void cxgb_down(struct adapter *adapter)
free_irq_resources(adapter);
quiesce_rx(adapter);
+ t3_sge_stop(adapter);
flush_workqueue(cxgb3_wq); /* wait for external IRQ handler */
}
diff --git a/drivers/net/davinci_emac.c b/drivers/net/davinci_emac.c
index 3f5db83c7cb..32960b9b02a 100644
--- a/drivers/net/davinci_emac.c
+++ b/drivers/net/davinci_emac.c
@@ -62,12 +62,11 @@
#include <linux/bitops.h>
#include <linux/io.h>
#include <linux/uaccess.h>
+#include <linux/davinci_emac.h>
#include <asm/irq.h>
#include <asm/page.h>
-#include <mach/emac.h>
-
static int debug_level;
module_param(debug_level, int, 0);
MODULE_PARM_DESC(debug_level, "DaVinci EMAC debug level (NETIF_MSG bits)");
@@ -465,6 +464,7 @@ struct emac_priv {
void __iomem *ctrl_base;
void __iomem *emac_ctrl_ram;
u32 ctrl_ram_size;
+ u32 hw_ram_addr;
struct emac_txch *txch[EMAC_DEF_MAX_TX_CH];
struct emac_rxch *rxch[EMAC_DEF_MAX_RX_CH];
u32 link; /* 1=link on, 0=link off */
@@ -488,6 +488,9 @@ struct emac_priv {
struct mii_bus *mii_bus;
struct phy_device *phydev;
spinlock_t lock;
+ /*platform specific members*/
+ void (*int_enable) (void);
+ void (*int_disable) (void);
};
/* clock frequency for EMAC */
@@ -495,11 +498,9 @@ static struct clk *emac_clk;
static unsigned long emac_bus_frequency;
static unsigned long mdio_max_freq;
-/* EMAC internal utility function */
-static inline u32 emac_virt_to_phys(void __iomem *addr)
-{
- return (u32 __force) io_v2p(addr);
-}
+#define emac_virt_to_phys(addr, priv) \
+ (((u32 __force)(addr) - (u32 __force)(priv->emac_ctrl_ram)) \
+ + priv->hw_ram_addr)
/* Cache macros - Packet buffers would be from skb pool which is cached */
#define EMAC_VIRT_NOCACHE(addr) (addr)
@@ -1001,6 +1002,8 @@ static void emac_int_disable(struct emac_priv *priv)
emac_ctrl_write(EMAC_DM646X_CMRXINTEN, 0x0);
emac_ctrl_write(EMAC_DM646X_CMTXINTEN, 0x0);
/* NOTE: Rx Threshold and Misc interrupts are not disabled */
+ if (priv->int_disable)
+ priv->int_disable();
local_irq_restore(flags);
@@ -1020,6 +1023,9 @@ static void emac_int_disable(struct emac_priv *priv)
static void emac_int_enable(struct emac_priv *priv)
{
if (priv->version == EMAC_VERSION_2) {
+ if (priv->int_enable)
+ priv->int_enable();
+
emac_ctrl_write(EMAC_DM646X_CMRXINTEN, 0xff);
emac_ctrl_write(EMAC_DM646X_CMTXINTEN, 0xff);
@@ -1301,7 +1307,7 @@ static int emac_tx_bdproc(struct emac_priv *priv, u32 ch, u32 budget)
curr_bd = txch->active_queue_head;
if (NULL == curr_bd) {
emac_write(EMAC_TXCP(ch),
- emac_virt_to_phys(txch->last_hw_bdprocessed));
+ emac_virt_to_phys(txch->last_hw_bdprocessed, priv));
txch->no_active_pkts++;
spin_unlock_irqrestore(&priv->tx_lock, flags);
return 0;
@@ -1311,7 +1317,7 @@ static int emac_tx_bdproc(struct emac_priv *priv, u32 ch, u32 budget)
while ((curr_bd) &&
((frame_status & EMAC_CPPI_OWNERSHIP_BIT) == 0) &&
(pkts_processed < budget)) {
- emac_write(EMAC_TXCP(ch), emac_virt_to_phys(curr_bd));
+ emac_write(EMAC_TXCP(ch), emac_virt_to_phys(curr_bd, priv));
txch->active_queue_head = curr_bd->next;
if (frame_status & EMAC_CPPI_EOQ_BIT) {
if (curr_bd->next) { /* misqueued packet */
@@ -1398,7 +1404,7 @@ static int emac_send(struct emac_priv *priv, struct emac_netpktobj *pkt, u32 ch)
txch->active_queue_tail = curr_bd;
if (1 != txch->queue_active) {
emac_write(EMAC_TXHDP(ch),
- emac_virt_to_phys(curr_bd));
+ emac_virt_to_phys(curr_bd, priv));
txch->queue_active = 1;
}
++txch->queue_reinit;
@@ -1410,10 +1416,11 @@ static int emac_send(struct emac_priv *priv, struct emac_netpktobj *pkt, u32 ch)
tail_bd->next = curr_bd;
txch->active_queue_tail = curr_bd;
tail_bd = EMAC_VIRT_NOCACHE(tail_bd);
- tail_bd->h_next = (int)emac_virt_to_phys(curr_bd);
+ tail_bd->h_next = (int)emac_virt_to_phys(curr_bd, priv);
frame_status = tail_bd->mode;
if (frame_status & EMAC_CPPI_EOQ_BIT) {
- emac_write(EMAC_TXHDP(ch), emac_virt_to_phys(curr_bd));
+ emac_write(EMAC_TXHDP(ch),
+ emac_virt_to_phys(curr_bd, priv));
frame_status &= ~(EMAC_CPPI_EOQ_BIT);
tail_bd->mode = frame_status;
++txch->end_of_queue_add;
@@ -1603,7 +1610,8 @@ static int emac_init_rxch(struct emac_priv *priv, u32 ch, char *param)
}
/* populate the hardware descriptor */
- curr_bd->h_next = emac_virt_to_phys(rxch->active_queue_head);
+ curr_bd->h_next = emac_virt_to_phys(rxch->active_queue_head,
+ priv);
/* FIXME buff_ptr = dma_map_single(... data_ptr ...) */
curr_bd->buff_ptr = virt_to_phys(curr_bd->data_ptr);
curr_bd->off_b_len = rxch->buf_size;
@@ -1878,7 +1886,7 @@ static void emac_addbd_to_rx_queue(struct emac_priv *priv, u32 ch,
rxch->active_queue_tail = curr_bd;
if (0 != rxch->queue_active) {
emac_write(EMAC_RXHDP(ch),
- emac_virt_to_phys(rxch->active_queue_head));
+ emac_virt_to_phys(rxch->active_queue_head, priv));
rxch->queue_active = 1;
}
} else {
@@ -1889,11 +1897,11 @@ static void emac_addbd_to_rx_queue(struct emac_priv *priv, u32 ch,
rxch->active_queue_tail = curr_bd;
tail_bd->next = curr_bd;
tail_bd = EMAC_VIRT_NOCACHE(tail_bd);
- tail_bd->h_next = emac_virt_to_phys(curr_bd);
+ tail_bd->h_next = emac_virt_to_phys(curr_bd, priv);
frame_status = tail_bd->mode;
if (frame_status & EMAC_CPPI_EOQ_BIT) {
emac_write(EMAC_RXHDP(ch),
- emac_virt_to_phys(curr_bd));
+ emac_virt_to_phys(curr_bd, priv));
frame_status &= ~(EMAC_CPPI_EOQ_BIT);
tail_bd->mode = frame_status;
++rxch->end_of_queue_add;
@@ -1986,7 +1994,7 @@ static int emac_rx_bdproc(struct emac_priv *priv, u32 ch, u32 budget)
curr_pkt->num_bufs = 1;
curr_pkt->pkt_length =
(frame_status & EMAC_RX_BD_PKT_LENGTH_MASK);
- emac_write(EMAC_RXCP(ch), emac_virt_to_phys(curr_bd));
+ emac_write(EMAC_RXCP(ch), emac_virt_to_phys(curr_bd, priv));
++rxch->processed_bd;
last_bd = curr_bd;
curr_bd = last_bd->next;
@@ -1997,7 +2005,7 @@ static int emac_rx_bdproc(struct emac_priv *priv, u32 ch, u32 budget)
if (curr_bd) {
++rxch->mis_queued_packets;
emac_write(EMAC_RXHDP(ch),
- emac_virt_to_phys(curr_bd));
+ emac_virt_to_phys(curr_bd, priv));
} else {
++rxch->end_of_queue;
rxch->queue_active = 0;
@@ -2098,7 +2106,7 @@ static int emac_hw_enable(struct emac_priv *priv)
emac_write(EMAC_RXINTMASKSET, BIT(ch));
rxch->queue_active = 1;
emac_write(EMAC_RXHDP(ch),
- emac_virt_to_phys(rxch->active_queue_head));
+ emac_virt_to_phys(rxch->active_queue_head, priv));
}
/* Enable MII */
@@ -2377,7 +2385,7 @@ static int emac_dev_open(struct net_device *ndev)
struct emac_priv *priv = netdev_priv(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];
/* Configuration items */
@@ -2659,6 +2667,9 @@ static int __devinit davinci_emac_probe(struct platform_device *pdev)
priv->phy_mask = pdata->phy_mask;
priv->rmii_en = pdata->rmii_en;
priv->version = pdata->version;
+ priv->int_enable = pdata->interrupt_enable;
+ priv->int_disable = pdata->interrupt_disable;
+
emac_dev = &ndev->dev;
/* Get EMAC platform data */
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -2690,6 +2701,12 @@ static int __devinit davinci_emac_probe(struct platform_device *pdev)
priv->ctrl_ram_size = pdata->ctrl_ram_size;
priv->emac_ctrl_ram = priv->remap_addr + pdata->ctrl_ram_offset;
+ if (pdata->hw_ram_addr)
+ priv->hw_ram_addr = pdata->hw_ram_addr;
+ else
+ priv->hw_ram_addr = (u32 __force)res->start +
+ pdata->ctrl_ram_offset;
+
res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
if (!res) {
dev_err(emac_dev, "DaVinci EMAC: Error getting irq res\n");
diff --git a/drivers/net/e1000e/defines.h b/drivers/net/e1000e/defines.h
index db05ec35574..e301e26d689 100644
--- a/drivers/net/e1000e/defines.h
+++ b/drivers/net/e1000e/defines.h
@@ -320,6 +320,8 @@
#define E1000_RXCSUM_IPPCSE 0x00001000 /* IP payload checksum enable */
/* Header split receive */
+#define E1000_RFCTL_NFSW_DIS 0x00000040
+#define E1000_RFCTL_NFSR_DIS 0x00000080
#define E1000_RFCTL_ACK_DIS 0x00001000
#define E1000_RFCTL_EXTEN 0x00008000
#define E1000_RFCTL_IPV6_EX_DIS 0x00010000
diff --git a/drivers/net/e1000e/ich8lan.c b/drivers/net/e1000e/ich8lan.c
index 54d03a0ce3c..8b5e157e9c8 100644
--- a/drivers/net/e1000e/ich8lan.c
+++ b/drivers/net/e1000e/ich8lan.c
@@ -2740,6 +2740,16 @@ static void e1000_initialize_hw_bits_ich8lan(struct e1000_hw *hw)
reg &= ~(1 << 31);
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;
}
/**
diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c
index 6aa526ee909..c3f061957c0 100644
--- a/drivers/net/gianfar.c
+++ b/drivers/net/gianfar.c
@@ -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 */
- tx_queue->tx_skbuff[tx_queue->skb_curtx] = skb;
txbdp_start->bufPtr = dma_map_single(&priv->ofdev->dev, skb->data,
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;
+ 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
* (wrapping if necessary) */
tx_queue->skb_curtx = (tx_queue->skb_curtx + 1) &
diff --git a/drivers/net/irda/irda-usb.c b/drivers/net/irda/irda-usb.c
index e8e33bb9d87..2c9b3af1661 100644
--- a/drivers/net/irda/irda-usb.c
+++ b/drivers/net/irda/irda-usb.c
@@ -1651,6 +1651,8 @@ static int irda_usb_probe(struct usb_interface *intf,
self->rx_urb = kcalloc(self->max_rx_urb, sizeof(struct urb *),
GFP_KERNEL);
+ if (!self->rx_urb)
+ goto err_free_net;
for (i = 0; i < self->max_rx_urb; i++) {
self->rx_urb[i] = usb_alloc_urb(0, GFP_KERNEL);
@@ -1783,6 +1785,8 @@ err_out_2:
err_out_1:
for (i = 0; i < self->max_rx_urb; i++)
usb_free_urb(self->rx_urb[i]);
+ kfree(self->rx_urb);
+err_free_net:
free_netdev(net);
err_out:
return ret;
diff --git a/drivers/net/qlcnic/qlcnic.h b/drivers/net/qlcnic/qlcnic.h
index b40a851ec7d..0da94b208db 100644
--- a/drivers/net/qlcnic/qlcnic.h
+++ b/drivers/net/qlcnic/qlcnic.h
@@ -423,6 +423,11 @@ struct qlcnic_adapter_stats {
u64 lro_pkts;
u64 rxbytes;
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[] = {
{0x1077, 0x8020, 0x1077, 0x203,
- "8200 Series Single Port 10GbE Converged Network Adapter \
- (TCP/IP Networking)"},
+ "8200 Series Single Port 10GbE Converged Network Adapter "
+ "(TCP/IP Networking)"},
{0x1077, 0x8020, 0x1077, 0x207,
- "8200 Series Dual Port 10GbE Converged Network Adapter \
- (TCP/IP Networking)"},
+ "8200 Series Dual Port 10GbE Converged Network Adapter "
+ "(TCP/IP Networking)"},
{0x1077, 0x8020, 0x1077, 0x20b,
"3200 Series Dual Port 10Gb Intelligent Ethernet Adapter"},
{0x1077, 0x8020, 0x1077, 0x20c,
diff --git a/drivers/net/qlcnic/qlcnic_ethtool.c b/drivers/net/qlcnic/qlcnic_ethtool.c
index 8da6ec8c13b..f83e15fe3e1 100644
--- a/drivers/net/qlcnic/qlcnic_ethtool.c
+++ b/drivers/net/qlcnic/qlcnic_ethtool.c
@@ -59,6 +59,17 @@ static const struct qlcnic_stats qlcnic_gstrings_stats[] = {
QLC_SIZEOF(stats.rxbytes), QLC_OFF(stats.rxbytes)},
{"tx_bytes",
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)
@@ -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)
{
struct qlcnic_adapter *adapter = netdev_priv(dev);
@@ -995,6 +1011,7 @@ const struct ethtool_ops qlcnic_ethtool_ops = {
.set_ringparam = qlcnic_set_ringparam,
.get_pauseparam = qlcnic_get_pauseparam,
.set_pauseparam = qlcnic_set_pauseparam,
+ .get_tx_csum = qlcnic_get_tx_csum,
.set_tx_csum = ethtool_op_set_tx_csum,
.set_sg = ethtool_op_set_sg,
.get_tso = qlcnic_get_tso,
diff --git a/drivers/net/qlcnic/qlcnic_hw.c b/drivers/net/qlcnic/qlcnic_hw.c
index 99a4d1379d0..da00e162b6d 100644
--- a/drivers/net/qlcnic/qlcnic_hw.c
+++ b/drivers/net/qlcnic/qlcnic_hw.c
@@ -349,6 +349,7 @@ qlcnic_send_cmd_descs(struct qlcnic_adapter *adapter,
if (nr_desc >= qlcnic_tx_avail(tx_ring)) {
netif_tx_stop_queue(tx_ring->txq);
__netif_tx_unlock_bh(tx_ring->txq);
+ adapter->stats.xmit_off++;
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);
}
-static int qlcnic_nic_add_mac(struct qlcnic_adapter *adapter,
- u8 *addr, struct list_head *del_list)
+static int qlcnic_nic_add_mac(struct qlcnic_adapter *adapter, u8 *addr)
{
struct list_head *head;
struct qlcnic_mac_list_s *cur;
/* 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);
-
- if (memcmp(addr, cur->mac_addr, ETH_ALEN) == 0) {
- list_move_tail(head, &adapter->mac_list);
+ if (memcmp(addr, cur->mac_addr, ETH_ALEN) == 0)
return 0;
- }
}
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;
u8 bcast_addr[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
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, &del_list);
- qlcnic_nic_add_mac(adapter, bcast_addr, &del_list);
+ qlcnic_nic_add_mac(adapter, adapter->mac_addr);
+ qlcnic_nic_add_mac(adapter, bcast_addr);
if (netdev->flags & IFF_PROMISC) {
mode = VPORT_MISS_MODE_ACCEPT_ALL;
@@ -454,22 +446,12 @@ void qlcnic_set_multi(struct net_device *netdev)
if (!netdev_mc_empty(netdev)) {
netdev_for_each_mc_addr(mc_ptr, netdev) {
- qlcnic_nic_add_mac(adapter, mc_ptr->dmi_addr,
- &del_list);
+ qlcnic_nic_add_mac(adapter, mc_ptr->dmi_addr);
}
}
send_fw_cmd:
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)
diff --git a/drivers/net/qlcnic/qlcnic_init.c b/drivers/net/qlcnic/qlcnic_init.c
index ea00ab4d4fe..7c34e4e29b3 100644
--- a/drivers/net/qlcnic/qlcnic_init.c
+++ b/drivers/net/qlcnic/qlcnic_init.c
@@ -568,21 +568,123 @@ struct uni_table_desc *qlcnic_get_table_desc(const u8 *unirom, int section)
return NULL;
}
+#define FILEHEADER_SIZE (14 * 4)
+
static int
-qlcnic_set_product_offs(struct qlcnic_adapter *adapter)
+qlcnic_validate_header(struct qlcnic_adapter *adapter)
{
- struct uni_table_desc *ptab_descr;
const u8 *unirom = adapter->fw->data;
- u32 i;
+ 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;
+ const u8 *unirom = adapter->fw->data;
int mn_present = qlcnic_has_mn(adapter);
+ __le32 entries;
+ __le32 entry_size;
+ __le32 tab_size;
+ u32 i;
ptab_descr = qlcnic_get_table_desc(unirom,
QLCNIC_UNI_DIR_SECT_PRODUCT_TBL);
- if (ptab_descr == NULL)
- return -1;
+ if (!ptab_descr)
+ return -EINVAL;
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:
for (i = 0; i < entries; i++) {
@@ -609,7 +711,37 @@ nomn:
mn_present = 0;
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
@@ -715,7 +847,7 @@ qlcnic_get_bios_version(struct qlcnic_adapter *adapter)
bios_ver = cpu_to_le32(*((u32 *) (&fw->data[prd_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
@@ -858,7 +990,7 @@ qlcnic_validate_firmware(struct qlcnic_adapter *adapter)
u8 fw_type = adapter->fw_type;
if (fw_type == QLCNIC_UNIFIED_ROMIMAGE) {
- if (qlcnic_set_product_offs(adapter))
+ if (qlcnic_validate_unified_romimage(adapter))
return -EINVAL;
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;
buffer->skb = dev_alloc_skb(rds_ring->skb_size);
- if (!buffer->skb)
+ if (!buffer->skb) {
+ adapter->stats.skb_alloc_failure++;
return -ENOMEM;
+ }
skb = buffer->skb;
@@ -1289,7 +1423,7 @@ qlcnic_process_lro(struct qlcnic_adapter *adapter,
netif_receive_skb(skb);
adapter->stats.lro_pkts++;
- adapter->stats.rxbytes += length;
+ adapter->stats.lrobytes += length;
return buffer;
}
@@ -1505,6 +1639,8 @@ qlcnic_process_rcv_diag(struct qlcnic_adapter *adapter,
adapter->diag_cnt++;
dev_kfree_skb_any(skb);
+ adapter->stats.rx_pkts++;
+ adapter->stats.rxbytes += length;
return buffer;
}
diff --git a/drivers/net/qlcnic/qlcnic_main.c b/drivers/net/qlcnic/qlcnic_main.c
index 665e8e56b6a..fc721564e69 100644
--- a/drivers/net/qlcnic/qlcnic_main.c
+++ b/drivers/net/qlcnic/qlcnic_main.c
@@ -118,6 +118,7 @@ qlcnic_update_cmd_producer(struct qlcnic_adapter *adapter,
if (qlcnic_tx_avail(tx_ring) <= TX_STOP_THRESH) {
netif_stop_queue(adapter->netdev);
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;
struct cmd_desc_type0 *hwdesc;
struct vlan_ethhdr *vh;
+ struct qlcnic_adapter *adapter = netdev_priv(netdev);
if (protocol == cpu_to_be16(ETH_P_8021Q)) {
@@ -1494,6 +1496,7 @@ qlcnic_tso_check(struct net_device *netdev,
tx_ring->producer = producer;
barrier();
+ adapter->stats.lso_frames++;
}
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))) {
netif_stop_queue(netdev);
+ adapter->stats.xmit_off++;
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) {
netif_wake_queue(netdev);
adapter->tx_timeo_cnt = 0;
+ adapter->stats.xmit_on++;
}
__netif_tx_unlock(tx_ring->txq);
}
diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
index dfc3573c91b..9d3ebf3e975 100644
--- a/drivers/net/r8169.c
+++ b/drivers/net/r8169.c
@@ -4270,7 +4270,7 @@ static netdev_tx_t rtl8169_start_xmit(struct sk_buff *skb,
tp->cur_tx += frags + 1;
- smp_wmb();
+ wmb();
RTL_W8(TxPoll, NPQ); /* set polling bit */
@@ -4621,7 +4621,7 @@ static int rtl8169_poll(struct napi_struct *napi, int budget)
* until it does.
*/
tp->intr_mask = 0xffff;
- smp_wmb();
+ wmb();
RTL_W16(IntrMask, tp->intr_event);
}
diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c
index 43bc66aa840..df70657260d 100644
--- a/drivers/net/s2io.c
+++ b/drivers/net/s2io.c
@@ -923,8 +923,8 @@ static int init_shared_mem(struct s2io_nic *nic)
tmp_v_addr = mac_control->stats_mem;
mac_control->stats_info = (struct stat_block *)tmp_v_addr;
memset(tmp_v_addr, 0, size);
- DBG_PRINT(INIT_DBG, "%s: Ring Mem PHY: 0x%llx\n", dev->name,
- (unsigned long long)tmp_p_addr);
+ DBG_PRINT(INIT_DBG, "%s: Ring Mem PHY: 0x%llx\n",
+ dev_name(&nic->pdev->dev), (unsigned long long)tmp_p_addr);
mac_control->stats_info->sw_stat.mem_allocated += mem_allocated;
return SUCCESS;
}
@@ -3480,7 +3480,7 @@ static void s2io_reset(struct s2io_nic *sp)
struct swStat *swstats;
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 */
pci_read_config_word(sp->pdev, PCIX_COMMAND_REGISTER, &(pci_cmd));
diff --git a/drivers/net/smc911x.h b/drivers/net/smc911x.h
index 05adb6a666c..3269292efec 100644
--- a/drivers/net/smc911x.h
+++ b/drivers/net/smc911x.h
@@ -42,12 +42,12 @@
#define SMC_USE_16BIT 0
#define SMC_USE_32BIT 1
#define SMC_IRQ_SENSE IRQF_TRIGGER_LOW
-#elif defined(CONFIG_ARCH_OMAP34XX)
+#elif defined(CONFIG_ARCH_OMAP3)
#define SMC_USE_16BIT 0
#define SMC_USE_32BIT 1
#define SMC_IRQ_SENSE IRQF_TRIGGER_LOW
#define SMC_MEM_RESERVED 1
-#elif defined(CONFIG_ARCH_OMAP24XX)
+#elif defined(CONFIG_ARCH_OMAP2)
#define SMC_USE_16BIT 0
#define SMC_USE_32BIT 1
#define SMC_IRQ_SENSE IRQF_TRIGGER_LOW
diff --git a/drivers/net/smc91x.h b/drivers/net/smc91x.h
index 54799544bda..a6ee883d1b0 100644
--- a/drivers/net/smc91x.h
+++ b/drivers/net/smc91x.h
@@ -330,6 +330,20 @@ static inline void LPD7_SMC_outsw (unsigned char* a, int r,
#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
+
#else
/*
diff --git a/drivers/net/typhoon.c b/drivers/net/typhoon.c
index e3ddcb8f29d..1cf012d3e07 100644
--- a/drivers/net/typhoon.c
+++ b/drivers/net/typhoon.c
@@ -480,7 +480,7 @@ typhoon_hello(struct typhoon *tp)
typhoon_inc_cmd_index(&ring->lastWrite, 1);
INIT_COMMAND_NO_RESPONSE(cmd, TYPHOON_CMD_HELLO_RESP);
- smp_wmb();
+ wmb();
iowrite32(ring->lastWrite, tp->ioaddr + TYPHOON_REG_CMD_READY);
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->card_state = Sleeping;
- smp_wmb();
tp->offload = TYPHOON_OFFLOAD_IP_CHKSUM | TYPHOON_OFFLOAD_TCP_CHKSUM;
tp->offload |= TYPHOON_OFFLOAD_UDP_CHKSUM | TSO_OFFLOAD_ON;
spin_lock_init(&tp->command_lock);
spin_lock_init(&tp->state_lock);
+
+ /* Force the writes to the shared memory area out before continuing. */
+ wmb();
}
static void
diff --git a/drivers/net/usb/pegasus.h b/drivers/net/usb/pegasus.h
index 5d02f020073..b90d8766ab7 100644
--- a/drivers/net/usb/pegasus.h
+++ b/drivers/net/usb/pegasus.h
@@ -177,7 +177,7 @@ PEGASUS_DEV( "USB 10/100 Fast Ethernet", VENDOR_ABOCOM, 0x400c,
PEGASUS_DEV( "USB 10/100 Fast Ethernet", VENDOR_ABOCOM, 0xabc1,
DEFAULT_GPIO_RESET )
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,
DEFAULT_GPIO_RESET )
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,
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,
DEFAULT_GPIO_RESET )
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,
DEFAULT_GPIO_RESET | PEGASUS_II )
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,
DEFAULT_GPIO_RESET )
PEGASUS_DEV( "IO DATA USB ET/TX-S", VENDOR_IODATA, 0x0913,
diff --git a/drivers/net/wireless/ath/ar9170/usb.c b/drivers/net/wireless/ath/ar9170/usb.c
index 4e30197afff..6b1cb706e41 100644
--- a/drivers/net/wireless/ath/ar9170/usb.c
+++ b/drivers/net/wireless/ath/ar9170/usb.c
@@ -94,6 +94,8 @@ static struct usb_device_id ar9170_usb_ids[] = {
{ USB_DEVICE(0x04bb, 0x093f) },
/* AVM FRITZ!WLAN USB Stick N */
{ USB_DEVICE(0x057C, 0x8401) },
+ /* NEC WL300NU-G */
+ { USB_DEVICE(0x0409, 0x0249) },
/* AVM FRITZ!WLAN USB Stick N 2.4 */
{ USB_DEVICE(0x057C, 0x8402), .driver_info = AR9170_REQ_FW1_ONLY },
@@ -416,7 +418,7 @@ static int ar9170_usb_exec_cmd(struct ar9170 *ar, enum ar9170_cmd cmd,
spin_unlock_irqrestore(&aru->common.cmdlock, flags);
usb_fill_int_urb(urb, aru->udev,
- usb_sndbulkpipe(aru->udev, AR9170_EP_CMD),
+ usb_sndintpipe(aru->udev, AR9170_EP_CMD),
aru->common.cmdbuf, plen + 4,
ar9170_usb_tx_urb_complete, NULL, 1);
diff --git a/drivers/net/wireless/ath/ath5k/eeprom.c b/drivers/net/wireless/ath/ath5k/eeprom.c
index 86654b9e109..a3cbfe4fc38 100644
--- a/drivers/net/wireless/ath/ath5k/eeprom.c
+++ b/drivers/net/wireless/ath/ath5k/eeprom.c
@@ -431,8 +431,8 @@ static int ath5k_eeprom_read_modes(struct ath5k_hw *ah, u32 *offset,
ee->ee_margin_tx_rx[mode] = (val >> 8) & 0x3f;
AR5K_EEPROM_READ(o++, val);
- ee->ee_i_cal[mode] = (val >> 8) & 0x3f;
- ee->ee_q_cal[mode] = (val >> 3) & 0x1f;
+ ee->ee_i_cal[mode] = (val >> 5) & 0x3f;
+ ee->ee_q_cal[mode] = val & 0x1f;
if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_2) {
AR5K_EEPROM_READ(o++, val);
diff --git a/drivers/net/wireless/ath/ath5k/phy.c b/drivers/net/wireless/ath/ath5k/phy.c
index cb569dbffa6..b6704c93f80 100644
--- a/drivers/net/wireless/ath/ath5k/phy.c
+++ b/drivers/net/wireless/ath/ath5k/phy.c
@@ -1362,10 +1362,16 @@ static int ath5k_hw_rf511x_calibrate(struct ath5k_hw *ah,
goto done;
/* 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++) {
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);
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;
@@ -1375,32 +1381,24 @@ static int ath5k_hw_rf511x_calibrate(struct ath5k_hw *ah,
else
q_coffd = q_pwr >> 7;
- /* No correction */
- if (i_coffd == 0 || q_coffd == 0)
+ /* protect against divide by 0 and loss of sign bits */
+ if (i_coffd == 0 || q_coffd < 2)
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 */
- if (i_coff > 31)
- i_coff = 31;
- if (i_coff < -32)
- i_coff = -32;
-
- if (ah->ah_version == AR5K_AR5211)
- q_coff = (i_pwr / q_coffd) - 64;
- else
- q_coff = (i_pwr / q_coffd) - 128;
+ q_coff = (i_pwr / q_coffd) - 128;
+ q_coff = clamp(q_coff, -16, 15); /* signed 5 bit */
- /* Boundary check */
- if (q_coff > 15)
- q_coff = 15;
- if (q_coff < -16)
- q_coff = -16;
+ 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);
- /* 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));
+ /* Commit new I/Q values (set enable bit last to match HAL sources) */
+ AR5K_REG_WRITE_BITS(ah, AR5K_PHY_IQ, AR5K_PHY_IQ_CORR_Q_I_COFF, i_coff);
+ AR5K_REG_WRITE_BITS(ah, AR5K_PHY_IQ, AR5K_PHY_IQ_CORR_Q_Q_COFF, q_coff);
+ AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_IQ, AR5K_PHY_IQ_CORR_ENABLE);
/* Re-enable calibration -if we don't we'll commit
* the same values again and again */
@@ -1846,7 +1844,7 @@ ath5k_hw_set_antenna_mode(struct ath5k_hw *ah, u8 ant_mode)
break;
case AR5K_ANTMODE_FIXED_A:
def_ant = 1;
- tx_ant = 0;
+ tx_ant = 1;
use_def_for_tx = true;
update_def_on_tx = false;
use_def_for_rts = true;
@@ -1855,7 +1853,7 @@ ath5k_hw_set_antenna_mode(struct ath5k_hw *ah, u8 ant_mode)
break;
case AR5K_ANTMODE_FIXED_B:
def_ant = 2;
- tx_ant = 0;
+ tx_ant = 2;
use_def_for_tx = true;
update_def_on_tx = false;
use_def_for_rts = true;
diff --git a/drivers/net/wireless/ath/ath5k/reg.h b/drivers/net/wireless/ath/ath5k/reg.h
index cbd11d4c98e..45d62e915e4 100644
--- a/drivers/net/wireless/ath/ath5k/reg.h
+++ b/drivers/net/wireless/ath/ath5k/reg.h
@@ -2203,6 +2203,7 @@
*/
#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_S 0
#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_ENABLE 0x00000800 /* Enable i/q correction */
diff --git a/drivers/net/wireless/ath/ath5k/reset.c b/drivers/net/wireless/ath/ath5k/reset.c
index 4120068792e..44bbbf2a6ed 100644
--- a/drivers/net/wireless/ath/ath5k/reset.c
+++ b/drivers/net/wireless/ath/ath5k/reset.c
@@ -870,12 +870,15 @@ static void ath5k_hw_commit_eeprom_settings(struct ath5k_hw *ah,
AR5K_PHY_OFDM_SELFCORR_CYPWR_THR1,
AR5K_INIT_CYCRSSI_THR1);
- /* I/Q correction
- * TODO: Per channel i/q infos ? */
- AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_IQ,
- AR5K_PHY_IQ_CORR_ENABLE |
- (ee->ee_i_cal[ee_mode] << AR5K_PHY_IQ_CORR_Q_I_COFF_S) |
- ee->ee_q_cal[ee_mode]);
+ /* I/Q correction (set enable bit last to match HAL sources) */
+ /* TODO: Per channel i/q infos ? */
+ if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_0) {
+ AR5K_REG_WRITE_BITS(ah, AR5K_PHY_IQ, AR5K_PHY_IQ_CORR_Q_I_COFF,
+ ee->ee_i_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 */
if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_5_1)
@@ -1393,10 +1396,9 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
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_BEACON_RESET_TSF);
-
+ AR5K_REG_DISABLE_BITS(ah, AR5K_BEACON, AR5K_BEACON_ENABLE);
+ ath5k_hw_reset_tsf(ah);
return 0;
}
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index c25216be616..f7ef11407e2 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -1534,8 +1534,7 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
all_wiphys_idle = ath9k_all_wiphys_idle(sc);
ath9k_set_wiphy_idle(aphy, idle);
- if (!idle && all_wiphys_idle)
- enable_radio = true;
+ enable_radio = (!idle && all_wiphys_idle);
/*
* After we unlock here its possible another wiphy
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
index b632c803ee1..02df4cbf179 100644
--- a/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
@@ -1359,25 +1359,6 @@ static enum ath9k_pkt_type get_hw_packet_type(struct sk_buff *skb)
return htype;
}
-static bool is_pae(struct sk_buff *skb)
-{
- struct ieee80211_hdr *hdr;
- __le16 fc;
-
- hdr = (struct ieee80211_hdr *)skb->data;
- fc = hdr->frame_control;
-
- if (ieee80211_is_data(fc)) {
- if (ieee80211_is_nullfunc(fc) ||
- /* Port Access Entity (IEEE 802.1X) */
- (skb->protocol == cpu_to_be16(ETH_P_PAE))) {
- return true;
- }
- }
-
- return false;
-}
-
static int get_hw_crypto_keytype(struct sk_buff *skb)
{
struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
@@ -1702,7 +1683,7 @@ static void ath_tx_start_dma(struct ath_softc *sc, struct ath_buf *bf,
goto tx_done;
}
- if ((tx_info->flags & IEEE80211_TX_CTL_AMPDU) && !is_pae(skb)) {
+ if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) {
/*
* Try aggregation if it's a unicast data frame
* and the destination is HT capable.
diff --git a/drivers/net/wireless/ipw2x00/ipw2200.c b/drivers/net/wireless/ipw2x00/ipw2200.c
index 192abfdc503..9e2ae8f3ecb 100644
--- a/drivers/net/wireless/ipw2x00/ipw2200.c
+++ b/drivers/net/wireless/ipw2x00/ipw2200.c
@@ -3186,14 +3186,27 @@ static int ipw_load_firmware(struct ipw_priv *priv, u8 * data, size_t len)
int total_nr = 0;
int i;
struct pci_pool *pool;
- u32 *virts[CB_NUMBER_OF_ELEMENTS_SMALL];
- dma_addr_t phys[CB_NUMBER_OF_ELEMENTS_SMALL];
+ void **virts;
+ dma_addr_t *phys;
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);
if (!pool) {
IPW_ERROR("pci_pool_create failed\n");
+ kfree(phys);
+ kfree(virts);
return -ENOMEM;
}
@@ -3263,6 +3276,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_destroy(pool);
+ kfree(phys);
+ kfree(virts);
return ret;
}
diff --git a/drivers/net/wireless/ipw2x00/libipw.h b/drivers/net/wireless/ipw2x00/libipw.h
index 9ac136b98bb..284b0e4cb81 100644
--- a/drivers/net/wireless/ipw2x00/libipw.h
+++ b/drivers/net/wireless/ipw2x00/libipw.h
@@ -797,7 +797,7 @@ struct libipw_device {
/* Probe / Beacon management */
struct list_head network_free_list;
struct list_head network_list;
- struct libipw_network *networks;
+ struct libipw_network *networks[MAX_NETWORK_COUNT];
int scans;
int scan_age;
diff --git a/drivers/net/wireless/ipw2x00/libipw_module.c b/drivers/net/wireless/ipw2x00/libipw_module.c
index 5b8841159b7..55965408ff3 100644
--- a/drivers/net/wireless/ipw2x00/libipw_module.c
+++ b/drivers/net/wireless/ipw2x00/libipw_module.c
@@ -67,16 +67,17 @@ void *libipw_wiphy_privid = &libipw_wiphy_privid;
static int libipw_networks_allocate(struct libipw_device *ieee)
{
- if (ieee->networks)
- return 0;
-
- ieee->networks =
- kzalloc(MAX_NETWORK_COUNT * sizeof(struct libipw_network),
- GFP_KERNEL);
- if (!ieee->networks) {
- printk(KERN_WARNING "%s: Out of memory allocating beacons\n",
- ieee->dev->name);
- return -ENOMEM;
+ int i, j;
+
+ for (i = 0; i < MAX_NETWORK_COUNT; i++) {
+ ieee->networks[i] = kzalloc(sizeof(struct libipw_network),
+ GFP_KERNEL);
+ if (!ieee->networks[i]) {
+ LIBIPW_ERROR("Out of memory allocating beacons\n");
+ for (j = 0; j < i; j++)
+ kfree(ieee->networks[j]);
+ return -ENOMEM;
+ }
}
return 0;
@@ -97,15 +98,11 @@ static inline void libipw_networks_free(struct libipw_device *ieee)
{
int i;
- if (!ieee->networks)
- return;
-
- for (i = 0; i < MAX_NETWORK_COUNT; i++)
- if (ieee->networks[i].ibss_dfs)
- kfree(ieee->networks[i].ibss_dfs);
-
- kfree(ieee->networks);
- ieee->networks = NULL;
+ for (i = 0; i < MAX_NETWORK_COUNT; i++) {
+ if (ieee->networks[i]->ibss_dfs)
+ kfree(ieee->networks[i]->ibss_dfs);
+ kfree(ieee->networks[i]);
+ }
}
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_list);
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);
}
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c
index e81577b1a25..f88f75dfd96 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945.c
@@ -184,7 +184,7 @@ static int iwl3945_hwrate_to_plcp_idx(u8 plcp)
{
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)
return idx;
return -1;
@@ -755,7 +755,7 @@ void iwl3945_hw_build_tx_cmd_rate(struct iwl_priv *priv,
int sta_id, int tx_id)
{
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;
int rate;
u8 rts_retry_limit;
@@ -2088,7 +2088,7 @@ static void iwl3945_hw_reg_init_channel_groups(struct iwl_priv *priv)
/* fill in channel group's nominal powers for each rate */
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) {
case IWL_RATE_36M_INDEX_TABLE:
if (i == 0) /* B/G */
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c
index 9a220d41544..6edae9b83bb 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965.c
+++ b/drivers/net/wireless/iwlwifi/iwl-4965.c
@@ -2040,16 +2040,14 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv,
tx_resp->failure_frame);
freed = iwlagn_tx_queue_reclaim(priv, txq_id, index);
- if (qc && likely(sta_id != IWL_INVALID_STATION))
- priv->stations[sta_id].tid[tid].tfds_in_queue -= freed;
+ iwl_free_tfds_in_queue(priv, sta_id, tid, freed);
if (priv->mac80211_registered &&
(iwl_queue_space(&txq->q) > txq->q.low_mark))
iwl_wake_queue(priv, txq_id);
}
- if (qc && likely(sta_id != IWL_INVALID_STATION))
- iwlagn_txq_check_empty(priv, sta_id, tid, txq_id);
+ iwlagn_txq_check_empty(priv, sta_id, tid, txq_id);
if (iwl_check_bits(status, TX_ABORT_REQUIRED_MSK))
IWL_ERR(priv, "TODO: Implement Tx ABORT REQUIRED!!!\n");
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
index 0f881947627..0c3c76803c5 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
@@ -345,6 +345,17 @@ static inline int get_num_of_ant_from_rate(u32 rate_n_flags)
!!(rate_n_flags & RATE_MCS_ANT_C_MSK);
}
+/*
+ * Static function to get the expected throughput from an iwl_scale_tbl_info
+ * that wraps a NULL pointer check
+ */
+static s32 get_expected_tpt(struct iwl_scale_tbl_info *tbl, int rs_index)
+{
+ if (tbl->expected_tpt)
+ return tbl->expected_tpt[rs_index];
+ return 0;
+}
+
/**
* rs_collect_tx_data - Update the success/failure sliding window
*
@@ -352,19 +363,21 @@ static inline int get_num_of_ant_from_rate(u32 rate_n_flags)
* at this rate. window->data contains the bitmask of successful
* packets.
*/
-static int rs_collect_tx_data(struct iwl_rate_scale_data *windows,
- int scale_index, s32 tpt, int attempts,
- int successes)
+static int rs_collect_tx_data(struct iwl_scale_tbl_info *tbl,
+ int scale_index, int attempts, int successes)
{
struct iwl_rate_scale_data *window = NULL;
static const u64 mask = (((u64)1) << (IWL_RATE_MAX_WINDOW - 1));
- s32 fail_count;
+ s32 fail_count, tpt;
if (scale_index < 0 || scale_index >= IWL_RATE_COUNT)
return -EINVAL;
/* Select window for current tx bit rate */
- window = &(windows[scale_index]);
+ window = &(tbl->win[scale_index]);
+
+ /* Get expected throughput */
+ tpt = get_expected_tpt(tbl, scale_index);
/*
* Keep track of only the latest 62 tx frame attempts in this rate's
@@ -734,16 +747,6 @@ static bool table_type_matches(struct iwl_scale_tbl_info *a,
return (a->lq_type == b->lq_type) && (a->ant_type == b->ant_type) &&
(a->is_SGI == b->is_SGI);
}
-/*
- * Static function to get the expected throughput from an iwl_scale_tbl_info
- * that wraps a NULL pointer check
- */
-static s32 get_expected_tpt(struct iwl_scale_tbl_info *tbl, int rs_index)
-{
- if (tbl->expected_tpt)
- return tbl->expected_tpt[rs_index];
- return 0;
-}
/*
* mac80211 sends us Tx status
@@ -760,12 +763,10 @@ static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband,
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
struct iwl_priv *priv = (struct iwl_priv *)priv_r;
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
- struct iwl_rate_scale_data *window = NULL;
enum mac80211_rate_control_flags mac_flags;
u32 tx_rate;
struct iwl_scale_tbl_info tbl_type;
- struct iwl_scale_tbl_info *curr_tbl, *other_tbl;
- s32 tpt = 0;
+ struct iwl_scale_tbl_info *curr_tbl, *other_tbl, *tmp_tbl;
IWL_DEBUG_RATE_LIMIT(priv, "get frame ack response, update rate scale window\n");
@@ -853,7 +854,6 @@ static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband,
IWL_DEBUG_RATE(priv, "Neither active nor search matches tx rate\n");
return;
}
- window = (struct iwl_rate_scale_data *)&(curr_tbl->win[0]);
/*
* Updating the frame history depends on whether packets were
@@ -866,8 +866,7 @@ static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband,
tx_rate = le32_to_cpu(table->rs_table[0].rate_n_flags);
rs_get_tbl_info_from_mcs(tx_rate, priv->band, &tbl_type,
&rs_index);
- tpt = get_expected_tpt(curr_tbl, rs_index);
- rs_collect_tx_data(window, rs_index, tpt,
+ rs_collect_tx_data(curr_tbl, rs_index,
info->status.ampdu_ack_len,
info->status.ampdu_ack_map);
@@ -897,19 +896,13 @@ static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband,
* table as active/search.
*/
if (table_type_matches(&tbl_type, curr_tbl))
- tpt = get_expected_tpt(curr_tbl, rs_index);
+ tmp_tbl = curr_tbl;
else if (table_type_matches(&tbl_type, other_tbl))
- tpt = get_expected_tpt(other_tbl, rs_index);
+ tmp_tbl = other_tbl;
else
continue;
-
- /* Constants mean 1 transmission, 0 successes */
- if (i < retries)
- rs_collect_tx_data(window, rs_index, tpt, 1,
- 0);
- else
- rs_collect_tx_data(window, rs_index, tpt, 1,
- legacy_success);
+ rs_collect_tx_data(tmp_tbl, rs_index, 1,
+ i < retries ? 0 : legacy_success);
}
/* Update success/fail counts if not searching for new mode */
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index 629cbf38aa9..4f0cb803f73 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -1229,7 +1229,15 @@ static void iwl_irq_tasklet(struct iwl_priv *priv)
/* Ack/clear/reset pending uCode interrupts.
* Note: Some bits in CSR_INT are "OR" of bits in CSR_FH_INT_STATUS,
*/
- iwl_write32(priv, CSR_INT, priv->_agn.inta);
+ /* There is a hardware bug in the interrupt mask function that some
+ * interrupts (i.e. CSR_INT_BIT_SCD) can still be generated even if
+ * they are disabled in the CSR_INT_MASK register. Furthermore the
+ * ICT interrupt handling mechanism has another bug that might cause
+ * these unmasked interrupts fail to be detected. We workaround the
+ * hardware bugs here by ACKing all the possible interrupts so that
+ * interrupt coalescing can still be achieved.
+ */
+ iwl_write32(priv, CSR_INT, priv->_agn.inta | ~priv->inta_mask);
inta = priv->_agn.inta;
@@ -2653,7 +2661,7 @@ static int iwl_mac_setup_register(struct iwl_priv *priv)
BIT(NL80211_IFTYPE_STATION) |
BIT(NL80211_IFTYPE_ADHOC);
- hw->wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY |
+ hw->wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY |
WIPHY_FLAG_DISABLE_BEACON_HINTS;
/*
@@ -2662,7 +2670,7 @@ static int iwl_mac_setup_register(struct iwl_priv *priv)
*/
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 */
hw->wiphy->max_scan_ie_len = IWL_MAX_PROBE_REQUEST - 24 - 2;
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h
index bc04b43cad3..10f95724536 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.h
+++ b/drivers/net/wireless/iwlwifi/iwl-core.h
@@ -458,6 +458,8 @@ void iwl_free_tfds_in_queue(struct iwl_priv *priv,
void iwl_txq_update_write_ptr(struct iwl_priv *priv, struct iwl_tx_queue *txq);
int iwl_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq,
int slots_num, u32 txq_id);
+void iwl_tx_queue_reset(struct iwl_priv *priv, struct iwl_tx_queue *txq,
+ int slots_num, u32 txq_id);
void iwl_tx_queue_free(struct iwl_priv *priv, int txq_id);
/*****************************************************
* TX power
diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c
index 0daa1c9f1c6..d817c9c184a 100644
--- a/drivers/net/wireless/iwlwifi/iwl-scan.c
+++ b/drivers/net/wireless/iwlwifi/iwl-scan.c
@@ -637,20 +637,9 @@ u16 iwl_fill_probe_req(struct iwl_priv *priv, struct ieee80211_mgmt *frame,
if (left < 0)
return 0;
*pos++ = WLAN_EID_SSID;
- if (!priv->is_internal_short_scan &&
- priv->scan_request->n_ssids) {
- struct cfg80211_ssid *ssid =
- priv->scan_request->ssids;
-
- /* Broadcast if ssid_len is 0 */
- *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;
- }
+ *pos++ = 0;
+
+ len += 2;
if (WARN_ON(left < ie_len))
return len;
@@ -778,26 +767,20 @@ static void iwl_bg_request_scan(struct work_struct *data)
if (priv->is_internal_short_scan) {
IWL_DEBUG_SCAN(priv, "Start internal passive scan.\n");
} else if (priv->scan_request->n_ssids) {
+ int i, p = 0;
IWL_DEBUG_SCAN(priv, "Kicking off active scan\n");
- /*
- * The first SSID to scan is stuffed into the probe request
- * template and the remaining ones are handled through the
- * direct_scan array.
- */
- if (priv->scan_request->n_ssids > 1) {
- int i, p = 0;
- for (i = 1; i < priv->scan_request->n_ssids; i++) {
- if (!priv->scan_request->ssids[i].ssid_len)
- continue;
- scan->direct_scan[p].id = WLAN_EID_SSID;
- scan->direct_scan[p].len =
- 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++;
- }
+ for (i = 0; i < priv->scan_request->n_ssids; i++) {
+ /* always does wildcard anyway */
+ if (!priv->scan_request->ssids[i].ssid_len)
+ continue;
+ scan->direct_scan[p].id = WLAN_EID_SSID;
+ scan->direct_scan[p].len =
+ 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;
} else
diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c
index 65090d386a5..a631afef5e3 100644
--- a/drivers/net/wireless/iwlwifi/iwl-tx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-tx.c
@@ -83,7 +83,7 @@ void iwl_free_tfds_in_queue(struct iwl_priv *priv,
if (priv->stations[sta_id].tid[tid].tfds_in_queue >= freed)
priv->stations[sta_id].tid[tid].tfds_in_queue -= freed;
else {
- IWL_ERR(priv, "free more than tfds_in_queue (%u:%d)\n",
+ IWL_DEBUG_TX(priv, "free more than tfds_in_queue (%u:%d)\n",
priv->stations[sta_id].tid[tid].tfds_in_queue,
freed);
priv->stations[sta_id].tid[tid].tfds_in_queue = 0;
@@ -152,10 +152,34 @@ void iwl_cmd_queue_free(struct iwl_priv *priv)
struct iwl_queue *q = &txq->q;
struct device *dev = &priv->pci_dev->dev;
int i;
+ bool huge = false;
if (q->n_bd == 0)
return;
+ for (; q->read_ptr != q->write_ptr;
+ q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd)) {
+ /* we have no way to tell if it is a huge cmd ATM */
+ i = get_cmd_index(q, q->read_ptr, 0);
+
+ if (txq->meta[i].flags & CMD_SIZE_HUGE) {
+ huge = true;
+ continue;
+ }
+
+ pci_unmap_single(priv->pci_dev,
+ pci_unmap_addr(&txq->meta[i], mapping),
+ pci_unmap_len(&txq->meta[i], len),
+ PCI_DMA_BIDIRECTIONAL);
+ }
+ if (huge) {
+ i = q->n_window;
+ pci_unmap_single(priv->pci_dev,
+ pci_unmap_addr(&txq->meta[i], mapping),
+ pci_unmap_len(&txq->meta[i], len),
+ PCI_DMA_BIDIRECTIONAL);
+ }
+
/* De-alloc array of command/tx buffers */
for (i = 0; i <= TFD_CMD_SLOTS; i++)
kfree(txq->cmd[i]);
@@ -424,6 +448,14 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
spin_lock_irqsave(&priv->hcmd_lock, flags);
+ /* If this is a huge cmd, mark the huge flag also on the meta.flags
+ * of the _original_ cmd. This is used for DMA mapping clean up.
+ */
+ if (cmd->flags & CMD_SIZE_HUGE) {
+ idx = get_cmd_index(q, q->write_ptr, 0);
+ txq->meta[idx].flags = CMD_SIZE_HUGE;
+ }
+
idx = get_cmd_index(q, q->write_ptr, cmd->flags & CMD_SIZE_HUGE);
out_cmd = txq->cmd[idx];
out_meta = &txq->meta[idx];
@@ -546,6 +578,7 @@ void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
bool huge = !!(pkt->hdr.sequence & SEQ_HUGE_FRAME);
struct iwl_device_cmd *cmd;
struct iwl_cmd_meta *meta;
+ struct iwl_tx_queue *txq = &priv->txq[IWL_CMD_QUEUE_NUM];
/* If a Tx command is being handled and it isn't in the actual
* command queue then there a command routing bug has been introduced
@@ -559,9 +592,17 @@ void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
return;
}
- cmd_index = get_cmd_index(&priv->txq[IWL_CMD_QUEUE_NUM].q, index, huge);
- cmd = priv->txq[IWL_CMD_QUEUE_NUM].cmd[cmd_index];
- meta = &priv->txq[IWL_CMD_QUEUE_NUM].meta[cmd_index];
+ /* If this is a huge cmd, clear the huge flag on the meta.flags
+ * of the _original_ cmd. So that iwl_cmd_queue_free won't unmap
+ * the DMA buffer for the scan (huge) command.
+ */
+ if (huge) {
+ cmd_index = get_cmd_index(&txq->q, index, 0);
+ txq->meta[cmd_index].flags = 0;
+ }
+ cmd_index = get_cmd_index(&txq->q, index, huge);
+ cmd = txq->cmd[cmd_index];
+ meta = &txq->meta[cmd_index];
pci_unmap_single(priv->pci_dev,
pci_unmap_addr(meta, mapping),
@@ -583,6 +624,7 @@ void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
get_cmd_string(cmd->hdr.cmd));
wake_up_interruptible(&priv->wait_command_queue);
}
+ meta->flags = 0;
}
EXPORT_SYMBOL(iwl_tx_cmd_complete);
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index 4d0394b3fb5..c9188b9c565 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -1946,7 +1946,7 @@ static void iwl3945_init_hw_rates(struct iwl_priv *priv,
{
int i;
- for (i = 0; i < IWL_RATE_COUNT; i++) {
+ for (i = 0; i < IWL_RATE_COUNT_LEGACY; i++) {
rates[i].bitrate = iwl3945_rates[i].ieee * 5;
rates[i].hw_value = i; /* Rate scaling will work on indexes */
rates[i].hw_value_short = i;
@@ -3943,7 +3943,7 @@ static int iwl3945_setup_mac(struct iwl_priv *priv)
BIT(NL80211_IFTYPE_STATION) |
BIT(NL80211_IFTYPE_ADHOC);
- hw->wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY |
+ hw->wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY |
WIPHY_FLAG_DISABLE_BEACON_HINTS;
hw->wiphy->max_scan_ssids = PROBE_OPTION_MAX_3945;
diff --git a/drivers/net/wireless/libertas/cfg.c b/drivers/net/wireless/libertas/cfg.c
index 4396dccd12a..82ebe1461a7 100644
--- a/drivers/net/wireless/libertas/cfg.c
+++ b/drivers/net/wireless/libertas/cfg.c
@@ -172,6 +172,8 @@ int lbs_cfg_register(struct lbs_private *priv)
if (ret < 0)
lbs_pr_err("cannot register wiphy device\n");
+ priv->wiphy_registered = true;
+
ret = register_netdev(priv->dev);
if (ret)
lbs_pr_err("cannot register network device\n");
@@ -190,9 +192,11 @@ void lbs_cfg_free(struct lbs_private *priv)
if (!wdev)
return;
- if (wdev->wiphy) {
+ if (priv->wiphy_registered)
wiphy_unregister(wdev->wiphy);
+
+ if (wdev->wiphy)
wiphy_free(wdev->wiphy);
- }
+
kfree(wdev);
}
diff --git a/drivers/net/wireless/libertas/dev.h b/drivers/net/wireless/libertas/dev.h
index 058d1720242..a54880e4ad2 100644
--- a/drivers/net/wireless/libertas/dev.h
+++ b/drivers/net/wireless/libertas/dev.h
@@ -36,6 +36,7 @@ struct lbs_private {
/* CFG80211 */
struct wireless_dev *wdev;
+ bool wiphy_registered;
/* Mesh */
struct net_device *mesh_dev; /* Virtual device */
diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c
index ac65e13eb0d..4e58ebe1558 100644
--- a/drivers/net/wireless/mwl8k.c
+++ b/drivers/net/wireless/mwl8k.c
@@ -3851,6 +3851,7 @@ MODULE_FIRMWARE("mwl8k/helper_8366.fw");
MODULE_FIRMWARE("mwl8k/fmimage_8366.fw");
static DEFINE_PCI_DEVICE_TABLE(mwl8k_pci_id_table) = {
+ { PCI_VDEVICE(MARVELL, 0x2a0a), .driver_data = MWL8363, },
{ PCI_VDEVICE(MARVELL, 0x2a0c), .driver_data = MWL8363, },
{ PCI_VDEVICE(MARVELL, 0x2a24), .driver_data = MWL8363, },
{ PCI_VDEVICE(MARVELL, 0x2a2b), .driver_data = MWL8687, },
diff --git a/drivers/net/wireless/p54/p54usb.c b/drivers/net/wireless/p54/p54usb.c
index b3c4fbd80d8..e3cfc001d2f 100644
--- a/drivers/net/wireless/p54/p54usb.c
+++ b/drivers/net/wireless/p54/p54usb.c
@@ -35,6 +35,7 @@ MODULE_FIRMWARE("isl3887usb");
static struct usb_device_id p54u_table[] __devinitdata = {
/* Version 1 devices (pci chip + net2280) */
{USB_DEVICE(0x0506, 0x0a11)}, /* 3COM 3CRWE254G72 */
+ {USB_DEVICE(0x06b9, 0x0120)}, /* Thomson SpeedTouch 120g */
{USB_DEVICE(0x0707, 0xee06)}, /* SMC 2862W-G */
{USB_DEVICE(0x07aa, 0x001c)}, /* Corega CG-WLUSB2GT */
{USB_DEVICE(0x083a, 0x4501)}, /* Accton 802.11g WN4501 USB */
diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c
index 267afd714c7..aceb95ef727 100644
--- a/drivers/net/wireless/rndis_wlan.c
+++ b/drivers/net/wireless/rndis_wlan.c
@@ -1546,51 +1546,67 @@ static void set_multicast_list(struct usbnet *usbdev)
{
struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
struct dev_mc_list *mclist;
- __le32 filter;
- int ret, i, size;
- char *buf;
+ __le32 filter, basefilter;
+ int ret;
+ 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) {
filter |= RNDIS_PACKET_TYPE_PROMISCUOUS |
RNDIS_PACKET_TYPE_ALL_LOCAL;
- } else if (usbdev->net->flags & IFF_ALLMULTI ||
- netdev_mc_count(usbdev->net) > priv->multicast_size) {
+ } else if (usbdev->net->flags & IFF_ALLMULTI) {
+ filter |= RNDIS_PACKET_TYPE_ALL_MULTICAST;
+ }
+
+ if (filter != basefilter)
+ 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 (!netdev_mc_empty(usbdev->net)) {
- size = min(priv->multicast_size, netdev_mc_count(usbdev->net));
- buf = kmalloc(size * ETH_ALEN, GFP_KERNEL);
- if (!buf) {
+ } else if (mc_count) {
+ int i = 0;
+
+ mc_addrs = kmalloc(mc_count * ETH_ALEN, GFP_ATOMIC);
+ if (!mc_addrs) {
netdev_warn(usbdev->net,
"couldn't alloc %d bytes of memory\n",
- size * ETH_ALEN);
+ mc_count * ETH_ALEN);
netif_addr_unlock_bh(usbdev->net);
return;
}
- i = 0;
- netdev_for_each_mc_addr(mclist, usbdev->net) {
- if (i == size)
- break;
- memcpy(buf + i++ * ETH_ALEN, mclist->dmi_addr, ETH_ALEN);
- }
+ netdev_for_each_mc_addr(mclist, usbdev->net)
+ memcpy(mc_addrs + 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,
- i * ETH_ALEN);
- if (ret == 0 && i > 0)
+ if (filter != basefilter)
+ goto set_filter;
+
+ 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;
else
filter |= RNDIS_PACKET_TYPE_ALL_MULTICAST;
netdev_dbg(usbdev->net, "OID_802_3_MULTICAST_LIST(%d, max: %d) -> %d\n",
- i, priv->multicast_size, ret);
-
- kfree(buf);
+ mc_count, priv->multicast_size, ret);
}
- netif_addr_unlock_bh(usbdev->net);
+set_filter:
ret = rndis_set_oid(usbdev, OID_GEN_CURRENT_PACKET_FILTER, &filter,
sizeof(filter));
if (ret < 0) {
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c
index c1eec17fe18..54d2716e389 100644
--- a/drivers/net/wireless/rt2x00/rt2500usb.c
+++ b/drivers/net/wireless/rt2x00/rt2500usb.c
@@ -1647,6 +1647,11 @@ static int rt2500usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
unsigned int i;
/*
+ * Disable powersaving as default.
+ */
+ rt2x00dev->hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
+
+ /*
* Initialize all hw fields.
*/
rt2x00dev->hw->flags =
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c
index d1694912310..68d0cfee3f2 100644
--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
@@ -812,9 +812,9 @@ static void rt2800_config_channel_rt3x(struct rt2x00_dev *rt2x00dev,
rt2800_rfcsr_write(rt2x00dev, 24,
rt2x00dev->calibration[conf_is_ht40(conf)]);
- rt2800_rfcsr_read(rt2x00dev, 23, &rfcsr);
+ rt2800_rfcsr_read(rt2x00dev, 7, &rfcsr);
rt2x00_set_field8(&rfcsr, RFCSR7_RF_TUNING, 1);
- rt2800_rfcsr_write(rt2x00dev, 23, rfcsr);
+ rt2800_rfcsr_write(rt2x00dev, 7, rfcsr);
}
static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev,
diff --git a/drivers/net/wireless/rt2x00/rt2x00soc.h b/drivers/net/wireless/rt2x00/rt2x00soc.h
index 4739edfe2f0..474cbfc1efc 100644
--- a/drivers/net/wireless/rt2x00/rt2x00soc.h
+++ b/drivers/net/wireless/rt2x00/rt2x00soc.h
@@ -26,8 +26,6 @@
#ifndef RT2X00SOC_H
#define RT2X00SOC_H
-#define KSEG1ADDR(__ptr) __ptr
-
/*
* SoC driver handlers.
*/
diff --git a/drivers/net/wireless/wl12xx/wl1251_debugfs.c b/drivers/net/wireless/wl12xx/wl1251_debugfs.c
index 0ccba57fb9f..05e4d68eb4c 100644
--- a/drivers/net/wireless/wl12xx/wl1251_debugfs.c
+++ b/drivers/net/wireless/wl12xx/wl1251_debugfs.c
@@ -466,7 +466,8 @@ out:
void wl1251_debugfs_reset(struct wl1251 *wl)
{
- memset(wl->stats.fw_stats, 0, sizeof(*wl->stats.fw_stats));
+ if (wl->stats.fw_stats != NULL)
+ memset(wl->stats.fw_stats, 0, sizeof(*wl->stats.fw_stats));
wl->stats.retry_count = 0;
wl->stats.excessive_retries = 0;
}