aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/8139cp.c10
-rw-r--r--drivers/net/atlx/atl1.c12
-rw-r--r--drivers/net/atlx/atl1.h3
-rw-r--r--drivers/net/atlx/atlx.c2
-rw-r--r--drivers/net/bonding/bond_main.c6
-rw-r--r--drivers/net/davinci_mdio.c5
-rw-r--r--drivers/net/dummy.c6
-rw-r--r--drivers/net/ks8851_mll.c2
-rw-r--r--drivers/net/ksz884x.c2
-rw-r--r--drivers/net/ppp_generic.c3
-rw-r--r--drivers/net/smsc911x.c14
-rw-r--r--drivers/net/usb/smsc75xx.c1
-rw-r--r--drivers/net/wimax/i2400m/netdev.c3
-rw-r--r--drivers/net/wireless/ath/ath9k/calib.c5
-rw-r--r--drivers/net/wireless/bcmdhd/bcmsdh_sdmmc_linux.c17
-rw-r--r--drivers/net/wireless/bcmdhd/dhd.h10
-rw-r--r--drivers/net/wireless/bcmdhd/dhd_cfg80211.c25
-rw-r--r--drivers/net/wireless/bcmdhd/dhd_common.c8
-rw-r--r--drivers/net/wireless/bcmdhd/dhd_linux.c15
-rw-r--r--drivers/net/wireless/bcmdhd/dhd_sdio.c5
-rw-r--r--drivers/net/wireless/bcmdhd/include/epivers.h8
-rw-r--r--drivers/net/wireless/bcmdhd/wl_cfg80211.c91
-rw-r--r--drivers/net/wireless/bcmdhd/wl_cfg80211.h5
-rw-r--r--drivers/net/wireless/bcmdhd/wl_cfgp2p.c49
-rw-r--r--drivers/net/wireless/bcmdhd/wl_cfgp2p.h7
-rw-r--r--drivers/net/wireless/rt2x00/rt2800usb.c35
-rw-r--r--drivers/net/wireless/rtlwifi/pci.c7
27 files changed, 245 insertions, 111 deletions
diff --git a/drivers/net/8139cp.c b/drivers/net/8139cp.c
index 10c4505..a8b82da 100644
--- a/drivers/net/8139cp.c
+++ b/drivers/net/8139cp.c
@@ -992,6 +992,11 @@ static inline void cp_start_hw (struct cp_private *cp)
cpw8(Cmd, RxOn | TxOn);
}
+static void cp_enable_irq(struct cp_private *cp)
+{
+ cpw16_f(IntrMask, cp_intr_mask);
+}
+
static void cp_init_hw (struct cp_private *cp)
{
struct net_device *dev = cp->dev;
@@ -1031,8 +1036,6 @@ static void cp_init_hw (struct cp_private *cp)
cpw16(MultiIntr, 0);
- cpw16_f(IntrMask, cp_intr_mask);
-
cpw8_f(Cfg9346, Cfg9346_Lock);
}
@@ -1164,6 +1167,8 @@ static int cp_open (struct net_device *dev)
if (rc)
goto err_out_hw;
+ cp_enable_irq(cp);
+
netif_carrier_off(dev);
mii_check_media(&cp->mii_if, netif_msg_link(cp), true);
netif_start_queue(dev);
@@ -2052,6 +2057,7 @@ static int cp_resume (struct pci_dev *pdev)
/* FIXME: sh*t may happen if the Rx ring buffer is depleted */
cp_init_rings_index (cp);
cp_init_hw (cp);
+ cp_enable_irq(cp);
netif_start_queue (dev);
spin_lock_irqsave (&cp->lock, flags);
diff --git a/drivers/net/atlx/atl1.c b/drivers/net/atlx/atl1.c
index cd5789f..48c27d3 100644
--- a/drivers/net/atlx/atl1.c
+++ b/drivers/net/atlx/atl1.c
@@ -2476,7 +2476,7 @@ static irqreturn_t atl1_intr(int irq, void *data)
"pcie phy link down %x\n", status);
if (netif_running(adapter->netdev)) { /* reset MAC */
iowrite32(0, adapter->hw.hw_addr + REG_IMR);
- schedule_work(&adapter->pcie_dma_to_rst_task);
+ schedule_work(&adapter->reset_dev_task);
return IRQ_HANDLED;
}
}
@@ -2488,7 +2488,7 @@ static irqreturn_t atl1_intr(int irq, void *data)
"pcie DMA r/w error (status = 0x%x)\n",
status);
iowrite32(0, adapter->hw.hw_addr + REG_IMR);
- schedule_work(&adapter->pcie_dma_to_rst_task);
+ schedule_work(&adapter->reset_dev_task);
return IRQ_HANDLED;
}
@@ -2633,10 +2633,10 @@ static void atl1_down(struct atl1_adapter *adapter)
atl1_clean_rx_ring(adapter);
}
-static void atl1_tx_timeout_task(struct work_struct *work)
+static void atl1_reset_dev_task(struct work_struct *work)
{
struct atl1_adapter *adapter =
- container_of(work, struct atl1_adapter, tx_timeout_task);
+ container_of(work, struct atl1_adapter, reset_dev_task);
struct net_device *netdev = adapter->netdev;
netif_device_detach(netdev);
@@ -3034,12 +3034,10 @@ static int __devinit atl1_probe(struct pci_dev *pdev,
(unsigned long)adapter);
adapter->phy_timer_pending = false;
- INIT_WORK(&adapter->tx_timeout_task, atl1_tx_timeout_task);
+ INIT_WORK(&adapter->reset_dev_task, atl1_reset_dev_task);
INIT_WORK(&adapter->link_chg_task, atlx_link_chg_task);
- INIT_WORK(&adapter->pcie_dma_to_rst_task, atl1_tx_timeout_task);
-
err = register_netdev(netdev);
if (err)
goto err_common;
diff --git a/drivers/net/atlx/atl1.h b/drivers/net/atlx/atl1.h
index 68de8cb..c27b724 100644
--- a/drivers/net/atlx/atl1.h
+++ b/drivers/net/atlx/atl1.h
@@ -759,9 +759,8 @@ struct atl1_adapter {
u16 link_speed;
u16 link_duplex;
spinlock_t lock;
- struct work_struct tx_timeout_task;
+ struct work_struct reset_dev_task;
struct work_struct link_chg_task;
- struct work_struct pcie_dma_to_rst_task;
struct timer_list phy_config_timer;
bool phy_timer_pending;
diff --git a/drivers/net/atlx/atlx.c b/drivers/net/atlx/atlx.c
index afb7f7d..2b7af06 100644
--- a/drivers/net/atlx/atlx.c
+++ b/drivers/net/atlx/atlx.c
@@ -193,7 +193,7 @@ static void atlx_tx_timeout(struct net_device *netdev)
{
struct atlx_adapter *adapter = netdev_priv(netdev);
/* Do the reset outside of interrupt context */
- schedule_work(&adapter->tx_timeout_task);
+ schedule_work(&adapter->reset_dev_task);
}
/*
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index 0b65c5f..e6da842 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -3076,7 +3076,11 @@ static void bond_ab_arp_commit(struct bonding *bond, int delta_in_ticks)
trans_start + delta_in_ticks)) ||
bond->curr_active_slave != slave) {
slave->link = BOND_LINK_UP;
- bond->current_arp_slave = NULL;
+ if (bond->current_arp_slave) {
+ bond_set_slave_inactive_flags(
+ bond->current_arp_slave);
+ bond->current_arp_slave = NULL;
+ }
pr_info("%s: link status definitely up for interface %s.\n",
bond->dev->name, slave->dev->name);
diff --git a/drivers/net/davinci_mdio.c b/drivers/net/davinci_mdio.c
index 7615040..f470ab6 100644
--- a/drivers/net/davinci_mdio.c
+++ b/drivers/net/davinci_mdio.c
@@ -181,6 +181,11 @@ static inline int wait_for_user_access(struct davinci_mdio_data *data)
__davinci_mdio_reset(data);
return -EAGAIN;
}
+
+ reg = __raw_readl(&regs->user[0].access);
+ if ((reg & USERACCESS_GO) == 0)
+ return 0;
+
dev_err(data->dev, "timed out waiting for user access\n");
return -ETIMEDOUT;
}
diff --git a/drivers/net/dummy.c b/drivers/net/dummy.c
index 39cf9b9..3fa19c1 100644
--- a/drivers/net/dummy.c
+++ b/drivers/net/dummy.c
@@ -106,14 +106,14 @@ static int dummy_dev_init(struct net_device *dev)
return 0;
}
-static void dummy_dev_free(struct net_device *dev)
+static void dummy_dev_uninit(struct net_device *dev)
{
free_percpu(dev->dstats);
- free_netdev(dev);
}
static const struct net_device_ops dummy_netdev_ops = {
.ndo_init = dummy_dev_init,
+ .ndo_uninit = dummy_dev_uninit,
.ndo_start_xmit = dummy_xmit,
.ndo_validate_addr = eth_validate_addr,
.ndo_set_multicast_list = set_multicast_list,
@@ -127,7 +127,7 @@ static void dummy_setup(struct net_device *dev)
/* Initialize the device structure. */
dev->netdev_ops = &dummy_netdev_ops;
- dev->destructor = dummy_dev_free;
+ dev->destructor = free_netdev;
/* Fill in device structure with ethernet-generic values. */
dev->tx_queue_len = 0;
diff --git a/drivers/net/ks8851_mll.c b/drivers/net/ks8851_mll.c
index 61631ca..3eacbb4 100644
--- a/drivers/net/ks8851_mll.c
+++ b/drivers/net/ks8851_mll.c
@@ -38,7 +38,7 @@
#define DRV_NAME "ks8851_mll"
static u8 KS_DEFAULT_MAC_ADDRESS[] = { 0x00, 0x10, 0xA1, 0x86, 0x95, 0x11 };
-#define MAX_RECV_FRAMES 32
+#define MAX_RECV_FRAMES 255
#define MAX_BUF_SIZE 2048
#define TX_BUF_SIZE 2000
#define RX_BUF_SIZE 2000
diff --git a/drivers/net/ksz884x.c b/drivers/net/ksz884x.c
index 41ea592..95b6664 100644
--- a/drivers/net/ksz884x.c
+++ b/drivers/net/ksz884x.c
@@ -5679,7 +5679,7 @@ static int netdev_set_mac_address(struct net_device *dev, void *addr)
memcpy(hw->override_addr, mac->sa_data, MAC_ADDR_LEN);
}
- memcpy(dev->dev_addr, mac->sa_data, MAX_ADDR_LEN);
+ memcpy(dev->dev_addr, mac->sa_data, ETH_ALEN);
interrupt = hw_block_intr(hw);
diff --git a/drivers/net/ppp_generic.c b/drivers/net/ppp_generic.c
index 33d0131..b890401 100644
--- a/drivers/net/ppp_generic.c
+++ b/drivers/net/ppp_generic.c
@@ -968,7 +968,6 @@ ppp_start_xmit(struct sk_buff *skb, struct net_device *dev)
proto = npindex_to_proto[npi];
put_unaligned_be16(proto, pp);
- netif_stop_queue(dev);
skb_queue_tail(&ppp->file.xq, skb);
ppp_xmit_process(ppp);
return NETDEV_TX_OK;
@@ -1063,6 +1062,8 @@ ppp_xmit_process(struct ppp *ppp)
code that we can accept some more. */
if (!ppp->xmit_pending && !skb_peek(&ppp->file.xq))
netif_wake_queue(ppp->dev);
+ else
+ netif_stop_queue(ppp->dev);
}
ppp_xmit_unlock(ppp);
}
diff --git a/drivers/net/smsc911x.c b/drivers/net/smsc911x.c
index c6d47d1..3d12e8c 100644
--- a/drivers/net/smsc911x.c
+++ b/drivers/net/smsc911x.c
@@ -1083,10 +1083,8 @@ smsc911x_rx_counterrors(struct net_device *dev, unsigned int rxstat)
/* Quickly dumps bad packets */
static void
-smsc911x_rx_fastforward(struct smsc911x_data *pdata, unsigned int pktbytes)
+smsc911x_rx_fastforward(struct smsc911x_data *pdata, unsigned int pktwords)
{
- unsigned int pktwords = (pktbytes + NET_IP_ALIGN + 3) >> 2;
-
if (likely(pktwords >= 4)) {
unsigned int timeout = 500;
unsigned int val;
@@ -1150,7 +1148,7 @@ static int smsc911x_poll(struct napi_struct *napi, int budget)
continue;
}
- skb = netdev_alloc_skb(dev, pktlength + NET_IP_ALIGN);
+ skb = netdev_alloc_skb(dev, pktwords << 2);
if (unlikely(!skb)) {
SMSC_WARN(pdata, rx_err,
"Unable to allocate skb for rx packet");
@@ -1160,14 +1158,12 @@ static int smsc911x_poll(struct napi_struct *napi, int budget)
break;
}
- skb->data = skb->head;
- skb_reset_tail_pointer(skb);
+ pdata->ops->rx_readfifo(pdata,
+ (unsigned int *)skb->data, pktwords);
/* Align IP on 16B boundary */
skb_reserve(skb, NET_IP_ALIGN);
skb_put(skb, pktlength - 4);
- pdata->ops->rx_readfifo(pdata,
- (unsigned int *)skb->head, pktwords);
skb->protocol = eth_type_trans(skb, dev);
skb_checksum_none_assert(skb);
netif_receive_skb(skb);
@@ -1390,7 +1386,7 @@ static int smsc911x_open(struct net_device *dev)
smsc911x_reg_write(pdata, FIFO_INT, temp);
/* set RX Data offset to 2 bytes for alignment */
- smsc911x_reg_write(pdata, RX_CFG, (2 << 8));
+ smsc911x_reg_write(pdata, RX_CFG, (NET_IP_ALIGN << 8));
/* enable NAPI polling before enabling RX interrupts */
napi_enable(&pdata->napi);
diff --git a/drivers/net/usb/smsc75xx.c b/drivers/net/usb/smsc75xx.c
index 15b3d68..de0de3e 100644
--- a/drivers/net/usb/smsc75xx.c
+++ b/drivers/net/usb/smsc75xx.c
@@ -1049,6 +1049,7 @@ static int smsc75xx_bind(struct usbnet *dev, struct usb_interface *intf)
dev->net->ethtool_ops = &smsc75xx_ethtool_ops;
dev->net->flags |= IFF_MULTICAST;
dev->net->hard_header_len += SMSC75XX_TX_OVERHEAD;
+ dev->hard_mtu = dev->net->mtu + dev->net->hard_header_len;
return 0;
}
diff --git a/drivers/net/wimax/i2400m/netdev.c b/drivers/net/wimax/i2400m/netdev.c
index 2edd8fe..0a99863 100644
--- a/drivers/net/wimax/i2400m/netdev.c
+++ b/drivers/net/wimax/i2400m/netdev.c
@@ -606,7 +606,8 @@ static void i2400m_get_drvinfo(struct net_device *net_dev,
struct i2400m *i2400m = net_dev_to_i2400m(net_dev);
strncpy(info->driver, KBUILD_MODNAME, sizeof(info->driver) - 1);
- strncpy(info->fw_version, i2400m->fw_name, sizeof(info->fw_version) - 1);
+ strncpy(info->fw_version,
+ i2400m->fw_name ? : "", sizeof(info->fw_version) - 1);
if (net_dev->dev.parent)
strncpy(info->bus_info, dev_name(net_dev->dev.parent),
sizeof(info->bus_info) - 1);
diff --git a/drivers/net/wireless/ath/ath9k/calib.c b/drivers/net/wireless/ath/ath9k/calib.c
index a1250c5..1f2f97f 100644
--- a/drivers/net/wireless/ath/ath9k/calib.c
+++ b/drivers/net/wireless/ath/ath9k/calib.c
@@ -19,7 +19,6 @@
/* Common calibration code */
-#define ATH9K_NF_TOO_HIGH -60
static int16_t ath9k_hw_get_nf_hist_mid(int16_t *nfCalBuffer)
{
@@ -335,10 +334,10 @@ static void ath9k_hw_nf_sanitize(struct ath_hw *ah, s16 *nf)
"NF calibrated [%s] [chain %d] is %d\n",
(i >= 3 ? "ext" : "ctl"), i % 3, nf[i]);
- if (nf[i] > ATH9K_NF_TOO_HIGH) {
+ if (nf[i] > limit->max) {
ath_dbg(common, ATH_DBG_CALIBRATE,
"NF[%d] (%d) > MAX (%d), correcting to MAX\n",
- i, nf[i], ATH9K_NF_TOO_HIGH);
+ i, nf[i], limit->max);
nf[i] = limit->max;
} else if (nf[i] < limit->min) {
ath_dbg(common, ATH_DBG_CALIBRATE,
diff --git a/drivers/net/wireless/bcmdhd/bcmsdh_sdmmc_linux.c b/drivers/net/wireless/bcmdhd/bcmsdh_sdmmc_linux.c
index 602523d..a78faeb 100644
--- a/drivers/net/wireless/bcmdhd/bcmsdh_sdmmc_linux.c
+++ b/drivers/net/wireless/bcmdhd/bcmsdh_sdmmc_linux.c
@@ -178,6 +178,8 @@ MODULE_DEVICE_TABLE(sdio, bcmsdh_sdmmc_ids);
static int bcmsdh_sdmmc_suspend(struct device *pdev)
{
struct sdio_func *func = dev_to_sdio_func(pdev);
+ mmc_pm_flag_t sdio_flags;
+ int ret;
if (func->num != 2)
return 0;
@@ -186,6 +188,21 @@ static int bcmsdh_sdmmc_suspend(struct device *pdev)
if (dhd_os_check_wakelock(bcmsdh_get_drvdata()))
return -EBUSY;
+
+ sdio_flags = sdio_get_host_pm_caps(func);
+
+ if (!(sdio_flags & MMC_PM_KEEP_POWER)) {
+ sd_err(("%s: can't keep power while host is suspended\n", __FUNCTION__));
+ return -EINVAL;
+ }
+
+ /* keep power while host suspended */
+ ret = sdio_set_host_pm_flags(func, MMC_PM_KEEP_POWER);
+ if (ret) {
+ sd_err(("%s: error while trying to keep power\n", __FUNCTION__));
+ return ret;
+ }
+
#if defined(OOB_INTR_ONLY)
bcmsdh_oob_intr_set(0);
#endif /* defined(OOB_INTR_ONLY) */
diff --git a/drivers/net/wireless/bcmdhd/dhd.h b/drivers/net/wireless/bcmdhd/dhd.h
index dc2e382..5cace1f 100644
--- a/drivers/net/wireless/bcmdhd/dhd.h
+++ b/drivers/net/wireless/bcmdhd/dhd.h
@@ -24,11 +24,12 @@
* software in any way with any other Broadcom software provided under a license
* other than the GPL, without Broadcom's express prior written consent.
*
- * $Id: dhd.h 325862 2012-04-04 22:59:48Z $
+ * $Id: dhd.h 328934 2012-04-23 05:15:42Z $
*/
-
-
+/****************
+ * Common types *
+ */
#ifndef _dhd_h_
#define _dhd_h_
@@ -90,6 +91,9 @@ enum dhd_bus_state {
#define DHD_SCAN_ACTIVE_TIME 40 /* ms : Embedded default Active setting from DHD Driver */
#define DHD_SCAN_PASSIVE_TIME 130 /* ms: Embedded default Passive setting from DHD Driver */
+#define DHD_BEACON_TIMEOUT_NORMAL 4
+#define DHD_BEACON_TIMEOUT_HIGH 10
+
enum dhd_bus_wake_state {
WAKE_LOCK_OFF,
WAKE_LOCK_PRIV,
diff --git a/drivers/net/wireless/bcmdhd/dhd_cfg80211.c b/drivers/net/wireless/bcmdhd/dhd_cfg80211.c
index 2503f51..183891d 100644
--- a/drivers/net/wireless/bcmdhd/dhd_cfg80211.c
+++ b/drivers/net/wireless/bcmdhd/dhd_cfg80211.c
@@ -41,7 +41,9 @@ static int dhd_dongle_up = FALSE;
static s32 wl_dongle_up(struct net_device *ndev, u32 up);
-
+/**
+ * Function implementations
+ */
s32 dhd_cfg80211_init(struct wl_priv *wl)
{
@@ -70,13 +72,22 @@ s32 dhd_cfg80211_down(struct wl_priv *wl)
s32 dhd_cfg80211_set_p2p_info(struct wl_priv *wl, int val)
{
dhd_pub_t *dhd = (dhd_pub_t *)(wl->pub);
+ int bcn_timeout = DHD_BEACON_TIMEOUT_HIGH;
+ char iovbuf[30];
+
dhd->op_mode |= val;
WL_ERR(("Set : op_mode=%d\n", dhd->op_mode));
#ifdef ARP_OFFLOAD_SUPPORT
+ /* IF P2P is enabled, disable arpoe */
dhd_arp_offload_set(dhd, 0);
dhd_arp_offload_enable(dhd, false);
-#endif
+#endif /* ARP_OFFLOAD_SUPPORT */
+
+ /* Setup timeout if Beacons are lost and roam is off to report link down */
+ bcm_mkiovar("bcn_timeout", (char *)&bcn_timeout, 4, iovbuf, sizeof(iovbuf));
+ dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0);
+
return 0;
}
@@ -84,13 +95,21 @@ s32 dhd_cfg80211_set_p2p_info(struct wl_priv *wl, int val)
s32 dhd_cfg80211_clean_p2p_info(struct wl_priv *wl)
{
dhd_pub_t *dhd = (dhd_pub_t *)(wl->pub);
+ int bcn_timeout = DHD_BEACON_TIMEOUT_NORMAL;
+ char iovbuf[30];
+
dhd->op_mode &= ~CONCURENT_MASK;
WL_ERR(("Clean : op_mode=%d\n", dhd->op_mode));
#ifdef ARP_OFFLOAD_SUPPORT
+ /* IF P2P is disabled, enable arpoe back for STA mode. */
dhd_arp_offload_set(dhd, dhd_arp_mode);
dhd_arp_offload_enable(dhd, true);
-#endif
+#endif /* ARP_OFFLOAD_SUPPORT */
+
+ /* Setup timeout if Beacons are lost and roam is off to report link down */
+ bcm_mkiovar("bcn_timeout", (char *)&bcn_timeout, 4, iovbuf, sizeof(iovbuf));
+ dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0);
return 0;
}
diff --git a/drivers/net/wireless/bcmdhd/dhd_common.c b/drivers/net/wireless/bcmdhd/dhd_common.c
index ca5a76e..60e1449 100644
--- a/drivers/net/wireless/bcmdhd/dhd_common.c
+++ b/drivers/net/wireless/bcmdhd/dhd_common.c
@@ -21,7 +21,7 @@
* software in any way with any other Broadcom software provided under a license
* other than the GPL, without Broadcom's express prior written consent.
*
- * $Id: dhd_common.c 319098 2012-03-07 01:05:20Z $
+ * $Id: dhd_common.c 329682 2012-04-26 09:20:38Z $
*/
#include <typedefs.h>
#include <osl.h>
@@ -996,6 +996,9 @@ wl_host_event(dhd_pub_t *dhd_pub, int *ifidx, void *pktdata,
datalen = ntoh32_ua((void *)&event->datalen);
evlen = datalen + sizeof(bcm_event_t);
+ DHD_TRACE(("RX: event_type:%d flags:%d status:%d reason:%d \n",
+ type, flags, status, reason));
+
switch (type) {
#ifdef PROP_TXSTATUS
case WLC_E_FIFO_CREDIT_MAP:
@@ -1723,6 +1726,7 @@ fail:
/*
* returns = TRUE if associated, FALSE if not associated
+ * third paramter retval can return error from error
*/
bool dhd_is_associated(dhd_pub_t *dhd, void *bss_buf, int *retval)
{
@@ -1891,7 +1895,7 @@ dhd_pno_enable(dhd_pub_t *dhd, int pfn_enabled)
DHD_ERROR(("%s pno is NOT enable : called in assoc mode , ignore\n", __FUNCTION__));
return ret;
}
-#endif
+#endif /* !WL_SCHED_SCAN */
/* Enable/disable PNO */
if ((ret = bcm_mkiovar("pfn", (char *)&pfn_enabled, 4, iovbuf, sizeof(iovbuf))) > 0) {
diff --git a/drivers/net/wireless/bcmdhd/dhd_linux.c b/drivers/net/wireless/bcmdhd/dhd_linux.c
index fcf8f0a..32e4eb8 100644
--- a/drivers/net/wireless/bcmdhd/dhd_linux.c
+++ b/drivers/net/wireless/bcmdhd/dhd_linux.c
@@ -22,7 +22,7 @@
* software in any way with any other Broadcom software provided under a license
* other than the GPL, without Broadcom's express prior written consent.
*
- * $Id: dhd_linux.c 325862 2012-04-04 22:59:48Z $
+ * $Id: dhd_linux.c 329682 2012-04-26 09:20:38Z $
*/
#include <typedefs.h>
@@ -1472,6 +1472,7 @@ dhd_rx_frame(dhd_pub_t *dhdp, int ifidx, void *pktbuf, int numpkt, uint8 chan)
*/
((athost_wl_status_info_t*)dhdp->wlfc_state)->stats.wlfc_header_only_pkt++;
PKTFREE(dhdp->osh, pktbuf, TRUE);
+ DHD_TRACE(("RX: wlfc header \n"));
continue;
}
#endif
@@ -2448,6 +2449,9 @@ dhd_open(struct net_device *net)
OLD_MOD_INC_USE_COUNT;
exit:
+ if (ret)
+ dhd_stop(net);
+
DHD_OS_WAKE_UNLOCK(&dhd->pub);
return ret;
}
@@ -2954,12 +2958,14 @@ dhd_preinit_ioctls(dhd_pub_t *dhd)
int ret = 0;
char eventmask[WL_EVENTING_MASK_LEN];
char iovbuf[WL_EVENTING_MASK_LEN + 12]; /* Room for "event_msgs" + '\0' + bitvec */
-
+#if !defined(WL_CFG80211)
uint up = 0;
+#endif
uint power_mode = PM_FAST;
uint32 dongle_align = DHD_SDALIGN;
uint32 glom = 0;
- uint bcn_timeout = 10;
+ uint bcn_timeout = DHD_BEACON_TIMEOUT_NORMAL;
+
uint retry_max = 3;
#if defined(ARP_OFFLOAD_SUPPORT)
int arpoe = 1;
@@ -3270,12 +3276,13 @@ dhd_preinit_ioctls(dhd_pub_t *dhd)
#endif /* defined(SOFTAP) */
#endif /* PKT_FILTER_SUPPORT */
+#if !defined(WL_CFG80211)
/* Force STA UP */
if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_UP, (char *)&up, sizeof(up), TRUE, 0)) < 0) {
DHD_ERROR(("%s Setting WL UP failed %d\n", __FUNCTION__, ret));
goto done;
}
-
+#endif
/* query for 'ver' to get version info from firmware */
memset(buf, 0, sizeof(buf));
ptr = buf;
diff --git a/drivers/net/wireless/bcmdhd/dhd_sdio.c b/drivers/net/wireless/bcmdhd/dhd_sdio.c
index d445f26..7fdd3144 100644
--- a/drivers/net/wireless/bcmdhd/dhd_sdio.c
+++ b/drivers/net/wireless/bcmdhd/dhd_sdio.c
@@ -21,7 +21,7 @@
* software in any way with any other Broadcom software provided under a license
* other than the GPL, without Broadcom's express prior written consent.
*
- * $Id: dhd_sdio.c 325395 2012-04-03 03:57:43Z $
+ * $Id: dhd_sdio.c 326662 2012-04-10 06:38:08Z $
*/
#include <typedefs.h>
@@ -4616,8 +4616,7 @@ clkwait:
int ret, i;
uint8* frame_seq = bus->ctrl_frame_buf + SDPCM_FRAMETAG_LEN;
- if (((bus->sih->chip == BCM4329_CHIP_ID) || /* limit to 4329 & 4330 for now */
- (bus->sih->chip == BCM4330_CHIP_ID)) && (*frame_seq != bus->tx_seq)) {
+ if (*frame_seq != bus->tx_seq) {
DHD_INFO(("%s IOCTL frame seq lag detected!"
" frm_seq:%d != bus->tx_seq:%d, corrected\n",
__FUNCTION__, *frame_seq, bus->tx_seq));
diff --git a/drivers/net/wireless/bcmdhd/include/epivers.h b/drivers/net/wireless/bcmdhd/include/epivers.h
index b3560bd..3bff73e 100644
--- a/drivers/net/wireless/bcmdhd/include/epivers.h
+++ b/drivers/net/wireless/bcmdhd/include/epivers.h
@@ -32,17 +32,17 @@
#define EPI_RC_NUMBER 195
-#define EPI_INCREMENTAL_NUMBER 53
+#define EPI_INCREMENTAL_NUMBER 61
#define EPI_BUILD_NUMBER 0
-#define EPI_VERSION 5, 90, 195, 53
+#define EPI_VERSION 5, 90, 195, 61
-#define EPI_VERSION_NUM 0x055ac335
+#define EPI_VERSION_NUM 0x055ac33d
#define EPI_VERSION_DEV 5.90.195
-#define EPI_VERSION_STR "5.90.195.53"
+#define EPI_VERSION_STR "5.90.195.61"
#endif
diff --git a/drivers/net/wireless/bcmdhd/wl_cfg80211.c b/drivers/net/wireless/bcmdhd/wl_cfg80211.c
index 4b83d2a..839f907 100644
--- a/drivers/net/wireless/bcmdhd/wl_cfg80211.c
+++ b/drivers/net/wireless/bcmdhd/wl_cfg80211.c
@@ -100,7 +100,10 @@ static const struct ieee80211_regdomain brcm_regdom = {
* we need cfg80211 to allow it (reg_flags = 0); so that
* hostapd could request auto channel by sending down ch 14
*/
- REG_RULE(2484-10, 2484+10, 20, 6, 20, 0),
+ REG_RULE(2484-10, 2484+10, 20, 6, 20,
+ NL80211_RRF_PASSIVE_SCAN |
+ NL80211_RRF_NO_IBSS |
+ NL80211_RRF_NO_OFDM),
/* IEEE 802.11a, channel 36..64 */
REG_RULE(5150-10, 5350+10, 40, 6, 20, 0),
/* IEEE 802.11a, channel 100..165 */
@@ -735,7 +738,7 @@ wl_cfg80211_add_virtual_iface(struct wiphy *wiphy, char *name,
s32 mode = 0;
#if defined(WL_ENABLE_P2P_IF)
s32 dhd_mode = 0;
-#endif
+#endif /* (WL_ENABLE_P2P_IF) */
chanspec_t chspec;
struct wl_priv *wl = wiphy_priv(wiphy);
struct net_device *_ndev;
@@ -807,7 +810,7 @@ wl_cfg80211_add_virtual_iface(struct wiphy *wiphy, char *name,
return ERR_PTR(-EAGAIN);
}
}
- if (!p2p_is_on(wl) && strstr(name, WL_P2P_INTERFACE_PREFIX)) {
+ if (wl->p2p && !wl->p2p->on && strstr(name, WL_P2P_INTERFACE_PREFIX)) {
p2p_on(wl) = true;
wl_cfgp2p_set_firm_p2p(wl);
wl_cfgp2p_init_discovery(wl);
@@ -819,7 +822,8 @@ wl_cfg80211_add_virtual_iface(struct wiphy *wiphy, char *name,
memset(wl->p2p->vir_ifname, 0, IFNAMSIZ);
strncpy(wl->p2p->vir_ifname, name, IFNAMSIZ - 1);
-
+ wldev_iovar_setint(_ndev, "mpc", 0);
+ wl_notify_escan_complete(wl, _ndev, true, true);
/* In concurrency case, STA may be already associated in a particular channel.
* so retrieve the current channel of primary interface and then start the virtual
* interface on that.
@@ -874,8 +878,10 @@ wl_cfg80211_add_virtual_iface(struct wiphy *wiphy, char *name,
else if (type == NL80211_IFTYPE_P2P_GO)
dhd_mode = P2P_GO_ENABLED;
DNGL_FUNC(dhd_cfg80211_set_p2p_info, (wl, dhd_mode));
-#endif
-
+#endif /* (WL_ENABLE_P2P_IF) */
+ /* Start the P2P I/F with PM disabled. Enable PM from
+ * the framework
+ */
if ((type == NL80211_IFTYPE_P2P_CLIENT) || (
type == NL80211_IFTYPE_P2P_GO))
vwdev->ps = NL80211_PS_DISABLED;
@@ -920,7 +926,7 @@ wl_cfg80211_del_virtual_iface(struct wiphy *wiphy, struct net_device *dev)
if (wl->p2p_supported) {
memcpy(p2p_mac.octet, wl->p2p->int_addr.octet, ETHER_ADDR_LEN);
if (wl->p2p->vif_created) {
- if (wl->scan_request) {
+ if (wl_get_drv_status(wl, SCANNING, dev)) {
wl_notify_escan_complete(wl, dev, true, true);
}
wldev_iovar_setint(dev, "mpc", 1);
@@ -948,7 +954,7 @@ wl_cfg80211_del_virtual_iface(struct wiphy *wiphy, struct net_device *dev)
WL_DBG(("IFDEL operation done\n"));
#if defined(WL_ENABLE_P2P_IF)
DNGL_FUNC(dhd_cfg80211_clean_p2p_info, (wl));
-#endif
+#endif /* (WL_ENABLE_P2P_IF)) */
} else {
WL_ERR(("IFDEL didn't complete properly\n"));
}
@@ -972,7 +978,7 @@ wl_cfg80211_change_virtual_iface(struct wiphy *wiphy, struct net_device *ndev,
chanspec_t chspec;
struct wl_priv *wl = wiphy_priv(wiphy);
- WL_DBG(("Enter \n"));
+ WL_DBG(("Enter type %d\n", type));
switch (type) {
case NL80211_IFTYPE_MONITOR:
case NL80211_IFTYPE_WDS:
@@ -1003,8 +1009,10 @@ wl_cfg80211_change_virtual_iface(struct wiphy *wiphy, struct net_device *ndev,
wl_set_mode_by_netdev(wl, ndev, mode);
if (wl->p2p_supported && wl->p2p->vif_created) {
WL_DBG(("p2p_vif_created (%d) p2p_on (%d)\n", wl->p2p->vif_created,
- p2p_on(wl)));
+ p2p_on(wl)));
wldev_iovar_setint(ndev, "mpc", 0);
+ wl_notify_escan_complete(wl, ndev, true, true);
+
/* In concurrency case, STA may be already associated in a particular
* channel. so retrieve the current channel of primary interface and
* then start the virtual interface on that.
@@ -1121,6 +1129,7 @@ wl_cfg80211_ifdel_ops(struct net_device *ndev)
WL_DBG(("index : %d\n", index));
}
+
/* Wake up any waiting thread */
wake_up_interruptible(&wl->netif_change_event);
@@ -2007,7 +2016,11 @@ wl_set_set_cipher(struct net_device *dev, struct cfg80211_connect_params *sme)
WL_DBG(("pval (%d) gval (%d)\n", pval, gval));
if (is_wps_conn(sme)) {
- err = wldev_iovar_setint_bsscfg(dev, "wsec", 4, bssidx);
+ if (sme->privacy)
+ err = wldev_iovar_setint_bsscfg(dev, "wsec", 4, bssidx);
+ else
+ /* WPS-2.0 allowes no security */
+ err = wldev_iovar_setint_bsscfg(dev, "wsec", 0, bssidx);
} else {
WL_DBG((" NO, is_wps_conn, Set pval | gval to WSEC"));
err = wldev_iovar_setint_bsscfg(dev, "wsec",
@@ -2847,7 +2860,6 @@ wl_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
err = -ENODEV;
if (!wl_get_drv_status(wl, CONNECTED, dev) ||
(dhd_is_associated(dhd, NULL, &err) == FALSE)) {
-
WL_ERR(("NOT assoc: %d\n", err));
goto get_station_err;
}
@@ -3168,7 +3180,7 @@ wl_cfg80211_scan_alloc_params(int channel, int nprobes, int *out_params_size)
/* Our scan params have 1 channel and 0 ssids */
params->channel_num = htod32((0 << WL_SCAN_PARAMS_NSSID_SHIFT) |
- (num_chans & WL_SCAN_PARAMS_COUNT_MASK));
+ (num_chans & WL_SCAN_PARAMS_COUNT_MASK));
*out_params_size = params_size; /* rtn size to the caller */
return params;
@@ -3195,7 +3207,7 @@ wl_cfg80211_remain_on_channel(struct wiphy *wiphy, struct net_device *dev,
ndev = dev;
}
- if (wl->scan_request) {
+ if (wl_get_drv_status(wl, SCANNING, ndev)) {
wl_notify_escan_complete(wl, ndev, true, true);
}
target_channel = ieee80211_frequency_to_channel(channel->center_freq);
@@ -3207,7 +3219,7 @@ wl_cfg80211_remain_on_channel(struct wiphy *wiphy, struct net_device *dev,
*cookie = id;
cfg80211_ready_on_channel(dev, *cookie, channel,
channel_type, duration, GFP_KERNEL);
- if (!p2p_is_on(wl)) {
+ if (wl->p2p && !wl->p2p->on) {
get_primary_mac(wl, &primary_mac);
wl_cfgp2p_generate_bss_mac(&primary_mac, &wl->p2p->dev_addr, &wl->p2p->int_addr);
@@ -3331,7 +3343,11 @@ wl_cfg80211_mgmt_tx(struct wiphy *wiphy, struct net_device *ndev,
struct ieee80211_channel *channel, bool offchan,
enum nl80211_channel_type channel_type,
bool channel_type_valid, unsigned int wait,
- const u8* buf, size_t len, u64 *cookie)
+ const u8* buf, size_t len,
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 2, 0)
+ bool no_cck,
+#endif
+ u64 *cookie)
{
wl_action_frame_t *action_frame;
wl_af_params_t *af_params;
@@ -3418,6 +3434,10 @@ wl_cfg80211_mgmt_tx(struct wiphy *wiphy, struct net_device *ndev,
WL_DBG(("Disconnect STA : %s scb_val.val %d\n",
bcm_ether_ntoa((const struct ether_addr *)mgmt->da, eabuf),
scb_val.val));
+ /* Wait for the deauth event to come, supplicant will do the delete iface immediately
+ * and we will have problem in sending deauth frame if we delete the bss in firmware
+ */
+ wl_delay(400);
cfg80211_mgmt_tx_status(ndev, *cookie, buf, len, true, GFP_KERNEL);
goto exit;
@@ -3521,7 +3541,7 @@ wl_cfg80211_mgmt_tx(struct wiphy *wiphy, struct net_device *ndev,
}
if (IS_P2P_SOCIAL(af_params->channel) &&
- (IS_P2P_PUB_ACT_REQ(act_frm, action_frame->len) ||
+ (IS_P2P_PUB_ACT_REQ(act_frm, &act_frm->elts[0], action_frame->len) ||
IS_GAS_REQ(sd_act_frm, action_frame->len)) &&
wl_to_p2p_bss_saved_ie(wl, P2PAPI_BSSCFG_DEVICE).p2p_probe_req_ie_len) {
/* channel offload require P2P IE for Probe request
@@ -3534,7 +3554,7 @@ wl_cfg80211_mgmt_tx(struct wiphy *wiphy, struct net_device *ndev,
} else {
ack = (wl_cfgp2p_tx_action_frame(wl, dev, af_params, bssidx)) ? false : true;
if (!ack) {
- for (retry = 1; retry < WL_CHANNEL_SYNC_RETRY; retry++) {
+ for (retry = 1; retry < retry_cnt; retry++) {
ack = (wl_cfgp2p_tx_action_frame(wl, dev,
af_params, bssidx)) ? false : true;
if (ack)
@@ -4771,17 +4791,24 @@ wl_notify_connect_status(struct wl_priv *wl, struct net_device *ndev,
bool act;
s32 err = 0;
u32 event = ntoh32(e->event_type);
+ u32 reason;
if (wl_get_mode_by_netdev(wl, ndev) == WL_MODE_AP) {
wl_notify_connect_status_ap(wl, ndev, e, data);
} else {
WL_DBG(("wl_notify_connect_status : event %d status : %d ndev %p\n",
ntoh32(e->event_type), ntoh32(e->status), ndev));
+ if((event == WLC_E_DEAUTH_IND) || (event == WLC_E_DISASSOC_IND)) {
+ reason = ntoh32(e->reason);
+ wl->deauth_reason = reason;
+ WL_ERR(("Received %s event with reason code: %d\n", (event == WLC_E_DEAUTH_IND)? "WLC_E_DEAUTH_IND":"WLC_E_DISASSOC_IND", reason));
+ }
if (wl_is_linkup(wl, e, ndev)) {
wl_link_up(wl);
act = true;
wl_update_prof(wl, ndev, e, &act, WL_PROF_ACT);
wl_update_prof(wl, ndev, NULL, (void *)&e->addr, WL_PROF_BSSID);
+ wl->deauth_reason = 0;
if (wl_is_ibssmode(wl, ndev)) {
printk("cfg80211_ibss_joined\n");
cfg80211_ibss_joined(ndev, (s8 *)&e->addr,
@@ -4809,7 +4836,6 @@ wl_notify_connect_status(struct wl_priv *wl, struct net_device *ndev,
if (wl_get_drv_status(wl, CONNECTED, ndev)) {
scb_val_t scbval;
u8 *curbssid = wl_read_prof(wl, ndev, WL_PROF_BSSID);
- printk("link down, call cfg80211_disconnected\n");
wl_clr_drv_status(wl, CONNECTED, ndev);
if (! wl_get_drv_status(wl, DISCONNECTING, ndev)) {
/* To make sure disconnect, explictly send dissassoc
@@ -4821,7 +4847,8 @@ wl_notify_connect_status(struct wl_priv *wl, struct net_device *ndev,
scbval.val = htod32(scbval.val);
wldev_ioctl(ndev, WLC_DISASSOC, &scbval,
sizeof(scb_val_t), true);
- cfg80211_disconnected(ndev, 0, NULL, 0, GFP_KERNEL);
+ WL_ERR(("link down, calling cfg80211_disconnected with deauth_reason:%d\n", wl->deauth_reason));
+ cfg80211_disconnected(ndev, wl->deauth_reason , NULL, 0, GFP_KERNEL);
wl_link_down(wl);
wl_init_prof(wl, ndev);
}
@@ -5821,7 +5848,7 @@ static void wl_scan_timeout(unsigned long data)
if (wl->scan_request) {
WL_ERR(("timer expired\n"));
if (wl->escan_on)
- wl_notify_escan_complete(wl, wl->escan_info.ndev, false, true);
+ wl_notify_escan_complete(wl, wl->escan_info.ndev, true, false);
else
wl_notify_iscan_complete(wl_to_iscan(wl), true);
}
@@ -5877,7 +5904,7 @@ wl_cfg80211_netdev_notifier_call(struct notifier_block * nb,
struct wl_priv *wl = wlcfg_drv_priv;
WL_DBG(("Enter \n"));
- if (!wdev || dev == wl_to_prmry_ndev(wl))
+ if (!wdev || !wl || dev == wl_to_prmry_ndev(wl))
return NOTIFY_DONE;
switch (state) {
case NETDEV_UNREGISTER:
@@ -5942,7 +5969,7 @@ static s32 wl_notify_escan_complete(struct wl_priv *wl,
}
}
}
- if (!in_atomic())
+ if (timer_pending(&wl->scan_timeout))
del_timer_sync(&wl->scan_timeout);
spin_lock_irqsave(&wl->cfgdrv_lock, flags);
@@ -5984,7 +6011,6 @@ static s32 wl_escan_handler(struct wl_priv *wl,
wl_scan_results_t *list;
u32 bi_length;
u32 i;
- u8 *p2p_dev_addr = NULL;
WL_DBG((" enter event type : %d, status : %d \n",
ntoh32(e->event_type), ntoh32(e->status)));
@@ -6033,8 +6059,7 @@ static s32 wl_escan_handler(struct wl_priv *wl,
}
if (wl_get_drv_status_all(wl, SENDING_ACT_FRM)) {
- p2p_dev_addr = wl_cfgp2p_retreive_p2p_dev_addr(bi, bi_length);
- if (p2p_dev_addr && !memcmp(p2p_dev_addr,
+ if (!memcmp(bi->BSSID.octet,
wl->afx_hdl->pending_tx_dst_addr.octet, ETHER_ADDR_LEN)) {
s32 channel = CHSPEC_CHANNEL(dtohchanspec(bi->chanspec));
WL_DBG(("ACTION FRAME SCAN : Peer found, channel : %d\n", channel));
@@ -6187,6 +6212,7 @@ static s32 wl_init_priv(struct wl_priv *wl)
wl->iscan_kickstart = false;
wl->active_scan = true;
wl->rf_blocked = false;
+ wl->deauth_reason = 0;
spin_lock_init(&wl->cfgdrv_lock);
mutex_init(&wl->ioctl_buf_sync);
init_waitqueue_head(&wl->netif_change_event);
@@ -6711,12 +6737,16 @@ s32 wl_update_wiphybands(struct wl_priv *wl)
}
if ((index >= 0) && nmode) {
wiphy->bands[index]->ht_cap.cap =
- IEEE80211_HT_CAP_DSSSCCK40
- | IEEE80211_HT_CAP_MAX_AMSDU | IEEE80211_HT_CAP_RX_STBC;
+ IEEE80211_HT_CAP_SGI_20 | IEEE80211_HT_CAP_DSSSCCK40 |
+ IEEE80211_HT_CAP_MAX_AMSDU;
wiphy->bands[index]->ht_cap.ht_supported = TRUE;
- wiphy->bands[index]->ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_16K;
+ wiphy->bands[index]->ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K;
wiphy->bands[index]->ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16;
}
+
+ if ((index >= 0) && bw_40) {
+ wiphy->bands[index]->ht_cap.cap |= IEEE80211_HT_CAP_SGI_40;
+ }
}
wiphy_apply_custom_regulatory(wiphy, &brcm_regdom);
@@ -7043,7 +7073,8 @@ static void wl_init_eq_lock(struct wl_priv *wl)
static void wl_delay(u32 ms)
{
- if (in_atomic() || ms < 1000 / HZ) {
+ if (ms < 1000 / HZ) {
+ cond_resched();
mdelay(ms);
} else {
msleep(ms);
diff --git a/drivers/net/wireless/bcmdhd/wl_cfg80211.h b/drivers/net/wireless/bcmdhd/wl_cfg80211.h
index 818eff5..fba8531 100644
--- a/drivers/net/wireless/bcmdhd/wl_cfg80211.h
+++ b/drivers/net/wireless/bcmdhd/wl_cfg80211.h
@@ -131,8 +131,8 @@ do { \
#define IFACE_MAX_CNT 2
#define WL_SCAN_TIMER_INTERVAL_MS 8000 /* Scan timeout */
-#define WL_CHANNEL_SYNC_RETRY 1
-#define WL_ACT_FRAME_RETRY 5
+#define WL_CHANNEL_SYNC_RETRY 3
+#define WL_ACT_FRAME_RETRY 4
#define WL_INVALID -1
@@ -449,6 +449,7 @@ struct wl_priv {
#endif /* WL_SCHED_SCAN */
bool sched_scan_running; /* scheduled scan req status */
u16 hostapd_chan; /* remember chan requested by framework for hostapd */
+ u16 deauth_reason; /* Place holder to save deauth/disassoc reasons */
};
static inline struct wl_bss_info *next_bss(struct wl_scan_results *list, struct wl_bss_info *bss)
diff --git a/drivers/net/wireless/bcmdhd/wl_cfgp2p.c b/drivers/net/wireless/bcmdhd/wl_cfgp2p.c
index 880123e..cfa5ac3 100644
--- a/drivers/net/wireless/bcmdhd/wl_cfgp2p.c
+++ b/drivers/net/wireless/bcmdhd/wl_cfgp2p.c
@@ -105,6 +105,7 @@ bool wl_cfgp2p_is_p2p_action(void *frame, u32 frame_len)
return false;
}
+
bool wl_cfgp2p_is_gas_action(void *frame, u32 frame_len)
{
@@ -128,6 +129,7 @@ bool wl_cfgp2p_is_gas_action(void *frame, u32 frame_len)
return false;
}
+
void wl_cfgp2p_print_actframe(bool tx, void *frame, u32 frame_len)
{
wifi_p2p_pub_act_frame_t *pact_frm;
@@ -271,7 +273,6 @@ wl_cfgp2p_init_priv(struct wl_priv *wl)
wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_DEVICE) = 0;
wl_to_p2p_bss_ndev(wl, P2PAPI_BSSCFG_CONNECTION) = NULL;
wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_CONNECTION) = 0;
- spin_lock_init(&wl->p2p->timer_lock);
return BCME_OK;
}
@@ -318,7 +319,7 @@ wl_cfgp2p_set_firm_p2p(struct wl_priv *wl)
ret = wldev_iovar_setbuf_bsscfg(ndev, "p2p_da_override", &null_eth_addr,
sizeof(null_eth_addr), wl->ioctl_buf, WLC_IOCTL_MAXLEN, 0, &wl->ioctl_buf_sync);
if (ret && ret != BCME_UNSUPPORTED) {
- CFGP2P_ERR(("failed to update device address\n"));
+ CFGP2P_ERR(("failed to update device address ret %d\n", ret));
}
return ret;
}
@@ -539,7 +540,7 @@ wl_cfgp2p_init_discovery(struct wl_priv *wl)
/* Set the initial discovery state to SCAN */
ret = wl_cfgp2p_set_p2p_mode(wl, WL_P2P_DISC_ST_SCAN, 0, 0,
- wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_DEVICE));
+ wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_DEVICE));
if (unlikely(ret != 0)) {
CFGP2P_ERR(("unable to set WL_P2P_DISC_ST_SCAN\n"));
@@ -690,7 +691,7 @@ wl_cfgp2p_escan(struct wl_priv *wl, struct net_device *dev, u16 active,
#define P2PAPI_SCAN_NPROBES 1
#define P2PAPI_SCAN_DWELL_TIME_MS 50
#define P2PAPI_SCAN_SOCIAL_DWELL_TIME_MS 40
-#define P2PAPI_SCAN_HOME_TIME_MS 10
+#define P2PAPI_SCAN_HOME_TIME_MS 60
struct net_device *pri_dev = wl_to_p2p_bss_ndev(wl, P2PAPI_BSSCFG_PRIMARY);
wl_set_p2p_status(wl, SCANNING);
/* Allocate scan params which need space for 3 channels and 0 ssids */
@@ -1180,12 +1181,15 @@ wl_cfgp2p_listen_complete(struct wl_priv *wl, struct net_device *ndev,
s32 ret = BCME_OK;
CFGP2P_DBG((" Enter\n"));
+
+ /* If p2p_info is de-initialized, do nothing */
+ if (!wl->p2p)
+ return ret;
+
if (wl_get_p2p_status(wl, LISTEN_EXPIRED) == 0) {
wl_set_p2p_status(wl, LISTEN_EXPIRED);
if (timer_pending(&wl->p2p->listen_timer)) {
- spin_lock_bh(&wl->p2p->timer_lock);
del_timer_sync(&wl->p2p->listen_timer);
- spin_unlock_bh(&wl->p2p->timer_lock);
}
cfg80211_remain_on_channel_expired(ndev, wl->last_roc_id, &wl->remain_on_chan,
wl->remain_on_chan_type, GFP_KERNEL);
@@ -1213,6 +1217,33 @@ wl_cfgp2p_listen_expired(unsigned long data)
}
/*
+ * Routine for cancelling the P2P LISTEN
+ */
+s32
+wl_cfgp2p_cancel_listen(struct wl_priv *wl, struct net_device *ndev,
+ bool notify)
+{
+ WL_DBG(("Enter \n"));
+
+ /* Irrespective of whether timer is running or not, reset
+ * the LISTEN state.
+ */
+ wl_cfgp2p_set_p2p_mode(wl, WL_P2P_DISC_ST_SCAN, 0, 0,
+ wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_DEVICE));
+
+ if (timer_pending(&wl->p2p->listen_timer)) {
+ del_timer_sync(&wl->p2p->listen_timer);
+
+ if (notify)
+ cfg80211_remain_on_channel_expired(ndev, wl->last_roc_id,
+ &wl->remain_on_chan, wl->remain_on_chan_type, GFP_KERNEL);
+ }
+
+
+ return 0;
+}
+
+/*
* Do a P2P Listen on the given channel for the given duration.
* A listen consists of sitting idle and responding to P2P probe requests
* with a P2P probe response.
@@ -1531,8 +1562,10 @@ wl_cfgp2p_supported(struct wl_priv *wl, struct net_device *ndev)
s32
wl_cfgp2p_down(struct wl_priv *wl)
{
- if (timer_pending(&wl->p2p->listen_timer))
- del_timer_sync(&wl->p2p->listen_timer);
+
+ wl_cfgp2p_cancel_listen(wl,
+ wl->p2p_net ? wl->p2p_net : wl_to_prmry_ndev(wl), TRUE);
+
wl_cfgp2p_deinit_priv(wl);
return 0;
}
diff --git a/drivers/net/wireless/bcmdhd/wl_cfgp2p.h b/drivers/net/wireless/bcmdhd/wl_cfgp2p.h
index 1e5b119..be497c3 100644
--- a/drivers/net/wireless/bcmdhd/wl_cfgp2p.h
+++ b/drivers/net/wireless/bcmdhd/wl_cfgp2p.h
@@ -77,7 +77,6 @@ struct p2p_info {
wl_p2p_sched_t noa;
wl_p2p_ops_t ops;
wlc_ssid_t ssid;
- spinlock_t timer_lock;
};
/* dongle status */
@@ -268,14 +267,16 @@ wl_cfgp2p_unregister_ndev(struct wl_priv *wl);
#define WL_P2P_INTERFACE_PREFIX "p2p"
#define WL_P2P_TEMP_CHAN "11"
+/* If the provision discovery is for JOIN operations, then we need not do an internal scan to find GO */
+#define IS_PROV_DISC_WITHOUT_GROUP_ID(p2p_ie, len) (wl_cfgp2p_retreive_p2pattrib(p2p_ie, P2P_SEID_GROUP_ID) == NULL )
#define IS_GAS_REQ(frame, len) (wl_cfgp2p_is_gas_action(frame, len) && \
((frame->action == P2PSD_ACTION_ID_GAS_IREQ) || \
(frame->action == P2PSD_ACTION_ID_GAS_CREQ)))
-#define IS_P2P_PUB_ACT_REQ(frame, len) (wl_cfgp2p_is_pub_action(frame, len) && \
+#define IS_P2P_PUB_ACT_REQ(frame, p2p_ie, len) (wl_cfgp2p_is_pub_action(frame, len) && \
((frame->subtype == P2P_PAF_GON_REQ) || \
(frame->subtype == P2P_PAF_INVITE_REQ) || \
- (frame->subtype == P2P_PAF_PROVDIS_REQ)))
+ ((frame->subtype == P2P_PAF_PROVDIS_REQ) && IS_PROV_DISC_WITHOUT_GROUP_ID(p2p_ie, len))))
#define IS_P2P_SOCIAL(ch) ((ch == SOCIAL_CHAN_1) || (ch == SOCIAL_CHAN_2) || (ch == SOCIAL_CHAN_3))
#define IS_P2P_SSID(ssid) (memcmp(ssid, WL_P2P_WILDCARD_SSID, WL_P2P_WILDCARD_SSID_LEN) == 0)
#endif /* _wl_cfgp2p_h_ */
diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c
index 97edee2..0781fb0 100644
--- a/drivers/net/wireless/rt2x00/rt2800usb.c
+++ b/drivers/net/wireless/rt2x00/rt2800usb.c
@@ -819,11 +819,14 @@ static struct usb_device_id rt2800usb_device_table[] = {
{ USB_DEVICE(0x050d, 0x8053) },
{ USB_DEVICE(0x050d, 0x805c) },
{ USB_DEVICE(0x050d, 0x815c) },
+ { USB_DEVICE(0x050d, 0x825a) },
{ USB_DEVICE(0x050d, 0x825b) },
{ USB_DEVICE(0x050d, 0x935a) },
{ USB_DEVICE(0x050d, 0x935b) },
/* Buffalo */
{ USB_DEVICE(0x0411, 0x00e8) },
+ { USB_DEVICE(0x0411, 0x0158) },
+ { USB_DEVICE(0x0411, 0x015d) },
{ USB_DEVICE(0x0411, 0x016f) },
{ USB_DEVICE(0x0411, 0x01a2) },
/* Corega */
@@ -838,6 +841,8 @@ static struct usb_device_id rt2800usb_device_table[] = {
{ USB_DEVICE(0x07d1, 0x3c0e) },
{ USB_DEVICE(0x07d1, 0x3c0f) },
{ USB_DEVICE(0x07d1, 0x3c11) },
+ { USB_DEVICE(0x07d1, 0x3c13) },
+ { USB_DEVICE(0x07d1, 0x3c15) },
{ USB_DEVICE(0x07d1, 0x3c16) },
{ USB_DEVICE(0x2001, 0x3c1b) },
/* Draytek */
@@ -846,6 +851,7 @@ static struct usb_device_id rt2800usb_device_table[] = {
{ USB_DEVICE(0x7392, 0x7711) },
{ USB_DEVICE(0x7392, 0x7717) },
{ USB_DEVICE(0x7392, 0x7718) },
+ { USB_DEVICE(0x7392, 0x7722) },
/* Encore */
{ USB_DEVICE(0x203d, 0x1480) },
{ USB_DEVICE(0x203d, 0x14a9) },
@@ -880,6 +886,7 @@ static struct usb_device_id rt2800usb_device_table[] = {
{ USB_DEVICE(0x1737, 0x0070) },
{ USB_DEVICE(0x1737, 0x0071) },
{ USB_DEVICE(0x1737, 0x0077) },
+ { USB_DEVICE(0x1737, 0x0078) },
/* Logitec */
{ USB_DEVICE(0x0789, 0x0162) },
{ USB_DEVICE(0x0789, 0x0163) },
@@ -903,9 +910,13 @@ static struct usb_device_id rt2800usb_device_table[] = {
{ USB_DEVICE(0x0db0, 0x871b) },
{ USB_DEVICE(0x0db0, 0x871c) },
{ USB_DEVICE(0x0db0, 0x899a) },
+ /* Ovislink */
+ { USB_DEVICE(0x1b75, 0x3071) },
+ { USB_DEVICE(0x1b75, 0x3072) },
/* Para */
{ USB_DEVICE(0x20b8, 0x8888) },
/* Pegatron */
+ { USB_DEVICE(0x1d4d, 0x0002) },
{ USB_DEVICE(0x1d4d, 0x000c) },
{ USB_DEVICE(0x1d4d, 0x000e) },
{ USB_DEVICE(0x1d4d, 0x0011) },
@@ -943,6 +954,7 @@ static struct usb_device_id rt2800usb_device_table[] = {
{ USB_DEVICE(0x0df6, 0x0048) },
{ USB_DEVICE(0x0df6, 0x0051) },
{ USB_DEVICE(0x0df6, 0x005f) },
+ { USB_DEVICE(0x0df6, 0x0060) },
/* SMC */
{ USB_DEVICE(0x083a, 0x6618) },
{ USB_DEVICE(0x083a, 0x7511) },
@@ -957,7 +969,9 @@ static struct usb_device_id rt2800usb_device_table[] = {
/* Sparklan */
{ USB_DEVICE(0x15a9, 0x0006) },
/* Sweex */
+ { USB_DEVICE(0x177f, 0x0153) },
{ USB_DEVICE(0x177f, 0x0302) },
+ { USB_DEVICE(0x177f, 0x0313) },
/* U-Media */
{ USB_DEVICE(0x157e, 0x300e) },
{ USB_DEVICE(0x157e, 0x3013) },
@@ -975,6 +989,8 @@ static struct usb_device_id rt2800usb_device_table[] = {
{ USB_DEVICE(0x0586, 0x341e) },
{ USB_DEVICE(0x0586, 0x343e) },
#ifdef CONFIG_RT2800USB_RT33XX
+ /* Belkin */
+ { USB_DEVICE(0x050d, 0x945b) },
/* Ralink */
{ USB_DEVICE(0x148f, 0x3370) },
{ USB_DEVICE(0x148f, 0x8070) },
@@ -999,6 +1015,7 @@ static struct usb_device_id rt2800usb_device_table[] = {
{ USB_DEVICE(0x148f, 0x3572) },
/* Sitecom */
{ USB_DEVICE(0x0df6, 0x0041) },
+ { USB_DEVICE(0x0df6, 0x0062) },
/* Toshiba */
{ USB_DEVICE(0x0930, 0x0a07) },
/* Zinwell */
@@ -1038,27 +1055,24 @@ static struct usb_device_id rt2800usb_device_table[] = {
{ USB_DEVICE(0x13d3, 0x3322) },
/* Belkin */
{ USB_DEVICE(0x050d, 0x1003) },
- { USB_DEVICE(0x050d, 0x825a) },
/* Buffalo */
{ USB_DEVICE(0x0411, 0x012e) },
{ USB_DEVICE(0x0411, 0x0148) },
{ USB_DEVICE(0x0411, 0x0150) },
- { USB_DEVICE(0x0411, 0x015d) },
/* Corega */
{ USB_DEVICE(0x07aa, 0x0041) },
{ USB_DEVICE(0x07aa, 0x0042) },
{ USB_DEVICE(0x18c5, 0x0008) },
/* D-Link */
{ USB_DEVICE(0x07d1, 0x3c0b) },
- { USB_DEVICE(0x07d1, 0x3c13) },
- { USB_DEVICE(0x07d1, 0x3c15) },
{ USB_DEVICE(0x07d1, 0x3c17) },
{ USB_DEVICE(0x2001, 0x3c17) },
/* Edimax */
{ USB_DEVICE(0x7392, 0x4085) },
- { USB_DEVICE(0x7392, 0x7722) },
/* Encore */
{ USB_DEVICE(0x203d, 0x14a1) },
+ /* Fujitsu Stylistic 550 */
+ { USB_DEVICE(0x1690, 0x0761) },
/* Gemtek */
{ USB_DEVICE(0x15a9, 0x0010) },
/* Gigabyte */
@@ -1070,19 +1084,13 @@ static struct usb_device_id rt2800usb_device_table[] = {
/* LevelOne */
{ USB_DEVICE(0x1740, 0x0605) },
{ USB_DEVICE(0x1740, 0x0615) },
- /* Linksys */
- { USB_DEVICE(0x1737, 0x0078) },
/* Logitec */
{ USB_DEVICE(0x0789, 0x0168) },
{ USB_DEVICE(0x0789, 0x0169) },
/* Motorola */
{ USB_DEVICE(0x100d, 0x9032) },
- /* Ovislink */
- { USB_DEVICE(0x1b75, 0x3071) },
- { USB_DEVICE(0x1b75, 0x3072) },
/* Pegatron */
{ USB_DEVICE(0x05a6, 0x0101) },
- { USB_DEVICE(0x1d4d, 0x0002) },
{ USB_DEVICE(0x1d4d, 0x0010) },
/* Planex */
{ USB_DEVICE(0x2019, 0x5201) },
@@ -1096,16 +1104,11 @@ static struct usb_device_id rt2800usb_device_table[] = {
{ USB_DEVICE(0x0df6, 0x004a) },
{ USB_DEVICE(0x0df6, 0x004d) },
{ USB_DEVICE(0x0df6, 0x0053) },
- { USB_DEVICE(0x0df6, 0x0060) },
- { USB_DEVICE(0x0df6, 0x0062) },
/* SMC */
{ USB_DEVICE(0x083a, 0xa512) },
{ USB_DEVICE(0x083a, 0xc522) },
{ USB_DEVICE(0x083a, 0xd522) },
{ USB_DEVICE(0x083a, 0xf511) },
- /* Sweex */
- { USB_DEVICE(0x177f, 0x0153) },
- { USB_DEVICE(0x177f, 0x0313) },
/* Zyxel */
{ USB_DEVICE(0x0586, 0x341a) },
#endif
diff --git a/drivers/net/wireless/rtlwifi/pci.c b/drivers/net/wireless/rtlwifi/pci.c
index 6c56198..61291a1 100644
--- a/drivers/net/wireless/rtlwifi/pci.c
+++ b/drivers/net/wireless/rtlwifi/pci.c
@@ -954,8 +954,13 @@ static void _rtl_pci_prepare_bcn_tasklet(struct ieee80211_hw *hw)
memset(&tcb_desc, 0, sizeof(struct rtl_tcb_desc));
ring = &rtlpci->tx_ring[BEACON_QUEUE];
pskb = __skb_dequeue(&ring->queue);
- if (pskb)
+ if (pskb) {
+ struct rtl_tx_desc *entry = &ring->desc[ring->idx];
+ pci_unmap_single(rtlpci->pdev, rtlpriv->cfg->ops->get_desc(
+ (u8 *) entry, true, HW_DESC_TXBUFF_ADDR),
+ pskb->len, PCI_DMA_TODEVICE);
kfree_skb(pskb);
+ }
/*NB: the beacon data buffer must be 32-bit aligned. */
pskb = ieee80211_beacon_get(hw, mac->vif);