wifi: bcm4329: Cumulative update to Version 4.218.248-18

This commit is contained in:
lbt 2011-03-31 19:19:41 +08:00
commit 28db32b654
14 changed files with 1171 additions and 518 deletions

View file

@ -7,6 +7,7 @@ DHDCFLAGS = -DLINUX -DBCMDRIVER -DBCMDONGLEHOST -DDHDTHREAD -DBCMWPA2 \
-DDHD_USE_STATIC_BUF -DDHD_DEBUG_TRAP -DSOFTAP -DSDIO_ISR_THREAD \
-DEMBEDDED_PLATFORM -DARP_OFFLOAD_SUPPORT -DPKT_FILTER_SUPPORT \
-DGET_CUSTOM_MAC_ENABLE -DSET_RANDOM_MAC_SOFTAP -DCSCAN \
-DKEEP_ALIVE -DCONFIG_US_NON_DFS_CHANNELS_ONLY \
-Idrivers/net/wireless/bcm4329 -Idrivers/net/wireless/bcm4329/include
#options defines dependent on platform board and applicantion requirements:

View file

@ -581,8 +581,6 @@ bcmsdh_unregister(void)
#endif /* BCMPLATFORM_BUS */
}
#if defined(OOB_INTR_ONLY)
void bcmsdh_oob_intr_set(bool enable)
{
@ -624,6 +622,9 @@ int bcmsdh_register_oob_intr(void * dhdp)
SDLX_MSG(("%s Enter\n", __FUNCTION__));
/* Example of HW_OOB for HW2: please refer to your host specifiction */
/* sdhcinfo->oob_flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL | IORESOURCE_IRQ_SHAREABLE; */
dev_set_drvdata(sdhcinfo->dev, dhdp);
if (!sdhcinfo->oob_irq_registered) {
@ -642,6 +643,20 @@ int bcmsdh_register_oob_intr(void * dhdp)
return 0;
}
void bcmsdh_set_irq(int flag)
{
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_unregister_oob_intr(void)
{
SDLX_MSG(("%s: Enter\n", __FUNCTION__));

View file

@ -675,7 +675,6 @@ 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);

View file

@ -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.49 2010/08/20 17:32:48 Exp $
* $Id: dhd.h,v 1.32.4.7.2.4.14.49.4.7 2010/11/12 22:48:36 Exp $
*/
/****************
@ -86,9 +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 {
@ -220,6 +222,8 @@ 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;
@ -348,8 +352,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
*/
@ -399,6 +406,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;

View file

@ -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.6 2010/05/17 18:18:13 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_
@ -63,7 +63,7 @@ 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
#endif /* DHD_DEBUG */
/* Deferred processing for the bus, return TRUE requests reschedule */
extern bool dhd_bus_dpc(struct dhd_bus *bus);

View file

@ -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.69.4.3 2010/09/10 21:30:16 Exp $
* $Id: dhd_common.c,v 1.5.6.8.2.6.6.69.4.20 2010/12/20 23:37:28 Exp $
*/
#include <typedefs.h>
#include <osl.h>
@ -39,6 +39,9 @@
#include <wlioctl.h>
#define CONFIG_BCM4329_FW_PATH "/system/etc/firmware/fw_bcm4329.bin"
#define CONFIG_BCM4329_NVRAM_PATH "/system/etc/firmware/nvram_GB8632.txt"
#ifdef SET_RANDOM_MAC_SOFTAP
#include <linux/random.h>
#include <linux/jiffies.h>
@ -52,9 +55,6 @@ int dhd_msg_level;
#include <wl_iw.h>
#define CONFIG_BCM4329_FW_PATH "/system/etc/firmware/fw_bcm4329.bin"
#define CONFIG_BCM4329_NVRAM_PATH "/system/etc/firmware/nvram_B23.txt"
char fw_path[MOD_PARAM_PATHLEN];
char nv_path[MOD_PARAM_PATHLEN];
@ -74,6 +74,13 @@ 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
@ -140,7 +147,7 @@ dhd_common_init(void)
* behaviour since the value of the globals may be different on the
* first time that the driver is initialized vs subsequent initializations.
*/
dhd_msg_level = DHD_ERROR_VAL |DHD_TRACE_VAL|DHD_INFO_VAL;
dhd_msg_level = DHD_ERROR_VAL;
#ifdef CONFIG_BCM4329_FW_PATH
strncpy(fw_path, CONFIG_BCM4329_FW_PATH, MOD_PARAM_PATHLEN-1);
#else
@ -1225,11 +1232,15 @@ dhd_preinit_ioctls(dhd_pub_t *dhd)
uint power_mode = PM_FAST;
uint32 dongle_align = DHD_SDALIGN;
uint32 glom = 0;
uint bcn_timeout = 3;
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
int ret;
struct ether_addr ea_addr;
#endif /* GET_CUSTOM_MAC_ENABLE */
@ -1256,7 +1267,6 @@ dhd_preinit_ioctls(dhd_pub_t *dhd)
#ifdef SET_RANDOM_MAC_SOFTAP
if (strstr(fw_path, "apsta") != NULL) {
uint rand_mac;
int ret;
srandom32((uint)jiffies);
rand_mac = random32();
@ -1287,6 +1297,11 @@ dhd_preinit_ioctls(dhd_pub_t *dhd)
}
}
/* Set Listen Interval */
bcm_mkiovar("assoc_listen", (char *)&listen_interval, 4, iovbuf, sizeof(iovbuf));
if ((ret = dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, iovbuf, sizeof(iovbuf))) < 0)
DHD_ERROR(("%s assoc_listen failed %d\n", __FUNCTION__, ret));
/* query for 'ver' to get version info from firmware */
memset(buf, 0, sizeof(buf));
ptr = buf;
@ -1315,6 +1330,12 @@ dhd_preinit_ioctls(dhd_pub_t *dhd)
bcm_mkiovar("roam_off", (char *)&dhd_roam, 4, iovbuf, sizeof(iovbuf));
dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, iovbuf, sizeof(iovbuf));
#if defined(SOFTAP)
if (ap_fw_loaded == TRUE) {
dhdcdc_set_ioctl(dhd, 0, WLC_SET_DTIMPRD, (char *)&dtim, sizeof(dtim));
}
#endif
if (dhd_roam == 0)
{
/* set internal roaming roaming parameters */
@ -1395,6 +1416,19 @@ dhd_preinit_ioctls(dhd_pub_t *dhd)
}
#endif /* PKT_FILTER_SUPPORT */
#if defined(KEEP_ALIVE)
{
/* Set Keep Alive : be sure to use FW with -keepalive */
int res;
if (ap_fw_loaded == FALSE) {
if ((res = dhd_keep_alive_onoff(dhd, 1)) < 0)
DHD_ERROR(("%s set keeplive failed %d\n", \
__FUNCTION__, res));
}
}
#endif
dhd_os_proto_unblock(dhd);
return 0;
@ -1449,7 +1483,7 @@ dhd_iscan_free_buf(void *dhdp, iscan_buf_t *iscan_delete)
dhd_pub_t *dhd = dhd_bus_pub(dhdp);
dhd_iscan_lock();
/* If iscan_delete is null then delete the entire
/* If iscan_delete is null then delete the entire
* chain or else delete specific one provided
*/
if (!iscan_delete) {
@ -1780,7 +1814,58 @@ fail:
return status;
}
#endif
#endif
/* Function to estimate possible DTIM_SKIP value */
int dhd_get_dtim_skip(dhd_pub_t *dhd)
{
int bcn_li_dtim;
char buf[128];
int ret;
int dtim_assoc = 0;
if ((dhd->dtim_skip == 0) || (dhd->dtim_skip == 1))
bcn_li_dtim = 3;
else
bcn_li_dtim = dhd->dtim_skip;
/* Read DTIM value if associated */
memset(buf, 0, sizeof(buf));
bcm_mkiovar("dtim_assoc", 0, 0, buf, sizeof(buf));
if ((ret = dhdcdc_query_ioctl(dhd, 0, WLC_GET_VAR, buf, sizeof(buf))) < 0) {
DHD_ERROR(("%s failed code %d\n", __FUNCTION__, ret));
bcn_li_dtim = 1;
goto exit;
}
else
dtim_assoc = dtoh32(*(int *)buf);
DHD_ERROR(("%s bcn_li_dtim=%d DTIM=%d Listen=%d\n", \
__FUNCTION__, bcn_li_dtim, dtim_assoc, LISTEN_INTERVAL));
/* if not assocated just eixt */
if (dtim_assoc == 0) {
goto exit;
}
/* check if sta listen interval fits into AP dtim */
if (dtim_assoc > LISTEN_INTERVAL) {
/* AP DTIM to big for our Listen Interval : no dtim skiping */
bcn_li_dtim = 1;
DHD_ERROR(("%s DTIM=%d > Listen=%d : too big ...\n", \
__FUNCTION__, dtim_assoc, LISTEN_INTERVAL));
goto exit;
}
if ((bcn_li_dtim * dtim_assoc) > LISTEN_INTERVAL) {
/* Round up dtim_skip to fit into STAs Listen Interval */
bcn_li_dtim = (int)(LISTEN_INTERVAL / dtim_assoc);
DHD_TRACE(("%s agjust dtim_skip as %d\n", __FUNCTION__, bcn_li_dtim));
}
exit:
return bcn_li_dtim;
}
#ifdef PNO_SUPPORT
int dhd_pno_clean(dhd_pub_t *dhd)
@ -1888,6 +1973,11 @@ dhd_pno_set(dhd_pub_t *dhd, wlc_ssid_t* ssids_local, int nssid, ushort scan_fr)
if (scan_fr != 0)
pfn_param.scan_freq = htod32(scan_fr);
if (pfn_param.scan_freq > PNO_SCAN_MAX_FW) {
DHD_ERROR(("%s pno freq above %d sec\n", __FUNCTION__, PNO_SCAN_MAX_FW));
return err;
}
bcm_mkiovar("pfn_set", (char *)&pfn_param, sizeof(pfn_param), iovbuf, sizeof(iovbuf));
dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, iovbuf, sizeof(iovbuf));
@ -1912,6 +2002,9 @@ dhd_pno_set(dhd_pub_t *dhd, wlc_ssid_t* ssids_local, int nssid, ushort scan_fr)
__FUNCTION__, i, err));
return err;
}
else
DHD_ERROR(("%s set OK with PNO time=%d\n", __FUNCTION__, \
pfn_param.scan_freq));
}
else DHD_ERROR(("%s failed err=%d\n", __FUNCTION__, err));
}
@ -1933,6 +2026,53 @@ int dhd_pno_get_status(dhd_pub_t *dhd)
#endif /* PNO_SUPPORT */
#if defined(KEEP_ALIVE)
int dhd_keep_alive_onoff(dhd_pub_t *dhd, int ka_on)
{
char buf[256];
char *buf_ptr = buf;
wl_keep_alive_pkt_t keep_alive_pkt;
char * str;
int str_len, buf_len;
int res = 0;
int keep_alive_period = KEEP_ALIVE_PERIOD; /* in ms */
DHD_TRACE(("%s: ka:%d\n", __FUNCTION__, ka_on));
if (ka_on) { /* on suspend */
keep_alive_pkt.period_msec = keep_alive_period;
} else {
/* on resume, turn off keep_alive packets */
keep_alive_pkt.period_msec = 0;
}
/* IOC var name */
str = "keep_alive";
str_len = strlen(str);
strncpy(buf, str, str_len);
buf[str_len] = '\0';
buf_len = str_len + 1;
/* set ptr to IOCTL payload after the var name */
buf_ptr += buf_len; /* include term Z */
/* copy Keep-alive attributes from local var keep_alive_pkt */
str = NULL_PKT_STR;
keep_alive_pkt.len_bytes = strlen(str);
memcpy(buf_ptr, &keep_alive_pkt, WL_KEEP_ALIVE_FIXED_LEN);
buf_ptr += WL_KEEP_ALIVE_FIXED_LEN;
/* copy packet data */
memcpy(buf_ptr, str, keep_alive_pkt.len_bytes);
buf_len += (WL_KEEP_ALIVE_FIXED_LEN + keep_alive_pkt.len_bytes);
res = dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, buf, buf_len);
return res;
}
#endif /* defined(KEEP_ALIVE) */
#if defined(CSCAN)
/* Androd ComboSCAN support */
@ -2183,4 +2323,4 @@ wl_iw_parse_channel_list(char** list_str, uint16* channel_list, int channel_num)
return num;
}
#endif
#endif

View file

@ -29,8 +29,8 @@
#ifdef DHD_DEBUG
#define DHD_ERROR(args) do {if ((dhd_msg_level & DHD_ERROR_VAL) && (net_ratelimit())) \
printf args;} while (0)
#define DHD_ERROR(args) do {if ((dhd_msg_level & DHD_ERROR_VAL) && (net_ratelimit())) \
printf args;} while (0)
#define DHD_TRACE(args) do {if (dhd_msg_level & DHD_TRACE_VAL) printf args;} while (0)
#define DHD_INFO(args) do {if (dhd_msg_level & DHD_INFO_VAL) printf args;} while (0)
#define DHD_DATA(args) do {if (dhd_msg_level & DHD_DATA_VAL) printf args;} while (0)

View file

@ -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,v 1.65.4.9.2.12.2.104 2010/08/20 19:15:40 Exp $
* $Id: dhd_linux.c,v 1.65.4.9.2.12.2.104.4.35 2010/11/17 03:13:21 Exp $
*/
#ifdef CONFIG_WIFI_CONTROL_FUNC
@ -107,7 +107,7 @@ int wifi_set_power(int on, unsigned long msec)
int wifi_set_reset(int on, unsigned long msec)
{
printk("%s = %d\n", __FUNCTION__, on);
DHD_TRACE(("%s = %d\n", __FUNCTION__, on));
if (wifi_control_data && wifi_control_data->set_reset) {
wifi_control_data->set_reset(on);
}
@ -118,7 +118,7 @@ int wifi_set_reset(int on, unsigned long msec)
int wifi_get_mac_addr(unsigned char *buf)
{
printk("%s\n", __FUNCTION__);
DHD_TRACE(("%s\n", __FUNCTION__));
if (!buf)
return -EINVAL;
if (wifi_control_data && wifi_control_data->get_mac_addr) {
@ -218,9 +218,10 @@ print_tainted()
#include <wl_iw.h>
#endif /* defined(CONFIG_WIRELESS_EXT) */
extern int dhdcdc_set_ioctl(dhd_pub_t *dhd, int ifidx, uint cmd, void *buf, uint len);
#if defined(CONFIG_HAS_EARLYSUSPEND)
#include <linux/earlysuspend.h>
extern int dhdcdc_set_ioctl(dhd_pub_t *dhd, int ifidx, uint cmd, void *buf, uint len);
#endif /* defined(CONFIG_HAS_EARLYSUSPEND) */
#ifdef PKT_FILTER_SUPPORT
@ -261,6 +262,8 @@ typedef struct dhd_info {
struct tasklet_struct tasklet;
spinlock_t sdlock;
spinlock_t txqlock;
spinlock_t dhd_lock;
/* Thread based operation */
bool threads_only;
struct semaphore sdsem;
@ -280,10 +283,10 @@ typedef struct dhd_info {
int wl_count;
int wl_packet;
int hang_was_sent;
struct mutex wl_start_lock;
int hang_was_sent; /* flag that message was send at least once */
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25))
struct mutex wl_start_lock; /* mutex when START called to prevent any other Linux calls */
#endif
/* Thread to issue ioctl for multicast */
long sysioc_pid;
struct semaphore sysioc_sem;
@ -307,7 +310,7 @@ char nvram_path[MOD_PARAM_PATHLEN];
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27))
struct semaphore dhd_registration_sem;
#define DHD_REGISTRATION_TIMEOUT 8000 /* msec : allowed time to finished dhd registration */
#define DHD_REGISTRATION_TIMEOUT 12000 /* msec : allowed time to finished dhd registration */
#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) */
/* load firmware and/or nvram values from the filesystem */
module_param_string(firmware_path, firmware_path, MOD_PARAM_PATHLEN, 0);
@ -521,6 +524,8 @@ static void dhd_set_packet_filter(int value, dhd_pub_t *dhd)
#endif
}
#if defined(CONFIG_HAS_EARLYSUSPEND)
static int dhd_set_suspend(int value, dhd_pub_t *dhd)
{
@ -539,7 +544,7 @@ static int dhd_set_suspend(int value, dhd_pub_t *dhd)
if (value && dhd->in_suspend) {
/* Kernel suspended */
DHD_TRACE(("%s: force extra Suspend setting \n", __FUNCTION__));
DHD_TRACE(("%s: force extra Suspend setting \n", __FUNCTION__));
dhdcdc_set_ioctl(dhd, 0, WLC_SET_PM,
(char *)&power_mode, sizeof(power_mode));
@ -547,26 +552,24 @@ static int dhd_set_suspend(int value, dhd_pub_t *dhd)
/* Enable packet filter, only allow unicast packet to send up */
dhd_set_packet_filter(1, dhd);
/* if dtim skip setup as default force it to wake each thrid dtim
* for better power saving.
* Note that side effect is chance to miss BC/MC packet
*/
if ((dhd->dtim_skip == 0) || (dhd->dtim_skip == 1))
bcn_li_dtim = 3;
else
bcn_li_dtim = dhd->dtim_skip;
/* if dtim skip setup as default force it to wake each thrid dtim
* for better power saving.
* Note that side effect is chance to miss BC/MC packet
*/
bcn_li_dtim = dhd_get_dtim_skip(dhd);
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 roaming */
/* Disable build-in roaming during suspend */
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 {
/* Kernel resumed */
DHD_TRACE(("%s: Remove extra suspend setting \n", __FUNCTION__));
DHD_TRACE(("%s: Remove extra suspend setting \n", __FUNCTION__));
power_mode = PM_FAST;
dhdcdc_set_ioctl(dhd, 0, WLC_SET_PM, (char *)&power_mode,
@ -575,11 +578,11 @@ static int dhd_set_suspend(int value, dhd_pub_t *dhd)
/* disable pkt filter */
dhd_set_packet_filter(0, dhd);
/* restore pre-suspend setting for dtim_skip */
bcm_mkiovar("bcn_li_dtim", (char *)&dhd->dtim_skip,
4, iovbuf, sizeof(iovbuf));
/* restore pre-suspend setting for dtim_skip */
bcm_mkiovar("bcn_li_dtim", (char *)&dhd->dtim_skip,
4, iovbuf, sizeof(iovbuf));
dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, iovbuf, sizeof(iovbuf));
dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, iovbuf, sizeof(iovbuf));
#ifdef CUSTOMER_HW2
roamvar = dhd_roam;
bcm_mkiovar("roam_off", (char *)&roamvar, 4, iovbuf, sizeof(iovbuf));
@ -901,13 +904,18 @@ _dhd_set_mac_address(dhd_info_t *dhd, int ifidx, struct ether_addr *addr)
#ifdef SOFTAP
extern struct net_device *ap_net_dev;
/* semaphore that the soft AP CODE waits on */
extern struct semaphore ap_eth_sema;
#endif
static void
dhd_op_if(dhd_if_t *ifp)
{
dhd_info_t *dhd;
int ret = 0, err = 0;
dhd_info_t *dhd;
int ret = 0, err = 0;
#ifdef SOFTAP
unsigned long flags;
#endif
ASSERT(ifp && ifp->info && ifp->idx); /* Virtual interfaces only */
@ -942,13 +950,12 @@ dhd_op_if(dhd_if_t *ifp)
ret = -EOPNOTSUPP;
} else {
#ifdef SOFTAP
/* semaphore that the soft AP CODE waits on */
extern struct semaphore ap_eth_sema;
flags = dhd_os_spin_lock(&dhd->pub);
/* save ptr to wl0.1 netdev for use in wl_iw.c */
ap_net_dev = ifp->net;
/* signal to the SOFTAP 'sleeper' thread, wl0.1 is ready */
up(&ap_eth_sema);
dhd_os_spin_unlock(&dhd->pub, flags);
#endif
DHD_TRACE(("\n ==== pid:%x, net_device for if:%s created ===\n\n",
current->pid, ifp->net->name));
@ -977,8 +984,10 @@ dhd_op_if(dhd_if_t *ifp)
dhd->iflist[ifp->idx] = NULL;
MFREE(dhd->pub.osh, ifp, sizeof(*ifp));
#ifdef SOFTAP
flags = dhd_os_spin_lock(&dhd->pub);
if (ifp->net == ap_net_dev)
ap_net_dev = NULL; /* NULL SOFTAP global as well */
dhd_os_spin_unlock(&dhd->pub, flags);
#endif /* SOFTAP */
}
}
@ -990,6 +999,7 @@ _dhd_sysioc_thread(void *data)
int i;
#ifdef SOFTAP
bool in_ap = FALSE;
unsigned long flags;
#endif
DAEMONIZE("dhd_sysioc");
@ -1001,7 +1011,9 @@ _dhd_sysioc_thread(void *data)
if (dhd->iflist[i]) {
DHD_TRACE(("%s: interface %d\n",__FUNCTION__, i));
#ifdef SOFTAP
flags = dhd_os_spin_lock(&dhd->pub);
in_ap = (ap_net_dev != NULL);
dhd_os_spin_unlock(&dhd->pub, flags);
#endif /* SOFTAP */
if (dhd->iflist[i]->state)
dhd_op_if(dhd->iflist[i]);
@ -1036,6 +1048,7 @@ _dhd_sysioc_thread(void *data)
dhd_os_wake_unlock(&dhd->pub);
dhd_os_start_unlock(&dhd->pub);
}
DHD_TRACE(("%s: stopped\n",__FUNCTION__));
complete_and_exit(&dhd->sysioc_exited, 0);
}
@ -1387,22 +1400,24 @@ dhd_watchdog_thread(void *data)
/* Run until signal received */
while (1) {
if (down_interruptible (&dhd->watchdog_sem) == 0) {
dhd_os_sdlock(&dhd->pub);
if (dhd->pub.dongle_reset == FALSE) {
DHD_TIMER(("%s:\n", __FUNCTION__));
/* Call the bus module watchdog */
dhd_bus_watchdog(&dhd->pub);
/* Count the tick for reference */
dhd->pub.tickcnt++;
/* Reschedule the watchdog */
if (dhd->wd_timer_valid)
mod_timer(&dhd->timer, jiffies + dhd_watchdog_ms * HZ / 1000);
}
/* Count the tick for reference */
dhd->pub.tickcnt++;
/* Reschedule the watchdog */
if (dhd->wd_timer_valid)
mod_timer(&dhd->timer, jiffies + dhd_watchdog_ms * HZ / 1000);
dhd_os_sdunlock(&dhd->pub);
dhd_os_wake_unlock(&dhd->pub);
}
else
} else {
break;
}
}
complete_and_exit(&dhd->watchdog_exited, 0);
@ -1414,11 +1429,17 @@ dhd_watchdog(ulong data)
dhd_info_t *dhd = (dhd_info_t *)data;
dhd_os_wake_lock(&dhd->pub);
if (dhd->pub.dongle_reset) {
dhd_os_wake_unlock(&dhd->pub);
return;
}
if (dhd->watchdog_pid >= 0) {
up(&dhd->watchdog_sem);
return;
}
dhd_os_sdlock(&dhd->pub);
/* Call the bus module watchdog */
dhd_bus_watchdog(&dhd->pub);
@ -1428,6 +1449,7 @@ dhd_watchdog(ulong data)
/* Reschedule the watchdog */
if (dhd->wd_timer_valid)
mod_timer(&dhd->timer, jiffies + dhd_watchdog_ms * HZ / 1000);
dhd_os_sdunlock(&dhd->pub);
dhd_os_wake_unlock(&dhd->pub);
}
@ -1852,7 +1874,7 @@ dhd_stop(struct net_device *net)
#if !defined(IGNORE_ETH0_DOWN)
dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(net);
DHD_TRACE(("%s: Enter\n", __FUNCTION__));
DHD_TRACE(("%s: Enter %s\n", __FUNCTION__, net->name));
if (dhd->pub.up == 0) {
return 0;
}
@ -1877,7 +1899,8 @@ dhd_open(struct net_device *net)
#endif
int ifidx;
wl_control_wl_start(net); /* start if needed */
/* Force start if ifconfig_up gets called before START command */
wl_control_wl_start(net);
ifidx = dhd_net2idx(dhd, net);
DHD_TRACE(("%s: ifidx %d\n", __FUNCTION__, ifidx));
@ -1887,7 +1910,6 @@ dhd_open(struct net_device *net)
return -1;
}
if (ifidx == 0) { /* do it only for primary eth0 */
atomic_set(&dhd->pend_8021x_cnt, 0);
@ -2045,6 +2067,7 @@ dhd_attach(osl_t *osh, struct dhd_bus *bus, uint bus_hdrlen)
/* Initialize the spinlocks */
spin_lock_init(&dhd->sdlock);
spin_lock_init(&dhd->txqlock);
spin_lock_init(&dhd->dhd_lock);
/* Initialize Wakelock stuff */
spin_lock_init(&dhd->wl_lock);
@ -2054,8 +2077,9 @@ dhd_attach(osl_t *osh, struct dhd_bus *bus, uint bus_hdrlen)
wake_lock_init(&dhd->wl_wifi, WAKE_LOCK_SUSPEND, "wlan_wake");
wake_lock_init(&dhd->wl_rxwake, WAKE_LOCK_SUSPEND, "wlan_rx_wake");
#endif
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25))
mutex_init(&dhd->wl_start_lock);
#endif
/* Link to info module */
dhd->pub.info = dhd;
@ -2184,8 +2208,8 @@ dhd_bus_start(dhd_pub_t *dhdp)
#if defined(OOB_INTR_ONLY)
/* Host registration for OOB interrupt */
if (bcmsdh_register_oob_intr(dhdp)) {
del_timer_sync(&dhd->timer);
dhd->wd_timer_valid = FALSE;
del_timer_sync(&dhd->timer);
DHD_ERROR(("%s Host failed to resgister for OOB\n", __FUNCTION__));
return -ENODEV;
}
@ -2196,8 +2220,8 @@ dhd_bus_start(dhd_pub_t *dhdp)
/* If bus is not ready, can't come up */
if (dhd->pub.busstate != DHD_BUS_DATA) {
del_timer_sync(&dhd->timer);
dhd->wd_timer_valid = FALSE;
del_timer_sync(&dhd->timer);
DHD_ERROR(("%s failed bus is not ready\n", __FUNCTION__));
return -ENODEV;
}
@ -2225,6 +2249,7 @@ dhd_bus_start(dhd_pub_t *dhdp)
setbit(dhdp->eventmask, WLC_E_TXFAIL);
setbit(dhdp->eventmask, WLC_E_JOIN_START);
setbit(dhdp->eventmask, WLC_E_SCAN_COMPLETE);
setbit(dhdp->eventmask, WLC_E_RELOAD);
#ifdef PNO_SUPPORT
setbit(dhdp->eventmask, WLC_E_PFN_NET_FOUND);
#endif /* PNO_SUPPORT */
@ -2362,6 +2387,7 @@ dhd_net_attach(dhd_pub_t *dhdp, int ifidx)
dhd->pub.mac.octet[3], dhd->pub.mac.octet[4], dhd->pub.mac.octet[5]);
#if defined(CONFIG_WIRELESS_EXT)
#if defined(CONFIG_FIRST_SCAN)
#ifdef SOFTAP
if (ifidx == 0)
/* Don't call for SOFTAP Interface in SOFTAP MODE */
@ -2369,6 +2395,7 @@ dhd_net_attach(dhd_pub_t *dhdp, int ifidx)
#else
wl_iw_iscan_set_scan_broadcast_prep(net, 1);
#endif /* SOFTAP */
#endif /* CONFIG_FIRST_SCAN */
#endif /* CONFIG_WIRELESS_EXT */
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27))
@ -2405,8 +2432,8 @@ dhd_bus_detach(dhd_pub_t *dhdp)
#endif /* defined(OOB_INTR_ONLY) */
/* Clear the watchdog timer */
del_timer_sync(&dhd->timer);
dhd->wd_timer_valid = FALSE;
del_timer_sync(&dhd->timer);
}
}
}
@ -2432,16 +2459,18 @@ dhd_detach(dhd_pub_t *dhdp)
/* Attach and link in the iw */
wl_iw_detach();
#endif
for (i = 1; i < DHD_MAX_IFS; i++)
if (dhd->iflist[i])
dhd_del_if(dhd, i);
if (dhd->sysioc_pid >= 0) {
KILL_PROC(dhd->sysioc_pid, SIGTERM);
wait_for_completion(&dhd->sysioc_exited);
}
for (i = 1; i < DHD_MAX_IFS; i++)
if (dhd->iflist[i]) {
dhd->iflist[i]->state = WLC_E_IF_DEL;
dhd->iflist[i]->idx = i;
dhd_op_if(dhd->iflist[i]);
}
ifp = dhd->iflist[0];
ASSERT(ifp);
#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 31))
@ -2598,6 +2627,7 @@ EXPORT_SYMBOL(rockchip_wifi_exit_module);
EXPORT_SYMBOL(mv88w8686_if_sdio_init_module);
EXPORT_SYMBOL(mv88w8686_if_sdio_exit_module);
/*
* OS specific functions required to implement DHD driver in OS independent way
*/
@ -2684,29 +2714,28 @@ void
dhd_os_wd_timer(void *bus, uint wdtick)
{
dhd_pub_t *pub = bus;
static uint save_dhd_watchdog_ms = 0;
dhd_info_t *dhd = (dhd_info_t *)pub->info;
unsigned long flags;
int del_timer_flag = FALSE;
flags = dhd_os_spin_lock(pub);
/* don't start the wd until fw is loaded */
if (pub->busstate == DHD_BUS_DOWN)
return;
/* Totally stop the timer */
if (!wdtick && dhd->wd_timer_valid == TRUE) {
del_timer_sync(&dhd->timer);
dhd->wd_timer_valid = FALSE;
save_dhd_watchdog_ms = wdtick;
return;
if (pub->busstate != DHD_BUS_DOWN) {
if (wdtick) {
dhd_watchdog_ms = (uint)wdtick;
dhd->wd_timer_valid = TRUE;
/* Re arm the timer, at last watchdog period */
mod_timer(&dhd->timer, jiffies + dhd_watchdog_ms * HZ / 1000);
} else if (dhd->wd_timer_valid == TRUE) {
/* Totally stop the timer */
dhd->wd_timer_valid = FALSE;
del_timer_flag = TRUE;
}
}
if (wdtick) {
dhd_watchdog_ms = (uint)wdtick;
/* Re arm the timer, at last watchdog period */
mod_timer(&dhd->timer, jiffies + dhd_watchdog_ms * HZ / 1000);
dhd->wd_timer_valid = TRUE;
save_dhd_watchdog_ms = wdtick;
dhd_os_spin_unlock(pub, flags);
if (del_timer_flag) {
del_timer_sync(&dhd->timer);
}
}
@ -2920,20 +2949,18 @@ void dhd_wait_event_wakeup(dhd_pub_t *dhd)
int
dhd_dev_reset(struct net_device *dev, uint8 flag)
{
int ret;
dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev);
/* Turning off watchdog */
if (flag)
dhd_os_wd_timer(&dhd->pub, 0);
ret = dhd_bus_devreset(&dhd->pub, flag);
if (ret) {
DHD_ERROR(("%s: dhd_bus_devreset: %d\n", __FUNCTION__, ret));
return ret;
}
DHD_ERROR(("%s: WLAN %s DONE\n", __FUNCTION__, flag ? "OFF" : "ON"));
dhd_bus_devreset(&dhd->pub, flag);
/* Turning on watchdog back */
if (!flag)
dhd_os_wd_timer(&dhd->pub, dhd_watchdog_ms);
DHD_ERROR(("%s: WLAN OFF DONE\n", __FUNCTION__));
return 1;
return ret;
}
int net_os_set_suspend_disable(struct net_device *dev, int val)
@ -3044,6 +3071,57 @@ dhd_dev_get_pno_status(struct net_device *dev)
#endif /* PNO_SUPPORT */
int net_os_send_hang_message(struct net_device *dev)
{
dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev);
int ret = 0;
if (dhd) {
if (!dhd->hang_was_sent) {
dhd->hang_was_sent = 1;
ret = wl_iw_send_priv_event(dev, "HANG");
}
}
return ret;
}
void dhd_bus_country_set(struct net_device *dev, char *country_code)
{
dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev);
if (dhd && dhd->pub.up)
strncpy(dhd->pub.country_code, country_code, WLC_CNTRY_BUF_SZ);
}
char *dhd_bus_country_get(struct net_device *dev)
{
dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev);
if (dhd && (dhd->pub.country_code[0] != 0))
return dhd->pub.country_code;
return NULL;
}
void dhd_os_start_lock(dhd_pub_t *pub)
{
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25))
dhd_info_t *dhd = (dhd_info_t *)(pub->info);
if (dhd)
mutex_lock(&dhd->wl_start_lock);
#endif
}
void dhd_os_start_unlock(dhd_pub_t *pub)
{
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25))
dhd_info_t *dhd = (dhd_info_t *)(pub->info);
if (dhd)
mutex_unlock(&dhd->wl_start_lock);
#endif
}
static int
dhd_get_pend_8021x_cnt(dhd_info_t *dhd)
{
@ -3226,32 +3304,21 @@ int net_os_wake_unlock(struct net_device *dev)
return ret;
}
int net_os_send_hang_message(struct net_device *dev)
unsigned long dhd_os_spin_lock(dhd_pub_t *pub)
{
dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev);
int ret = 0;
dhd_info_t *dhd = (dhd_info_t *)(pub->info);
unsigned long flags = 0;
if (dhd) {
if (!dhd->hang_was_sent) {
dhd->hang_was_sent = 1;
ret = wl_iw_send_priv_event(dev, "HANG");
}
}
return ret;
if (dhd)
spin_lock_irqsave(&dhd->dhd_lock, flags);
return flags;
}
void dhd_os_start_lock(dhd_pub_t *pub)
void dhd_os_spin_unlock(dhd_pub_t *pub, unsigned long flags)
{
dhd_info_t *dhd = (dhd_info_t *)(pub->info);
if (dhd)
mutex_lock(&dhd->wl_start_lock);
}
void dhd_os_start_unlock(dhd_pub_t *pub)
{
dhd_info_t *dhd = (dhd_info_t *)(pub->info);
if (dhd)
mutex_unlock(&dhd->wl_start_lock);
spin_unlock_irqrestore(&dhd->dhd_lock, flags);
}

View file

@ -146,6 +146,8 @@
DHD_SPINWAIT_SLEEP_INIT(sdioh_spinwait_sleep);
extern int dhdcdc_set_ioctl(dhd_pub_t *dhd, int ifidx, uint cmd, void *buf, uint len);
extern void bcmsdh_set_irq(int flag);
#ifdef DHD_DEBUG
/* Device console log buffer state */
typedef struct dhd_console {
@ -438,7 +440,7 @@ static bool dhdsdio_probe_attach(dhd_bus_t *bus, osl_t *osh, void *sdh,
void * regsva, uint16 devid);
static bool dhdsdio_probe_malloc(dhd_bus_t *bus, osl_t *osh, void *sdh);
static bool dhdsdio_probe_init(dhd_bus_t *bus, osl_t *osh, void *sdh);
static void dhdsdio_release_dongle(dhd_bus_t *bus, osl_t *osh);
static void dhdsdio_release_dongle(dhd_bus_t *bus, osl_t *osh, int reset_flag);
static uint process_nvram_vars(char *varbuf, uint len);
@ -705,6 +707,7 @@ dhdsdio_sdclk(dhd_bus_t *bus, bool on)
static int
dhdsdio_clkctl(dhd_bus_t *bus, uint target, bool pendok)
{
int ret = BCME_OK;
#ifdef DHD_DEBUG
uint oldstate = bus->clkstate;
#endif /* DHD_DEBUG */
@ -717,7 +720,7 @@ dhdsdio_clkctl(dhd_bus_t *bus, uint target, bool pendok)
dhd_os_wd_timer(bus->dhd, dhd_watchdog_ms);
bus->activity = TRUE;
}
return BCME_OK;
return ret;
}
switch (target) {
@ -726,29 +729,32 @@ dhdsdio_clkctl(dhd_bus_t *bus, uint target, bool pendok)
if (bus->clkstate == CLK_NONE)
dhdsdio_sdclk(bus, TRUE);
/* Now request HT Avail on the backplane */
dhdsdio_htclk(bus, TRUE, pendok);
dhd_os_wd_timer(bus->dhd, dhd_watchdog_ms);
bus->activity = TRUE;
ret = dhdsdio_htclk(bus, TRUE, pendok);
if (ret == BCME_OK) {
dhd_os_wd_timer(bus->dhd, dhd_watchdog_ms);
bus->activity = TRUE;
}
break;
case CLK_SDONLY:
/* Remove HT request, or bring up SD clock */
if (bus->clkstate == CLK_NONE)
dhdsdio_sdclk(bus, TRUE);
ret = dhdsdio_sdclk(bus, TRUE);
else if (bus->clkstate == CLK_AVAIL)
dhdsdio_htclk(bus, FALSE, FALSE);
ret = dhdsdio_htclk(bus, FALSE, FALSE);
else
DHD_ERROR(("dhdsdio_clkctl: request for %d -> %d\n",
bus->clkstate, target));
dhd_os_wd_timer(bus->dhd, dhd_watchdog_ms);
if (ret == BCME_OK)
dhd_os_wd_timer(bus->dhd, dhd_watchdog_ms);
break;
case CLK_NONE:
/* Make sure to remove HT request */
if (bus->clkstate == CLK_AVAIL)
dhdsdio_htclk(bus, FALSE, FALSE);
ret = dhdsdio_htclk(bus, FALSE, FALSE);
/* Now remove the SD clock */
dhdsdio_sdclk(bus, FALSE);
ret = dhdsdio_sdclk(bus, FALSE);
dhd_os_wd_timer(bus->dhd, 0);
break;
}
@ -756,7 +762,7 @@ dhdsdio_clkctl(dhd_bus_t *bus, uint target, bool pendok)
DHD_INFO(("dhdsdio_clkctl: %d -> %d\n", oldstate, bus->clkstate));
#endif /* DHD_DEBUG */
return BCME_OK;
return ret;
}
int
@ -2719,6 +2725,9 @@ dhd_bus_stop(struct dhd_bus *bus, bool enforce_mutex)
BUS_WAKE(bus);
/* Change our idea of bus state */
bus->dhd->busstate = DHD_BUS_DOWN;
/* Enable clock for device interrupts */
dhdsdio_clkctl(bus, CLK_AVAIL, FALSE);
@ -2727,9 +2736,6 @@ dhd_bus_stop(struct dhd_bus *bus, bool enforce_mutex)
local_hostintmask = bus->hostintmask;
bus->hostintmask = 0;
/* Change our idea of bus state */
bus->dhd->busstate = DHD_BUS_DOWN;
/* Force clocks on backplane to be sure F2 interrupt propagates */
saveclk = bcmsdh_cfg_read(bus->sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, &err);
if (!err) {
@ -2782,23 +2788,24 @@ dhd_bus_init(dhd_pub_t *dhdp, bool enforce_mutex)
dhd_timeout_t tmo;
uint retries = 0;
uint8 ready, enable;
int err, ret = 0;
int err, ret = BCME_ERROR;
uint8 saveclk;
DHD_TRACE(("%s: Enter\n", __FUNCTION__));
ASSERT(bus->dhd);
if (!bus->dhd)
return 0;
return BCME_OK;
if (enforce_mutex)
dhd_os_sdlock(bus->dhd);
/* Make sure backplane clock is on, needed to generate F2 interrupt */
dhdsdio_clkctl(bus, CLK_AVAIL, FALSE);
if (bus->clkstate != CLK_AVAIL)
err = dhdsdio_clkctl(bus, CLK_AVAIL, FALSE);
if ((err != BCME_OK) || (bus->clkstate != CLK_AVAIL)) {
DHD_ERROR(("%s: Failed to set backplane clock: err %d\n", __FUNCTION__, err));
goto exit;
}
/* Force clocks on backplane to be sure F2 interrupt propagates */
saveclk = bcmsdh_cfg_read(bus->sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, &err);
@ -2873,6 +2880,7 @@ dhd_bus_init(dhd_pub_t *dhdp, bool enforce_mutex)
if (dhdp->busstate != DHD_BUS_DATA)
dhdsdio_clkctl(bus, CLK_NONE, FALSE);
ret = BCME_OK;
exit:
if (enforce_mutex)
dhd_os_sdunlock(bus->dhd);
@ -4631,8 +4639,6 @@ dhd_bus_watchdog(dhd_pub_t *dhdp)
if (bus->sleeping)
return FALSE;
dhd_os_sdlock(bus->dhd);
/* Poll period: check device if appropriate. */
if (bus->poll && (++bus->polltick >= bus->pollrate)) {
uint32 intstatus = 0;
@ -4702,8 +4708,6 @@ dhd_bus_watchdog(dhd_pub_t *dhdp)
}
}
dhd_os_sdunlock(bus->dhd);
return bus->ipend;
}
@ -5299,7 +5303,7 @@ dhdsdio_release(dhd_bus_t *bus, osl_t *osh)
if (bus->dhd) {
dhdsdio_release_dongle(bus, osh);
dhdsdio_release_dongle(bus, osh, TRUE);
dhd_detach(bus->dhd);
bus->dhd = NULL;
@ -5343,11 +5347,11 @@ dhdsdio_release_malloc(dhd_bus_t *bus, osl_t *osh)
static void
dhdsdio_release_dongle(dhd_bus_t *bus, osl_t *osh)
dhdsdio_release_dongle(dhd_bus_t *bus, osl_t *osh, int reset_flag)
{
DHD_TRACE(("%s: Enter\n", __FUNCTION__));
if (bus->dhd && bus->dhd->dongle_reset)
if ((bus->dhd && bus->dhd->dongle_reset) && reset_flag)
return;
if (bus->sih) {
@ -5797,27 +5801,24 @@ dhd_bus_devreset(dhd_pub_t *dhdp, uint8 flag)
if (flag == TRUE) {
if (!bus->dhd->dongle_reset) {
dhd_os_sdlock(dhdp);
/* Turning off watchdog */
dhd_os_wd_timer(dhdp, 0);
#if !defined(IGNORE_ETH0_DOWN)
/* Force flow control as protection when stop come before ifconfig_down */
dhd_txflowcontrol(bus->dhd, 0, ON);
#endif /* !defined(IGNORE_ETH0_DOWN) */
/* save country settinng if was pre-setup with priv ioctl */
dhd_os_proto_block(dhdp);
dhdcdc_query_ioctl(bus->dhd, 0, WLC_GET_COUNTRY,
bus->dhd->country_code, sizeof(bus->dhd->country_code));
dhd_os_proto_unblock(dhdp);
/* Expect app to have torn down any connection before calling */
/* Stop the bus, disable F2 */
dhd_os_sdlock(dhdp);
dhd_bus_stop(bus, FALSE);
#if defined(OOB_INTR_ONLY)
bcmsdh_set_irq(FALSE);
#endif /* defined(OOB_INTR_ONLY) */
/* Clean tx/rx buffer pointers, detach from the dongle */
dhdsdio_release_dongle(bus, bus->dhd->osh);
dhdsdio_release_dongle(bus, bus->dhd->osh, TRUE);
bus->dhd->dongle_reset = TRUE;
bus->dhd->up = FALSE;
dhd_os_sdunlock(dhdp);
DHD_TRACE(("%s: WLAN OFF DONE\n", __FUNCTION__));
@ -5845,25 +5846,31 @@ dhd_bus_devreset(dhd_pub_t *dhdp, uint8 flag)
dhdsdio_download_firmware(bus, bus->dhd->osh, bus->sdh)) {
/* Re-init bus, enable F2 transfer */
dhd_bus_init((dhd_pub_t *) bus->dhd, FALSE);
bcmerror = dhd_bus_init((dhd_pub_t *) bus->dhd, FALSE);
if (bcmerror == BCME_OK) {
#if defined(OOB_INTR_ONLY)
dhd_enable_oob_intr(bus, TRUE);
bcmsdh_set_irq(TRUE);
dhd_enable_oob_intr(bus, TRUE);
#endif /* defined(OOB_INTR_ONLY) */
bus->dhd->dongle_reset = FALSE;
bus->dhd->up = TRUE;
bus->dhd->dongle_reset = FALSE;
bus->dhd->up = TRUE;
#if !defined(IGNORE_ETH0_DOWN)
/* Restore flow control */
dhd_txflowcontrol(bus->dhd, 0, OFF);
#endif
/* Restore flow control */
dhd_txflowcontrol(bus->dhd, 0, OFF);
#endif
/* Turning on watchdog back */
dhd_os_wd_timer(dhdp, dhd_watchdog_ms);
DHD_TRACE(("%s: WLAN ON DONE\n", __FUNCTION__));
DHD_TRACE(("%s: WLAN ON DONE\n", __FUNCTION__));
} else {
dhd_bus_stop(bus, FALSE);
dhdsdio_release_dongle(bus, bus->dhd->osh, FALSE);
}
} else
bcmerror = BCME_SDIO_ERROR;
} else
bcmerror = BCME_SDIO_ERROR;
dhd_os_sdunlock(dhdp);
} else {
bcmerror = BCME_NOTDOWN;

View file

@ -33,16 +33,16 @@
#define EPI_RC_NUMBER 248
#define EPI_INCREMENTAL_NUMBER 6
#define EPI_INCREMENTAL_NUMBER 18
#define EPI_BUILD_NUMBER 0
#define EPI_VERSION 4, 218, 248, 6
#define EPI_VERSION 4, 218, 248, 18
#define EPI_VERSION_NUM 0x04daf806
#define EPI_VERSION_NUM 0x04daf812
#define EPI_VERSION_STR "4.218.248.6"
#define EPI_ROUTER_VERSION_STR "4.219.248.6"
#define EPI_VERSION_STR "4.218.248.18"
#define EPI_ROUTER_VERSION_STR "4.219.248.18"
#endif

View file

@ -24,7 +24,7 @@
*
* Dependencies: proto/bcmeth.h
*
* $Id: bcmevent.h,v 9.34.4.1.20.16 2009/09/25 23:52:38 Exp $
* $Id: bcmevent.h,v 9.34.4.1.20.16.64.1 2010/11/08 21:57:03 Exp $
*
*/
@ -131,10 +131,10 @@ typedef BWL_PRE_PACKED_STRUCT struct bcm_event {
#define WLC_E_ACTION_FRAME 58
#define WLC_E_ACTION_FRAME_COMPLETE 59
#define WLC_E_ESCAN_RESULT 69
#define WLC_E_WAKE_EVENT 70
#define WLC_E_LAST 71
#define WLC_E_ESCAN_RESULT 69
#define WLC_E_WAKE_EVENT 70
#define WLC_E_RELOAD 71
#define WLC_E_LAST 72
@ -205,6 +205,7 @@ typedef BWL_PRE_PACKED_STRUCT struct bcm_event {
#define WLC_E_IF_ADD 1
#define WLC_E_IF_DEL 2
#define WLC_E_RELOAD_STATUS1 1
#include <packed_section_end.h>

View file

@ -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: wlioctl.h,v 1.601.4.15.2.14.2.62 2010/08/19 01:20:12 Exp $
* $Id: wlioctl.h,v 1.601.4.15.2.14.2.62.4.1 2010/11/17 03:09:28 Exp $
*/
@ -857,6 +857,7 @@ typedef struct wl_ioctl {
#define PM_MAX 1
#define PM_FAST 2
#define LISTEN_INTERVAL 20
#define INTERFERE_NONE 0
#define NON_WLAN 1

File diff suppressed because it is too large Load diff

View file

@ -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: wl_iw.h,v 1.5.34.1.6.36.4.1 2010/09/10 19:24:30 Exp $
* $Id: wl_iw.h,v 1.5.34.1.6.36.4.15 2010/11/17 03:13:51 Exp $
*/
@ -52,6 +52,7 @@
#define PNOSETUP_SET_CMD "PNOSETUP "
#define PNOENABLE_SET_CMD "PNOFORCE"
#define PNODEBUG_SET_CMD "PNODEBUG"
#define SETDFSCHANNELS_CMD "SETDFSCHANNELS"
#define MAC2STR(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5]
#define MACSTR "%02x:%02x:%02x:%02x:%02x:%02x"
@ -87,8 +88,9 @@ typedef struct wl_iw_extra_params {
#define AP_LPB_CMD (SIOCIWFIRSTPRIV+23)
#define WL_AP_STOP (SIOCIWFIRSTPRIV+25)
#define WL_FW_RELOAD (SIOCIWFIRSTPRIV+27)
#define WL_COMBO_SCAN (SIOCIWFIRSTPRIV+29)
#define WL_AP_SPARE3 (SIOCIWFIRSTPRIV+31)
#define WL_AP_STA_DISASSOC (SIOCIWFIRSTPRIV+29)
#define WL_COMBO_SCAN (SIOCIWFIRSTPRIV+31)
#define G_SCAN_RESULTS (8*1024)
#define WE_ADD_EVENT_FIX 0x80
#define G_WLAN_SET_ON 0
@ -116,19 +118,18 @@ typedef struct wl_iw {
dhd_pub_t * pub;
} wl_iw_t;
#define WLC_IW_SS_CACHE_MAXLEN 512
#define WLC_IW_SS_CACHE_MAXLEN 2048
#define WLC_IW_SS_CACHE_CTRL_FIELD_MAXLEN 32
#define WLC_IW_BSS_INFO_MAXLEN \
(WLC_IW_SS_CACHE_MAXLEN - WLC_IW_SS_CACHE_CTRL_FIELD_MAXLEN)
typedef struct wl_iw_ss_cache {
struct wl_iw_ss_cache *next;
int dirty;
uint32 buflen;
uint32 version;
uint32 count;
wl_bss_info_t bss_info[1];
char dummy[WLC_IW_BSS_INFO_MAXLEN - sizeof(wl_bss_info_t)];
int dirty;
struct wl_iw_ss_cache *next;
} wl_iw_ss_cache_t;
typedef struct wl_iw_ss_cache_ctrl {
@ -140,6 +141,7 @@ typedef struct wl_iw_ss_cache_ctrl {
uint m_cons_br_scan_cnt;
struct timer_list *m_timer;
} wl_iw_ss_cache_ctrl_t;
typedef enum broadcast_first_scan {
BROADCAST_SCAN_FIRST_IDLE = 0,
BROADCAST_SCAN_FIRST_STARTED,
@ -158,12 +160,14 @@ struct ap_profile {
uint32 channel;
uint32 preamble;
uint32 max_scb;
uint32 closednet;
char country_code[WLC_CNTRY_BUF_SZ];
};
#define MACLIST_MODE_DISABLED 0
#define MACLIST_MODE_ENABLED 1
#define MACLIST_MODE_ALLOW 2
#define MACLIST_MODE_DENY 1
#define MACLIST_MODE_ALLOW 2
struct mflist {
uint count;
struct ether_addr ea[16];
@ -171,8 +175,7 @@ struct mflist {
struct mac_list_set {
uint32 mode;
struct mflist white_list;
struct mflist black_list;
struct mflist mac_list;
};
#endif
@ -196,7 +199,9 @@ extern int net_os_set_suspend_disable(struct net_device *dev, int val);
extern int net_os_set_suspend(struct net_device *dev, int val);
extern int net_os_set_dtim_skip(struct net_device *dev, int val);
extern int net_os_set_packet_filter(struct net_device *dev, int val);
extern int net_os_send_hang_message(struct net_device *dev);
extern void dhd_bus_country_set(struct net_device *dev, char *country_code);
extern char *dhd_bus_country_get(struct net_device *dev);
extern int dhd_get_dtim_skip(dhd_pub_t *dhd);
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)
#define IWE_STREAM_ADD_EVENT(info, stream, ends, iwe, extra) \
@ -225,12 +230,13 @@ extern int dhd_dev_pno_enable(struct net_device *dev, int pfn_enabled);
extern int dhd_dev_get_pno_status(struct net_device *dev);
#define PNO_TLV_PREFIX 'S'
#define PNO_TLV_VERSION 1
#define PNO_TLV_SUBVERSION 1
#define PNO_TLV_RESERVED 0
#define PNO_TLV_VERSION '1'
#define PNO_TLV_SUBVERSION '2'
#define PNO_TLV_RESERVED '0'
#define PNO_TLV_TYPE_SSID_IE 'S'
#define PNO_TLV_TYPE_TIME 'T'
#define PNO_EVENT_UP "PNO_EVENT"
#define PNO_SCAN_MAX_FW 508
typedef struct cmd_tlv {
char prefix;