Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

bcm4329: update to 4.218.248-23

Includes changes from: https://github.com/pershoot/gtab-2632/commits/gingerbread/drivers/net/wireless/bcm4329
Plus modifications for Huawei U8160 support
  • Loading branch information...
commit b549d807f142fcb9cfef2b93225ad0200dfb1d6e 1 parent 9638998
@psyke83 authored
Showing with 7,120 additions and 1,672 deletions.
  1. +16 −2 drivers/net/wireless/bcm4329/Kconfig
  2. +12 −10 drivers/net/wireless/bcm4329/Makefile
  3. +2 −2 drivers/net/wireless/bcm4329/aiutils.c
  4. +9 −4 drivers/net/wireless/bcm4329/bcmpcispi.c
  5. +2 −6 drivers/net/wireless/bcm4329/bcmsdh.c
  6. +84 −36 drivers/net/wireless/bcm4329/bcmsdh_linux.c
  7. +9 −8 drivers/net/wireless/bcm4329/bcmsdh_sdmmc.c
  8. +39 −13 drivers/net/wireless/bcm4329/bcmsdh_sdmmc_linux.c
  9. +1 −1  drivers/net/wireless/bcm4329/bcmsdspi_linux.c
  10. +9 −12 drivers/net/wireless/bcm4329/bcmsdstd.c
  11. +5 −3 drivers/net/wireless/bcm4329/bcmsdstd_linux.c
  12. +1 −1  drivers/net/wireless/bcm4329/bcmutils.c
  13. +1 −1  drivers/net/wireless/bcm4329/bcmwifi.c
  14. +104 −30 drivers/net/wireless/bcm4329/dhd.h
  15. +6 −2 drivers/net/wireless/bcm4329/dhd_bus.h
  16. +32 −281 drivers/net/wireless/bcm4329/dhd_cdc.c
  17. +1,564 −28 drivers/net/wireless/bcm4329/dhd_common.c
  18. +78 −11 drivers/net/wireless/bcm4329/dhd_custom_gpio.c
  19. +5 −2 drivers/net/wireless/bcm4329/dhd_dbg.h
  20. +859 −162 drivers/net/wireless/bcm4329/dhd_linux.c
  21. +1 −1  drivers/net/wireless/bcm4329/dhd_linux_sched.c
  22. +7 −3 drivers/net/wireless/bcm4329/dhd_proto.h
  23. +453 −71 drivers/net/wireless/bcm4329/dhd_sdio.c
  24. +1 −1  drivers/net/wireless/bcm4329/dngl_stats.h
  25. +216 −0 drivers/net/wireless/bcm4329/firmware/LICENSE.TXT
  26. +2 −2 drivers/net/wireless/bcm4329/hndpmu.c
  27. +1 −1  drivers/net/wireless/bcm4329/include/aidmp.h
  28. +1 −1  drivers/net/wireless/bcm4329/include/bcmcdc.h
  29. +1 −1  drivers/net/wireless/bcm4329/include/bcmdevs.h
  30. +1 −1  drivers/net/wireless/bcm4329/include/bcmendian.h
  31. +1 −1  drivers/net/wireless/bcm4329/include/bcmpcispi.h
  32. +1 −1  drivers/net/wireless/bcm4329/include/bcmperf.h
  33. +1 −1  drivers/net/wireless/bcm4329/include/bcmsdbus.h
  34. +1 −1  drivers/net/wireless/bcm4329/include/bcmsdh.h
  35. +1 −1  drivers/net/wireless/bcm4329/include/bcmsdh_sdmmc.h
  36. +4 −3 drivers/net/wireless/bcm4329/include/bcmsdpcm.h
  37. +1 −1  drivers/net/wireless/bcm4329/include/bcmsdspi.h
  38. +1 −1  drivers/net/wireless/bcm4329/include/bcmspi.h
  39. +134 −0 drivers/net/wireless/bcm4329/include/bcmspibrcm.h
  40. +1 −1  drivers/net/wireless/bcm4329/include/bcmutils.h
  41. +2 −2 drivers/net/wireless/bcm4329/include/bcmwifi.h
  42. +3 −2 drivers/net/wireless/bcm4329/include/dhdioctl.h
  43. +6 −6 drivers/net/wireless/bcm4329/include/epivers.h
  44. +2 −2 drivers/net/wireless/bcm4329/include/hndpmu.h
  45. +88 −0 drivers/net/wireless/bcm4329/include/hndrte_armtrap.h
  46. +63 −0 drivers/net/wireless/bcm4329/include/hndrte_cons.h
  47. +1 −1  drivers/net/wireless/bcm4329/include/hndsoc.h
  48. +2 −3 drivers/net/wireless/bcm4329/include/linux_osl.h
  49. +4 −3 drivers/net/wireless/bcm4329/include/linuxver.h
  50. +1 −1  drivers/net/wireless/bcm4329/include/miniopt.h
  51. +1 −1  drivers/net/wireless/bcm4329/include/msgtrace.h
  52. +1 −1  drivers/net/wireless/bcm4329/include/osl.h
  53. +1 −1  drivers/net/wireless/bcm4329/include/packed_section_end.h
  54. +1 −1  drivers/net/wireless/bcm4329/include/packed_section_start.h
  55. +1 −1  drivers/net/wireless/bcm4329/include/pcicfg.h
  56. +3 −0  drivers/net/wireless/bcm4329/include/proto/802.11.h
  57. +1 −1  drivers/net/wireless/bcm4329/include/proto/802.11e.h
  58. +1 −1  drivers/net/wireless/bcm4329/include/proto/802.1d.h
  59. +1 −1  drivers/net/wireless/bcm4329/include/proto/bcmeth.h
  60. +7 −6 drivers/net/wireless/bcm4329/include/proto/bcmevent.h
  61. +1 −1  drivers/net/wireless/bcm4329/include/proto/bcmip.h
  62. +3 −2 drivers/net/wireless/bcm4329/include/proto/ethernet.h
  63. +1 −1  drivers/net/wireless/bcm4329/include/proto/sdspi.h
  64. +1 −1  drivers/net/wireless/bcm4329/include/proto/vlan.h
  65. +1 −1  drivers/net/wireless/bcm4329/include/proto/wpa.h
  66. +0 −111 drivers/net/wireless/bcm4329/include/sbchipc.h
  67. +1 −1  drivers/net/wireless/bcm4329/include/sbconfig.h
  68. +1 −1  drivers/net/wireless/bcm4329/include/sbhnddma.h
  69. +1 −1  drivers/net/wireless/bcm4329/include/sbpcmcia.h
  70. +1 −1  drivers/net/wireless/bcm4329/include/sbsdio.h
  71. +1 −1  drivers/net/wireless/bcm4329/include/sbsdpcmdev.h
  72. +1 −1  drivers/net/wireless/bcm4329/include/sbsocram.h
  73. +1 −1  drivers/net/wireless/bcm4329/include/sdio.h
  74. +1 −2  drivers/net/wireless/bcm4329/include/siutils.h
  75. +153 −0 drivers/net/wireless/bcm4329/include/spid.h
  76. +1 −1  drivers/net/wireless/bcm4329/include/trxhdr.h
  77. +1 −1  drivers/net/wireless/bcm4329/include/typedefs.h
  78. +18 −9 drivers/net/wireless/bcm4329/include/wlioctl.h
  79. +6 −5 drivers/net/wireless/bcm4329/linux_osl.c
  80. +1 −1  drivers/net/wireless/bcm4329/miniopt.c
  81. +2 −2 drivers/net/wireless/bcm4329/sbutils.c
  82. +3 −2 drivers/net/wireless/bcm4329/siutils.c
  83. +1 −1  drivers/net/wireless/bcm4329/siutils_priv.h
  84. +2,894 −754 drivers/net/wireless/bcm4329/wl_iw.c
  85. +140 −28 drivers/net/wireless/bcm4329/wl_iw.h
  86. +27 −0 include/linux/wlan_plat.h
View
18 drivers/net/wireless/bcm4329/Kconfig
@@ -13,13 +13,27 @@ config BCM4329
config BCM4329_FW_PATH
depends on BCM4329
string "Firmware path"
- default "/system/etc/firmware/fw_bcm4329.bin"
+ default "/system/lib/hw/wlan/fw_bcm4329.bin"
---help---
Path to the firmware file.
config BCM4329_NVRAM_PATH
depends on BCM4329
string "NVRAM path"
- default "/proc/calibration"
+ default "/system/lib/hw/wlan/nvram.txt"
---help---
Path to the calibration file.
+
+config BCM4329_ENABLE_CSCAN
+ depends on BCM4329
+ bool "Enable CSCAN"
+ default n
+ ---help---
+ Enable the use of CSCAN methods.
+
+config BCM4329_ENABLE_PNO_SUPPORT
+ depends on BCM4329_ENABLE_CSCAN
+ bool "Enable PNO_SUPPORT"
+ default n
+ ---help---
+ Enable the use of PNO_SUPPORT methods.
View
22 drivers/net/wireless/bcm4329/Makefile
@@ -1,18 +1,20 @@
# bcm4329
-DHDCFLAGS = -DLINUX -DBCMDRIVER -DBCMDONGLEHOST -DDHDTHREAD -DBCMWPA2 \
- -DUNRELEASEDCHIP -Dlinux -DDHD_SDALIGN=64 -DMAX_HDR_READ=64 \
- -DDHD_FIRSTREAD=64 -DDHD_GPL -DDHD_SCHED -DBDC -DTOE -DDHD_BCMEVENTS \
- -DSHOW_EVENTS -DBCMSDIO -DDHD_GPL -DBCMLXSDMMC -DBCMPLATFORM_BUS \
- -Wall -Wstrict-prototypes -Werror -DOOB_INTR_ONLY -DCUSTOMER_HW2 \
- -DDHD_USE_STATIC_BUF -DMMC_SDIO_ABORT -DSOFTAP \
+DHDCFLAGS = -DLINUX -DBCMDRIVER -DBCMDONGLEHOST -DDHDTHREAD \
+ -DBCMWPA2 -DBCMWAPI_WPI -DUNRELEASEDCHIP -DCONFIG_WIRELESS_EXT \
+ -DDHD_GPL -DDHD_SCHED -DBDC -DTOE -DDHD_BCMEVENTS \
+ -DSHOW_EVENTS -DBCMSDIO -DDHD_GPL -DHW_OOB -DOOB_INTR_ONLY \
+ -DBCMLXSDMMC -DBCMPLATFORM_BUS -DEMBEDDED_PLATFORM -DOEM_ANDROID \
+ -DARP_OFFLOAD_SUPPORT -DPKT_FILTER_SUPPORT \
+ -DCUSTOMER_HW2 -DCUSTOM_OOB_GPIO_NUM=17 -DCUSTOM_SDCC_WIFI_SLOT=2 \
+ -DSOFTAP -Wall -Wstrict-prototypes \ \
-Idrivers/net/wireless/bcm4329 -Idrivers/net/wireless/bcm4329/include
DHDOFILES = dhd_linux.o linux_osl.o bcmutils.o dhd_common.o dhd_custom_gpio.o \
- wl_iw.o siutils.o sbutils.o aiutils.o hndpmu.o bcmwifi.o dhd_sdio.o \
- dhd_linux_sched.o dhd_cdc.o bcmsdh_sdmmc.o bcmsdh.o bcmsdh_linux.o \
+ siutils.o sbutils.o aiutils.o hndpmu.o dhd_linux_sched.o bcmwifi.o \
+ wl_iw.o dhd_cdc.o dhd_sdio.o bcmsdh_sdmmc.o bcmsdh.o bcmsdh_linux.o \
bcmsdh_sdmmc_linux.o
-obj-$(CONFIG_BCM4329) += bcm4329.o
-bcm4329-objs += $(DHDOFILES)
+obj-$(CONFIG_BCM4329) += dhd.o
+dhd-objs += $(DHDOFILES)
EXTRA_CFLAGS = $(DHDCFLAGS)
EXTRA_LDFLAGS += --strip-debug
View
4 drivers/net/wireless/bcm4329/aiutils.c
@@ -2,7 +2,7 @@
* Misc utility routines for accessing chip-specific features
* of the SiliconBackplane-based Broadcom chips.
*
- * Copyright (C) 1999-2009, Broadcom Corporation
+ * Copyright (C) 1999-2010, Broadcom Corporation
*
* Unless you and Broadcom execute a separate written software license
* agreement governing use of this software, this software is licensed to you
@@ -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: aiutils.c,v 1.6.4.7.4.5 2009/09/25 00:32:01 Exp $
+ * $Id: aiutils.c,v 1.6.4.7.4.6 2010/04/21 20:43:47 Exp $
*/
#include <typedefs.h>
View
13 drivers/net/wireless/bcm4329/bcmpcispi.c
@@ -1,7 +1,7 @@
/*
* Broadcom SPI over PCI-SPI Host Controller, low-level hardware driver
*
- * Copyright (C) 1999-2009, Broadcom Corporation
+ * Copyright (C) 1999-2010, Broadcom Corporation
*
* Unless you and Broadcom execute a separate written software license
* agreement governing use of this software, this software is licensed to you
@@ -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: bcmpcispi.c,v 1.22.2.4.4.5 2008/07/09 21:23:30 Exp $
+ * $Id: bcmpcispi.c,v 1.22.2.4.4.5.6.1 2010/08/13 00:26:05 Exp $
*/
#include <typedefs.h>
@@ -606,18 +606,23 @@ spi_spinbits(sdioh_info_t *sd)
spin_count = 0;
while ((SPIPCI_RREG(sd->osh, &regs->spih_stat) & SPIH_WFEMPTY) == 0) {
if (spin_count > SPI_SPIN_BOUND) {
- ASSERT(FALSE); /* Spin bound exceeded */
+ sd_err(("%s: SPIH_WFEMPTY spin bits out of bound %u times \n",
+ __FUNCTION__, spin_count));
+ ASSERT(FALSE);
}
spin_count++;
}
- spin_count = 0;
+
/* Wait for SPI Transfer state machine to return to IDLE state.
* The state bits are only implemented in Rev >= 5 FPGA. These
* bits are hardwired to 00 for Rev < 5, so this check doesn't cause
* any problems.
*/
+ spin_count = 0;
while ((SPIPCI_RREG(osh, &regs->spih_stat) & SPIH_STATE_MASK) != 0) {
if (spin_count > SPI_SPIN_BOUND) {
+ sd_err(("%s: SPIH_STATE_MASK spin bits out of bound %u times \n",
+ __FUNCTION__, spin_count));
ASSERT(FALSE);
}
spin_count++;
View
8 drivers/net/wireless/bcm4329/bcmsdh.c
@@ -2,7 +2,7 @@
* BCMSDH interface glue
* implement bcmsdh API for SDIOH driver
*
- * Copyright (C) 1999-2009, Broadcom Corporation
+ * Copyright (C) 1999-2010, Broadcom Corporation
*
* Unless you and Broadcom execute a separate written software license
* agreement governing use of this software, this software is licensed to you
@@ -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: bcmsdh.c,v 1.35.2.1.4.8.6.11 2009/10/20 09:48:20 Exp $
+ * $Id: bcmsdh.c,v 1.35.2.1.4.8.6.13 2010/04/06 03:26:57 Exp $
*/
/* ****************** BCMSDH Interface Functions *************************** */
@@ -40,9 +40,7 @@
#include <sdio.h> /* sdio spec */
-/* Defines number of access retries to configuration registers */
#define SDIOH_API_ACCESS_RETRY_LIMIT 2
-
const uint bcmsdh_msglevel = BCMSDH_ERROR_VAL;
@@ -59,7 +57,6 @@ struct bcmsdh_info
bcmsdh_info_t * l_bcmsdh = NULL;
#if defined(OOB_INTR_ONLY) && defined(HW_OOB)
-
extern int
sdioh_enable_hw_oob_intr(void *sdioh, bool enable);
@@ -68,7 +65,6 @@ bcmsdh_enable_hw_oob_intr(bcmsdh_info_t *sdh, bool enable)
{
sdioh_enable_hw_oob_intr(sdh->sdioh, enable);
}
-
#endif
bcmsdh_info_t *
View
120 drivers/net/wireless/bcm4329/bcmsdh_linux.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: bcmsdh_linux.c,v 1.42.10.10.2.12 2010/03/10 03:09:48 Exp $
+ * $Id: bcmsdh_linux.c,v 1.42.10.10.2.14.4.2 2010/09/15 00:30:11 Exp $
*/
/**
@@ -75,7 +75,11 @@ struct bcmsdh_hc {
bcmsdh_info_t *sdh; /* SDIO Host Controller handle */
void *ch;
unsigned int oob_irq;
- unsigned long oob_flags;
+ unsigned long oob_flags; /* OOB Host specifiction as edge and etc */
+ bool oob_irq_registered;
+#if defined(OOB_INTR_ONLY)
+ spinlock_t irq_lock;
+#endif
};
static bcmsdh_hc_t *sdhcinfo = NULL;
@@ -176,7 +180,7 @@ int bcmsdh_probe(struct device *dev)
#endif /* BCMLXSDMMC */
int irq = 0;
uint32 vendevid;
- unsigned long irq_flags = IRQF_TRIGGER_FALLING;
+ unsigned long irq_flags = 0;
#if !defined(BCMLXSDMMC) && defined(BCMPLATFORM_BUS)
pdev = to_platform_device(dev);
@@ -187,6 +191,12 @@ int bcmsdh_probe(struct device *dev)
#endif /* BCMLXSDMMC */
#if defined(OOB_INTR_ONLY)
+#ifdef HW_OOB
+ irq_flags = \
+ IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL | IORESOURCE_IRQ_SHAREABLE;
+#else
+ irq_flags = IRQF_TRIGGER_FALLING;
+#endif /* HW_OOB */
irq = dhd_customer_oob_irq_map(&irq_flags);
if (irq < 0) {
SDLX_MSG(("%s: Host irq is not defined\n", __FUNCTION__));
@@ -225,6 +235,10 @@ int bcmsdh_probe(struct device *dev)
sdhc->sdh = sdh;
sdhc->oob_irq = irq;
sdhc->oob_flags = irq_flags;
+ sdhc->oob_irq_registered = FALSE; /* to make sure.. */
+#if defined(OOB_INTR_ONLY)
+ spin_lock_init(&sdhc->irq_lock);
+#endif
/* chain SDIO Host Controller info together */
sdhc->next = sdhcinfo;
@@ -287,7 +301,7 @@ int bcmsdh_remove(struct device *dev)
MFREE(osh, sdhc, sizeof(bcmsdh_hc_t));
osl_detach(osh);
-#if !defined(BCMLXSDMMC)
+#if !defined(BCMLXSDMMC) || defined(OOB_INTR_ONLY)
dev_set_drvdata(dev, NULL);
#endif /* !defined(BCMLXSDMMC) */
@@ -338,7 +352,7 @@ extern uint sd_pci_slot; /* Force detection to a particular PCI */
/* slot only . Allows for having multiple */
/* WL devices at once in a PC */
/* Only one instance of dhd will be */
- /* useable at a time */
+ /* usable at a time */
/* Upper word is bus number, */
/* lower word is slot number */
/* Default value of 0xFFFFffff turns this */
@@ -365,20 +379,21 @@ bcmsdh_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
if (pdev->bus->number != (sd_pci_slot>>16) ||
PCI_SLOT(pdev->devfn) != (sd_pci_slot&0xffff)) {
SDLX_MSG(("%s: %s: bus %X, slot %X, vend %X, dev %X\n",
- __FUNCTION__,
- bcmsdh_chipmatch(pdev->vendor, pdev->device)
- ? "Found compatible SDIOHC"
- : "Probing unknown device",
- pdev->bus->number, PCI_SLOT(pdev->devfn), pdev->vendor,
- pdev->device));
+ __FUNCTION__,
+ bcmsdh_chipmatch(pdev->vendor, pdev->device) ?
+ "Found compatible SDIOHC" :
+ "Probing unknown device",
+ pdev->bus->number, PCI_SLOT(pdev->devfn),
+ pdev->vendor, pdev->device));
return -ENODEV;
}
SDLX_MSG(("%s: %s: bus %X, slot %X, vendor %X, device %X (good PCI location)\n",
- __FUNCTION__,
- bcmsdh_chipmatch(pdev->vendor, pdev->device)
- ? "Using compatible SDIOHC"
- : "WARNING, forced use of unkown device",
- pdev->bus->number, PCI_SLOT(pdev->devfn), pdev->vendor, pdev->device));
+ __FUNCTION__,
+ bcmsdh_chipmatch(pdev->vendor, pdev->device) ?
+ "Using compatible SDIOHC" :
+ "WARNING, forced use of unkown device",
+ pdev->bus->number, PCI_SLOT(pdev->devfn),
+ pdev->vendor, pdev->device));
}
if ((pdev->vendor == VENDOR_TI) && ((pdev->device == PCIXX21_FLASHMEDIA_ID) ||
@@ -439,7 +454,7 @@ bcmsdh_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
pci_set_master(pdev);
rc = pci_enable_device(pdev);
if (rc) {
- SDLX_MSG(("%s: Cannot enble PCI device\n", __FUNCTION__));
+ SDLX_MSG(("%s: Cannot enable PCI device\n", __FUNCTION__));
goto err;
}
if (!(sdh = bcmsdh_attach(osh, (void *)(uintptr)pci_resource_start(pdev, 0),
@@ -567,14 +582,31 @@ bcmsdh_unregister(void)
}
#if defined(OOB_INTR_ONLY)
+void bcmsdh_oob_intr_set(bool enable)
+{
+ static bool curstate = 1;
+ unsigned long flags;
+
+ spin_lock_irqsave(&sdhcinfo->irq_lock, flags);
+ if (curstate != enable) {
+ if (enable)
+ enable_irq(sdhcinfo->oob_irq);
+ else
+ disable_irq_nosync(sdhcinfo->oob_irq);
+ curstate = enable;
+ }
+ spin_unlock_irqrestore(&sdhcinfo->irq_lock, flags);
+}
+
static irqreturn_t wlan_oob_irq(int irq, void *dev_id)
{
dhd_pub_t *dhdp;
dhdp = (dhd_pub_t *)dev_get_drvdata(sdhcinfo->dev);
+ bcmsdh_oob_intr_set(0);
+
if (dhdp == NULL) {
- disable_irq(sdhcinfo->oob_irq);
SDLX_MSG(("Out of band GPIO interrupt fired way too early\n"));
return IRQ_HANDLED;
}
@@ -590,35 +622,51 @@ int bcmsdh_register_oob_intr(void * dhdp)
SDLX_MSG(("%s Enter\n", __FUNCTION__));
- dev_set_drvdata(sdhcinfo->dev, dhdp);
+/* Example of HW_OOB for HW2: please refer to your host specifiction */
+/* sdhcinfo->oob_flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL | IORESOURCE_IRQ_SHAREABLE; */
- /* Refer to customer Host IRQ docs about proper irqflags definition */
- error = request_irq(sdhcinfo->oob_irq, wlan_oob_irq, sdhcinfo->oob_flags,
- "bcmsdh_sdmmc", NULL);
+ dev_set_drvdata(sdhcinfo->dev, dhdp);
- if (error)
- return -ENODEV;
+ if (!sdhcinfo->oob_irq_registered) {
+ SDLX_MSG(("%s IRQ=%d Type=%X \n", __FUNCTION__, \
+ (int)sdhcinfo->oob_irq, (int)sdhcinfo->oob_flags));
+ /* Refer to customer Host IRQ docs about proper irqflags definition */
+ error = request_irq(sdhcinfo->oob_irq, wlan_oob_irq, sdhcinfo->oob_flags,
+ "bcmsdh_sdmmc", NULL);
+ if (error)
+ return -ENODEV;
- set_irq_wake(sdhcinfo->oob_irq, 1);
+ set_irq_wake(sdhcinfo->oob_irq, 1);
+ sdhcinfo->oob_irq_registered = TRUE;
+ }
return 0;
}
-void bcmsdh_unregister_oob_intr(void)
+void bcmsdh_set_irq(int flag)
{
- SDLX_MSG(("%s: Enter\n", __FUNCTION__));
-
- set_irq_wake(sdhcinfo->oob_irq, 0);
- disable_irq(sdhcinfo->oob_irq); /* just in case.. */
- free_irq(sdhcinfo->oob_irq, NULL);
+ if (sdhcinfo->oob_irq_registered) {
+ SDLX_MSG(("%s Flag = %d", __FUNCTION__, flag));
+ if (flag) {
+ enable_irq(sdhcinfo->oob_irq);
+ enable_irq_wake(sdhcinfo->oob_irq);
+ } else {
+ disable_irq_wake(sdhcinfo->oob_irq);
+ disable_irq(sdhcinfo->oob_irq);
+ }
+ }
}
-void bcmsdh_oob_intr_set(bool enable)
+void bcmsdh_unregister_oob_intr(void)
{
- if (enable)
- enable_irq(sdhcinfo->oob_irq);
- else
- disable_irq(sdhcinfo->oob_irq);
+ SDLX_MSG(("%s: Enter\n", __FUNCTION__));
+
+ if (sdhcinfo->oob_irq_registered) {
+ set_irq_wake(sdhcinfo->oob_irq, 0);
+ disable_irq(sdhcinfo->oob_irq); /* just in case.. */
+ free_irq(sdhcinfo->oob_irq, NULL);
+ sdhcinfo->oob_irq_registered = FALSE;
+ }
}
#endif /* defined(OOB_INTR_ONLY) */
/* Module parameters specific to each host-controller driver */
View
17 drivers/net/wireless/bcm4329/bcmsdh_sdmmc.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: bcmsdh_sdmmc.c,v 1.1.2.5.6.28 2009/11/04 20:36:52 Exp $
+ * $Id: bcmsdh_sdmmc.c,v 1.1.2.5.6.30.4.1 2010/09/02 23:12:21 Exp $
*/
#include <typedefs.h>
@@ -55,7 +55,7 @@ extern void sdio_function_cleanup(void);
#if !defined(OOB_INTR_ONLY)
static void IRQHandler(struct sdio_func *func);
static void IRQHandlerF2(struct sdio_func *func);
-#endif
+#endif /* !defined(OOB_INTR_ONLY) */
static int sdioh_sdmmc_get_cisaddr(sdioh_info_t *sd, uint32 regaddr);
extern int sdio_reset_comm(struct mmc_card *card);
@@ -228,9 +228,8 @@ sdioh_enable_func_intr(void)
return SDIOH_API_RC_FAIL;
}
- reg |= 1 << 1; /* enable function-1 interrupt */
- reg |= 2 << 1; /* enable function-2 interrupt */
- reg |= 1; /* Master interrupt enable */
+ /* Enable F1 and F2 interrupts, set master enable */
+ reg |= (INTR_CTL_FUNC1_EN | INTR_CTL_FUNC2_EN | INTR_CTL_MASTER_EN);
sdio_writeb(gInstance->func[0], reg, SDIOD_CCCR_INTEN, &err);
sdio_release_host(gInstance->func[0]);
@@ -259,8 +258,7 @@ sdioh_disable_func_intr(void)
return SDIOH_API_RC_FAIL;
}
- reg &= ~(1 << 1);
- reg &= ~(1 << 2);
+ reg &= ~(INTR_CTL_FUNC1_EN | INTR_CTL_FUNC2_EN);
/* Disable master interrupt with the last function interrupt */
if (!(reg & 0xFE))
reg = 0;
@@ -677,6 +675,7 @@ sdioh_enable_hw_oob_intr(sdioh_info_t *sd, bool enable)
data = 3; /* enable hw oob interrupt */
else
data = 4; /* disable hw oob interrupt */
+ data |= 4; /* Active HIGH */
status = sdioh_request_byte(sd, SDIOH_WRITE, 0, 0xf2, &data);
return status;
@@ -1066,11 +1065,13 @@ sdioh_request_buffer(sdioh_info_t *sd, uint pio_dma, uint fix_inc, uint write, u
return (Status);
}
+/* this function performs "abort" for both of host & device */
extern int
sdioh_abort(sdioh_info_t *sd, uint func)
{
+#if defined(MMC_SDIO_ABORT)
char t_func = (char) func;
-
+#endif /* defined(MMC_SDIO_ABORT) */
sd_trace(("%s: Enter\n", __FUNCTION__));
#if defined(MMC_SDIO_ABORT)
View
52 drivers/net/wireless/bcm4329/bcmsdh_sdmmc_linux.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: bcmsdh_sdmmc_linux.c,v 1.1.2.5.6.11 2009/11/04 20:36:52 Exp $
+ * $Id: bcmsdh_sdmmc_linux.c,v 1.1.2.5.6.17 2010/08/13 00:36:19 Exp $
*/
#include <typedefs.h>
@@ -39,13 +39,22 @@
#if !defined(SDIO_VENDOR_ID_BROADCOM)
#define SDIO_VENDOR_ID_BROADCOM 0x02d0
-#endif /* !defined(SDIO_DEVICE_ID_BROADCOM_4325) */
+#endif /* !defined(SDIO_VENDOR_ID_BROADCOM) */
+
+#define SDIO_DEVICE_ID_BROADCOM_DEFAULT 0x0000
+
+#if !defined(SDIO_DEVICE_ID_BROADCOM_4325_SDGWB)
+#define SDIO_DEVICE_ID_BROADCOM_4325_SDGWB 0x0492 /* BCM94325SDGWB */
+#endif /* !defined(SDIO_DEVICE_ID_BROADCOM_4325_SDGWB) */
#if !defined(SDIO_DEVICE_ID_BROADCOM_4325)
-#define SDIO_DEVICE_ID_BROADCOM_4325 0x0000
+#define SDIO_DEVICE_ID_BROADCOM_4325 0x0493
#endif /* !defined(SDIO_DEVICE_ID_BROADCOM_4325) */
#if !defined(SDIO_DEVICE_ID_BROADCOM_4329)
#define SDIO_DEVICE_ID_BROADCOM_4329 0x4329
#endif /* !defined(SDIO_DEVICE_ID_BROADCOM_4329) */
+#if !defined(SDIO_DEVICE_ID_BROADCOM_4319)
+#define SDIO_DEVICE_ID_BROADCOM_4319 0x4319
+#endif /* !defined(SDIO_DEVICE_ID_BROADCOM_4329) */
#include <bcmsdh_sdmmc.h>
@@ -53,6 +62,7 @@
extern void sdioh_sdmmc_devintr_off(sdioh_info_t *sd);
extern void sdioh_sdmmc_devintr_on(sdioh_info_t *sd);
+extern int sdio_reset_comm(struct mmc_card *card);
int sdio_function_init(void);
void sdio_function_cleanup(void);
@@ -60,6 +70,10 @@ void sdio_function_cleanup(void);
#define DESCRIPTION "bcmsdh_sdmmc Driver"
#define AUTHOR "Broadcom Corporation"
+#ifdef CUSTOMER_HW4
+void dhd_reset_chip(void);
+#endif
+
/* module param defaults */
static int clockoverride = 0;
@@ -73,8 +87,6 @@ PBCMSDH_SDMMC_INSTANCE gInstance;
extern int bcmsdh_probe(struct device *dev);
extern int bcmsdh_remove(struct device *dev);
-struct device sdmmc_dev;
-
static int bcmsdh_sdmmc_probe(struct sdio_func *func,
const struct sdio_device_id *id)
@@ -87,14 +99,29 @@ static int bcmsdh_sdmmc_probe(struct sdio_func *func,
sd_trace(("sdio_device: 0x%04x\n", func->device));
sd_trace(("Function#: 0x%04x\n", func->num));
+ /*Linux native mmc stack enables high speed only if card's CCCR
+ version >=1.20. BCM4329 reports CCCR Version 1.10 but it supports
+ high speed*/
+#ifdef MMC_SDIO_BROKEN_CCCR_REV
+ if( func->vendor == SDIO_VENDOR_ID_BROADCOM && \
+ func->device == SDIO_DEVICE_ID_BROADCOM_4329)
+ {
+ sd_trace(("setting high speed support ignoring card CCCR\n"));
+ func->card->cccr.high_speed = 1;
+ }
+#endif
if (func->num == 1) {
+#ifdef CUSTOMER_HW4
+ dhd_reset_chip();
+ sdio_reset_comm(func->card);
+#endif
sdio_func_0.num = 0;
sdio_func_0.card = func->card;
gInstance->func[0] = &sdio_func_0;
if(func->device == 0x4) { /* 4318 */
gInstance->func[2] = NULL;
sd_trace(("NIC found, calling bcmsdh_probe...\n"));
- ret = bcmsdh_probe(&sdmmc_dev);
+ ret = bcmsdh_probe(&func->dev);
}
}
@@ -102,7 +129,7 @@ static int bcmsdh_sdmmc_probe(struct sdio_func *func,
if (func->num == 2) {
sd_trace(("F2 found, calling bcmsdh_probe...\n"));
- ret = bcmsdh_probe(&sdmmc_dev);
+ ret = bcmsdh_probe(&func->dev);
}
return ret;
@@ -117,16 +144,18 @@ static void bcmsdh_sdmmc_remove(struct sdio_func *func)
sd_info(("Function#: 0x%04x\n", func->num));
if (func->num == 2) {
- sd_trace(("F2 found, calling bcmsdh_probe...\n"));
- bcmsdh_remove(&sdmmc_dev);
+ sd_trace(("F2 found, calling bcmsdh_remove...\n"));
+ bcmsdh_remove(&func->dev);
}
}
/* devices we support, null terminated */
static const struct sdio_device_id bcmsdh_sdmmc_ids[] = {
+ { SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_DEFAULT) },
+ { SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4325_SDGWB) },
{ SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4325) },
{ SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4329) },
- { SDIO_DEVICE_CLASS(SDIO_CLASS_NONE) },
+ { SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4319) },
{ /* end: all zeroes */ },
};
@@ -240,10 +269,8 @@ int sdio_function_init(void)
if (!gInstance)
return -ENOMEM;
- bzero(&sdmmc_dev, sizeof(sdmmc_dev));
error = sdio_register_driver(&bcmsdh_sdmmc_driver);
-
return error;
}
@@ -255,7 +282,6 @@ void sdio_function_cleanup(void)
{
sd_trace(("%s Enter\n", __FUNCTION__));
-
sdio_unregister_driver(&bcmsdh_sdmmc_driver);
if (gInstance)
View
2  drivers/net/wireless/bcm4329/bcmsdspi_linux.c
@@ -1,7 +1,7 @@
/*
* Broadcom SPI Host Controller Driver - Linux Per-port
*
- * Copyright (C) 1999-2009, Broadcom Corporation
+ * Copyright (C) 1999-2010, Broadcom Corporation
*
* Unless you and Broadcom execute a separate written software license
* agreement governing use of this software, this software is licensed to you
View
21 drivers/net/wireless/bcm4329/bcmsdstd.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: bcmsdstd.c,v 1.64.4.1.4.4.2.17 2010/03/10 03:09:48 Exp $
+ * $Id: bcmsdstd.c,v 1.64.4.1.4.4.2.18 2010/08/17 17:00:48 Exp $
*/
#include <typedefs.h>
@@ -119,7 +119,7 @@ extern void sdstd_wreg16(sdioh_info_t *sd, uint reg, uint16 data);
void
sdstd_wreg16(sdioh_info_t *sd, uint reg, uint16 data)
{
- *(volatile uint16 *)(sd->mem_space + reg) = (volatile uint16) data;
+ *(volatile uint16 *)(sd->mem_space + reg) = (uint16)data;
sd_ctrl(("16: W Reg 0x%02x, Data 0x%x\n", reg, data));
}
@@ -129,7 +129,7 @@ sdstd_or_reg16(sdioh_info_t *sd, uint reg, uint16 val)
volatile uint16 data = *(volatile uint16 *)(sd->mem_space + reg);
sd_ctrl(("16: OR Reg 0x%02x, Val 0x%x\n", reg, val));
data |= val;
- *(volatile uint16 *)(sd->mem_space + reg) = (volatile uint16)data;
+ *(volatile uint16 *)(sd->mem_space + reg) = (uint16)data;
}
static void
@@ -140,7 +140,7 @@ sdstd_mod_reg16(sdioh_info_t *sd, uint reg, int16 mask, uint16 val)
sd_ctrl(("16: MOD Reg 0x%02x, Mask 0x%x, Val 0x%x\n", reg, mask, val));
data &= ~mask;
data |= (val & mask);
- *(volatile uint16 *)(sd->mem_space + reg) = (volatile uint16)data;
+ *(volatile uint16 *)(sd->mem_space + reg) = (uint16)data;
}
@@ -155,7 +155,7 @@ sdstd_rreg(sdioh_info_t *sd, uint reg)
static inline void
sdstd_wreg(sdioh_info_t *sd, uint reg, uint32 data)
{
- *(volatile uint32 *)(sd->mem_space + reg) = (volatile uint32)data;
+ *(volatile uint32 *)(sd->mem_space + reg) = (uint32)data;
sd_ctrl(("32: W Reg 0x%02x, Data 0x%x\n", reg, data));
}
@@ -164,7 +164,7 @@ sdstd_wreg(sdioh_info_t *sd, uint reg, uint32 data)
static inline void
sdstd_wreg8(sdioh_info_t *sd, uint reg, uint8 data)
{
- *(volatile uint8 *)(sd->mem_space + reg) = (volatile uint8)data;
+ *(volatile uint8 *)(sd->mem_space + reg) = (uint8)data;
sd_ctrl(("08: W Reg 0x%02x, Data 0x%x\n", reg, data));
}
static uint8
@@ -287,7 +287,7 @@ sdioh_detach(osl_t *osh, sdioh_info_t *sd)
return SDIOH_API_RC_SUCCESS;
}
-/* Configure callback to client when we recieve client interrupt */
+/* Configure callback to client when we receive client interrupt */
extern SDIOH_API_RC
sdioh_interrupt_register(sdioh_info_t *sd, sdioh_cb_fn_t fn, void *argh)
{
@@ -2778,10 +2778,6 @@ sdstd_card_buf(sdioh_info_t *sd, int rw, int func, bool fifo, uint32 addr, int n
data++;
}
- /* Handle < 4 bytes. wlc_pio.c currently (as of 12/20/05) truncates buflen
- * to be evenly divisable by 4. However dongle passes arbitrary lengths,
- * so handle it here
- */
bytes = blocksize % 4;
/* If no leftover bytes, go to next block */
@@ -2898,7 +2894,8 @@ set_client_block_size(sdioh_info_t *sd, int func, int block_size)
}
/* Reset and re-initialize the device */
-int sdioh_sdio_reset(sdioh_info_t *si)
+int
+sdioh_sdio_reset(sdioh_info_t *si)
{
uint8 hreg;
View
8 drivers/net/wireless/bcm4329/bcmsdstd_linux.c
@@ -1,7 +1,7 @@
/*
* 'Standard' SDIO HOST CONTROLLER driver - linux portion
*
- * Copyright (C) 1999-2009, Broadcom Corporation
+ * Copyright (C) 1999-2010, Broadcom Corporation
*
* Unless you and Broadcom execute a separate written software license
* agreement governing use of this software, this software is licensed to you
@@ -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: bcmsdstd_linux.c,v 1.11.18.2 2008/05/28 18:36:56 Exp $
+ * $Id: bcmsdstd_linux.c,v 1.11.18.2.16.1 2010/08/17 17:03:13 Exp $
*/
#include <typedefs.h>
@@ -186,7 +186,9 @@ sdstd_lock(sdioh_info_t *sd)
spin_lock_irqsave(&sdos->lock, flags);
if (sd->lockcount) {
- sd_err(("%s: Already locked!\n", __FUNCTION__));
+ sd_err(("%s: Already locked! called from %p\n",
+ __FUNCTION__,
+ __builtin_return_address(0)));
ASSERT(sd->lockcount == 0);
}
sdstd_devintr_off(sd);
View
2  drivers/net/wireless/bcm4329/bcmutils.c
@@ -20,7 +20,7 @@
* Notwithstanding the above, under no circumstances may you combine this
* 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: bcmutils.c,v 1.210.4.5.2.4.6.17 2009/11/17 02:20:12 Exp $
+ * $Id: bcmutils.c,v 1.210.4.5.2.4.6.19 2010/04/26 06:05:25 Exp $
*/
#include <typedefs.h>
View
2  drivers/net/wireless/bcm4329/bcmwifi.c
@@ -3,7 +3,7 @@
* Contents are wifi-specific, used by any kernel or app-level
* software that might want wifi things as it grows.
*
- * Copyright (C) 1999-2009, Broadcom Corporation
+ * Copyright (C) 1999-2010, Broadcom Corporation
*
* Unless you and Broadcom execute a separate written software license
* agreement governing use of this software, this software is licensed to you
View
134 drivers/net/wireless/bcm4329/dhd.h
@@ -24,7 +24,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.h,v 1.32.4.7.2.4.14.27 2010/01/19 06:42:55 Exp $
+ * $Id: dhd.h,v 1.32.4.7.2.4.14.49.4.9 2011/01/14 22:40:45 Exp $
*/
/****************
@@ -59,10 +59,11 @@
#include <wlioctl.h>
-#if defined(NDIS60)
-#include <wdf.h>
-#include <WdfMiniport.h>
-#endif
+#ifdef DHD_DEBUG
+#ifndef DHD_DEBUG_TRAP
+#define DHD_DEBUG_TRAP
+#endif
+#endif
/* Forward decls */
struct dhd_bus;
@@ -85,6 +86,11 @@ enum dhd_bus_wake_state {
WAKE_LOCK_TMOUT,
WAKE_LOCK_WATCHDOG,
WAKE_LOCK_LINK_DOWN_TMOUT,
+ WAKE_LOCK_PNO_FIND_TMOUT,
+ WAKE_LOCK_SOFTAP_SET,
+ WAKE_LOCK_SOFTAP_STOP,
+ WAKE_LOCK_SOFTAP_START,
+ WAKE_LOCK_SOFTAP_THREAD,
WAKE_LOCK_MAX
};
enum dhd_prealloc_index {
@@ -137,7 +143,7 @@ typedef struct dhd_pub {
ulong rx_readahead_cnt; /* Number of packets where header read-ahead was used. */
ulong tx_realloc; /* Number of tx packets we had to realloc for headroom */
- ulong fc_packets; /* Number of flow control pkts recvd */
+ ulong fc_packets; /* Number of flow control pkts recvd */
/* Last error return */
int bcmerror;
@@ -146,44 +152,49 @@ typedef struct dhd_pub {
/* Last error from dongle */
int dongle_error;
- uint8 country_code[WLC_CNTRY_BUF_SZ];
-} dhd_pub_t;
-
-#if defined(NDIS60)
-
-typedef struct _wdf_device_info {
- dhd_pub_t *dhd;
-} wdf_device_info_t;
+ /* Suspend disable flag and "in suspend" flag */
+ int suspend_disable_flag; /* "1" to disable all extra powersaving during suspend */
+ int in_suspend; /* flag set to 1 when early suspend called */
+ int hang_was_sent; /* flag that message was send at least once */
+#ifdef PNO_SUPPORT
+ int pno_enable; /* pno status : "1" is pno enable */
+#endif /* PNO_SUPPORT */
+ int dtim_skip; /* dtim skip , default 0 means wake each dtim */
-WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(wdf_device_info_t, dhd_get_wdf_device_info)
+ /* Pkt filter defination */
+ char * pktfilter[100];
+ int pktfilter_count;
+ uint8 country_code[WLC_CNTRY_BUF_SZ];
+ char eventmask[WL_EVENTING_MASK_LEN];
-#endif /* NDIS60 && !UNDERC_CE */
+} dhd_pub_t;
- #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && defined(CONFIG_PM_SLEEP)
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && defined(CONFIG_PM_SLEEP)
#define DHD_PM_RESUME_WAIT_INIT(a) DECLARE_WAIT_QUEUE_HEAD(a);
- #define _DHD_PM_RESUME_WAIT(a, b) do {\
+ #define _DHD_PM_RESUME_WAIT(a, b) do { \
int retry = 0; \
+ smp_mb(); \
while (dhd_mmc_suspend && retry++ != b) { \
wait_event_interruptible_timeout(a, FALSE, HZ/100); \
} \
} while (0)
- #define DHD_PM_RESUME_WAIT(a) _DHD_PM_RESUME_WAIT(a, 30)
+ #define DHD_PM_RESUME_WAIT(a) _DHD_PM_RESUME_WAIT(a, 200)
#define DHD_PM_RESUME_WAIT_FOREVER(a) _DHD_PM_RESUME_WAIT(a, ~0)
#define DHD_PM_RESUME_RETURN_ERROR(a) do { if (dhd_mmc_suspend) return a; } while (0)
#define DHD_PM_RESUME_RETURN do { if (dhd_mmc_suspend) return; } while (0)
#define DHD_SPINWAIT_SLEEP_INIT(a) DECLARE_WAIT_QUEUE_HEAD(a);
#define SPINWAIT_SLEEP(a, exp, us) do { \
- uint countdown = (us) + 9; \
- while ((exp) && (countdown >= 10)) { \
+ uint countdown = (us) + 9999; \
+ while ((exp) && (countdown >= 10000)) { \
wait_event_interruptible_timeout(a, FALSE, HZ/100); \
- countdown -= 10; \
+ countdown -= 10000; \
} \
} while (0)
- #else
+#else
#define DHD_PM_RESUME_WAIT_INIT(a)
#define DHD_PM_RESUME_WAIT(a)
@@ -200,15 +211,35 @@ WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(wdf_device_info_t, dhd_get_wdf_device_info)
} \
} while (0)
- #endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && defined(CONFIG_PM_SLEEP) */
+#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && defined(CONFIG_PM_SLEEP) */
+
#define DHD_IF_VIF 0x01 /* Virtual IF (Hidden from user) */
+inline static void NETIF_ADDR_LOCK(struct net_device *dev)
+{
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29))
+ netif_addr_lock_bh(dev);
+#endif
+}
+
+inline static void NETIF_ADDR_UNLOCK(struct net_device *dev)
+{
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29))
+ netif_addr_unlock_bh(dev);
+#endif
+}
+
/* Wakelock Functions */
extern int dhd_os_wake_lock(dhd_pub_t *pub);
extern int dhd_os_wake_unlock(dhd_pub_t *pub);
extern int dhd_os_wake_lock_timeout(dhd_pub_t *pub);
extern int dhd_os_wake_lock_timeout_enable(dhd_pub_t *pub);
+extern void dhd_os_start_lock(dhd_pub_t *pub);
+extern void dhd_os_start_unlock(dhd_pub_t *pub);
+extern unsigned long dhd_os_spin_lock(dhd_pub_t *pub);
+extern void dhd_os_spin_unlock(dhd_pub_t *pub, unsigned long flags);
+
typedef struct dhd_if_event {
uint8 ifidx;
uint8 action;
@@ -274,9 +305,13 @@ extern void dhd_os_sdlock_rxq(dhd_pub_t * pub);
extern void dhd_os_sdunlock_rxq(dhd_pub_t * pub);
extern void dhd_os_sdlock_sndup_rxq(dhd_pub_t * pub);
extern void dhd_customer_gpio_wlan_ctrl(int onoff);
+extern int dhd_custom_get_mac_address(unsigned char *buf);
extern void dhd_os_sdunlock_sndup_rxq(dhd_pub_t * pub);
extern void dhd_os_sdlock_eventq(dhd_pub_t * pub);
extern void dhd_os_sdunlock_eventq(dhd_pub_t * pub);
+#ifdef DHD_DEBUG
+extern int write_to_file(dhd_pub_t *dhd, uint8 *buf, int size);
+#endif /* DHD_DEBUG */
#if defined(OOB_INTR_ONLY)
extern int dhd_customer_oob_irq_map(unsigned long *irq_flags_ptr);
#endif /* defined(OOB_INTR_ONLY) */
@@ -323,6 +358,7 @@ extern int dhd_bus_devreset(dhd_pub_t *dhdp, uint8 flag);
extern uint dhd_bus_status(dhd_pub_t *dhdp);
extern int dhd_bus_start(dhd_pub_t *dhdp);
+extern void print_buf(void *pbuf, int len, int bytes_per_line);
typedef enum cust_gpio_modes {
@@ -331,7 +367,11 @@ typedef enum cust_gpio_modes {
WLAN_POWER_ON,
WLAN_POWER_OFF
} cust_gpio_modes_t;
+
extern int wl_iw_iscan_set_scan_broadcast_prep(struct net_device *dev, uint flag);
+extern int wl_iw_send_priv_event(struct net_device *dev, char *flag);
+extern int net_os_send_hang_message(struct net_device *dev);
+
/*
* Insmod parameters for debug/test
*/
@@ -339,10 +379,10 @@ extern int wl_iw_iscan_set_scan_broadcast_prep(struct net_device *dev, uint flag
/* Watchdog timer interval */
extern uint dhd_watchdog_ms;
-
#if defined(DHD_DEBUG)
-extern uint wl_msg_level;
-#endif /* DHD_DEBUG */
+/* Console output poll interval */
+extern uint dhd_console_ms;
+#endif /* defined(DHD_DEBUG) */
/* Use interrupts */
extern uint dhd_intr;
@@ -350,6 +390,27 @@ extern uint dhd_intr;
/* Use polling */
extern uint dhd_poll;
+/* ARP offload agent mode */
+extern uint dhd_arp_mode;
+
+/* ARP offload enable */
+extern uint dhd_arp_enable;
+
+/* Pkt filte enable control */
+extern uint dhd_pkt_filter_enable;
+
+/* Pkt filter init setup */
+extern uint dhd_pkt_filter_init;
+
+/* Pkt filter mode control */
+extern uint dhd_master_mode;
+
+/* Roaming mode control */
+extern uint dhd_roam;
+
+/* Roaming mode control */
+extern uint dhd_radio_up;
+
/* Initial idletime ticks (may be -1 for immediate idle, 0 for no idle) */
extern int dhd_idletime;
#define DHD_IDLETIME_TICKS 1
@@ -360,6 +421,10 @@ extern uint dhd_sdiod_drive_strength;
/* Override to force tx queueing all the time */
extern uint dhd_force_tx_queueing;
+/* Default KEEP_ALIVE Period is 55 sec to prevent AP from sending Keep Alive probe frame */
+#define KEEP_ALIVE_PERIOD 55000
+#define NULL_PKT_STR "null_pkt"
+
#ifdef SDTEST
/* Echo packet generator (SDIO), pkts/s */
extern uint dhd_pktgen;
@@ -380,11 +445,20 @@ extern char nv_path[MOD_PARAM_PATHLEN];
#define DHD_DEL_IF -0xe
#define DHD_BAD_IF -0xf
-#ifdef APSTA_PINGTEST
-#define MAX_GUEST 8
-#endif
extern void dhd_wait_for_event(dhd_pub_t *dhd, bool *lockvar);
extern void dhd_wait_event_wakeup(dhd_pub_t*dhd);
+/* dhd_commn arp offload wrapers */
+extern void dhd_arp_cleanup(dhd_pub_t *dhd);
+int dhd_arp_get_arp_hostip_table(dhd_pub_t *dhd, void *buf, int buflen);
+void dhd_arp_offload_add_ip(dhd_pub_t *dhd, u32 ipaddr);
+
+#define DHD_UNICAST_FILTER_NUM 0
+#define DHD_BROADCAST_FILTER_NUM 1
+#define DHD_MULTICAST4_FILTER_NUM 2
+#define DHD_MULTICAST6_FILTER_NUM 3
+extern int net_os_set_packet_filter(struct net_device *dev, int val);
+extern int net_os_rxfilter_add_remove(struct net_device *dev, int val, int num);
+
#endif /* _dhd_h_ */
View
8 drivers/net/wireless/bcm4329/dhd_bus.h
@@ -4,7 +4,7 @@
* Provides type definitions and function prototypes used to link the
* DHD OS, bus, and protocol modules.
*
- * Copyright (C) 1999-2009, Broadcom Corporation
+ * Copyright (C) 1999-2010, Broadcom Corporation
*
* Unless you and Broadcom execute a separate written software license
* agreement governing use of this software, this software is licensed to you
@@ -24,7 +24,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_bus.h,v 1.4.6.3.2.3.6.5 2009/06/02 21:56:30 Exp $
+ * $Id: dhd_bus.h,v 1.4.6.3.2.3.6.7 2010/08/13 01:35:24 Exp $
*/
#ifndef _dhd_bus_h_
@@ -60,6 +60,10 @@ extern int dhd_bus_rxctl(struct dhd_bus *bus, uchar *msg, uint msglen);
/* Watchdog timer function */
extern bool dhd_bus_watchdog(dhd_pub_t *dhd);
+#ifdef DHD_DEBUG
+/* Device console input function */
+extern int dhd_bus_console_in(dhd_pub_t *dhd, uchar *msg, uint msglen);
+#endif /* DHD_DEBUG */
/* Deferred processing for the bus, return TRUE requests reschedule */
extern bool dhd_bus_dpc(struct dhd_bus *bus);
View
313 drivers/net/wireless/bcm4329/dhd_cdc.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_cdc.c,v 1.22.4.2.4.7.2.34 2010/01/21 22:08:34 Exp $
+ * $Id: dhd_cdc.c,v 1.22.4.2.4.7.2.41 2010/06/23 19:58:18 Exp $
*
* BDC is like CDC, except it includes a header for data packets to convey
* packet priority over the bus, and flags (e.g. to indicate checksum status
@@ -41,6 +41,7 @@
#include <dhd_bus.h>
#include <dhd_dbg.h>
+extern int dhd_preinit_ioctls(dhd_pub_t *dhd);
/* Packet alignment for most efficient SDIO (can change based on platform) */
#ifndef DHD_SDALIGN
@@ -149,7 +150,8 @@ dhdcdc_query_ioctl(dhd_pub_t *dhd, int ifidx, uint cmd, void *buf, uint len)
memcpy(prot->buf, buf, len);
if ((ret = dhdcdc_msg(dhd)) < 0) {
- DHD_ERROR(("dhdcdc_query_ioctl: dhdcdc_msg failed w/status %d\n", ret));
+ if (!dhd->hang_was_sent)
+ DHD_ERROR(("dhdcdc_query_ioctl: dhdcdc_msg failed w/status %d\n", ret));
goto done;
}
@@ -193,7 +195,7 @@ dhdcdc_query_ioctl(dhd_pub_t *dhd, int ifidx, uint cmd, void *buf, uint len)
return ret;
}
-static int
+int
dhdcdc_set_ioctl(dhd_pub_t *dhd, int ifidx, uint cmd, void *buf, uint len)
{
dhd_prot_t *prot = dhd->prot;
@@ -204,13 +206,25 @@ dhdcdc_set_ioctl(dhd_pub_t *dhd, int ifidx, uint cmd, void *buf, uint len)
DHD_TRACE(("%s: Enter\n", __FUNCTION__));
DHD_CTL(("%s: cmd %d len %d\n", __FUNCTION__, cmd, len));
+ if (dhd->busstate == DHD_BUS_DOWN) {
+ DHD_ERROR(("%s : bus is down. we have nothing to do\n", __FUNCTION__));
+ return -EIO;
+ }
+
+ /* don't talk to the dongle if fw is about to be reloaded */
+ if (dhd->hang_was_sent) {
+ DHD_ERROR(("%s: HANG was sent up earlier. Not talking to the chip\n",
+ __FUNCTION__));
+ return -EIO;
+ }
+
memset(msg, 0, sizeof(cdc_ioctl_t));
msg->cmd = htol32(cmd);
msg->len = htol32(len);
msg->flags = (++prot->reqid << CDCF_IOC_ID_SHIFT) | CDCF_IOC_SET;
CDC_SET_IF_IDX(msg, ifidx);
- msg->flags |= htol32(msg->flags);
+ msg->flags = htol32(msg->flags);
if (buf)
memcpy(prot->buf, buf, len);
@@ -250,7 +264,7 @@ dhd_prot_ioctl(dhd_pub_t *dhd, int ifidx, wl_ioctl_t * ioc, void * buf, int len)
dhd_prot_t *prot = dhd->prot;
int ret = -1;
- if (dhd->busstate == DHD_BUS_DOWN) {
+ if ((dhd->busstate == DHD_BUS_DOWN) || dhd->hang_was_sent) {
DHD_ERROR(("%s : bus is down. we have nothing to do\n", __FUNCTION__));
return ret;
}
@@ -322,23 +336,12 @@ dhd_prot_dump(dhd_pub_t *dhdp, struct bcmstrbuf *strbuf)
bcm_bprintf(strbuf, "Protocol CDC: reqid %d\n", dhdp->prot->reqid);
}
-#ifdef APSTA_PINGTEST
-extern struct ether_addr guest_eas[MAX_GUEST];
-#endif
void
dhd_prot_hdrpush(dhd_pub_t *dhd, int ifidx, void *pktbuf)
{
#ifdef BDC
struct bdc_header *h;
-#ifdef APSTA_PINGTEST
- struct ether_header *eh;
- int i;
-#ifdef DHD_DEBUG
- char eabuf1[ETHER_ADDR_STR_LEN];
- char eabuf2[ETHER_ADDR_STR_LEN];
-#endif /* DHD_DEBUG */
-#endif /* APSTA_PINGTEST */
#endif /* BDC */
DHD_TRACE(("%s: Enter\n", __FUNCTION__));
@@ -346,9 +349,6 @@ dhd_prot_hdrpush(dhd_pub_t *dhd, int ifidx, void *pktbuf)
#ifdef BDC
/* Push BDC header used to convey priority for buses that don't */
-#ifdef APSTA_PINGTEST
- eh = (struct ether_header *)PKTDATA(dhd->osh, pktbuf);
-#endif
PKTPUSH(dhd->osh, pktbuf, BDC_HEADER_LEN);
@@ -361,19 +361,6 @@ dhd_prot_hdrpush(dhd_pub_t *dhd, int ifidx, void *pktbuf)
h->priority = (PKTPRIO(pktbuf) & BDC_PRIORITY_MASK);
h->flags2 = 0;
-#ifdef APSTA_PINGTEST
- for (i = 0; i < MAX_GUEST; ++i) {
- if (!ETHER_ISNULLADDR(eh->ether_dhost) &&
- bcmp(eh->ether_dhost, guest_eas[i].octet, ETHER_ADDR_LEN) == 0) {
- DHD_TRACE(("send on if 1; sa %s, da %s\n",
- bcm_ether_ntoa((struct ether_addr *)(eh->ether_shost), eabuf1),
- bcm_ether_ntoa((struct ether_addr *)(eh->ether_dhost), eabuf2)));
- /* assume all guest STAs are on interface 1 */
- h->flags2 = 1;
- break;
- }
- }
-#endif /* APSTA_PINGTEST */
h->rssi = 0;
#endif /* BDC */
BDC_SET_IF_IDX(h, ifidx);
@@ -510,266 +497,30 @@ dhd_prot_dstats(dhd_pub_t *dhd)
return;
}
-int dhd_set_suspend(int value, dhd_pub_t *dhd)
-{
- int power_mode = PM_MAX;
- wl_pkt_filter_enable_t enable_parm;
- char iovbuf[32];
- int bcn_li_dtim = 3;
-#ifdef CUSTOMER_HW2
- uint roamvar = 1;
-#endif /* CUSTOMER_HW2 */
-
-#define htod32(i) i
-
- if (dhd && dhd->up) {
- dhd_os_proto_block(dhd);
- if (value) {
- dhdcdc_set_ioctl(dhd, 0, WLC_SET_PM,
- (char *)&power_mode, sizeof(power_mode));
- /* Enable packet filter, only allow unicast packet to send up */
- enable_parm.id = htod32(100);
- enable_parm.enable = htod32(1);
- bcm_mkiovar("pkt_filter_enable", (char *)&enable_parm,
- sizeof(wl_pkt_filter_enable_t), iovbuf, sizeof(iovbuf));
- dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, iovbuf, sizeof(iovbuf));
- /* set bcn_li_dtim */
- bcm_mkiovar("bcn_li_dtim", (char *)&bcn_li_dtim,
- 4, iovbuf, sizeof(iovbuf));
- dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, iovbuf, sizeof(iovbuf));
-#ifdef CUSTOMER_HW2
- /* Disable build-in roaming to allowed ext supplicant to take of romaing */
- bcm_mkiovar("roam_off", (char *)&roamvar, 4, iovbuf, sizeof(iovbuf));
- dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, iovbuf, sizeof(iovbuf));
-#endif /* CUSTOMER_HW2 */
- } else {
- power_mode = PM_FAST;
- dhdcdc_set_ioctl(dhd, 0, WLC_SET_PM, (char *)&power_mode,
- sizeof(power_mode));
- /* disable pkt filter */
- enable_parm.id = htod32(100);
- enable_parm.enable = htod32(0);
- bcm_mkiovar("pkt_filter_enable", (char *)&enable_parm,
- sizeof(wl_pkt_filter_enable_t), iovbuf, sizeof(iovbuf));
- dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, iovbuf, sizeof(iovbuf));
- /* set bcn_li_dtim */
- bcn_li_dtim = 0;
- bcm_mkiovar("bcn_li_dtim", (char *)&bcn_li_dtim,
- 4, iovbuf, sizeof(iovbuf));
- dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, iovbuf, sizeof(iovbuf));
-#ifdef CUSTOMER_HW2
- roamvar = 0;
- bcm_mkiovar("roam_off", (char *)&roamvar, 4, iovbuf, sizeof(iovbuf));
- dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, iovbuf, sizeof(iovbuf));
-#endif /* CUSTOMER_HW2 */
- }
- dhd_os_proto_unblock(dhd);
- }
-
- return 0;
-}
-
-#define strtoul(nptr, endptr, base) bcm_strtoul((nptr), (endptr), (base))
-
-/* Convert user's input in hex pattern to byte-size mask */
-static int
-wl_pattern_atoh(char *src, char *dst)
-{
- int i;
- if (strncmp(src, "0x", 2) != 0 &&
- strncmp(src, "0X", 2) != 0) {
- printf("Mask invalid format. Needs to start with 0x\n");
- return -1;
- }
- src = src + 2; /* Skip past 0x */
- if (strlen(src) % 2 != 0) {
- printf("Mask invalid format. Needs to be of even length\n");
- return -1;
- }
- for (i = 0; *src != '\0'; i++) {
- char num[3];
- strncpy(num, src, 2);
- num[2] = '\0';
- dst[i] = (uint8)strtoul(num, NULL, 16);
- src += 2;
- }
- return i;
-}
-
int
-dhd_preinit_ioctls(dhd_pub_t *dhd)
+dhd_prot_init(dhd_pub_t *dhd)
{
- char eventmask[WL_EVENTING_MASK_LEN];
- char iovbuf[WL_EVENTING_MASK_LEN + 12]; /* Room for "event_msgs" + '\0' + bitvec */
- int ret;
- uint up = 0;
-#ifdef CUSTOMER_HW2
- uint roamvar = 0;
-#else
- uint roamvar = 1;
-#endif
- uint power_mode = PM_FAST;
- uint32 dongle_align = DHD_SDALIGN;
- uint32 glom = 0;
-
- uint bcn_timeout = 3;
- int arpoe = 1;
- int arp_ol = 0xf;
- int scan_assoc_time = 40;
- int scan_unassoc_time = 80;
- const char *str;
- wl_pkt_filter_t pkt_filter;
- wl_pkt_filter_t *pkt_filterp;
- int buf_len;
- int str_len;
- uint32 mask_size;
- uint32 pattern_size;
- char buf[256];
- uint filter_mode = 1;
-
- dhd_os_proto_block(dhd);
- /* Get the device MAC address */
- strcpy(iovbuf, "cur_etheraddr");
- if ((ret = dhdcdc_query_ioctl(dhd, 0, WLC_GET_VAR, iovbuf, sizeof(iovbuf))) < 0) {
- DHD_ERROR(("%s: can't get MAC address , error=%d\n", __FUNCTION__, ret));
- dhd_os_proto_unblock(dhd);
- return BCME_NOTUP;
- }
- memcpy(dhd->mac.octet, iovbuf, ETHER_ADDR_LEN);
-
- /* Set Country code */
- if (dhd->country_code[0] != 0) {
- if (dhdcdc_set_ioctl(dhd, 0, WLC_SET_COUNTRY,
- dhd->country_code, sizeof(dhd->country_code)) < 0) {
- DHD_ERROR(("%s: country code setting failed\n", __FUNCTION__));
- }
- }
-
- /* Set PowerSave mode */
- dhdcdc_set_ioctl(dhd, 0, WLC_SET_PM, (char *)&power_mode, sizeof(power_mode));
+ int ret = 0;
+ char buf[128];
- /* Match Host and Dongle rx alignment */
- bcm_mkiovar("bus:txglomalign", (char *)&dongle_align, 4, iovbuf, sizeof(iovbuf));
- dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, iovbuf, sizeof(iovbuf));
+ DHD_TRACE(("%s: Enter\n", __FUNCTION__));
- /* disable glom option per default */
- bcm_mkiovar("bus:txglom", (char *)&glom, 4, iovbuf, sizeof(iovbuf));
- dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, iovbuf, sizeof(iovbuf));
- /* Setup timeout if Beacons are lost and roam is off to report link down */
- if (roamvar) {
- bcm_mkiovar("bcn_timeout", (char *)&bcn_timeout, 4, iovbuf, sizeof(iovbuf));
- dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, iovbuf, sizeof(iovbuf));
- }
+ dhd_os_proto_block(dhd);
- /* Enable/Disable build-in roaming to allowed ext supplicant to take of romaing */
- bcm_mkiovar("roam_off", (char *)&roamvar, 4, iovbuf, sizeof(iovbuf));
- dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, iovbuf, sizeof(iovbuf));
-
- /* Force STA UP */
- dhdcdc_set_ioctl(dhd, 0, WLC_UP, (char *)&up, sizeof(up));
-
- /* Setup event_msgs */
- bcm_mkiovar("event_msgs", eventmask, WL_EVENTING_MASK_LEN, iovbuf, sizeof(iovbuf));
- dhdcdc_query_ioctl(dhd, 0, WLC_GET_VAR, iovbuf, sizeof(iovbuf));
- bcopy(iovbuf, eventmask, WL_EVENTING_MASK_LEN);
-
- setbit(eventmask, WLC_E_SET_SSID);
- setbit(eventmask, WLC_E_PRUNE);
- setbit(eventmask, WLC_E_AUTH);
- setbit(eventmask, WLC_E_REASSOC);
- setbit(eventmask, WLC_E_REASSOC_IND);
- setbit(eventmask, WLC_E_DEAUTH_IND);
- setbit(eventmask, WLC_E_DISASSOC_IND);
- setbit(eventmask, WLC_E_DISASSOC);
- setbit(eventmask, WLC_E_JOIN);
- setbit(eventmask, WLC_E_ASSOC_IND);
- setbit(eventmask, WLC_E_PSK_SUP);
- setbit(eventmask, WLC_E_LINK);
- setbit(eventmask, WLC_E_NDIS_LINK);
- setbit(eventmask, WLC_E_MIC_ERROR);
- setbit(eventmask, WLC_E_PMKID_CACHE);
- setbit(eventmask, WLC_E_TXFAIL);
- setbit(eventmask, WLC_E_JOIN_START);
- setbit(eventmask, WLC_E_SCAN_COMPLETE);
-
- bcm_mkiovar("event_msgs", eventmask, WL_EVENTING_MASK_LEN, iovbuf, sizeof(iovbuf));
- dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, iovbuf, sizeof(iovbuf));
-
- dhdcdc_set_ioctl(dhd, 0, WLC_SET_SCAN_CHANNEL_TIME, (char *)&scan_assoc_time,
- sizeof(scan_assoc_time));
- dhdcdc_set_ioctl(dhd, 0, WLC_SET_SCAN_UNASSOC_TIME, (char *)&scan_unassoc_time,
- sizeof(scan_unassoc_time));
-
- /* Set ARP offload */
- bcm_mkiovar("arpoe", (char *)&arpoe, 4, iovbuf, sizeof(iovbuf));
- dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, iovbuf, sizeof(iovbuf));
- bcm_mkiovar("arp_ol", (char *)&arp_ol, 4, iovbuf, sizeof(iovbuf));
- dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, iovbuf, sizeof(iovbuf));
-
- /* add a default packet filter pattern */
- str = "pkt_filter_add";
- str_len = strlen(str);
- strncpy(buf, str, str_len);
- buf[ str_len ] = '\0';
- buf_len = str_len + 1;
-
- pkt_filterp = (wl_pkt_filter_t *) (buf + str_len + 1);
-
- /* Parse packet filter id. */
- pkt_filter.id = htod32(100);
-
- /* Parse filter polarity. */
- pkt_filter.negate_match = htod32(0);
-
- /* Parse filter type. */
- pkt_filter.type = htod32(0);
-
- /* Parse pattern filter offset. */
- pkt_filter.u.pattern.offset = htod32(0);
-
- /* Parse pattern filter mask. */
- mask_size = htod32(wl_pattern_atoh("0xff",
- (char *) pkt_filterp->u.pattern.mask_and_pattern));
-
- /* Parse pattern filter pattern. */
- pattern_size = htod32(wl_pattern_atoh("0x00",
- (char *) &pkt_filterp->u.pattern.mask_and_pattern[mask_size]));
-
- if (mask_size != pattern_size) {
- DHD_ERROR(("Mask and pattern not the same size\n"));
+ /* Get the device MAC address */
+ strcpy(buf, "cur_etheraddr");
+ ret = dhdcdc_query_ioctl(dhd, 0, WLC_GET_VAR, buf, sizeof(buf));
+ if (ret < 0) {
dhd_os_proto_unblock(dhd);
- return -EINVAL;
+ return ret;
}
-
- pkt_filter.u.pattern.size_bytes = mask_size;
- buf_len += WL_PKT_FILTER_FIXED_LEN;
- buf_len += (WL_PKT_FILTER_PATTERN_FIXED_LEN + 2 * mask_size);
-
- /* Keep-alive attributes are set in local variable (keep_alive_pkt), and
- ** then memcpy'ed into buffer (keep_alive_pktp) since there is no
- ** guarantee that the buffer is properly aligned.
- */
- memcpy((char *)pkt_filterp, &pkt_filter,
- WL_PKT_FILTER_FIXED_LEN + WL_PKT_FILTER_PATTERN_FIXED_LEN);
-
- dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, buf, buf_len);
-
- /* set mode to allow pattern */
- bcm_mkiovar("pkt_filter_mode", (char *)&filter_mode, 4, iovbuf, sizeof(iovbuf));
- dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, iovbuf, sizeof(iovbuf));
+ memcpy(dhd->mac.octet, buf, ETHER_ADDR_LEN);
dhd_os_proto_unblock(dhd);
- return 0;
-}
-
-int
-dhd_prot_init(dhd_pub_t *dhd)
-{
- int ret = 0;
- DHD_TRACE(("%s: Enter\n", __FUNCTION__));
-
+#ifdef EMBEDDED_PLATFORM
ret = dhd_preinit_ioctls(dhd);
+#endif /* EMBEDDED_PLATFORM */
/* Always assumes wl for now */
dhd->iswl = TRUE;
View
1,592 drivers/net/wireless/bcm4329/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,v 1.5.6.8.2.6.6.41 2010/02/24 01:52:41 Exp $
+ * $Id: dhd_common.c,v 1.5.6.8.2.6.6.69.4.25 2011-02-11 21:16:02 Exp $
*/
#include <typedefs.h>
#include <osl.h>
@@ -37,9 +37,21 @@
#include <dhd_dbg.h>
#include <msgtrace.h>
+#include <wlioctl.h>
+
+#ifdef SET_RANDOM_MAC_SOFTAP
+#include <linux/random.h>
+#include <linux/jiffies.h>
+#endif
+
+#ifdef GET_CUSTOM_MAC_ENABLE
+int wifi_get_mac_addr(unsigned char *buf);
+#endif /* GET_CUSTOM_MAC_ENABLE */
int dhd_msg_level;
+#include <wl_iw.h>
+
char fw_path[MOD_PARAM_PATHLEN];
char nv_path[MOD_PARAM_PATHLEN];
@@ -48,6 +60,32 @@ uint32 dhd_conn_event;
uint32 dhd_conn_status;
uint32 dhd_conn_reason;
+#define htod32(i) i
+#define htod16(i) i
+#define dtoh32(i) i
+#define dtoh16(i) i
+
+extern int dhdcdc_set_ioctl(dhd_pub_t *dhd, int ifidx, uint cmd, void *buf, uint len);
+extern void dhd_ind_scan_confirm(void *h, bool status);
+extern int dhd_wl_ioctl(dhd_pub_t *dhd, uint cmd, char *buf, uint buflen);
+void dhd_iscan_lock(void);
+void dhd_iscan_unlock(void);
+
+#if defined(SOFTAP)
+extern bool ap_fw_loaded;
+#endif
+#if defined(KEEP_ALIVE)
+int dhd_keep_alive_onoff(dhd_pub_t *dhd, int ka_on);
+#endif /* KEEP_ALIVE */
+
+/* Packet alignment for most efficient SDIO (can change based on platform) */
+#ifndef DHD_SDALIGN
+#define DHD_SDALIGN 32
+#endif
+#if !ISPOWEROF2(DHD_SDALIGN)
+#error DHD_SDALIGN is not a power of 2!
+#endif
+
#ifdef DHD_DEBUG
const char dhd_version[] = "Dongle Host Driver, version " EPI_VERSION_STR "\nCompiled on "
__DATE__ " at " __TIME__;
@@ -57,7 +95,6 @@ const char dhd_version[] = "Dongle Host Driver, version " EPI_VERSION_STR;
void dhd_set_timer(void *bus, uint wdtick);
-
/* IOVar table */
enum {
IOV_VERSION = 1,
@@ -66,6 +103,10 @@ enum {
IOV_BCMERROR,
IOV_WDTICK,
IOV_DUMP,
+#ifdef DHD_DEBUG
+ IOV_CONS,
+ IOV_DCONSOLE_POLL,
+#endif
IOV_CLEARCOUNTS,
IOV_LOGDUMP,
IOV_LOGCAL,
@@ -84,13 +125,16 @@ const bcm_iovar_t dhd_iovars[] = {
{"bcmerror", IOV_BCMERROR, 0, IOVT_INT8, 0 },
{"wdtick", IOV_WDTICK, 0, IOVT_UINT32, 0 },
{"dump", IOV_DUMP, 0, IOVT_BUFFER, DHD_IOCTL_MAXLEN },
+#ifdef DHD_DEBUG
+ {"dconpoll", IOV_DCONSOLE_POLL, 0, IOVT_UINT32, 0 },
+ {"cons", IOV_CONS, 0, IOVT_BUFFER, 0 },
+#endif
{"clearcounts", IOV_CLEARCOUNTS, 0, IOVT_VOID, 0 },
{"gpioob", IOV_GPIOOB, 0, IOVT_UINT32, 0 },
{"ioctl_timeout", IOV_IOCTLTIMEOUT, 0, IOVT_UINT32, 0 },
{NULL, 0, 0, 0, 0 }
};
-
void
dhd_common_init(void)
{
@@ -224,6 +268,21 @@ dhd_doiovar(dhd_pub_t *dhd_pub, const bcm_iovar_t *vi, uint32 actionid, const ch
bcmerror = dhd_dump(dhd_pub, arg, len);
break;
+#ifdef DHD_DEBUG
+ case IOV_GVAL(IOV_DCONSOLE_POLL):
+ int_val = (int32)dhd_console_ms;
+ bcopy(&int_val, arg, val_size);
+ break;
+
+ case IOV_SVAL(IOV_DCONSOLE_POLL):
+ dhd_console_ms = (uint)int_val;
+ break;
+
+ case IOV_SVAL(IOV_CONS):
+ if (len > 0)
+ bcmerror = dhd_bus_console_in(dhd_pub, arg, len - 1);
+ break;
+#endif
case IOV_SVAL(IOV_CLEARCOUNTS):
dhd_pub->tx_packets = dhd_pub->rx_packets = 0;
@@ -460,9 +519,6 @@ dhd_ioctl(dhd_pub_t *dhd_pub, dhd_ioctl_t *ioc, void *buf, uint buflen)
return bcmerror;
}
-#ifdef APSTA_PINGTEST
-struct ether_addr guest_eas[MAX_GUEST];
-#endif
#ifdef SHOW_EVENTS
static void
@@ -571,16 +627,6 @@ wl_show_host_event(wl_event_msg_t *event, void *event_data)
case WLC_E_ASSOC_IND:
case WLC_E_REASSOC_IND:
-#ifdef APSTA_PINGTEST
- {
- int i;
- for (i = 0; i < MAX_GUEST; ++i)
- if (ETHER_ISNULLADDR(&guest_eas[i]))
- break;
- if (i < MAX_GUEST)
- bcopy(event->addr.octet, guest_eas[i].octet, ETHER_ADDR_LEN);
- }
-#endif /* APSTA_PINGTEST */
DHD_EVENT(("MACEVENT: %s, MAC %s\n", event_name, eabuf));
break;
@@ -601,18 +647,6 @@ wl_show_host_event(wl_event_msg_t *event, void *event_data)
case WLC_E_DEAUTH_IND:
case WLC_E_DISASSOC_IND:
-#ifdef APSTA_PINGTEST
- {
- int i;
- for (i = 0; i < MAX_GUEST; ++i) {
- if (bcmp(guest_eas[i].octet, event->addr.octet,
- ETHER_ADDR_LEN) == 0) {
- bzero(guest_eas[i].octet, ETHER_ADDR_LEN);
- break;
- }
- }
- }
-#endif /* APSTA_PINGTEST */
DHD_EVENT(("MACEVENT: %s, MAC %s, reason %d\n", event_name, eabuf, (int)reason));
break;
@@ -893,3 +927,1505 @@ wl_event_to_host_order(wl_event_msg_t *evt)
evt->datalen = ntoh32(evt->datalen);
evt->version = ntoh16(evt->version);
}
+
+void print_buf(void *pbuf, int len, int bytes_per_line)
+{
+ int i, j = 0;
+ unsigned char *buf = pbuf;
+
+ if (bytes_per_line == 0) {
+ bytes_per_line = len;
+ }
+
+ for (i = 0; i < len; i++) {
+ printf("%2.2x", *buf++);
+ j++;
+ if (j == bytes_per_line) {
+ printf("\n");
+ j = 0;
+ } else {
+ printf(":");
+ }
+ }
+ printf("\n");
+}
+
+#define strtoul(nptr, endptr, base) bcm_strtoul((nptr), (endptr), (base))
+
+#ifdef PKT_FILTER_SUPPORT
+/* Convert user's input in hex pattern to byte-size mask */
+static int
+wl_pattern_atoh(char *src, char *dst)
+{
+ int i;
+ if (strncmp(src, "0x", 2) != 0 &&
+ strncmp(src, "0X", 2) != 0) {
+ DHD_ERROR(("Mask invalid format. Needs to start with 0x\n"));
+ return -1;
+ }
+ src = src + 2; /* Skip past 0x */
+ if (strlen(src) % 2 != 0) {
+ DHD_ERROR(("Mask invalid format. Needs to be of even length\n"));
+ return -1;
+ }
+ for (i = 0; *src != '\0'; i++) {
+ char num[3];
+ strncpy(num, src, 2);
+ num[2] = '\0';
+ dst[i] = (uint8)strtoul(num, NULL, 16);
+ src += 2;
+ }
+ return i;
+}
+
+void
+dhd_pktfilter_offload_enable(dhd_pub_t * dhd, char *arg, int enable, int master_mode)
+{
+ char *argv[8];
+ int i = 0;
+ const char *str;
+ int buf_len;
+ int str_len;
+ char *arg_save = 0, *arg_org = 0;
+ int rc;
+ char buf[128];
+ wl_pkt_filter_enable_t enable_parm;
+ wl_pkt_filter_enable_t * pkt_filterp;
+
+ if (!arg)
+ return;
+
+ if (!(arg_save = MALLOC(dhd->osh, strlen(arg) + 1))) {
+ DHD_ERROR(("%s: kmalloc failed\n", __FUNCTION__));
+ goto fail;
+ }
+ arg_org = arg_save;
+ memcpy(arg_save, arg, strlen(arg) + 1);
+
+ argv[i] = bcmstrtok(&arg_save, " ", 0);
+
+ i = 0;
+ if (NULL == argv[i]) {
+ DHD_ERROR(("No args provided\n"));
+ goto fail;
+ }
+
+ str = "pkt_filter_enable";
+ str_len = strlen(str);
+ strncpy(buf, str, str_len);
+ buf[str_len] = '\0';
+ buf_len = str_len + 1;
+
+ pkt_filterp = (wl_pkt_filter_enable_t *)(buf + str_len + 1);
+
+ /* Parse packet filter id. */
+ enable_parm.id = htod32(strtoul(argv[i], NULL, 0));
+
+ /* Parse enable/disable value. */
+ enable_parm.enable = htod32(enable);
+
+ buf_len += sizeof(enable_parm);
+ memcpy((char *)pkt_filterp,
+ &enable_parm,
+ sizeof(enable_parm));
+
+ /* Enable/disable the specified filter. */
+ rc = dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, buf, buf_len);
+ rc = rc >= 0 ? 0 : rc;
+ if (rc)
+ DHD_TRACE(("%s: failed to add pktfilter %s, retcode = %d\n",
+ __FUNCTION__, arg, rc));
+ else
+ DHD_TRACE(("%s: successfully added pktfilter %s\n",
+ __FUNCTION__, arg));
+
+ /* Contorl the master mode */
+ bcm_mkiovar("pkt_filter_mode", (char *)&master_mode, 4, buf, sizeof(buf));
+ rc = dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, buf, sizeof(buf));
+ rc = rc >= 0 ? 0 : rc;
+ if (rc)
+ DHD_TRACE(("%s: failed to add pktfilter %s, retcode = %d\n",
+ __FUNCTION__, arg, rc));
+
+fail:
+ if (arg_org)
+ MFREE(dhd->osh, arg_org, strlen(arg) + 1);
+}
+
+void
+dhd_pktfilter_offload_set(dhd_pub_t * dhd, char *arg)
+{
+ const char *str;
+ wl_pkt_filter_t pkt_filter;
+ wl_pkt_filter_t *pkt_filterp;
+ int buf_len;
+ int str_len;
+ int rc;
+ uint32 mask_size;
+ uint32 pattern_size;
+ char *argv[8], * buf = 0;
+ int i = 0;
+ char *arg_save = 0, *arg_org = 0;
+#define BUF_SIZE 2048
+
+ if (!arg)
+ return;
+
+ if (!(arg_save = MALLOC(dhd->osh, strlen(arg) + 1))) {
+ DHD_ERROR(("%s: kmalloc failed\n", __FUNCTION__));
+ goto fail;
+ }
+
+ arg_org = arg_save;
+
+ if (!(buf = MALLOC(dhd->osh, BUF_SIZE))) {
+ DHD_ERROR(("%s: kmalloc failed\n", __FUNCTION__));
+ goto fail;
+ }
+
+ memcpy(arg_save, arg, strlen(arg) + 1);
+
+ if (strlen(arg) > BUF_SIZE) {
+ DHD_ERROR(("Not enough buffer %d < %d\n", (int)strlen(arg), (int)sizeof(buf)));
+ goto fail;
+ }
+
+ argv[i] = bcmstrtok(&arg_save, " ", 0);
+ while (argv[i++])
+ argv[i] = bcmstrtok(&arg_save, " ", 0);
+
+ i = 0;
+ if (NULL == argv[i]) {
+ DHD_ERROR(("No args provided\n"));
+ goto fail;
+ }
+
+ str = "pkt_filter_add";
+ str_len = strlen(str);
+ strncpy(buf, str, str_len);
+ buf[ str_len ] = '\0';
+ buf_len = str_len + 1;
+
+ pkt_filterp = (wl_pkt_filter_t *) (buf + str_len + 1);
+
+ /* Parse packet filter id. */
+ pkt_filter.id = htod32(strtoul(argv[i], NULL, 0));
+
+ if (NULL == argv[++i]) {
+ DHD_ERROR(("Polarity not provided\n"));
+ goto fail;
+ }
+
+ /* Parse filter polarity. */
+ pkt_filter.negate_match = htod32(strtoul(argv[i], NULL, 0));
+
+ if (NULL == argv[++i]) {
+ DHD_ERROR(("Filter type not provided\n"));
+ goto fail;
+ }
+
+ /* Parse filter type. */
+ pkt_filter.type = htod32(strtoul(argv[i], NULL, 0));
+
+ if (NULL == argv[++i]) {
+ DHD_ERROR(("Offset not provided\n"));
+ goto fail;
+ }
+
+ /* Parse pattern filter offset. */
+ pkt_filter.u.pattern.offset = htod32(strtoul(argv[i], NULL, 0));
+
+ if (NULL == argv[++i]) {
+ DHD_ERROR(("Bitmask not provided\n"));
+ goto fail;
+ }
+
+ /* Parse pattern filter mask. */
+ mask_size =
+ htod32(wl_pattern_atoh(argv[i], (char *) pkt_filterp->u.pattern.mask_and_pattern));
+
+ if (NULL == argv[++i]) {
+ DHD_ERROR(("Pattern not provided\n"));
+ goto fail;
+ }
+
+ /* Parse pattern filter pattern. */
+ pattern_size =
+ htod32(wl_pattern_atoh(argv[i],
+ (char *) &pkt_filterp->u.pattern.mask_and_pattern[mask_size]));
+
+ if (mask_size != pattern_size) {
+ DHD_ERROR(("Mask and pattern not the same size\n"));
+ goto fail;
+ }
+
+ pkt_filter.u.pattern.size_bytes = mask_size;
+ buf_len += WL_PKT_FILTER_FIXED_LEN;
+ buf_len += (WL_PKT_FILTER_PATTERN_FIXED_LEN + 2 * mask_size);
+
+ /* Keep-alive attributes are set in local variable (keep_alive_pkt), and
+ ** then memcpy'ed into buffer (keep_alive_pktp) since there is no
+ ** guarantee that the buffer is properly aligned.
+ */
+ memcpy((char *)pkt_filterp,
+ &pkt_filter,
+ WL_PKT_FILTER_FIXED_LEN + WL_PKT_FILTER_PATTERN_FIXED_LEN);
+
+ rc = dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, buf, buf_len);
+ rc = rc >= 0 ? 0 : rc;
+
+ if (rc)
+ DHD_TRACE(("%s: failed to add pktfilter %s, retcode = %d\n",
+ __FUNCTION__, arg, rc));
+ else
+ DHD_TRACE(("%s: successfully added pktfilter %s\n",
+ __FUNCTION__, arg));
+
+fail:
+ if (arg_org)
+ MFREE(dhd->osh, arg_org, strlen(arg) + 1);
+
+ if (buf)
+ MFREE(dhd->osh, buf, BUF_SIZE);
+}
+#endif
+
+#ifdef ARP_OFFLOAD_SUPPORT
+void
+dhd_arp_offload_set(dhd_pub_t * dhd, int arp_mode)
+{
+ char iovbuf[32];
+ int retcode;
+
+ bcm_mkiovar("arp_ol", (char *)&arp_mode, 4, iovbuf, sizeof(iovbuf));
+ retcode = dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, iovbuf, sizeof(iovbuf));
+ retcode = retcode >= 0 ? 0 : retcode;
+ if (retcode)
+ DHD_TRACE(("%s: failed to set ARP offload mode to 0x%x, retcode = %d\n",
+ __FUNCTION__, arp_mode, retcode));
+ else
+ DHD_TRACE(("%s: successfully set ARP offload mode to 0x%x\n",
+ __FUNCTION__, arp_mode));
+}
+
+void
+dhd_arp_offload_enable(dhd_pub_t * dhd, int arp_enable)
+{
+ char iovbuf[32];
+ int retcode;
+
+ bcm_mkiovar("arpoe", (char *)&arp_enable, 4, iovbuf, sizeof(iovbuf));
+ retcode = dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, iovbuf, sizeof(iovbuf));
+ retcode = retcode >= 0 ? 0 : retcode;
+ if (retcode)
+ DHD_TRACE(("%s: failed to enabe ARP offload to %d, retcode = %d\n",
+ __FUNCTION__, arp_enable, retcode));
+ else
+ DHD_TRACE(("%s: successfully enabed ARP offload to %d\n",
+ __FUNCTION__, arp_enable));
+}
+#endif
+
+
+void dhd_arp_cleanup(dhd_pub_t *dhd)
+{
+#ifdef ARP_OFFLOAD_SUPPORT
+ int ret = 0;
+ int iov_len = 0;
+ char iovbuf[128];
+
+ if (dhd == NULL) return;
+
+ dhd_os_proto_block(dhd);
+
+ iov_len = bcm_mkiovar("arp_hostip_clear", 0, 0, iovbuf, sizeof(iovbuf));
+ if ((ret = dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, iovbuf, iov_len)) < 0)
+ DHD_ERROR(("%s failed code %d\n", __FUNCTION__, ret));
+
+ iov_len = bcm_mkiovar("arp_table_clear", 0, 0, iovbuf, sizeof(iovbuf));
+ if ((ret = dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, iovbuf, iov_len)) < 0)
+ DHD_ERROR(("%s failed code %d\n", __FUNCTION__, ret));
+
+ dhd_os_proto_unblock(dhd);
+
+#endif /* ARP_OFFLOAD_SUPPORT */
+}
+
+void dhd_arp_offload_add_ip(dhd_pub_t *dhd, u32 ipaddr)
+{
+#ifdef ARP_OFFLOAD_SUPPORT
+ int iov_len = 0;
+ char iovbuf[32];
+ int retcode;
+
+ dhd_os_proto_block(dhd);
+
+ iov_len = bcm_mkiovar("arp_hostip", (char *)&ipaddr, 4, iovbuf, sizeof(iovbuf));
+ retcode = dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, iovbuf, iov_len);
+
+ dhd_os_proto_unblock(dhd);
+
+ if (retcode)
+ DHD_TRACE(("%s: ARP ip addr add failed, retcode = %d\n",
+ __FUNCTION__, retcode));
+ else
+ DHD_TRACE(("%s: ARP ipaddr entry added\n",
+ __FUNCTION__));
+#endif /* ARP_OFFLOAD_SUPPORT */
+}
+
+
+int dhd_arp_get_arp_hostip_table(dhd_pub_t *dhd, void *buf, int buflen)
+{
+#ifdef ARP_OFFLOAD_SUPPORT
+ int retcode;
+ int iov_len = 0;
+
+ if (!buf)
+ return -1;
+
+ dhd_os_proto_block(dhd);
+
+ iov_len = bcm_mkiovar("arp_hostip", 0, 0, buf, buflen);
+ retcode = dhdcdc_query_ioctl(dhd, 0, WLC_GET_VAR, buf, buflen);
+
+ dhd_os_proto_unblock(dhd);
+
+ if (retcode) {
+ DHD_TRACE(("%s: ioctl WLC_GET_VAR error %d\n",
+ __FUNCTION__, retcode));
+
+ return -1;
+ }
+#endif /* ARP_OFFLOAD_SUPPORT */
+ return 0;
+}
+
+
+int
+dhd_preinit_ioctls(dhd_pub_t *dhd)
+{
+ char iovbuf[WL_EVENTING_MASK_LEN + 12]; /* Room for "event_msgs" + '\0' + bitvec */
+ uint up = 0;
+ char buf[128], *ptr;
+ uint power_mode = PM_FAST;
+ uint32 dongle_align = DHD_SDALIGN;
+ uint32 glom = 0;
+ uint bcn_timeout = 4;
+ int scan_assoc_time = 40;
+ int scan_unassoc_time = 40;
+ uint32 listen_interval = LISTEN_INTERVAL; /* Default Listen Interval in Beacons */
+#if defined(SOFTAP)
+ uint dtim = 1;
+#endif
+ int ret = 0;
+#ifdef GET_CUSTOM_MAC_ENABLE
+ struct ether_addr ea_addr;
+#endif /* GET_CUSTOM_MAC_ENABLE */
+
+ dhd_os_proto_block(dhd);
+
+#ifdef GET_CUSTOM_MAC_ENABLE
+ /*
+ ** Read MAC address from external customer place
+ ** NOTE that default mac address has to be present in otp or nvram file
+ ** to bring up firmware but unique per board mac address maybe provided
+ ** by customer code
+ */
+ ret = dhd_custom_get_mac_address(ea_addr.octet);
+ if (!ret) {
+ bcm_mkiovar("cur_etheraddr", (void *)&ea_addr, ETHER_ADDR_LEN, buf, sizeof(buf));
+ ret = dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, buf, sizeof(buf));
+ if (ret < 0) {
+ DHD_ERROR(("%s: can't set MAC address , error=%d\n", __FUNCTION__, ret));
+ } else
+ memcpy(dhd->mac.octet, (void *)&ea_addr, ETHER_ADDR_LEN);
+ }
+#endif /* GET_CUSTOM_MAC_ENABLE */
+
+#ifdef SET_RANDOM_MAC_SOFTAP
+ if (strstr(fw_path, "apsta") != NULL) {
+ uint rand_mac;
+
+ srandom32((uint)jiffies);
+ rand_mac = random32();
+ iovbuf[0] = 0x02; /* locally administered bit */
+ iovbuf[1] = 0x1A;
+ iovbuf[2] = 0x11;
+ iovbuf[3] = (unsigned char)(rand_mac & 0x0F) | 0xF0;
+ iovbuf[4] = (unsigned char)(rand_mac >> 8);
+ iovbuf[5] = (unsigned char)(rand_mac >> 16);
+
+ printk("Broadcom Dongle Host Driver mac=%02x:%02x:%02x:%02x:%02x:%02x\n",
+ iovbuf[0], iovbuf[1], iovbuf[2], iovbuf[3], iovbuf[4], iovbuf[5]);
+
+ bcm_mkiovar("cur_etheraddr", (void *)iovbuf, ETHER_ADDR_LEN, buf, sizeof(buf));
+ ret = dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, buf, sizeof(buf));
+ if (ret < 0) {
+ DHD_ERROR(("%s: can't set MAC address , error=%d\n", __FUNCTION__, ret));
+ } else
+ memcpy(dhd->mac.octet, iovbuf, ETHER_ADDR_LEN);
+ }
+#endif /* SET_RANDOM_MAC_SOFTAP */
+
+ /* Set Country code */
+ if (dhd->country_code[0] != 0) {
+ if (dhdcdc_set_ioctl(dhd, 0, WLC_SET_COUNTRY,
+ dhd->country_code, sizeof(dhd->country_code)) < 0) {
+ DHD_ERROR(("%s: country code setting failed\n", __FUNCTION__));