mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-10 21:07:02 +09:00
net: wireless: bcmdhd: Update to Version 5.90.195.61
- Deauth frame from p2p GO to client doesn't go from firmware if we do del_virtual_iface immediately. Putting a delay after sending deauth frame to allowed FW to send out deauth frame. - IF_DEL operation was timing out due to wrong status check. Fixed it and added few debug prints. - Sending Provision Discovery directly to GO instead of doing an internal scan. Also put the internal scan count to 3 to have better timings for GO-NEG. - Increase beacon timeout only for concurrent mode. For STA only operation, use the default beacon timeout value (4). - If scan abort is due to timeout, aborting the scan in FW is not required. Moreover, as this scan_timeout call is coming in timer interrupt context, all blocking calls such as fw scan abort will result in kernel panic : don’t call abort in Firmware. - Add p2p_cancel_listen routine. Fix p2p_listen_complete related kernel crash seen while turning off WiFi. Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
This commit is contained in:
@@ -24,11 +24,12 @@
|
||||
* software in any way with any other Broadcom software provided under a license
|
||||
* other than the GPL, without Broadcom's express prior written consent.
|
||||
*
|
||||
* $Id: dhd.h 325862 2012-04-04 22:59:48Z $
|
||||
* $Id: dhd.h 328934 2012-04-23 05:15:42Z $
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/****************
|
||||
* Common types *
|
||||
*/
|
||||
|
||||
#ifndef _dhd_h_
|
||||
#define _dhd_h_
|
||||
@@ -90,6 +91,9 @@ enum dhd_bus_state {
|
||||
#define DHD_SCAN_ACTIVE_TIME 40 /* ms : Embedded default Active setting from DHD Driver */
|
||||
#define DHD_SCAN_PASSIVE_TIME 130 /* ms: Embedded default Passive setting from DHD Driver */
|
||||
|
||||
#define DHD_BEACON_TIMEOUT_NORMAL 4
|
||||
#define DHD_BEACON_TIMEOUT_HIGH 10
|
||||
|
||||
enum dhd_bus_wake_state {
|
||||
WAKE_LOCK_OFF,
|
||||
WAKE_LOCK_PRIV,
|
||||
|
||||
@@ -41,7 +41,9 @@ static int dhd_dongle_up = FALSE;
|
||||
|
||||
static s32 wl_dongle_up(struct net_device *ndev, u32 up);
|
||||
|
||||
|
||||
/**
|
||||
* Function implementations
|
||||
*/
|
||||
|
||||
s32 dhd_cfg80211_init(struct wl_priv *wl)
|
||||
{
|
||||
@@ -70,13 +72,22 @@ s32 dhd_cfg80211_down(struct wl_priv *wl)
|
||||
s32 dhd_cfg80211_set_p2p_info(struct wl_priv *wl, int val)
|
||||
{
|
||||
dhd_pub_t *dhd = (dhd_pub_t *)(wl->pub);
|
||||
int bcn_timeout = DHD_BEACON_TIMEOUT_HIGH;
|
||||
char iovbuf[30];
|
||||
|
||||
dhd->op_mode |= val;
|
||||
WL_ERR(("Set : op_mode=%d\n", dhd->op_mode));
|
||||
|
||||
#ifdef ARP_OFFLOAD_SUPPORT
|
||||
/* IF P2P is enabled, disable arpoe */
|
||||
dhd_arp_offload_set(dhd, 0);
|
||||
dhd_arp_offload_enable(dhd, false);
|
||||
#endif
|
||||
#endif /* ARP_OFFLOAD_SUPPORT */
|
||||
|
||||
/* Setup timeout if Beacons are lost and roam is off to report link down */
|
||||
bcm_mkiovar("bcn_timeout", (char *)&bcn_timeout, 4, iovbuf, sizeof(iovbuf));
|
||||
dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0);
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -84,13 +95,21 @@ s32 dhd_cfg80211_set_p2p_info(struct wl_priv *wl, int val)
|
||||
s32 dhd_cfg80211_clean_p2p_info(struct wl_priv *wl)
|
||||
{
|
||||
dhd_pub_t *dhd = (dhd_pub_t *)(wl->pub);
|
||||
int bcn_timeout = DHD_BEACON_TIMEOUT_NORMAL;
|
||||
char iovbuf[30];
|
||||
|
||||
dhd->op_mode &= ~CONCURENT_MASK;
|
||||
WL_ERR(("Clean : op_mode=%d\n", dhd->op_mode));
|
||||
|
||||
#ifdef ARP_OFFLOAD_SUPPORT
|
||||
/* IF P2P is disabled, enable arpoe back for STA mode. */
|
||||
dhd_arp_offload_set(dhd, dhd_arp_mode);
|
||||
dhd_arp_offload_enable(dhd, true);
|
||||
#endif
|
||||
#endif /* ARP_OFFLOAD_SUPPORT */
|
||||
|
||||
/* Setup timeout if Beacons are lost and roam is off to report link down */
|
||||
bcm_mkiovar("bcn_timeout", (char *)&bcn_timeout, 4, iovbuf, sizeof(iovbuf));
|
||||
dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
* software in any way with any other Broadcom software provided under a license
|
||||
* other than the GPL, without Broadcom's express prior written consent.
|
||||
*
|
||||
* $Id: dhd_common.c 319098 2012-03-07 01:05:20Z $
|
||||
* $Id: dhd_common.c 329682 2012-04-26 09:20:38Z $
|
||||
*/
|
||||
#include <typedefs.h>
|
||||
#include <osl.h>
|
||||
@@ -996,6 +996,9 @@ wl_host_event(dhd_pub_t *dhd_pub, int *ifidx, void *pktdata,
|
||||
datalen = ntoh32_ua((void *)&event->datalen);
|
||||
evlen = datalen + sizeof(bcm_event_t);
|
||||
|
||||
DHD_TRACE(("RX: event_type:%d flags:%d status:%d reason:%d \n",
|
||||
type, flags, status, reason));
|
||||
|
||||
switch (type) {
|
||||
#ifdef PROP_TXSTATUS
|
||||
case WLC_E_FIFO_CREDIT_MAP:
|
||||
@@ -1723,6 +1726,7 @@ fail:
|
||||
|
||||
/*
|
||||
* returns = TRUE if associated, FALSE if not associated
|
||||
* third paramter retval can return error from error
|
||||
*/
|
||||
bool dhd_is_associated(dhd_pub_t *dhd, void *bss_buf, int *retval)
|
||||
{
|
||||
@@ -1891,7 +1895,7 @@ dhd_pno_enable(dhd_pub_t *dhd, int pfn_enabled)
|
||||
DHD_ERROR(("%s pno is NOT enable : called in assoc mode , ignore\n", __FUNCTION__));
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
#endif /* !WL_SCHED_SCAN */
|
||||
|
||||
/* Enable/disable PNO */
|
||||
if ((ret = bcm_mkiovar("pfn", (char *)&pfn_enabled, 4, iovbuf, sizeof(iovbuf))) > 0) {
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
* software in any way with any other Broadcom software provided under a license
|
||||
* other than the GPL, without Broadcom's express prior written consent.
|
||||
*
|
||||
* $Id: dhd_linux.c 325862 2012-04-04 22:59:48Z $
|
||||
* $Id: dhd_linux.c 329682 2012-04-26 09:20:38Z $
|
||||
*/
|
||||
|
||||
#include <typedefs.h>
|
||||
@@ -1472,6 +1472,7 @@ dhd_rx_frame(dhd_pub_t *dhdp, int ifidx, void *pktbuf, int numpkt, uint8 chan)
|
||||
*/
|
||||
((athost_wl_status_info_t*)dhdp->wlfc_state)->stats.wlfc_header_only_pkt++;
|
||||
PKTFREE(dhdp->osh, pktbuf, TRUE);
|
||||
DHD_TRACE(("RX: wlfc header \n"));
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
@@ -2962,7 +2963,8 @@ dhd_preinit_ioctls(dhd_pub_t *dhd)
|
||||
uint power_mode = PM_FAST;
|
||||
uint32 dongle_align = DHD_SDALIGN;
|
||||
uint32 glom = 0;
|
||||
uint bcn_timeout = 10;
|
||||
uint bcn_timeout = DHD_BEACON_TIMEOUT_NORMAL;
|
||||
|
||||
uint retry_max = 3;
|
||||
#if defined(ARP_OFFLOAD_SUPPORT)
|
||||
int arpoe = 1;
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
* software in any way with any other Broadcom software provided under a license
|
||||
* other than the GPL, without Broadcom's express prior written consent.
|
||||
*
|
||||
* $Id: dhd_sdio.c 325395 2012-04-03 03:57:43Z $
|
||||
* $Id: dhd_sdio.c 326662 2012-04-10 06:38:08Z $
|
||||
*/
|
||||
|
||||
#include <typedefs.h>
|
||||
@@ -4616,8 +4616,7 @@ clkwait:
|
||||
int ret, i;
|
||||
uint8* frame_seq = bus->ctrl_frame_buf + SDPCM_FRAMETAG_LEN;
|
||||
|
||||
if (((bus->sih->chip == BCM4329_CHIP_ID) || /* limit to 4329 & 4330 for now */
|
||||
(bus->sih->chip == BCM4330_CHIP_ID)) && (*frame_seq != bus->tx_seq)) {
|
||||
if (*frame_seq != bus->tx_seq) {
|
||||
DHD_INFO(("%s IOCTL frame seq lag detected!"
|
||||
" frm_seq:%d != bus->tx_seq:%d, corrected\n",
|
||||
__FUNCTION__, *frame_seq, bus->tx_seq));
|
||||
|
||||
@@ -32,17 +32,17 @@
|
||||
|
||||
#define EPI_RC_NUMBER 195
|
||||
|
||||
#define EPI_INCREMENTAL_NUMBER 53
|
||||
#define EPI_INCREMENTAL_NUMBER 61
|
||||
|
||||
#define EPI_BUILD_NUMBER 0
|
||||
|
||||
#define EPI_VERSION 5, 90, 195, 53
|
||||
#define EPI_VERSION 5, 90, 195, 61
|
||||
|
||||
#define EPI_VERSION_NUM 0x055ac335
|
||||
#define EPI_VERSION_NUM 0x055ac33d
|
||||
|
||||
#define EPI_VERSION_DEV 5.90.195
|
||||
|
||||
|
||||
#define EPI_VERSION_STR "5.90.195.53"
|
||||
#define EPI_VERSION_STR "5.90.195.61"
|
||||
|
||||
#endif
|
||||
|
||||
@@ -100,7 +100,10 @@ static const struct ieee80211_regdomain brcm_regdom = {
|
||||
* we need cfg80211 to allow it (reg_flags = 0); so that
|
||||
* hostapd could request auto channel by sending down ch 14
|
||||
*/
|
||||
REG_RULE(2484-10, 2484+10, 20, 6, 20, 0),
|
||||
REG_RULE(2484-10, 2484+10, 20, 6, 20,
|
||||
NL80211_RRF_PASSIVE_SCAN |
|
||||
NL80211_RRF_NO_IBSS |
|
||||
NL80211_RRF_NO_OFDM),
|
||||
/* IEEE 802.11a, channel 36..64 */
|
||||
REG_RULE(5150-10, 5350+10, 40, 6, 20, 0),
|
||||
/* IEEE 802.11a, channel 100..165 */
|
||||
@@ -735,7 +738,7 @@ wl_cfg80211_add_virtual_iface(struct wiphy *wiphy, char *name,
|
||||
s32 mode = 0;
|
||||
#if defined(WL_ENABLE_P2P_IF)
|
||||
s32 dhd_mode = 0;
|
||||
#endif
|
||||
#endif /* (WL_ENABLE_P2P_IF) */
|
||||
chanspec_t chspec;
|
||||
struct wl_priv *wl = wiphy_priv(wiphy);
|
||||
struct net_device *_ndev;
|
||||
@@ -807,7 +810,7 @@ wl_cfg80211_add_virtual_iface(struct wiphy *wiphy, char *name,
|
||||
return ERR_PTR(-EAGAIN);
|
||||
}
|
||||
}
|
||||
if (!p2p_is_on(wl) && strstr(name, WL_P2P_INTERFACE_PREFIX)) {
|
||||
if (wl->p2p && !wl->p2p->on && strstr(name, WL_P2P_INTERFACE_PREFIX)) {
|
||||
p2p_on(wl) = true;
|
||||
wl_cfgp2p_set_firm_p2p(wl);
|
||||
wl_cfgp2p_init_discovery(wl);
|
||||
@@ -819,7 +822,8 @@ wl_cfg80211_add_virtual_iface(struct wiphy *wiphy, char *name,
|
||||
memset(wl->p2p->vir_ifname, 0, IFNAMSIZ);
|
||||
strncpy(wl->p2p->vir_ifname, name, IFNAMSIZ - 1);
|
||||
|
||||
|
||||
wldev_iovar_setint(_ndev, "mpc", 0);
|
||||
wl_notify_escan_complete(wl, _ndev, true, true);
|
||||
/* In concurrency case, STA may be already associated in a particular channel.
|
||||
* so retrieve the current channel of primary interface and then start the virtual
|
||||
* interface on that.
|
||||
@@ -874,8 +878,10 @@ wl_cfg80211_add_virtual_iface(struct wiphy *wiphy, char *name,
|
||||
else if (type == NL80211_IFTYPE_P2P_GO)
|
||||
dhd_mode = P2P_GO_ENABLED;
|
||||
DNGL_FUNC(dhd_cfg80211_set_p2p_info, (wl, dhd_mode));
|
||||
#endif
|
||||
|
||||
#endif /* (WL_ENABLE_P2P_IF) */
|
||||
/* Start the P2P I/F with PM disabled. Enable PM from
|
||||
* the framework
|
||||
*/
|
||||
if ((type == NL80211_IFTYPE_P2P_CLIENT) || (
|
||||
type == NL80211_IFTYPE_P2P_GO))
|
||||
vwdev->ps = NL80211_PS_DISABLED;
|
||||
@@ -920,7 +926,7 @@ wl_cfg80211_del_virtual_iface(struct wiphy *wiphy, struct net_device *dev)
|
||||
if (wl->p2p_supported) {
|
||||
memcpy(p2p_mac.octet, wl->p2p->int_addr.octet, ETHER_ADDR_LEN);
|
||||
if (wl->p2p->vif_created) {
|
||||
if (wl->scan_request) {
|
||||
if (wl_get_drv_status(wl, SCANNING, dev)) {
|
||||
wl_notify_escan_complete(wl, dev, true, true);
|
||||
}
|
||||
wldev_iovar_setint(dev, "mpc", 1);
|
||||
@@ -948,7 +954,7 @@ wl_cfg80211_del_virtual_iface(struct wiphy *wiphy, struct net_device *dev)
|
||||
WL_DBG(("IFDEL operation done\n"));
|
||||
#if defined(WL_ENABLE_P2P_IF)
|
||||
DNGL_FUNC(dhd_cfg80211_clean_p2p_info, (wl));
|
||||
#endif
|
||||
#endif /* (WL_ENABLE_P2P_IF)) */
|
||||
} else {
|
||||
WL_ERR(("IFDEL didn't complete properly\n"));
|
||||
}
|
||||
@@ -972,7 +978,7 @@ wl_cfg80211_change_virtual_iface(struct wiphy *wiphy, struct net_device *ndev,
|
||||
chanspec_t chspec;
|
||||
struct wl_priv *wl = wiphy_priv(wiphy);
|
||||
|
||||
WL_DBG(("Enter \n"));
|
||||
WL_DBG(("Enter type %d\n", type));
|
||||
switch (type) {
|
||||
case NL80211_IFTYPE_MONITOR:
|
||||
case NL80211_IFTYPE_WDS:
|
||||
@@ -1003,8 +1009,10 @@ wl_cfg80211_change_virtual_iface(struct wiphy *wiphy, struct net_device *ndev,
|
||||
wl_set_mode_by_netdev(wl, ndev, mode);
|
||||
if (wl->p2p_supported && wl->p2p->vif_created) {
|
||||
WL_DBG(("p2p_vif_created (%d) p2p_on (%d)\n", wl->p2p->vif_created,
|
||||
p2p_on(wl)));
|
||||
p2p_on(wl)));
|
||||
wldev_iovar_setint(ndev, "mpc", 0);
|
||||
wl_notify_escan_complete(wl, ndev, true, true);
|
||||
|
||||
/* In concurrency case, STA may be already associated in a particular
|
||||
* channel. so retrieve the current channel of primary interface and
|
||||
* then start the virtual interface on that.
|
||||
@@ -1121,6 +1129,7 @@ wl_cfg80211_ifdel_ops(struct net_device *ndev)
|
||||
WL_DBG(("index : %d\n", index));
|
||||
|
||||
}
|
||||
|
||||
/* Wake up any waiting thread */
|
||||
wake_up_interruptible(&wl->netif_change_event);
|
||||
|
||||
@@ -2007,7 +2016,11 @@ wl_set_set_cipher(struct net_device *dev, struct cfg80211_connect_params *sme)
|
||||
WL_DBG(("pval (%d) gval (%d)\n", pval, gval));
|
||||
|
||||
if (is_wps_conn(sme)) {
|
||||
err = wldev_iovar_setint_bsscfg(dev, "wsec", 4, bssidx);
|
||||
if (sme->privacy)
|
||||
err = wldev_iovar_setint_bsscfg(dev, "wsec", 4, bssidx);
|
||||
else
|
||||
/* WPS-2.0 allowes no security */
|
||||
err = wldev_iovar_setint_bsscfg(dev, "wsec", 0, bssidx);
|
||||
} else {
|
||||
WL_DBG((" NO, is_wps_conn, Set pval | gval to WSEC"));
|
||||
err = wldev_iovar_setint_bsscfg(dev, "wsec",
|
||||
@@ -2847,7 +2860,6 @@ wl_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
|
||||
err = -ENODEV;
|
||||
if (!wl_get_drv_status(wl, CONNECTED, dev) ||
|
||||
(dhd_is_associated(dhd, NULL, &err) == FALSE)) {
|
||||
|
||||
WL_ERR(("NOT assoc: %d\n", err));
|
||||
goto get_station_err;
|
||||
}
|
||||
@@ -3168,7 +3180,7 @@ wl_cfg80211_scan_alloc_params(int channel, int nprobes, int *out_params_size)
|
||||
|
||||
/* Our scan params have 1 channel and 0 ssids */
|
||||
params->channel_num = htod32((0 << WL_SCAN_PARAMS_NSSID_SHIFT) |
|
||||
(num_chans & WL_SCAN_PARAMS_COUNT_MASK));
|
||||
(num_chans & WL_SCAN_PARAMS_COUNT_MASK));
|
||||
|
||||
*out_params_size = params_size; /* rtn size to the caller */
|
||||
return params;
|
||||
@@ -3195,7 +3207,7 @@ wl_cfg80211_remain_on_channel(struct wiphy *wiphy, struct net_device *dev,
|
||||
ndev = dev;
|
||||
}
|
||||
|
||||
if (wl->scan_request) {
|
||||
if (wl_get_drv_status(wl, SCANNING, ndev)) {
|
||||
wl_notify_escan_complete(wl, ndev, true, true);
|
||||
}
|
||||
target_channel = ieee80211_frequency_to_channel(channel->center_freq);
|
||||
@@ -3207,7 +3219,7 @@ wl_cfg80211_remain_on_channel(struct wiphy *wiphy, struct net_device *dev,
|
||||
*cookie = id;
|
||||
cfg80211_ready_on_channel(dev, *cookie, channel,
|
||||
channel_type, duration, GFP_KERNEL);
|
||||
if (!p2p_is_on(wl)) {
|
||||
if (wl->p2p && !wl->p2p->on) {
|
||||
get_primary_mac(wl, &primary_mac);
|
||||
wl_cfgp2p_generate_bss_mac(&primary_mac, &wl->p2p->dev_addr, &wl->p2p->int_addr);
|
||||
|
||||
@@ -3331,7 +3343,11 @@ wl_cfg80211_mgmt_tx(struct wiphy *wiphy, struct net_device *ndev,
|
||||
struct ieee80211_channel *channel, bool offchan,
|
||||
enum nl80211_channel_type channel_type,
|
||||
bool channel_type_valid, unsigned int wait,
|
||||
const u8* buf, size_t len, u64 *cookie)
|
||||
const u8* buf, size_t len,
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 2, 0)
|
||||
bool no_cck,
|
||||
#endif
|
||||
u64 *cookie)
|
||||
{
|
||||
wl_action_frame_t *action_frame;
|
||||
wl_af_params_t *af_params;
|
||||
@@ -3418,6 +3434,10 @@ wl_cfg80211_mgmt_tx(struct wiphy *wiphy, struct net_device *ndev,
|
||||
WL_DBG(("Disconnect STA : %s scb_val.val %d\n",
|
||||
bcm_ether_ntoa((const struct ether_addr *)mgmt->da, eabuf),
|
||||
scb_val.val));
|
||||
/* Wait for the deauth event to come, supplicant will do the delete iface immediately
|
||||
* and we will have problem in sending deauth frame if we delete the bss in firmware
|
||||
*/
|
||||
wl_delay(400);
|
||||
cfg80211_mgmt_tx_status(ndev, *cookie, buf, len, true, GFP_KERNEL);
|
||||
goto exit;
|
||||
|
||||
@@ -3521,7 +3541,7 @@ wl_cfg80211_mgmt_tx(struct wiphy *wiphy, struct net_device *ndev,
|
||||
}
|
||||
|
||||
if (IS_P2P_SOCIAL(af_params->channel) &&
|
||||
(IS_P2P_PUB_ACT_REQ(act_frm, action_frame->len) ||
|
||||
(IS_P2P_PUB_ACT_REQ(act_frm, &act_frm->elts[0], action_frame->len) ||
|
||||
IS_GAS_REQ(sd_act_frm, action_frame->len)) &&
|
||||
wl_to_p2p_bss_saved_ie(wl, P2PAPI_BSSCFG_DEVICE).p2p_probe_req_ie_len) {
|
||||
/* channel offload require P2P IE for Probe request
|
||||
@@ -3534,7 +3554,7 @@ wl_cfg80211_mgmt_tx(struct wiphy *wiphy, struct net_device *ndev,
|
||||
} else {
|
||||
ack = (wl_cfgp2p_tx_action_frame(wl, dev, af_params, bssidx)) ? false : true;
|
||||
if (!ack) {
|
||||
for (retry = 1; retry < WL_CHANNEL_SYNC_RETRY; retry++) {
|
||||
for (retry = 1; retry < retry_cnt; retry++) {
|
||||
ack = (wl_cfgp2p_tx_action_frame(wl, dev,
|
||||
af_params, bssidx)) ? false : true;
|
||||
if (ack)
|
||||
@@ -4771,17 +4791,24 @@ wl_notify_connect_status(struct wl_priv *wl, struct net_device *ndev,
|
||||
bool act;
|
||||
s32 err = 0;
|
||||
u32 event = ntoh32(e->event_type);
|
||||
u32 reason;
|
||||
|
||||
if (wl_get_mode_by_netdev(wl, ndev) == WL_MODE_AP) {
|
||||
wl_notify_connect_status_ap(wl, ndev, e, data);
|
||||
} else {
|
||||
WL_DBG(("wl_notify_connect_status : event %d status : %d ndev %p\n",
|
||||
ntoh32(e->event_type), ntoh32(e->status), ndev));
|
||||
if((event == WLC_E_DEAUTH_IND) || (event == WLC_E_DISASSOC_IND)) {
|
||||
reason = ntoh32(e->reason);
|
||||
wl->deauth_reason = reason;
|
||||
WL_ERR(("Received %s event with reason code: %d\n", (event == WLC_E_DEAUTH_IND)? "WLC_E_DEAUTH_IND":"WLC_E_DISASSOC_IND", reason));
|
||||
}
|
||||
if (wl_is_linkup(wl, e, ndev)) {
|
||||
wl_link_up(wl);
|
||||
act = true;
|
||||
wl_update_prof(wl, ndev, e, &act, WL_PROF_ACT);
|
||||
wl_update_prof(wl, ndev, NULL, (void *)&e->addr, WL_PROF_BSSID);
|
||||
wl->deauth_reason = 0;
|
||||
if (wl_is_ibssmode(wl, ndev)) {
|
||||
printk("cfg80211_ibss_joined\n");
|
||||
cfg80211_ibss_joined(ndev, (s8 *)&e->addr,
|
||||
@@ -4809,7 +4836,6 @@ wl_notify_connect_status(struct wl_priv *wl, struct net_device *ndev,
|
||||
if (wl_get_drv_status(wl, CONNECTED, ndev)) {
|
||||
scb_val_t scbval;
|
||||
u8 *curbssid = wl_read_prof(wl, ndev, WL_PROF_BSSID);
|
||||
printk("link down, call cfg80211_disconnected\n");
|
||||
wl_clr_drv_status(wl, CONNECTED, ndev);
|
||||
if (! wl_get_drv_status(wl, DISCONNECTING, ndev)) {
|
||||
/* To make sure disconnect, explictly send dissassoc
|
||||
@@ -4821,7 +4847,8 @@ wl_notify_connect_status(struct wl_priv *wl, struct net_device *ndev,
|
||||
scbval.val = htod32(scbval.val);
|
||||
wldev_ioctl(ndev, WLC_DISASSOC, &scbval,
|
||||
sizeof(scb_val_t), true);
|
||||
cfg80211_disconnected(ndev, 0, NULL, 0, GFP_KERNEL);
|
||||
WL_ERR(("link down, calling cfg80211_disconnected with deauth_reason:%d\n", wl->deauth_reason));
|
||||
cfg80211_disconnected(ndev, wl->deauth_reason , NULL, 0, GFP_KERNEL);
|
||||
wl_link_down(wl);
|
||||
wl_init_prof(wl, ndev);
|
||||
}
|
||||
@@ -5821,7 +5848,7 @@ static void wl_scan_timeout(unsigned long data)
|
||||
if (wl->scan_request) {
|
||||
WL_ERR(("timer expired\n"));
|
||||
if (wl->escan_on)
|
||||
wl_notify_escan_complete(wl, wl->escan_info.ndev, false, true);
|
||||
wl_notify_escan_complete(wl, wl->escan_info.ndev, true, false);
|
||||
else
|
||||
wl_notify_iscan_complete(wl_to_iscan(wl), true);
|
||||
}
|
||||
@@ -5877,7 +5904,7 @@ wl_cfg80211_netdev_notifier_call(struct notifier_block * nb,
|
||||
struct wl_priv *wl = wlcfg_drv_priv;
|
||||
|
||||
WL_DBG(("Enter \n"));
|
||||
if (!wdev || dev == wl_to_prmry_ndev(wl))
|
||||
if (!wdev || !wl || dev == wl_to_prmry_ndev(wl))
|
||||
return NOTIFY_DONE;
|
||||
switch (state) {
|
||||
case NETDEV_UNREGISTER:
|
||||
@@ -5942,7 +5969,7 @@ static s32 wl_notify_escan_complete(struct wl_priv *wl,
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!in_atomic())
|
||||
if (timer_pending(&wl->scan_timeout))
|
||||
del_timer_sync(&wl->scan_timeout);
|
||||
spin_lock_irqsave(&wl->cfgdrv_lock, flags);
|
||||
|
||||
@@ -5984,7 +6011,6 @@ static s32 wl_escan_handler(struct wl_priv *wl,
|
||||
wl_scan_results_t *list;
|
||||
u32 bi_length;
|
||||
u32 i;
|
||||
u8 *p2p_dev_addr = NULL;
|
||||
|
||||
WL_DBG((" enter event type : %d, status : %d \n",
|
||||
ntoh32(e->event_type), ntoh32(e->status)));
|
||||
@@ -6033,8 +6059,7 @@ static s32 wl_escan_handler(struct wl_priv *wl,
|
||||
}
|
||||
|
||||
if (wl_get_drv_status_all(wl, SENDING_ACT_FRM)) {
|
||||
p2p_dev_addr = wl_cfgp2p_retreive_p2p_dev_addr(bi, bi_length);
|
||||
if (p2p_dev_addr && !memcmp(p2p_dev_addr,
|
||||
if (!memcmp(bi->BSSID.octet,
|
||||
wl->afx_hdl->pending_tx_dst_addr.octet, ETHER_ADDR_LEN)) {
|
||||
s32 channel = CHSPEC_CHANNEL(dtohchanspec(bi->chanspec));
|
||||
WL_DBG(("ACTION FRAME SCAN : Peer found, channel : %d\n", channel));
|
||||
@@ -6187,6 +6212,7 @@ static s32 wl_init_priv(struct wl_priv *wl)
|
||||
wl->iscan_kickstart = false;
|
||||
wl->active_scan = true;
|
||||
wl->rf_blocked = false;
|
||||
wl->deauth_reason = 0;
|
||||
spin_lock_init(&wl->cfgdrv_lock);
|
||||
mutex_init(&wl->ioctl_buf_sync);
|
||||
init_waitqueue_head(&wl->netif_change_event);
|
||||
@@ -6711,12 +6737,16 @@ s32 wl_update_wiphybands(struct wl_priv *wl)
|
||||
}
|
||||
if ((index >= 0) && nmode) {
|
||||
wiphy->bands[index]->ht_cap.cap =
|
||||
IEEE80211_HT_CAP_DSSSCCK40
|
||||
| IEEE80211_HT_CAP_MAX_AMSDU | IEEE80211_HT_CAP_RX_STBC;
|
||||
IEEE80211_HT_CAP_SGI_20 | IEEE80211_HT_CAP_DSSSCCK40 |
|
||||
IEEE80211_HT_CAP_MAX_AMSDU;
|
||||
wiphy->bands[index]->ht_cap.ht_supported = TRUE;
|
||||
wiphy->bands[index]->ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_16K;
|
||||
wiphy->bands[index]->ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K;
|
||||
wiphy->bands[index]->ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16;
|
||||
}
|
||||
|
||||
if ((index >= 0) && bw_40) {
|
||||
wiphy->bands[index]->ht_cap.cap |= IEEE80211_HT_CAP_SGI_40;
|
||||
}
|
||||
}
|
||||
|
||||
wiphy_apply_custom_regulatory(wiphy, &brcm_regdom);
|
||||
@@ -7043,7 +7073,8 @@ static void wl_init_eq_lock(struct wl_priv *wl)
|
||||
|
||||
static void wl_delay(u32 ms)
|
||||
{
|
||||
if (in_atomic() || ms < 1000 / HZ) {
|
||||
if (ms < 1000 / HZ) {
|
||||
cond_resched();
|
||||
mdelay(ms);
|
||||
} else {
|
||||
msleep(ms);
|
||||
|
||||
@@ -131,8 +131,8 @@ do { \
|
||||
#define IFACE_MAX_CNT 2
|
||||
|
||||
#define WL_SCAN_TIMER_INTERVAL_MS 8000 /* Scan timeout */
|
||||
#define WL_CHANNEL_SYNC_RETRY 1
|
||||
#define WL_ACT_FRAME_RETRY 5
|
||||
#define WL_CHANNEL_SYNC_RETRY 3
|
||||
#define WL_ACT_FRAME_RETRY 4
|
||||
|
||||
#define WL_INVALID -1
|
||||
|
||||
@@ -449,6 +449,7 @@ struct wl_priv {
|
||||
#endif /* WL_SCHED_SCAN */
|
||||
bool sched_scan_running; /* scheduled scan req status */
|
||||
u16 hostapd_chan; /* remember chan requested by framework for hostapd */
|
||||
u16 deauth_reason; /* Place holder to save deauth/disassoc reasons */
|
||||
};
|
||||
|
||||
static inline struct wl_bss_info *next_bss(struct wl_scan_results *list, struct wl_bss_info *bss)
|
||||
|
||||
@@ -105,6 +105,7 @@ bool wl_cfgp2p_is_p2p_action(void *frame, u32 frame_len)
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool wl_cfgp2p_is_gas_action(void *frame, u32 frame_len)
|
||||
{
|
||||
|
||||
@@ -128,6 +129,7 @@ bool wl_cfgp2p_is_gas_action(void *frame, u32 frame_len)
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
void wl_cfgp2p_print_actframe(bool tx, void *frame, u32 frame_len)
|
||||
{
|
||||
wifi_p2p_pub_act_frame_t *pact_frm;
|
||||
@@ -271,7 +273,6 @@ wl_cfgp2p_init_priv(struct wl_priv *wl)
|
||||
wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_DEVICE) = 0;
|
||||
wl_to_p2p_bss_ndev(wl, P2PAPI_BSSCFG_CONNECTION) = NULL;
|
||||
wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_CONNECTION) = 0;
|
||||
spin_lock_init(&wl->p2p->timer_lock);
|
||||
return BCME_OK;
|
||||
|
||||
}
|
||||
@@ -318,7 +319,7 @@ wl_cfgp2p_set_firm_p2p(struct wl_priv *wl)
|
||||
ret = wldev_iovar_setbuf_bsscfg(ndev, "p2p_da_override", &null_eth_addr,
|
||||
sizeof(null_eth_addr), wl->ioctl_buf, WLC_IOCTL_MAXLEN, 0, &wl->ioctl_buf_sync);
|
||||
if (ret && ret != BCME_UNSUPPORTED) {
|
||||
CFGP2P_ERR(("failed to update device address\n"));
|
||||
CFGP2P_ERR(("failed to update device address ret %d\n", ret));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@@ -539,7 +540,7 @@ wl_cfgp2p_init_discovery(struct wl_priv *wl)
|
||||
|
||||
/* Set the initial discovery state to SCAN */
|
||||
ret = wl_cfgp2p_set_p2p_mode(wl, WL_P2P_DISC_ST_SCAN, 0, 0,
|
||||
wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_DEVICE));
|
||||
wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_DEVICE));
|
||||
|
||||
if (unlikely(ret != 0)) {
|
||||
CFGP2P_ERR(("unable to set WL_P2P_DISC_ST_SCAN\n"));
|
||||
@@ -690,7 +691,7 @@ wl_cfgp2p_escan(struct wl_priv *wl, struct net_device *dev, u16 active,
|
||||
#define P2PAPI_SCAN_NPROBES 1
|
||||
#define P2PAPI_SCAN_DWELL_TIME_MS 50
|
||||
#define P2PAPI_SCAN_SOCIAL_DWELL_TIME_MS 40
|
||||
#define P2PAPI_SCAN_HOME_TIME_MS 10
|
||||
#define P2PAPI_SCAN_HOME_TIME_MS 60
|
||||
struct net_device *pri_dev = wl_to_p2p_bss_ndev(wl, P2PAPI_BSSCFG_PRIMARY);
|
||||
wl_set_p2p_status(wl, SCANNING);
|
||||
/* Allocate scan params which need space for 3 channels and 0 ssids */
|
||||
@@ -1180,12 +1181,15 @@ wl_cfgp2p_listen_complete(struct wl_priv *wl, struct net_device *ndev,
|
||||
s32 ret = BCME_OK;
|
||||
|
||||
CFGP2P_DBG((" Enter\n"));
|
||||
|
||||
/* If p2p_info is de-initialized, do nothing */
|
||||
if (!wl->p2p)
|
||||
return ret;
|
||||
|
||||
if (wl_get_p2p_status(wl, LISTEN_EXPIRED) == 0) {
|
||||
wl_set_p2p_status(wl, LISTEN_EXPIRED);
|
||||
if (timer_pending(&wl->p2p->listen_timer)) {
|
||||
spin_lock_bh(&wl->p2p->timer_lock);
|
||||
del_timer_sync(&wl->p2p->listen_timer);
|
||||
spin_unlock_bh(&wl->p2p->timer_lock);
|
||||
}
|
||||
cfg80211_remain_on_channel_expired(ndev, wl->last_roc_id, &wl->remain_on_chan,
|
||||
wl->remain_on_chan_type, GFP_KERNEL);
|
||||
@@ -1212,6 +1216,33 @@ wl_cfgp2p_listen_expired(unsigned long data)
|
||||
wl_cfg80211_event(wl_to_p2p_bss_ndev(wl, P2PAPI_BSSCFG_DEVICE), &msg, NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Routine for cancelling the P2P LISTEN
|
||||
*/
|
||||
s32
|
||||
wl_cfgp2p_cancel_listen(struct wl_priv *wl, struct net_device *ndev,
|
||||
bool notify)
|
||||
{
|
||||
WL_DBG(("Enter \n"));
|
||||
|
||||
/* Irrespective of whether timer is running or not, reset
|
||||
* the LISTEN state.
|
||||
*/
|
||||
wl_cfgp2p_set_p2p_mode(wl, WL_P2P_DISC_ST_SCAN, 0, 0,
|
||||
wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_DEVICE));
|
||||
|
||||
if (timer_pending(&wl->p2p->listen_timer)) {
|
||||
del_timer_sync(&wl->p2p->listen_timer);
|
||||
|
||||
if (notify)
|
||||
cfg80211_remain_on_channel_expired(ndev, wl->last_roc_id,
|
||||
&wl->remain_on_chan, wl->remain_on_chan_type, GFP_KERNEL);
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Do a P2P Listen on the given channel for the given duration.
|
||||
* A listen consists of sitting idle and responding to P2P probe requests
|
||||
@@ -1531,8 +1562,10 @@ wl_cfgp2p_supported(struct wl_priv *wl, struct net_device *ndev)
|
||||
s32
|
||||
wl_cfgp2p_down(struct wl_priv *wl)
|
||||
{
|
||||
if (timer_pending(&wl->p2p->listen_timer))
|
||||
del_timer_sync(&wl->p2p->listen_timer);
|
||||
|
||||
wl_cfgp2p_cancel_listen(wl,
|
||||
wl->p2p_net ? wl->p2p_net : wl_to_prmry_ndev(wl), TRUE);
|
||||
|
||||
wl_cfgp2p_deinit_priv(wl);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -77,7 +77,6 @@ struct p2p_info {
|
||||
wl_p2p_sched_t noa;
|
||||
wl_p2p_ops_t ops;
|
||||
wlc_ssid_t ssid;
|
||||
spinlock_t timer_lock;
|
||||
};
|
||||
|
||||
/* dongle status */
|
||||
@@ -268,14 +267,16 @@ wl_cfgp2p_unregister_ndev(struct wl_priv *wl);
|
||||
#define WL_P2P_INTERFACE_PREFIX "p2p"
|
||||
#define WL_P2P_TEMP_CHAN "11"
|
||||
|
||||
/* If the provision discovery is for JOIN operations, then we need not do an internal scan to find GO */
|
||||
#define IS_PROV_DISC_WITHOUT_GROUP_ID(p2p_ie, len) (wl_cfgp2p_retreive_p2pattrib(p2p_ie, P2P_SEID_GROUP_ID) == NULL )
|
||||
|
||||
#define IS_GAS_REQ(frame, len) (wl_cfgp2p_is_gas_action(frame, len) && \
|
||||
((frame->action == P2PSD_ACTION_ID_GAS_IREQ) || \
|
||||
(frame->action == P2PSD_ACTION_ID_GAS_CREQ)))
|
||||
#define IS_P2P_PUB_ACT_REQ(frame, len) (wl_cfgp2p_is_pub_action(frame, len) && \
|
||||
#define IS_P2P_PUB_ACT_REQ(frame, p2p_ie, len) (wl_cfgp2p_is_pub_action(frame, len) && \
|
||||
((frame->subtype == P2P_PAF_GON_REQ) || \
|
||||
(frame->subtype == P2P_PAF_INVITE_REQ) || \
|
||||
(frame->subtype == P2P_PAF_PROVDIS_REQ)))
|
||||
((frame->subtype == P2P_PAF_PROVDIS_REQ) && IS_PROV_DISC_WITHOUT_GROUP_ID(p2p_ie, len))))
|
||||
#define IS_P2P_SOCIAL(ch) ((ch == SOCIAL_CHAN_1) || (ch == SOCIAL_CHAN_2) || (ch == SOCIAL_CHAN_3))
|
||||
#define IS_P2P_SSID(ssid) (memcmp(ssid, WL_P2P_WILDCARD_SSID, WL_P2P_WILDCARD_SSID_LEN) == 0)
|
||||
#endif /* _wl_cfgp2p_h_ */
|
||||
|
||||
Reference in New Issue
Block a user