diff options
author | Dmitry Shmidt <dimitrysh@google.com> | 2011-09-27 11:21:13 -0700 |
---|---|---|
committer | Dan Willemsen <dwillemsen@nvidia.com> | 2011-11-30 21:39:09 -0800 |
commit | 09a8dc7361d0e603d9935ec7f736fabaa2e6dc7a (patch) | |
tree | 660b5b4137fe5d07017b786877ed0416bdaf716b /drivers/net | |
parent | 002a954c0ce004f9553c90e1945a5388966abeed (diff) |
net: wireless: bcmdhd: Combined P2P fix
- Fix random kernel panic during p2p certification and change private
command for set_ap_wps_ie of wpa_supplicant
- Fix problem for 5.1.18 discoverability exchange of P2P sigma
- Fix problem for 7.1.3 to change PM_FAST to PM_MAX (802.11 legacy power save)
- Change type of signal variable in wl_inform_single_bss from uint to int
- Fix crash on P2P interface removal
- Add new DHD_BLOC logic for our internal purposes to keep track of FW crashes
and build info
Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/wireless/bcmdhd/bcmsdh_sdmmc.c | 4 | ||||
-rw-r--r-- | drivers/net/wireless/bcmdhd/dhd_dbg.h | 3 | ||||
-rw-r--r-- | drivers/net/wireless/bcmdhd/dhd_linux.c | 18 | ||||
-rw-r--r-- | drivers/net/wireless/bcmdhd/dhd_sdio.c | 7 | ||||
-rw-r--r-- | drivers/net/wireless/bcmdhd/wl_android.c | 22 | ||||
-rw-r--r-- | drivers/net/wireless/bcmdhd/wl_cfg80211.c | 21 | ||||
-rw-r--r-- | drivers/net/wireless/bcmdhd/wl_cfg80211.h | 5 | ||||
-rw-r--r-- | drivers/net/wireless/bcmdhd/wl_cfgp2p.c | 16 | ||||
-rw-r--r-- | drivers/net/wireless/bcmdhd/wl_iw.c | 27 |
9 files changed, 62 insertions, 61 deletions
diff --git a/drivers/net/wireless/bcmdhd/bcmsdh_sdmmc.c b/drivers/net/wireless/bcmdhd/bcmsdh_sdmmc.c index a48e85c774dc..70bacbd3793d 100644 --- a/drivers/net/wireless/bcmdhd/bcmsdh_sdmmc.c +++ b/drivers/net/wireless/bcmdhd/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.14.64.3 2010-12-23 01:13:15 Exp $ + * $Id: bcmsdh_sdmmc.c 282820 2011-09-09 15:40:35Z $ */ #include <typedefs.h> @@ -30,7 +30,7 @@ #include <bcmutils.h> #include <osl.h> #include <sdio.h> /* SDIO Device and Protocol Specs */ -#include <sdioh.h> /* SDIO Host Controller Specification */ +#include <sdioh.h> /* Standard SDIO Host Controller Specification */ #include <bcmsdbus.h> /* bcmsdh to/from specific controller APIs */ #include <sdiovar.h> /* ioctl/iovars */ diff --git a/drivers/net/wireless/bcmdhd/dhd_dbg.h b/drivers/net/wireless/bcmdhd/dhd_dbg.h index 10851c43e847..a195cbe88e5b 100644 --- a/drivers/net/wireless/bcmdhd/dhd_dbg.h +++ b/drivers/net/wireless/bcmdhd/dhd_dbg.h @@ -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_dbg.h,v 1.9.6.1 2010-12-22 23:47:24 Exp $ + * $Id: dhd_dbg.h 285933 2011-09-23 21:45:31Z $ */ #ifndef _dhd_dbg_ @@ -95,6 +95,7 @@ #define DHD_LOG(args) +#define DHD_BLOG(cp, size) #define DHD_NONE(args) extern int dhd_msg_level; diff --git a/drivers/net/wireless/bcmdhd/dhd_linux.c b/drivers/net/wireless/bcmdhd/dhd_linux.c index eee6c3f82c7b..2363da9e0a5d 100644 --- a/drivers/net/wireless/bcmdhd/dhd_linux.c +++ b/drivers/net/wireless/bcmdhd/dhd_linux.c @@ -22,7 +22,7 @@ * software in any way with any other Broadcom software provided under a license * other than the GPL, without Broadcom's express prior written consent. * - * $Id: dhd_linux.c 285209 2011-09-21 01:21:24Z $ + * $Id: dhd_linux.c 285933 2011-09-23 21:45:31Z $ */ #include <typedefs.h> @@ -473,7 +473,7 @@ static int dhd_toe_set(dhd_info_t *dhd, int idx, uint32 toe_ol); static int dhd_wl_host_event(dhd_info_t *dhd, int *ifidx, void *pktdata, wl_event_msg_t *event_ptr, void **data_ptr); -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && defined(CONFIG_PM_SLEEP) && 1 +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && defined(CONFIG_PM_SLEEP) static int dhd_sleep_pm_callback(struct notifier_block *nfb, unsigned long action, void *ignored) { int ret = NOTIFY_DONE; @@ -2225,9 +2225,11 @@ dhd_cleanup_virt_ifaces(dhd_info_t *dhd) for (i = 1; i < DHD_MAX_IFS; i++) { if (dhd->iflist[i]) { DHD_TRACE(("Deleting IF: %d \n", i)); - dhd->iflist[i]->state = WLC_E_IF_DEL; - dhd->iflist[i]->idx = i; - dhd_op_if(dhd->iflist[i]); + if (dhd->iflist[i]->state != WLC_E_IF_DEL) { + dhd->iflist[i]->state = WLC_E_IF_DEL; + dhd->iflist[i]->idx = i; + dhd_op_if(dhd->iflist[i]); + } } } @@ -2389,7 +2391,7 @@ dhd_osl_detach(osl_t *osh) DHD_ERROR(("%s: MEMORY LEAK %d bytes\n", __FUNCTION__, MALLOCED(osh))); } osl_detach(osh); -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && 1 +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) up(&dhd_registration_sem); #endif } @@ -2636,7 +2638,7 @@ dhd_attach(osl_t *osh, struct dhd_bus *bus, uint bus_hdrlen) */ memcpy(netdev_priv(net), &dhd, sizeof(dhd)); -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && defined(CONFIG_PM_SLEEP) && 1 +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && defined(CONFIG_PM_SLEEP) register_pm_notifier(&dhd_sleep_pm_notifier); #endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && defined(CONFIG_PM_SLEEP) */ @@ -2930,6 +2932,8 @@ dhd_preinit_ioctls(dhd_pub_t *dhd) bcmstrtok(&ptr, "\n", 0); /* Print fw version info */ DHD_ERROR(("Firmware version = %s\n", buf)); + DHD_BLOG(buf, strlen(buf) + 1); + DHD_BLOG(dhd_version, strlen(dhd_version) + 1); } /* Set PowerSave mode */ dhd_wl_ioctl_cmd(dhd, WLC_SET_PM, (char *)&power_mode, sizeof(power_mode), TRUE, 0); diff --git a/drivers/net/wireless/bcmdhd/dhd_sdio.c b/drivers/net/wireless/bcmdhd/dhd_sdio.c index b79ef4417121..361b2a2e1cd9 100644 --- a/drivers/net/wireless/bcmdhd/dhd_sdio.c +++ b/drivers/net/wireless/bcmdhd/dhd_sdio.c @@ -21,7 +21,7 @@ * software in any way with any other Broadcom software provided under a license * other than the GPL, without Broadcom's express prior written consent. * - * $Id: dhd_sdio.c 285209 2011-09-21 01:21:24Z $ + * $Id: dhd_sdio.c 285933 2011-09-23 21:45:31Z $ */ #include <typedefs.h> @@ -1579,6 +1579,7 @@ const bcm_iovar_t dhdsdio_iovars[] = { {"cpu", IOV_CPU, 0, IOVT_BOOL, 0 }, #ifdef DHD_DEBUG {"checkdied", IOV_CHECKDIED, 0, IOVT_BUFFER, 0 }, + {"serial", IOV_SERIALCONS, 0, IOVT_UINT32, 0 }, #endif /* DHD_DEBUG */ #endif /* DHD_DEBUG */ #ifdef SDTEST @@ -2087,8 +2088,10 @@ dhdsdio_checkdied(dhd_bus_t *bus, uint8 *data, uint size) * will truncate a lot of the printfs */ - if (dhd_msg_level & DHD_ERROR_VAL) + if (dhd_msg_level & DHD_ERROR_VAL) { printf("CONSOLE: %s\n", line); + DHD_BLOG(line, strlen(line) + 1); + } } } } diff --git a/drivers/net/wireless/bcmdhd/wl_android.c b/drivers/net/wireless/bcmdhd/wl_android.c index 8c0e3ae7a261..ccb9aa855d07 100644 --- a/drivers/net/wireless/bcmdhd/wl_android.c +++ b/drivers/net/wireless/bcmdhd/wl_android.c @@ -75,9 +75,8 @@ #define CMD_P2P_SET_NOA "P2P_SET_NOA" #define CMD_P2P_GET_NOA "P2P_GET_NOA" #define CMD_P2P_SET_PS "P2P_SET_PS" -#define CMD_SET_ASSOC_RESP_IE "SET_ASSOC_RESP_IE" -#define CMD_SET_PROBE_RESP_IE "SET_PROBE_RESP_IE" -#define CMD_SET_BEACON_IE "SET_BEACON_IE" +#define CMD_SET_AP_WPS_P2P_IE "SET_AP_WPS_P2P_IE" + #ifdef PNO_SUPPORT #define CMD_PNOSSIDCLR_SET "PNOSSIDCLR" @@ -546,20 +545,11 @@ int wl_android_priv_cmd(struct net_device *net, struct ifreq *ifr, int cmd) priv_cmd.total_len - skip); } #ifdef WL_CFG80211 - else if (strnicmp(command, CMD_SET_ASSOC_RESP_IE, strlen(CMD_SET_ASSOC_RESP_IE)) == 0) { - int skip = strlen(CMD_SET_ASSOC_RESP_IE) + 1; - bytes_written = wl_cfg80211_set_wps_p2p_ie(net, command + skip, - priv_cmd.total_len - skip, WL_ASSOC_RESP); - } - else if (strnicmp(command, CMD_SET_PROBE_RESP_IE, strlen(CMD_SET_PROBE_RESP_IE)) == 0) { - int skip = strlen(CMD_SET_PROBE_RESP_IE) + 1; - bytes_written = wl_cfg80211_set_wps_p2p_ie(net, command + skip, - priv_cmd.total_len - skip, WL_PROBE_RESP); - } - else if (strnicmp(command, CMD_SET_BEACON_IE, strlen(CMD_SET_BEACON_IE)) == 0) { - int skip = strlen(CMD_SET_BEACON_IE) + 1; + else if (strnicmp(command, CMD_SET_AP_WPS_P2P_IE, + strlen(CMD_SET_AP_WPS_P2P_IE)) == 0) { + int skip = strlen(CMD_SET_AP_WPS_P2P_IE) + 3; bytes_written = wl_cfg80211_set_wps_p2p_ie(net, command + skip, - priv_cmd.total_len - skip, WL_BEACON); + priv_cmd.total_len - skip, *(command + skip - 2) - '0'); } #endif /* WL_CFG80211 */ else { diff --git a/drivers/net/wireless/bcmdhd/wl_cfg80211.c b/drivers/net/wireless/bcmdhd/wl_cfg80211.c index 65c48063879d..16cb75ffa758 100644 --- a/drivers/net/wireless/bcmdhd/wl_cfg80211.c +++ b/drivers/net/wireless/bcmdhd/wl_cfg80211.c @@ -3326,6 +3326,8 @@ wl_cfg80211_mgmt_tx(struct wiphy *wiphy, struct net_device *dev, wldev_iovar_setint(dev, "mpc", 0); } else if (act_frm->subtype == P2P_PAF_GON_CONF) { wldev_iovar_setint(dev, "mpc", 1); + } else if (act_frm->subtype == P2P_PAF_DEVDIS_REQ) { + af_params->dwell_time = WL_LONG_DWELL_TIME; } } @@ -4127,7 +4129,7 @@ static s32 wl_inform_single_bss(struct wl_priv *wl, struct wl_bss_info *bi) struct wl_scan_req *sr = wl_to_sr(wl); struct beacon_proberesp *beacon_proberesp; s32 mgmt_type; - u32 signal; + s32 signal; u32 freq; s32 err = 0; @@ -4149,7 +4151,7 @@ static s32 wl_inform_single_bss(struct wl_priv *wl, struct wl_bss_info *bi) band = wiphy->bands[IEEE80211_BAND_2GHZ]; else band = wiphy->bands[IEEE80211_BAND_5GHZ]; - notif_bss_info->rssi = bi->RSSI; + notif_bss_info->rssi = dtoh16(bi->RSSI); memcpy(mgmt->bssid, &bi->BSSID, ETHER_ADDR_LEN); mgmt_type = wl->active_scan ? IEEE80211_STYPE_PROBE_RESP : IEEE80211_STYPE_BEACON; @@ -4178,9 +4180,9 @@ static s32 wl_inform_single_bss(struct wl_priv *wl, struct wl_bss_info *bi) WL_DBG(("SSID : \"%s\", rssi %d, channel %d, capability : 0x04%x, bssid %pM" "mgmt_type %d frame_len %d\n", bi->SSID, - notif_bss_info->rssi, notif_bss_info->channel, - mgmt->u.beacon.capab_info, &bi->BSSID, mgmt_type, - notif_bss_info->frame_len)); + notif_bss_info->rssi, notif_bss_info->channel, + mgmt->u.beacon.capab_info, &bi->BSSID, mgmt_type, + notif_bss_info->frame_len)); signal = notif_bss_info->rssi * 100; @@ -4334,11 +4336,11 @@ wl_notify_connect_status(struct wl_priv *wl, struct net_device *ndev, isfree = true; if (event == WLC_E_ASSOC_IND && reason == DOT11_SC_SUCCESS) { - cfg80211_send_rx_assoc(ndev, mgmt_frame, len); + cfg80211_rx_mgmt(ndev, freq, mgmt_frame, len, GFP_ATOMIC); } else if (event == WLC_E_DISASSOC_IND) { - cfg80211_send_disassoc(ndev, mgmt_frame, len); + cfg80211_rx_mgmt(ndev, freq, mgmt_frame, len, GFP_ATOMIC); } else if ((event == WLC_E_DEAUTH_IND) || (event == WLC_E_DEAUTH)) { - cfg80211_send_disassoc(ndev, mgmt_frame, len); + cfg80211_rx_mgmt(ndev, freq, mgmt_frame, len, GFP_ATOMIC); } } else { @@ -6686,7 +6688,8 @@ s32 wl_cfg80211_set_wps_p2p_ie(struct net_device *net, char *buf, int len, pktflag = VNDR_IE_ASSOCRSP_FLAG; break; } - ret = wl_cfgp2p_set_management_ie(wl, ndev, bssidx, pktflag, buf, len); + if (pktflag) + ret = wl_cfgp2p_set_management_ie(wl, ndev, bssidx, pktflag, buf, len); } return ret; diff --git a/drivers/net/wireless/bcmdhd/wl_cfg80211.h b/drivers/net/wireless/bcmdhd/wl_cfg80211.h index 066103ebe10e..8403ccebef31 100644 --- a/drivers/net/wireless/bcmdhd/wl_cfg80211.h +++ b/drivers/net/wireless/bcmdhd/wl_cfg80211.h @@ -127,8 +127,9 @@ do { \ #define WL_AP_MAX 256 /* virtually unlimitted as long * as kernel memory allows */ -#define WL_FILE_NAME_MAX 256 -#define WL_DWELL_TIME 200 +#define WL_FILE_NAME_MAX 256 +#define WL_DWELL_TIME 200 +#define WL_LONG_DWELL_TIME 1000 #define VWDEV_CNT 3 #define WL_SCAN_TIMER_INTERVAL_MS 8000 /* Scan timeout */ diff --git a/drivers/net/wireless/bcmdhd/wl_cfgp2p.c b/drivers/net/wireless/bcmdhd/wl_cfgp2p.c index 653fbcdf7e65..2a5fdd10aa4b 100644 --- a/drivers/net/wireless/bcmdhd/wl_cfgp2p.c +++ b/drivers/net/wireless/bcmdhd/wl_cfgp2p.c @@ -1021,15 +1021,12 @@ wl_cfgp2p_discover_listen(struct wl_priv *wl, s32 channel, u32 duration_ms) ret = BCME_NOTREADY; goto exit; } - if (!wl_get_p2p_status(wl, LISTEN_EXPIRED)) { - wl_set_p2p_status(wl, LISTEN_EXPIRED); - if (timer_pending(&wl->p2p->listen_timer)) { - spin_lock_bh(&wl->p2p->timer_lock); - del_timer_sync(&wl->p2p->listen_timer); - spin_unlock_bh(&wl->p2p->timer_lock); - } + if (timer_pending(&wl->p2p->listen_timer)) { + CFGP2P_DBG(("previous LISTEN is not completed yet\n")); + goto exit; + } else - wl_clr_p2p_status(wl, LISTEN_EXPIRED); + wl_clr_p2p_status(wl, LISTEN_EXPIRED); wl_cfgp2p_set_p2p_mode(wl, WL_P2P_DISC_ST_LISTEN, channel, (u16) duration_ms, wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_DEVICE)); @@ -1322,6 +1319,7 @@ s32 wl_cfgp2p_set_p2p_noa(struct wl_priv *wl, struct net_device *ndev, char* buf wl_p2p_sched_t dongle_noa; CFGP2P_DBG((" Enter\n")); + memset(&dongle_noa, 0, sizeof(dongle_noa)); if (wl->p2p && wl->p2p->vif_created) { @@ -1436,7 +1434,7 @@ s32 wl_cfgp2p_set_p2p_ps(struct wl_priv *wl, struct net_device *ndev, char* buf, } if (legacy_ps != -1) { - s32 pm = legacy_ps ? PM_FAST : PM_OFF; + s32 pm = legacy_ps ? PM_MAX : PM_OFF; ret = wldev_ioctl(wl_to_p2p_bss_ndev(wl, P2PAPI_BSSCFG_CONNECTION), WLC_SET_PM, &pm, sizeof(pm), true); if (unlikely(ret)) { diff --git a/drivers/net/wireless/bcmdhd/wl_iw.c b/drivers/net/wireless/bcmdhd/wl_iw.c index f71f29a242fb..3acdea19cb4f 100644 --- a/drivers/net/wireless/bcmdhd/wl_iw.c +++ b/drivers/net/wireless/bcmdhd/wl_iw.c @@ -5287,6 +5287,7 @@ wl_iw_set_pmksa( uint i; int ret = 0; char eabuf[ETHER_ADDR_STR_LEN]; + pmkid_t * pmkid_array = pmkid_list.pmkids.pmkid; WL_WSEC(("%s: SIOCSIWPMKSA\n", dev->name)); @@ -5319,18 +5320,18 @@ wl_iw_set_pmksa( } for (i = 0; i < pmkid_list.pmkids.npmkid; i++) - if (!bcmp(&iwpmksa->bssid.sa_data[0], &pmkid_list.pmkids.pmkid[i].BSSID, + if (!bcmp(&iwpmksa->bssid.sa_data[0], &pmkid_array[i].BSSID, ETHER_ADDR_LEN)) break; if ((pmkid_list.pmkids.npmkid > 0) && (i < pmkid_list.pmkids.npmkid)) { - bzero(&pmkid_list.pmkids.pmkid[i], sizeof(pmkid_t)); + bzero(&pmkid_array[i], sizeof(pmkid_t)); for (; i < (pmkid_list.pmkids.npmkid - 1); i++) { - bcopy(&pmkid_list.pmkids.pmkid[i+1].BSSID, - &pmkid_list.pmkids.pmkid[i].BSSID, + bcopy(&pmkid_array[i+1].BSSID, + &pmkid_array[i].BSSID, ETHER_ADDR_LEN); - bcopy(&pmkid_list.pmkids.pmkid[i+1].PMKID, - &pmkid_list.pmkids.pmkid[i].PMKID, + bcopy(&pmkid_array[i+1].PMKID, + &pmkid_array[i].PMKID, WPA2_PMKID_LEN); } pmkid_list.pmkids.npmkid--; @@ -5341,14 +5342,14 @@ wl_iw_set_pmksa( else if (iwpmksa->cmd == IW_PMKSA_ADD) { for (i = 0; i < pmkid_list.pmkids.npmkid; i++) - if (!bcmp(&iwpmksa->bssid.sa_data[0], &pmkid_list.pmkids.pmkid[i].BSSID, + if (!bcmp(&iwpmksa->bssid.sa_data[0], &pmkid_array[i].BSSID, ETHER_ADDR_LEN)) break; if (i < MAXPMKID) { bcopy(&iwpmksa->bssid.sa_data[0], - &pmkid_list.pmkids.pmkid[i].BSSID, + &pmkid_array[i].BSSID, ETHER_ADDR_LEN); - bcopy(&iwpmksa->pmkid[0], &pmkid_list.pmkids.pmkid[i].PMKID, + bcopy(&iwpmksa->pmkid[0], &pmkid_array[i].PMKID, WPA2_PMKID_LEN); if (i == pmkid_list.pmkids.npmkid) pmkid_list.pmkids.npmkid++; @@ -5361,10 +5362,10 @@ wl_iw_set_pmksa( uint k; k = pmkid_list.pmkids.npmkid; WL_WSEC(("wl_iw_set_pmksa,IW_PMKSA_ADD - PMKID: %s = ", - bcm_ether_ntoa(&pmkid_list.pmkids.pmkid[k].BSSID, + bcm_ether_ntoa(&pmkid_array[k].BSSID, eabuf))); for (j = 0; j < WPA2_PMKID_LEN; j++) - WL_WSEC(("%02x ", pmkid_list.pmkids.pmkid[k].PMKID[j])); + WL_WSEC(("%02x ", pmkid_array[k].PMKID[j])); WL_WSEC(("\n")); } } @@ -5372,10 +5373,10 @@ wl_iw_set_pmksa( for (i = 0; i < pmkid_list.pmkids.npmkid; i++) { uint j; WL_WSEC(("\nPMKID[%d]: %s = ", i, - bcm_ether_ntoa(&pmkid_list.pmkids.pmkid[i].BSSID, + bcm_ether_ntoa(&pmkid_array[i].BSSID, eabuf))); for (j = 0; j < WPA2_PMKID_LEN; j++) - WL_WSEC(("%02x ", pmkid_list.pmkids.pmkid[i].PMKID[j])); + WL_WSEC(("%02x ", pmkid_array[i].PMKID[j])); } WL_WSEC(("\n")); |