aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/bcmdhd/wl_cfgp2p.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/bcmdhd/wl_cfgp2p.c')
-rw-r--r--drivers/net/wireless/bcmdhd/wl_cfgp2p.c1020
1 files changed, 648 insertions, 372 deletions
diff --git a/drivers/net/wireless/bcmdhd/wl_cfgp2p.c b/drivers/net/wireless/bcmdhd/wl_cfgp2p.c
index 00334f5..12b4949 100644
--- a/drivers/net/wireless/bcmdhd/wl_cfgp2p.c
+++ b/drivers/net/wireless/bcmdhd/wl_cfgp2p.c
@@ -1,7 +1,7 @@
/*
* Linux cfgp2p driver
*
- * Copyright (C) 1999-2012, Broadcom Corporation
+ * Copyright (C) 1999-2014, 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: wl_cfgp2p.c 391443 2013-03-18 07:53:46Z $
+ * $Id: wl_cfgp2p.c 454364 2014-02-10 09:20:25Z $
*
*/
#include <typedefs.h>
@@ -53,22 +53,41 @@ static bool
wl_cfgp2p_has_ie(u8 *ie, u8 **tlvs, u32 *tlvs_len, const u8 *oui, u32 oui_len, u8 type);
static u32
-wl_cfgp2p_vndr_ie(struct wl_priv *wl, u8 *iebuf, s32 pktflag,
+wl_cfgp2p_vndr_ie(struct bcm_cfg80211 *cfg, u8 *iebuf, s32 pktflag,
s8 *oui, s32 ie_id, s8 *data, s32 datalen, const s8* add_del_cmd);
+static s32 wl_cfgp2p_cancel_listen(struct bcm_cfg80211 *cfg, struct net_device *ndev,
+ struct wireless_dev *wdev, bool notify);
+#if defined(WL_ENABLE_P2P_IF)
static int wl_cfgp2p_start_xmit(struct sk_buff *skb, struct net_device *ndev);
static int wl_cfgp2p_do_ioctl(struct net_device *net, struct ifreq *ifr, int cmd);
static int wl_cfgp2p_if_open(struct net_device *net);
static int wl_cfgp2p_if_stop(struct net_device *net);
-static s32 wl_cfgp2p_cancel_listen(struct wl_priv *wl, struct net_device *ndev,
- bool notify);
static const struct net_device_ops wl_cfgp2p_if_ops = {
- .ndo_open = wl_cfgp2p_if_open,
- .ndo_stop = wl_cfgp2p_if_stop,
- .ndo_do_ioctl = wl_cfgp2p_do_ioctl,
- .ndo_start_xmit = wl_cfgp2p_start_xmit,
+ .ndo_open = wl_cfgp2p_if_open,
+ .ndo_stop = wl_cfgp2p_if_stop,
+ .ndo_do_ioctl = wl_cfgp2p_do_ioctl,
+ .ndo_start_xmit = wl_cfgp2p_start_xmit,
};
+#endif /* WL_ENABLE_P2P_IF */
+
+#if defined(WL_NEWCFG_PRIVCMD_SUPPORT)
+static int wl_cfgp2p_start_xmit(struct sk_buff *skb, struct net_device *ndev);
+static int wl_cfgp2p_do_ioctl(struct net_device *net, struct ifreq *ifr, int cmd);
+
+static int wl_cfgp2p_if_dummy(struct net_device *net)
+{
+ return 0;
+}
+
+static const struct net_device_ops wl_cfgp2p_if_ops = {
+ .ndo_open = wl_cfgp2p_if_dummy,
+ .ndo_stop = wl_cfgp2p_if_dummy,
+ .ndo_do_ioctl = wl_cfgp2p_do_ioctl,
+ .ndo_start_xmit = wl_cfgp2p_start_xmit,
+};
+#endif /* WL_NEWCFG_PRIVCMD_SUPPORT */
bool wl_cfgp2p_is_pub_action(void *frame, u32 frame_len)
{
@@ -109,7 +128,6 @@ bool wl_cfgp2p_is_p2p_action(void *frame, u32 frame_len)
return false;
}
-#ifdef WL11U
#define GAS_RESP_LEN 2
#define DOUBLE_TLV_BODY_OFF 4
#define GAS_RESP_OFFSET 4
@@ -141,7 +159,6 @@ bool wl_cfgp2p_find_gas_subtype(u8 subtype, u8* data, u32 len)
return false;
}
-#endif /* WL11U */
bool wl_cfgp2p_is_gas_action(void *frame, u32 frame_len)
{
@@ -152,7 +169,7 @@ bool wl_cfgp2p_is_gas_action(void *frame, u32 frame_len)
return false;
sd_act_frm = (wifi_p2psd_gas_pub_act_frame_t *)frame;
- if (frame_len < sizeof(wifi_p2psd_gas_pub_act_frame_t) - 1)
+ if (frame_len < (sizeof(wifi_p2psd_gas_pub_act_frame_t) - 1))
return false;
if (sd_act_frm->category != P2PSD_ACTION_CATEGORY)
return false;
@@ -182,6 +199,29 @@ bool wl_cfgp2p_is_gas_action(void *frame, u32 frame_len)
return false;
#endif /* WL11U */
}
+#ifdef CUSTOMER_HW4
+bool wl_cfgp2p_is_p2p_gas_action(void *frame, u32 frame_len)
+{
+
+ wifi_p2psd_gas_pub_act_frame_t *sd_act_frm;
+
+ if (frame == NULL)
+ return false;
+
+ sd_act_frm = (wifi_p2psd_gas_pub_act_frame_t *)frame;
+ if (frame_len < (sizeof(wifi_p2psd_gas_pub_act_frame_t) - 1))
+ return false;
+ if (sd_act_frm->category != P2PSD_ACTION_CATEGORY)
+ return false;
+
+ if (sd_act_frm->action == P2PSD_ACTION_ID_GAS_IREQ)
+ return wl_cfgp2p_find_gas_subtype(P2PSD_GAS_OUI_SUBTYPE,
+ (u8 *)sd_act_frm->query_data,
+ frame_len);
+ else
+ return false;
+}
+#endif /* CUSTOMER_HW4 */
void wl_cfgp2p_print_actframe(bool tx, void *frame, u32 frame_len, u32 channel)
{
wifi_p2p_pub_act_frame_t *pact_frm;
@@ -292,17 +332,17 @@ void wl_cfgp2p_print_actframe(bool tx, void *frame, u32 frame_len, u32 channel)
*
*/
s32
-wl_cfgp2p_init_priv(struct wl_priv *wl)
+wl_cfgp2p_init_priv(struct bcm_cfg80211 *cfg)
{
- if (!(wl->p2p = kzalloc(sizeof(struct p2p_info), GFP_KERNEL))) {
+ if (!(cfg->p2p = kzalloc(sizeof(struct p2p_info), GFP_KERNEL))) {
CFGP2P_ERR(("struct p2p_info allocation failed\n"));
return -ENOMEM;
}
#define INIT_IE(IE_TYPE, BSS_TYPE) \
do { \
- memset(wl_to_p2p_bss_saved_ie(wl, BSS_TYPE).p2p_ ## IE_TYPE ## _ie, 0, \
- sizeof(wl_to_p2p_bss_saved_ie(wl, BSS_TYPE).p2p_ ## IE_TYPE ## _ie)); \
- wl_to_p2p_bss_saved_ie(wl, BSS_TYPE).p2p_ ## IE_TYPE ## _ie_len = 0; \
+ memset(wl_to_p2p_bss_saved_ie(cfg, BSS_TYPE).p2p_ ## IE_TYPE ## _ie, 0, \
+ sizeof(wl_to_p2p_bss_saved_ie(cfg, BSS_TYPE).p2p_ ## IE_TYPE ## _ie)); \
+ wl_to_p2p_bss_saved_ie(cfg, BSS_TYPE).p2p_ ## IE_TYPE ## _ie_len = 0; \
} while (0);
INIT_IE(probe_req, P2PAPI_BSSCFG_PRIMARY);
@@ -321,12 +361,12 @@ wl_cfgp2p_init_priv(struct wl_priv *wl)
INIT_IE(assoc_res, P2PAPI_BSSCFG_CONNECTION);
INIT_IE(beacon, P2PAPI_BSSCFG_CONNECTION);
#undef INIT_IE
- wl_to_p2p_bss_ndev(wl, P2PAPI_BSSCFG_PRIMARY) = wl_to_prmry_ndev(wl);
- wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_PRIMARY) = 0;
- wl_to_p2p_bss_ndev(wl, P2PAPI_BSSCFG_DEVICE) = NULL;
- 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;
+ wl_to_p2p_bss_ndev(cfg, P2PAPI_BSSCFG_PRIMARY) = bcmcfg_to_prmry_ndev(cfg);
+ wl_to_p2p_bss_bssidx(cfg, P2PAPI_BSSCFG_PRIMARY) = 0;
+ wl_to_p2p_bss_ndev(cfg, P2PAPI_BSSCFG_DEVICE) = NULL;
+ wl_to_p2p_bss_bssidx(cfg, P2PAPI_BSSCFG_DEVICE) = 0;
+ wl_to_p2p_bss_ndev(cfg, P2PAPI_BSSCFG_CONNECTION) = NULL;
+ wl_to_p2p_bss_bssidx(cfg, P2PAPI_BSSCFG_CONNECTION) = 0;
return BCME_OK;
}
@@ -335,22 +375,22 @@ wl_cfgp2p_init_priv(struct wl_priv *wl)
*
*/
void
-wl_cfgp2p_deinit_priv(struct wl_priv *wl)
+wl_cfgp2p_deinit_priv(struct bcm_cfg80211 *cfg)
{
CFGP2P_DBG(("In\n"));
- if (wl->p2p) {
- kfree(wl->p2p);
- wl->p2p = NULL;
+ if (cfg->p2p) {
+ kfree(cfg->p2p);
+ cfg->p2p = NULL;
}
- wl->p2p_supported = 0;
+ cfg->p2p_supported = 0;
}
/*
* Set P2P functions into firmware
*/
s32
-wl_cfgp2p_set_firm_p2p(struct wl_priv *wl)
+wl_cfgp2p_set_firm_p2p(struct bcm_cfg80211 *cfg)
{
- struct net_device *ndev = wl_to_prmry_ndev(wl);
+ struct net_device *ndev = bcmcfg_to_prmry_ndev(cfg);
struct ether_addr null_eth_addr = { { 0, 0, 0, 0, 0, 0 } };
s32 ret = BCME_OK;
s32 val = 0;
@@ -380,7 +420,7 @@ wl_cfgp2p_set_firm_p2p(struct wl_priv *wl)
* firmware for P2P device address
*/
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);
+ sizeof(null_eth_addr), cfg->ioctl_buf, WLC_IOCTL_MAXLEN, 0, &cfg->ioctl_buf_sync);
if (ret && ret != BCME_UNSUPPORTED) {
CFGP2P_ERR(("failed to update device address ret %d\n", ret));
}
@@ -395,74 +435,74 @@ wl_cfgp2p_set_firm_p2p(struct wl_priv *wl)
* Returns 0 if success.
*/
s32
-wl_cfgp2p_ifadd(struct wl_priv *wl, struct ether_addr *mac, u8 if_type,
+wl_cfgp2p_ifadd(struct bcm_cfg80211 *cfg, struct ether_addr *mac, u8 if_type,
chanspec_t chspec)
{
wl_p2p_if_t ifreq;
s32 err;
u32 scb_timeout = WL_SCB_TIMEOUT;
- struct net_device *ndev = wl_to_prmry_ndev(wl);
+ struct net_device *ndev = bcmcfg_to_prmry_ndev(cfg);
ifreq.type = if_type;
ifreq.chspec = chspec;
memcpy(ifreq.addr.octet, mac->octet, sizeof(ifreq.addr.octet));
- CFGP2P_DBG(("---wl p2p_ifadd "MACDBG" %s %u\n",
+ CFGP2P_DBG(("---cfg p2p_ifadd "MACDBG" %s %u\n",
MAC2STRDBG(ifreq.addr.octet),
(if_type == WL_P2P_IF_GO) ? "go" : "client",
(chspec & WL_CHANSPEC_CHAN_MASK) >> WL_CHANSPEC_CHAN_SHIFT));
err = wldev_iovar_setbuf(ndev, "p2p_ifadd", &ifreq, sizeof(ifreq),
- wl->ioctl_buf, WLC_IOCTL_MAXLEN, &wl->ioctl_buf_sync);
+ cfg->ioctl_buf, WLC_IOCTL_MAXLEN, &cfg->ioctl_buf_sync);
if (unlikely(err < 0))
- printk("'wl p2p_ifadd' error %d\n", err);
+ printk("'cfg p2p_ifadd' error %d\n", err);
else if (if_type == WL_P2P_IF_GO) {
err = wldev_ioctl(ndev, WLC_SET_SCB_TIMEOUT, &scb_timeout, sizeof(u32), true);
if (unlikely(err < 0))
- printk("'wl scb_timeout' error %d\n", err);
+ printk("'cfg scb_timeout' error %d\n", err);
}
return err;
}
/* Disable a P2P BSS.
* Parameters:
- * @mac : MAC address of the BSS to create
+ * @mac : MAC address of the BSS to disable
* Returns 0 if success.
*/
s32
-wl_cfgp2p_ifdisable(struct wl_priv *wl, struct ether_addr *mac)
+wl_cfgp2p_ifdisable(struct bcm_cfg80211 *cfg, struct ether_addr *mac)
{
s32 ret;
- struct net_device *netdev = wl_to_prmry_ndev(wl);
+ struct net_device *netdev = bcmcfg_to_prmry_ndev(cfg);
- CFGP2P_INFO(("------primary idx %d : wl p2p_ifdis "MACDBG"\n",
+ CFGP2P_INFO(("------primary idx %d : cfg p2p_ifdis "MACDBG"\n",
netdev->ifindex, MAC2STRDBG(mac->octet)));
ret = wldev_iovar_setbuf(netdev, "p2p_ifdis", mac, sizeof(*mac),
- wl->ioctl_buf, WLC_IOCTL_MAXLEN, &wl->ioctl_buf_sync);
+ cfg->ioctl_buf, WLC_IOCTL_MAXLEN, &cfg->ioctl_buf_sync);
if (unlikely(ret < 0)) {
- printk("'wl p2p_ifdis' error %d\n", ret);
+ printk("'cfg p2p_ifdis' error %d\n", ret);
}
return ret;
}
/* Delete a P2P BSS.
* Parameters:
- * @mac : MAC address of the BSS to create
+ * @mac : MAC address of the BSS to delete
* Returns 0 if success.
*/
s32
-wl_cfgp2p_ifdel(struct wl_priv *wl, struct ether_addr *mac)
+wl_cfgp2p_ifdel(struct bcm_cfg80211 *cfg, struct ether_addr *mac)
{
s32 ret;
- struct net_device *netdev = wl_to_prmry_ndev(wl);
+ struct net_device *netdev = bcmcfg_to_prmry_ndev(cfg);
- CFGP2P_INFO(("------primary idx %d : wl p2p_ifdel "MACDBG"\n",
+ CFGP2P_INFO(("------primary idx %d : cfg p2p_ifdel "MACDBG"\n",
netdev->ifindex, MAC2STRDBG(mac->octet)));
ret = wldev_iovar_setbuf(netdev, "p2p_ifdel", mac, sizeof(*mac),
- wl->ioctl_buf, WLC_IOCTL_MAXLEN, &wl->ioctl_buf_sync);
+ cfg->ioctl_buf, WLC_IOCTL_MAXLEN, &cfg->ioctl_buf_sync);
if (unlikely(ret < 0)) {
- printk("'wl p2p_ifdel' error %d\n", ret);
+ printk("'cfg p2p_ifdel' error %d\n", ret);
}
return ret;
}
@@ -473,34 +513,34 @@ wl_cfgp2p_ifdel(struct wl_priv *wl, struct ether_addr *mac)
* Returns 0 if success.
*/
s32
-wl_cfgp2p_ifchange(struct wl_priv *wl, struct ether_addr *mac, u8 if_type,
+wl_cfgp2p_ifchange(struct bcm_cfg80211 *cfg, struct ether_addr *mac, u8 if_type,
chanspec_t chspec)
{
wl_p2p_if_t ifreq;
s32 err;
u32 scb_timeout = WL_SCB_TIMEOUT;
- struct net_device *netdev = wl_to_p2p_bss_ndev(wl, P2PAPI_BSSCFG_CONNECTION);
+ struct net_device *netdev = wl_to_p2p_bss_ndev(cfg, P2PAPI_BSSCFG_CONNECTION);
ifreq.type = if_type;
ifreq.chspec = chspec;
memcpy(ifreq.addr.octet, mac->octet, sizeof(ifreq.addr.octet));
- CFGP2P_INFO(("---wl p2p_ifchange "MACDBG" %s %u"
+ CFGP2P_INFO(("---cfg p2p_ifchange "MACDBG" %s %u"
" chanspec 0x%04x\n", MAC2STRDBG(ifreq.addr.octet),
(if_type == WL_P2P_IF_GO) ? "go" : "client",
(chspec & WL_CHANSPEC_CHAN_MASK) >> WL_CHANSPEC_CHAN_SHIFT,
ifreq.chspec));
err = wldev_iovar_setbuf(netdev, "p2p_ifupd", &ifreq, sizeof(ifreq),
- wl->ioctl_buf, WLC_IOCTL_MAXLEN, &wl->ioctl_buf_sync);
+ cfg->ioctl_buf, WLC_IOCTL_MAXLEN, &cfg->ioctl_buf_sync);
if (unlikely(err < 0)) {
- printk("'wl p2p_ifupd' error %d\n", err);
+ printk("'cfg p2p_ifupd' error %d\n", err);
} else if (if_type == WL_P2P_IF_GO) {
err = wldev_ioctl(netdev, WLC_SET_SCB_TIMEOUT, &scb_timeout, sizeof(u32), true);
if (unlikely(err < 0))
- printk("'wl scb_timeout' error %d\n", err);
+ printk("'cfg scb_timeout' error %d\n", err);
}
return err;
}
@@ -513,30 +553,30 @@ wl_cfgp2p_ifchange(struct wl_priv *wl, struct ether_addr *mac, u8 if_type,
* Returns 0 if success.
*/
s32
-wl_cfgp2p_ifidx(struct wl_priv *wl, struct ether_addr *mac, s32 *index)
+wl_cfgp2p_ifidx(struct bcm_cfg80211 *cfg, struct ether_addr *mac, s32 *index)
{
s32 ret;
u8 getbuf[64];
- struct net_device *dev = wl_to_prmry_ndev(wl);
+ struct net_device *dev = bcmcfg_to_prmry_ndev(cfg);
- CFGP2P_INFO(("---wl p2p_if "MACDBG"\n", MAC2STRDBG(mac->octet)));
+ CFGP2P_INFO(("---cfg p2p_if "MACDBG"\n", MAC2STRDBG(mac->octet)));
ret = wldev_iovar_getbuf_bsscfg(dev, "p2p_if", mac, sizeof(*mac), getbuf,
- sizeof(getbuf), wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_PRIMARY), NULL);
+ sizeof(getbuf), wl_to_p2p_bss_bssidx(cfg, P2PAPI_BSSCFG_PRIMARY), NULL);
if (ret == 0) {
memcpy(index, getbuf, sizeof(s32));
- CFGP2P_INFO(("---wl p2p_if ==> %d\n", *index));
+ CFGP2P_INFO(("---cfg p2p_if ==> %d\n", *index));
}
return ret;
}
static s32
-wl_cfgp2p_set_discovery(struct wl_priv *wl, s32 on)
+wl_cfgp2p_set_discovery(struct bcm_cfg80211 *cfg, s32 on)
{
s32 ret = BCME_OK;
- struct net_device *ndev = wl_to_prmry_ndev(wl);
+ struct net_device *ndev = bcmcfg_to_prmry_ndev(cfg);
CFGP2P_DBG(("enter\n"));
ret = wldev_iovar_setint(ndev, "p2p_disc", on);
@@ -558,7 +598,7 @@ wl_cfgp2p_set_discovery(struct wl_priv *wl, s32 on)
*/
s32
-wl_cfgp2p_set_p2p_mode(struct wl_priv *wl, u8 mode, u32 channel, u16 listen_ms, int bssidx)
+wl_cfgp2p_set_p2p_mode(struct bcm_cfg80211 *cfg, u8 mode, u32 channel, u16 listen_ms, int bssidx)
{
wl_p2p_disc_st_t discovery_mode;
s32 ret;
@@ -570,7 +610,7 @@ wl_cfgp2p_set_p2p_mode(struct wl_priv *wl, u8 mode, u32 channel, u16 listen_ms,
return -1;
}
- dev = wl_cfgp2p_find_ndev(wl, bssidx);
+ dev = wl_cfgp2p_find_ndev(cfg, bssidx);
if (unlikely(dev == NULL)) {
CFGP2P_ERR(("bssidx %d is not assigned\n", bssidx));
return BCME_NOTFOUND;
@@ -581,18 +621,18 @@ wl_cfgp2p_set_p2p_mode(struct wl_priv *wl, u8 mode, u32 channel, u16 listen_ms,
discovery_mode.chspec = wl_ch_host_to_driver(channel);
discovery_mode.dwell = listen_ms;
ret = wldev_iovar_setbuf_bsscfg(dev, "p2p_state", &discovery_mode,
- sizeof(discovery_mode), wl->ioctl_buf, WLC_IOCTL_MAXLEN,
- bssidx, &wl->ioctl_buf_sync);
+ sizeof(discovery_mode), cfg->ioctl_buf, WLC_IOCTL_MAXLEN,
+ bssidx, &cfg->ioctl_buf_sync);
return ret;
}
/* Get the index of the P2P Discovery BSS */
static s32
-wl_cfgp2p_get_disc_idx(struct wl_priv *wl, s32 *index)
+wl_cfgp2p_get_disc_idx(struct bcm_cfg80211 *cfg, s32 *index)
{
s32 ret;
- struct net_device *dev = wl_to_p2p_bss_ndev(wl, P2PAPI_BSSCFG_PRIMARY);
+ struct net_device *dev = wl_to_p2p_bss_ndev(cfg, P2PAPI_BSSCFG_PRIMARY);
ret = wldev_iovar_getint(dev, "p2p_dev", index);
CFGP2P_INFO(("p2p_dev bsscfg_idx=%d ret=%d\n", *index, ret));
@@ -605,7 +645,7 @@ wl_cfgp2p_get_disc_idx(struct wl_priv *wl, s32 *index)
}
s32
-wl_cfgp2p_init_discovery(struct wl_priv *wl)
+wl_cfgp2p_init_discovery(struct bcm_cfg80211 *cfg)
{
s32 index = 0;
@@ -613,35 +653,35 @@ wl_cfgp2p_init_discovery(struct wl_priv *wl)
CFGP2P_DBG(("enter\n"));
- if (wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_DEVICE) != 0) {
+ if (wl_to_p2p_bss_bssidx(cfg, P2PAPI_BSSCFG_DEVICE) != 0) {
CFGP2P_ERR(("do nothing, already initialized\n"));
return ret;
}
- ret = wl_cfgp2p_set_discovery(wl, 1);
+ ret = wl_cfgp2p_set_discovery(cfg, 1);
if (ret < 0) {
CFGP2P_ERR(("set discover error\n"));
return ret;
}
/* Enable P2P Discovery in the WL Driver */
- ret = wl_cfgp2p_get_disc_idx(wl, &index);
+ ret = wl_cfgp2p_get_disc_idx(cfg, &index);
if (ret < 0) {
return ret;
}
- wl_to_p2p_bss_ndev(wl, P2PAPI_BSSCFG_DEVICE) =
- wl_to_p2p_bss_ndev(wl, P2PAPI_BSSCFG_PRIMARY);
- wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_DEVICE) = index;
+ wl_to_p2p_bss_ndev(cfg, P2PAPI_BSSCFG_DEVICE) =
+ wl_to_p2p_bss_ndev(cfg, P2PAPI_BSSCFG_PRIMARY);
+ wl_to_p2p_bss_bssidx(cfg, P2PAPI_BSSCFG_DEVICE) = index;
/* 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));
+ ret = wl_cfgp2p_set_p2p_mode(cfg, WL_P2P_DISC_ST_SCAN, 0, 0,
+ wl_to_p2p_bss_bssidx(cfg, P2PAPI_BSSCFG_DEVICE));
if (unlikely(ret != 0)) {
CFGP2P_ERR(("unable to set WL_P2P_DISC_ST_SCAN\n"));
- wl_cfgp2p_set_discovery(wl, 0);
- wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_DEVICE) = 0;
- wl_to_p2p_bss_ndev(wl, P2PAPI_BSSCFG_DEVICE) = NULL;
+ wl_cfgp2p_set_discovery(cfg, 0);
+ wl_to_p2p_bss_bssidx(cfg, P2PAPI_BSSCFG_DEVICE) = 0;
+ wl_to_p2p_bss_ndev(cfg, P2PAPI_BSSCFG_DEVICE) = NULL;
return 0;
}
return ret;
@@ -649,24 +689,24 @@ wl_cfgp2p_init_discovery(struct wl_priv *wl)
/* Deinitialize P2P Discovery
* Parameters :
- * @wl : wl_private data
+ * @cfg : wl_private data
* Returns 0 if succes
*/
static s32
-wl_cfgp2p_deinit_discovery(struct wl_priv *wl)
+wl_cfgp2p_deinit_discovery(struct bcm_cfg80211 *cfg)
{
s32 ret = BCME_OK;
CFGP2P_DBG(("enter\n"));
- if (wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_DEVICE) == 0) {
+ if (wl_to_p2p_bss_bssidx(cfg, P2PAPI_BSSCFG_DEVICE) == 0) {
CFGP2P_ERR(("do nothing, not initialized\n"));
return -1;
}
/* Set the 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));
+ ret = wl_cfgp2p_set_p2p_mode(cfg, WL_P2P_DISC_ST_SCAN, 0, 0,
+ wl_to_p2p_bss_bssidx(cfg, P2PAPI_BSSCFG_DEVICE));
/* Disable P2P discovery in the WL driver (deletes the discovery BSSCFG) */
- ret = wl_cfgp2p_set_discovery(wl, 0);
+ ret = wl_cfgp2p_set_discovery(cfg, 0);
/* Clear our saved WPS and P2P IEs for the discovery BSS. The driver
* deleted these IEs when wl_cfgp2p_set_discovery() deleted the discovery
@@ -676,42 +716,36 @@ wl_cfgp2p_deinit_discovery(struct wl_priv *wl)
/* Clear the saved bsscfg index of the discovery BSSCFG to indicate we
* have no discovery BSS.
*/
- wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_DEVICE) = WL_INVALID;
- wl_to_p2p_bss_ndev(wl, P2PAPI_BSSCFG_DEVICE) = NULL;
+ wl_to_p2p_bss_bssidx(cfg, P2PAPI_BSSCFG_DEVICE) = WL_INVALID;
+ wl_to_p2p_bss_ndev(cfg, P2PAPI_BSSCFG_DEVICE) = NULL;
return ret;
}
/* Enable P2P Discovery
* Parameters:
- * @wl : wl_private data
+ * @cfg : wl_private data
* @ie : probe request ie (WPS IE + P2P IE)
* @ie_len : probe request ie length
* Returns 0 if success.
*/
s32
-wl_cfgp2p_enable_discovery(struct wl_priv *wl, struct net_device *dev,
+wl_cfgp2p_enable_discovery(struct bcm_cfg80211 *cfg, struct net_device *dev,
const u8 *ie, u32 ie_len)
{
s32 ret = BCME_OK;
s32 bssidx;
- if (wl_to_prmry_ndev(wl) == dev) {
- bssidx = wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_DEVICE);
- } else if (wl_cfgp2p_find_idx(wl, dev, &bssidx) != BCME_OK) {
- WL_ERR(("Find p2p index from dev(%p) failed\n", dev));
- return BCME_ERROR;
- }
- if (wl_get_p2p_status(wl, DISCOVERY_ON)) {
+ if (wl_get_p2p_status(cfg, DISCOVERY_ON)) {
CFGP2P_INFO((" DISCOVERY is already initialized, we have nothing to do\n"));
goto set_ie;
}
- wl_set_p2p_status(wl, DISCOVERY_ON);
+ wl_set_p2p_status(cfg, DISCOVERY_ON);
CFGP2P_DBG(("enter\n"));
- ret = wl_cfgp2p_init_discovery(wl);
+ ret = wl_cfgp2p_init_discovery(cfg);
if (unlikely(ret < 0)) {
CFGP2P_ERR((" init discovery error %d\n", ret));
goto exit;
@@ -720,14 +754,21 @@ wl_cfgp2p_enable_discovery(struct wl_priv *wl, struct net_device *dev,
* P2P probe responses have the privacy bit set in the 802.11 WPA IE.
* Some peer devices may not initiate WPS with us if this bit is not set.
*/
- ret = wldev_iovar_setint_bsscfg(wl_to_p2p_bss_ndev(wl, P2PAPI_BSSCFG_DEVICE),
- "wsec", AES_ENABLED, wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_DEVICE));
+ ret = wldev_iovar_setint_bsscfg(wl_to_p2p_bss_ndev(cfg, P2PAPI_BSSCFG_DEVICE),
+ "wsec", AES_ENABLED, wl_to_p2p_bss_bssidx(cfg, P2PAPI_BSSCFG_DEVICE));
if (unlikely(ret < 0)) {
CFGP2P_ERR((" wsec error %d\n", ret));
}
set_ie:
if (ie_len) {
- ret = wl_cfgp2p_set_management_ie(wl, dev,
+ if (bcmcfg_to_prmry_ndev(cfg) == dev) {
+ bssidx = wl_to_p2p_bss_bssidx(cfg, P2PAPI_BSSCFG_DEVICE);
+ } else if (wl_cfgp2p_find_idx(cfg, dev, &bssidx) != BCME_OK) {
+ WL_ERR(("Find p2p index from dev(%p) failed\n", dev));
+ return BCME_ERROR;
+ }
+
+ ret = wl_cfgp2p_set_management_ie(cfg, dev,
bssidx,
VNDR_IE_PRBREQ_FLAG, ie, ie_len);
@@ -742,23 +783,23 @@ exit:
/* Disable P2P Discovery
* Parameters:
- * @wl : wl_private_data
+ * @cfg : wl_private_data
* Returns 0 if success.
*/
s32
-wl_cfgp2p_disable_discovery(struct wl_priv *wl)
+wl_cfgp2p_disable_discovery(struct bcm_cfg80211 *cfg)
{
s32 ret = BCME_OK;
CFGP2P_DBG((" enter\n"));
- wl_clr_p2p_status(wl, DISCOVERY_ON);
+ wl_clr_p2p_status(cfg, DISCOVERY_ON);
- if (wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_DEVICE) == 0) {
+ if (wl_to_p2p_bss_bssidx(cfg, P2PAPI_BSSCFG_DEVICE) == 0) {
CFGP2P_ERR((" do nothing, not initialized\n"));
goto exit;
}
- ret = wl_cfgp2p_set_p2p_mode(wl, WL_P2P_DISC_ST_SCAN, 0, 0,
- wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_DEVICE));
+ ret = wl_cfgp2p_set_p2p_mode(cfg, WL_P2P_DISC_ST_SCAN, 0, 0,
+ wl_to_p2p_bss_bssidx(cfg, P2PAPI_BSSCFG_DEVICE));
if (unlikely(ret < 0)) {
@@ -768,21 +809,22 @@ wl_cfgp2p_disable_discovery(struct wl_priv *wl)
* waiting out an action frame tx dwell time.
*/
#ifdef NOT_YET
- if (wl_get_p2p_status(wl, SCANNING)) {
+ if (wl_get_p2p_status(cfg, SCANNING)) {
p2pwlu_scan_abort(hdl, FALSE);
}
#endif
- wl_clr_p2p_status(wl, DISCOVERY_ON);
- ret = wl_cfgp2p_deinit_discovery(wl);
+ wl_clr_p2p_status(cfg, DISCOVERY_ON);
+ ret = wl_cfgp2p_deinit_discovery(cfg);
exit:
return ret;
}
s32
-wl_cfgp2p_escan(struct wl_priv *wl, struct net_device *dev, u16 active,
+wl_cfgp2p_escan(struct bcm_cfg80211 *cfg, struct net_device *dev, u16 active,
u32 num_chans, u16 *channels,
- s32 search_state, u16 action, u32 bssidx, struct ether_addr *tx_dst_addr)
+ s32 search_state, u16 action, u32 bssidx, struct ether_addr *tx_dst_addr,
+ p2p_scan_purpose_t p2p_scan_purpose)
{
s32 ret = BCME_OK;
s32 memsize;
@@ -800,7 +842,7 @@ wl_cfgp2p_escan(struct wl_priv *wl, struct net_device *dev, u16 active,
#define P2PAPI_SCAN_NPROBS_TIME_MS 30
#define P2PAPI_SCAN_AF_SEARCH_DWELL_TIME_MS 100
- struct net_device *pri_dev = wl_to_p2p_bss_ndev(wl, P2PAPI_BSSCFG_PRIMARY);
+ struct net_device *pri_dev = wl_to_p2p_bss_ndev(cfg, P2PAPI_BSSCFG_PRIMARY);
/* Allocate scan params which need space for 3 channels and 0 ssids */
eparams_size = (WL_SCAN_PARAMS_FIXED_SIZE +
OFFSETOF(wl_escan_params_t, params)) +
@@ -814,13 +856,13 @@ wl_cfgp2p_escan(struct wl_priv *wl, struct net_device *dev, u16 active,
return -1;
}
memset(memblk, 0, memsize);
- memset(wl->ioctl_buf, 0, WLC_IOCTL_MAXLEN);
+ memset(cfg->ioctl_buf, 0, WLC_IOCTL_MAXLEN);
if (search_state == WL_P2P_DISC_ST_SEARCH) {
/*
* If we in SEARCH STATE, we don't need to set SSID explictly
* because dongle use P2P WILDCARD internally by default
*/
- wl_cfgp2p_set_p2p_mode(wl, WL_P2P_DISC_ST_SEARCH, 0, 0, bssidx);
+ wl_cfgp2p_set_p2p_mode(cfg, WL_P2P_DISC_ST_SEARCH, 0, 0, bssidx);
/* use null ssid */
ssid.SSID_len = 0;
memset(&ssid.SSID, 0, sizeof(ssid.SSID));
@@ -831,7 +873,7 @@ wl_cfgp2p_escan(struct wl_priv *wl, struct net_device *dev, u16 active,
* we have to set ssid to P2P WILDCARD because
* we just do broadcast scan unless setting SSID
*/
- wl_cfgp2p_set_p2p_mode(wl, WL_P2P_DISC_ST_SCAN, 0, 0, bssidx);
+ wl_cfgp2p_set_p2p_mode(cfg, WL_P2P_DISC_ST_SCAN, 0, 0, bssidx);
/* use wild card ssid */
ssid.SSID_len = WL_P2P_WILDCARD_SSID_LEN;
memset(&ssid.SSID, 0, sizeof(ssid.SSID));
@@ -863,26 +905,32 @@ wl_cfgp2p_escan(struct wl_priv *wl, struct net_device *dev, u16 active,
eparams->params.home_time = htod32(P2PAPI_SCAN_HOME_TIME_MS);
- /* SOCIAL_CHAN_CNT + 1 takes care of the Progressive scan supported by
- * the supplicant
- */
- if ((num_chans == SOCIAL_CHAN_CNT) || (num_chans == SOCIAL_CHAN_CNT + 1))
+ switch (p2p_scan_purpose) {
+ case P2P_SCAN_SOCIAL_CHANNEL:
eparams->params.active_time = htod32(P2PAPI_SCAN_SOCIAL_DWELL_TIME_MS);
- else if (num_chans == AF_PEER_SEARCH_CNT)
+ break;
+ case P2P_SCAN_AFX_PEER_NORMAL:
+ case P2P_SCAN_AFX_PEER_REDUCED:
eparams->params.active_time = htod32(P2PAPI_SCAN_AF_SEARCH_DWELL_TIME_MS);
- else if (wl_get_drv_status_all(wl, CONNECTED))
+ break;
+ case P2P_SCAN_CONNECT_TRY:
+ eparams->params.active_time = htod32(WL_SCAN_CONNECT_DWELL_TIME_MS);
+ break;
+ default :
+ if (wl_get_drv_status_all(cfg, CONNECTED))
eparams->params.active_time = -1;
else
eparams->params.active_time = htod32(P2PAPI_SCAN_DWELL_TIME_MS);
- eparams->params.nprobes = htod32((eparams->params.active_time /
- P2PAPI_SCAN_NPROBS_TIME_MS));
+ break;
+ }
- /* Override scan params to find a peer for a connection */
- if (num_chans == 1) {
- eparams->params.active_time = htod32(WL_SCAN_CONNECT_DWELL_TIME_MS);
+ if (p2p_scan_purpose == P2P_SCAN_CONNECT_TRY)
eparams->params.nprobes = htod32(eparams->params.active_time /
WL_SCAN_JOIN_PROBE_INTERVAL_MS);
- }
+ else
+ eparams->params.nprobes = htod32((eparams->params.active_time /
+ P2PAPI_SCAN_NPROBS_TIME_MS));
+
if (eparams->params.nprobes <= 0)
eparams->params.nprobes = 1;
@@ -897,11 +945,8 @@ wl_cfgp2p_escan(struct wl_priv *wl, struct net_device *dev, u16 active,
}
eparams->version = htod32(ESCAN_REQ_VERSION);
eparams->action = htod16(action);
-#if defined(CUSTOMER_HW4) && defined(DUAL_ESCAN_RESULT_BUFFER)
- eparams->sync_id = wl->escan_info.cur_sync_id;
-#else
- eparams->sync_id = htod16(0x1234);
-#endif /* CUSTOMER_HW4 && DUAL_ESCAN_RESULT_BUFFER */
+ wl_escan_set_sync_id(eparams->sync_id, cfg);
+ wl_escan_set_type(cfg, WL_SCANTYPE_P2P);
CFGP2P_INFO(("SCAN CHANNELS : "));
for (i = 0; i < num_chans; i++) {
@@ -912,35 +957,46 @@ wl_cfgp2p_escan(struct wl_priv *wl, struct net_device *dev, u16 active,
CFGP2P_INFO(("\n"));
ret = wldev_iovar_setbuf_bsscfg(pri_dev, "p2p_scan",
- memblk, memsize, wl->ioctl_buf, WLC_IOCTL_MAXLEN, bssidx, &wl->ioctl_buf_sync);
+ memblk, memsize, cfg->ioctl_buf, WLC_IOCTL_MAXLEN, bssidx, &cfg->ioctl_buf_sync);
if (ret == BCME_OK)
- wl_set_p2p_status(wl, SCANNING);
+ wl_set_p2p_status(cfg, SCANNING);
return ret;
}
/* search function to reach at common channel to send action frame
* Parameters:
- * @wl : wl_private data
+ * @cfg : wl_private data
* @ndev : net device for bssidx
* @bssidx : bssidx for BSS
* Returns 0 if success.
*/
s32
-wl_cfgp2p_act_frm_search(struct wl_priv *wl, struct net_device *ndev,
+wl_cfgp2p_act_frm_search(struct bcm_cfg80211 *cfg, struct net_device *ndev,
s32 bssidx, s32 channel, struct ether_addr *tx_dst_addr)
{
s32 ret = 0;
u32 chan_cnt = 0;
u16 *default_chan_list = NULL;
- if (!p2p_is_on(wl) || ndev == NULL || bssidx == WL_INVALID)
+ p2p_scan_purpose_t p2p_scan_purpose = P2P_SCAN_AFX_PEER_NORMAL;
+ if (!p2p_is_on(cfg) || ndev == NULL || bssidx == WL_INVALID)
return -BCME_ERROR;
CFGP2P_ERR((" Enter\n"));
- if (bssidx == wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_PRIMARY))
- bssidx = wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_DEVICE);
+ if (bssidx == wl_to_p2p_bss_bssidx(cfg, P2PAPI_BSSCFG_PRIMARY))
+ bssidx = wl_to_p2p_bss_bssidx(cfg, P2PAPI_BSSCFG_DEVICE);
if (channel)
chan_cnt = AF_PEER_SEARCH_CNT;
else
chan_cnt = SOCIAL_CHAN_CNT;
+#ifdef CUSTOMER_HW4
+ if (cfg->afx_hdl->pending_tx_act_frm && cfg->afx_hdl->is_active) {
+ wl_action_frame_t *action_frame;
+ action_frame = &(cfg->afx_hdl->pending_tx_act_frm->action_frame);
+ if (wl_cfgp2p_is_p2p_gas_action(action_frame->data, action_frame->len)) {
+ chan_cnt = 1;
+ p2p_scan_purpose = P2P_SCAN_AFX_PEER_REDUCED;
+ }
+ }
+#endif /* CUSTOMER_HW4 */
default_chan_list = kzalloc(chan_cnt * sizeof(*default_chan_list), GFP_KERNEL);
if (default_chan_list == NULL) {
CFGP2P_ERR(("channel list allocation failed \n"));
@@ -958,9 +1014,9 @@ wl_cfgp2p_act_frm_search(struct wl_priv *wl, struct net_device *ndev,
default_chan_list[1] = SOCIAL_CHAN_2;
default_chan_list[2] = SOCIAL_CHAN_3;
}
- ret = wl_cfgp2p_escan(wl, ndev, true, chan_cnt,
+ ret = wl_cfgp2p_escan(cfg, ndev, true, chan_cnt,
default_chan_list, WL_P2P_DISC_ST_SEARCH,
- WL_SCAN_ACTION_START, bssidx, tx_dst_addr);
+ WL_SCAN_ACTION_START, bssidx, NULL, p2p_scan_purpose);
kfree(default_chan_list);
exit:
return ret;
@@ -1041,7 +1097,7 @@ end:
/* Delete and Set a management vndr ie to firmware
* Parameters:
- * @wl : wl_private data
+ * @cfg : wl_private data
* @ndev : net device for bssidx
* @bssidx : bssidx for BSS
* @pktflag : packet flag for IE (VNDR_IE_PRBREQ_FLAG,VNDR_IE_PRBRSP_FLAG, VNDR_IE_ASSOCRSP_FLAG,
@@ -1052,7 +1108,7 @@ end:
*/
s32
-wl_cfgp2p_set_management_ie(struct wl_priv *wl, struct net_device *ndev, s32 bssidx,
+wl_cfgp2p_set_management_ie(struct bcm_cfg80211 *cfg, struct net_device *ndev, s32 bssidx,
s32 pktflag, const u8 *vndr_ie, u32 vndr_ie_len)
{
s32 ret = BCME_OK;
@@ -1069,13 +1125,13 @@ wl_cfgp2p_set_management_ie(struct wl_priv *wl, struct net_device *ndev, s32 bss
u8 *ptr;
s32 type = -1;
s32 remained_buf_len;
-#define IE_TYPE(type, bsstype) (wl_to_p2p_bss_saved_ie(wl, bsstype).p2p_ ## type ## _ie)
-#define IE_TYPE_LEN(type, bsstype) (wl_to_p2p_bss_saved_ie(wl, bsstype).p2p_ ## type ## _ie_len)
+#define IE_TYPE(type, bsstype) (wl_to_p2p_bss_saved_ie(cfg, bsstype).p2p_ ## type ## _ie)
+#define IE_TYPE_LEN(type, bsstype) (wl_to_p2p_bss_saved_ie(cfg, bsstype).p2p_ ## type ## _ie_len)
memset(g_mgmt_ie_buf, 0, sizeof(g_mgmt_ie_buf));
curr_ie_buf = g_mgmt_ie_buf;
CFGP2P_DBG((" bssidx %d, pktflag : 0x%02X\n", bssidx, pktflag));
- if (wl->p2p != NULL) {
- if (wl_cfgp2p_find_type(wl, bssidx, &type)) {
+ if (cfg->p2p != NULL) {
+ if (wl_cfgp2p_find_type(cfg, bssidx, &type)) {
CFGP2P_ERR(("cannot find type from bssidx : %d\n", bssidx));
return BCME_ERROR;
}
@@ -1112,17 +1168,17 @@ wl_cfgp2p_set_management_ie(struct wl_priv *wl, struct net_device *ndev, s32 bss
CFGP2P_ERR(("not suitable type\n"));
return BCME_ERROR;
}
- } else if (wl_get_mode_by_netdev(wl, ndev) == WL_MODE_AP) {
+ } else if (wl_get_mode_by_netdev(cfg, ndev) == WL_MODE_AP) {
switch (pktflag) {
case VNDR_IE_PRBRSP_FLAG :
- mgmt_ie_buf = wl->ap_info->probe_res_ie;
- mgmt_ie_len = &wl->ap_info->probe_res_ie_len;
- mgmt_ie_buf_len = sizeof(wl->ap_info->probe_res_ie);
+ mgmt_ie_buf = cfg->ap_info->probe_res_ie;
+ mgmt_ie_len = &cfg->ap_info->probe_res_ie_len;
+ mgmt_ie_buf_len = sizeof(cfg->ap_info->probe_res_ie);
break;
case VNDR_IE_BEACON_FLAG :
- mgmt_ie_buf = wl->ap_info->beacon_ie;
- mgmt_ie_len = &wl->ap_info->beacon_ie_len;
- mgmt_ie_buf_len = sizeof(wl->ap_info->beacon_ie);
+ mgmt_ie_buf = cfg->ap_info->beacon_ie;
+ mgmt_ie_len = &cfg->ap_info->beacon_ie_len;
+ mgmt_ie_buf_len = sizeof(cfg->ap_info->beacon_ie);
break;
default:
mgmt_ie_buf = NULL;
@@ -1131,17 +1187,17 @@ wl_cfgp2p_set_management_ie(struct wl_priv *wl, struct net_device *ndev, s32 bss
return BCME_ERROR;
}
bssidx = 0;
- } else if (wl_get_mode_by_netdev(wl, ndev) == WL_MODE_BSS) {
+ } else if (wl_get_mode_by_netdev(cfg, ndev) == WL_MODE_BSS) {
switch (pktflag) {
case VNDR_IE_PRBREQ_FLAG :
- mgmt_ie_buf = wl->sta_info->probe_req_ie;
- mgmt_ie_len = &wl->sta_info->probe_req_ie_len;
- mgmt_ie_buf_len = sizeof(wl->sta_info->probe_req_ie);
+ mgmt_ie_buf = cfg->sta_info->probe_req_ie;
+ mgmt_ie_len = &cfg->sta_info->probe_req_ie_len;
+ mgmt_ie_buf_len = sizeof(cfg->sta_info->probe_req_ie);
break;
case VNDR_IE_ASSOCREQ_FLAG :
- mgmt_ie_buf = wl->sta_info->assoc_req_ie;
- mgmt_ie_len = &wl->sta_info->assoc_req_ie_len;
- mgmt_ie_buf_len = sizeof(wl->sta_info->assoc_req_ie);
+ mgmt_ie_buf = cfg->sta_info->assoc_req_ie;
+ mgmt_ie_len = &cfg->sta_info->assoc_req_ie_len;
+ mgmt_ie_buf_len = sizeof(cfg->sta_info->assoc_req_ie);
break;
default:
mgmt_ie_buf = NULL;
@@ -1197,7 +1253,7 @@ wl_cfgp2p_set_management_ie(struct wl_priv *wl, struct net_device *ndev, s32 bss
vndrie_info->vndrie.oui[0], vndrie_info->vndrie.oui[1],
vndrie_info->vndrie.oui[2]));
- del_add_ie_buf_len = wl_cfgp2p_vndr_ie(wl, curr_ie_buf,
+ del_add_ie_buf_len = wl_cfgp2p_vndr_ie(cfg, curr_ie_buf,
pktflag, vndrie_info->vndrie.oui,
vndrie_info->vndrie.id,
vndrie_info->ie_ptr + VNDR_IE_FIXED_LEN,
@@ -1227,7 +1283,7 @@ wl_cfgp2p_set_management_ie(struct wl_priv *wl, struct net_device *ndev, s32 bss
vndrie_info->vndrie.oui[0], vndrie_info->vndrie.oui[1],
vndrie_info->vndrie.oui[2]));
- del_add_ie_buf_len = wl_cfgp2p_vndr_ie(wl, curr_ie_buf,
+ del_add_ie_buf_len = wl_cfgp2p_vndr_ie(cfg, curr_ie_buf,
pktflag, vndrie_info->vndrie.oui,
vndrie_info->vndrie.id,
vndrie_info->ie_ptr + VNDR_IE_FIXED_LEN,
@@ -1246,7 +1302,7 @@ wl_cfgp2p_set_management_ie(struct wl_priv *wl, struct net_device *ndev, s32 bss
break;
}
- /* save the parsed IE in wl struct */
+ /* save the parsed IE in cfg struct */
memcpy(ptr + (*mgmt_ie_len), vndrie_info->ie_ptr,
vndrie_info->ie_len);
*mgmt_ie_len += vndrie_info->ie_len;
@@ -1257,8 +1313,8 @@ wl_cfgp2p_set_management_ie(struct wl_priv *wl, struct net_device *ndev, s32 bss
}
if (total_ie_buf_len) {
ret = wldev_iovar_setbuf_bsscfg(ndev, "vndr_ie", g_mgmt_ie_buf,
- total_ie_buf_len, wl->ioctl_buf, WLC_IOCTL_MAXLEN,
- bssidx, &wl->ioctl_buf_sync);
+ total_ie_buf_len, cfg->ioctl_buf, WLC_IOCTL_MAXLEN,
+ bssidx, &cfg->ioctl_buf_sync);
if (ret)
CFGP2P_ERR(("vndr ie set error : %d\n", ret));
}
@@ -1271,25 +1327,25 @@ exit:
/* Clear the manament IE buffer of BSSCFG
* Parameters:
- * @wl : wl_private data
+ * @cfg : wl_private data
* @bssidx : bssidx for BSS
*
* Returns 0 if success.
*/
s32
-wl_cfgp2p_clear_management_ie(struct wl_priv *wl, s32 bssidx)
+wl_cfgp2p_clear_management_ie(struct bcm_cfg80211 *cfg, s32 bssidx)
{
s32 vndrie_flag[] = {VNDR_IE_BEACON_FLAG, VNDR_IE_PRBRSP_FLAG, VNDR_IE_ASSOCRSP_FLAG,
VNDR_IE_PRBREQ_FLAG, VNDR_IE_ASSOCREQ_FLAG};
s32 index = -1;
s32 type = -1;
- struct net_device *ndev = wl_cfgp2p_find_ndev(wl, bssidx);
+ struct net_device *ndev = wl_cfgp2p_find_ndev(cfg, bssidx);
#define INIT_IE(IE_TYPE, BSS_TYPE) \
do { \
- memset(wl_to_p2p_bss_saved_ie(wl, BSS_TYPE).p2p_ ## IE_TYPE ## _ie, 0, \
- sizeof(wl_to_p2p_bss_saved_ie(wl, BSS_TYPE).p2p_ ## IE_TYPE ## _ie)); \
- wl_to_p2p_bss_saved_ie(wl, BSS_TYPE).p2p_ ## IE_TYPE ## _ie_len = 0; \
+ memset(wl_to_p2p_bss_saved_ie(cfg, BSS_TYPE).p2p_ ## IE_TYPE ## _ie, 0, \
+ sizeof(wl_to_p2p_bss_saved_ie(cfg, BSS_TYPE).p2p_ ## IE_TYPE ## _ie)); \
+ wl_to_p2p_bss_saved_ie(cfg, BSS_TYPE).p2p_ ## IE_TYPE ## _ie_len = 0; \
} while (0);
if (bssidx < 0 || ndev == NULL) {
@@ -1297,13 +1353,13 @@ wl_cfgp2p_clear_management_ie(struct wl_priv *wl, s32 bssidx)
return BCME_BADARG;
}
- if (wl_cfgp2p_find_type(wl, bssidx, &type)) {
+ if (wl_cfgp2p_find_type(cfg, bssidx, &type)) {
CFGP2P_ERR(("invalid argument\n"));
return BCME_BADARG;
}
for (index = 0; index < ARRAYSIZE(vndrie_flag); index++) {
/* clean up vndr ies in dongle */
- wl_cfgp2p_set_management_ie(wl, ndev, bssidx, vndrie_flag[index], NULL, 0);
+ wl_cfgp2p_set_management_ie(cfg, ndev, bssidx, vndrie_flag[index], NULL, 0);
}
INIT_IE(probe_req, type);
INIT_IE(probe_res, type);
@@ -1391,7 +1447,7 @@ wl_cfgp2p_find_wfdie(u8 *parse, u32 len)
return NULL;
}
static u32
-wl_cfgp2p_vndr_ie(struct wl_priv *wl, u8 *iebuf, s32 pktflag,
+wl_cfgp2p_vndr_ie(struct bcm_cfg80211 *cfg, u8 *iebuf, s32 pktflag,
s8 *oui, s32 ie_id, s8 *data, s32 datalen, const s8* add_del_cmd)
{
vndr_ie_setbuf_t hdr; /* aligned temporary vndr_ie buffer header */
@@ -1446,20 +1502,20 @@ wl_cfgp2p_vndr_ie(struct wl_priv *wl, u8 *iebuf, s32 pktflag,
/*
* Search the bssidx based on dev argument
* Parameters:
- * @wl : wl_private data
+ * @cfg : wl_private data
* @ndev : net device to search bssidx
* @bssidx : output arg to store bssidx of the bsscfg of firmware.
* Returns error
*/
s32
-wl_cfgp2p_find_idx(struct wl_priv *wl, struct net_device *ndev, s32 *bssidx)
+wl_cfgp2p_find_idx(struct bcm_cfg80211 *cfg, struct net_device *ndev, s32 *bssidx)
{
u32 i;
if (ndev == NULL || bssidx == NULL) {
CFGP2P_ERR((" argument is invalid\n"));
return BCME_BADARG;
}
- if (!wl->p2p_supported) {
+ if (!cfg->p2p_supported) {
*bssidx = P2PAPI_BSSCFG_PRIMARY;
return BCME_OK;
}
@@ -1467,15 +1523,15 @@ wl_cfgp2p_find_idx(struct wl_priv *wl, struct net_device *ndev, s32 *bssidx)
* because the ndev is same with ndev of PRIMARY BSS.
*/
for (i = 0; i < P2PAPI_BSSCFG_MAX; i++) {
- if (ndev == wl_to_p2p_bss_ndev(wl, i)) {
- *bssidx = wl_to_p2p_bss_bssidx(wl, i);
+ if (ndev == wl_to_p2p_bss_ndev(cfg, i)) {
+ *bssidx = wl_to_p2p_bss_bssidx(cfg, i);
return BCME_OK;
}
}
return BCME_BADARG;
}
struct net_device *
-wl_cfgp2p_find_ndev(struct wl_priv *wl, s32 bssidx)
+wl_cfgp2p_find_ndev(struct bcm_cfg80211 *cfg, s32 bssidx)
{
u32 i;
struct net_device *ndev = NULL;
@@ -1485,8 +1541,8 @@ wl_cfgp2p_find_ndev(struct wl_priv *wl, s32 bssidx)
}
for (i = 0; i < P2PAPI_BSSCFG_MAX; i++) {
- if (bssidx == wl_to_p2p_bss_bssidx(wl, i)) {
- ndev = wl_to_p2p_bss_ndev(wl, i);
+ if (bssidx == wl_to_p2p_bss_bssidx(cfg, i)) {
+ ndev = wl_to_p2p_bss_ndev(cfg, i);
break;
}
}
@@ -1497,14 +1553,14 @@ exit:
/*
* Search the driver array idx based on bssidx argument
* Parameters:
- * @wl : wl_private data
+ * @cfg : wl_private data
* @bssidx : bssidx which indicate bsscfg->idx of firmware.
* @type : output arg to store array idx of p2p->bss.
* Returns error
*/
s32
-wl_cfgp2p_find_type(struct wl_priv *wl, s32 bssidx, s32 *type)
+wl_cfgp2p_find_type(struct bcm_cfg80211 *cfg, s32 bssidx, s32 *type)
{
u32 i;
if (bssidx < 0 || type == NULL) {
@@ -1513,7 +1569,7 @@ wl_cfgp2p_find_type(struct wl_priv *wl, s32 bssidx, s32 *type)
}
for (i = 0; i < P2PAPI_BSSCFG_MAX; i++) {
- if (bssidx == wl_to_p2p_bss_bssidx(wl, i)) {
+ if (bssidx == wl_to_p2p_bss_bssidx(cfg, i)) {
*type = i;
return BCME_OK;
}
@@ -1527,65 +1583,70 @@ exit:
* Callback function for WLC_E_P2P_DISC_LISTEN_COMPLETE
*/
s32
-wl_cfgp2p_listen_complete(struct wl_priv *wl, struct net_device *ndev,
- const wl_event_msg_t *e, void *data)
+wl_cfgp2p_listen_complete(struct bcm_cfg80211 *cfg, bcm_struct_cfgdev *cfgdev,
+ const wl_event_msg_t *e, void *data)
{
s32 ret = BCME_OK;
- struct net_device *netdev;
- if (!wl || !wl->p2p)
+ struct net_device *ndev = NULL;
+
+ if (!cfg || !cfg->p2p)
return BCME_ERROR;
- if (wl->p2p_net == ndev) {
- netdev = wl_to_prmry_ndev(wl);
- } else {
- netdev = ndev;
- }
+
CFGP2P_DBG((" Enter\n"));
- if (wl_get_p2p_status(wl, LISTEN_EXPIRED) == 0) {
- wl_set_p2p_status(wl, LISTEN_EXPIRED);
- if (timer_pending(&wl->p2p->listen_timer)) {
- del_timer_sync(&wl->p2p->listen_timer);
+
+ ndev = cfgdev_to_wlc_ndev(cfgdev, cfg);
+
+ if (wl_get_p2p_status(cfg, LISTEN_EXPIRED) == 0) {
+ wl_set_p2p_status(cfg, LISTEN_EXPIRED);
+ if (timer_pending(&cfg->p2p->listen_timer)) {
+ del_timer_sync(&cfg->p2p->listen_timer);
}
- if (wl->afx_hdl->is_listen == TRUE &&
- wl_get_drv_status_all(wl, FINDING_COMMON_CHANNEL)) {
+ if (cfg->afx_hdl->is_listen == TRUE &&
+ wl_get_drv_status_all(cfg, FINDING_COMMON_CHANNEL)) {
WL_DBG(("Listen DONE for action frame\n"));
- complete(&wl->act_frm_scan);
+ complete(&cfg->act_frm_scan);
}
#ifdef WL_CFG80211_SYNC_GON
- else if (wl_get_drv_status_all(wl, WAITING_NEXT_ACT_FRM_LISTEN)) {
- wl_clr_drv_status(wl, WAITING_NEXT_ACT_FRM_LISTEN, netdev);
+ else if (wl_get_drv_status_all(cfg, WAITING_NEXT_ACT_FRM_LISTEN)) {
+ wl_clr_drv_status(cfg, WAITING_NEXT_ACT_FRM_LISTEN, ndev);
WL_DBG(("Listen DONE and wake up wait_next_af !!(%d)\n",
- jiffies_to_msecs(jiffies - wl->af_tx_sent_jiffies)));
+ jiffies_to_msecs(jiffies - cfg->af_tx_sent_jiffies)));
- if (wl_get_drv_status_all(wl, WAITING_NEXT_ACT_FRM))
- wl_clr_drv_status(wl, WAITING_NEXT_ACT_FRM, netdev);
+ if (wl_get_drv_status_all(cfg, WAITING_NEXT_ACT_FRM))
+ wl_clr_drv_status(cfg, WAITING_NEXT_ACT_FRM, ndev);
- complete(&wl->wait_next_af);
+ complete(&cfg->wait_next_af);
}
#endif /* WL_CFG80211_SYNC_GON */
#ifndef WL_CFG80211_VSDB_PRIORITIZE_SCAN_REQUEST
- if (wl_get_drv_status_all(wl, REMAINING_ON_CHANNEL)) {
+ if (wl_get_drv_status_all(cfg, REMAINING_ON_CHANNEL)) {
#else
- if (wl_get_drv_status_all(wl, REMAINING_ON_CHANNEL) ||
- wl_get_drv_status_all(wl, FAKE_REMAINING_ON_CHANNEL)) {
+ if (wl_get_drv_status_all(cfg, REMAINING_ON_CHANNEL) ||
+ wl_get_drv_status_all(cfg, FAKE_REMAINING_ON_CHANNEL)) {
#endif /* WL_CFG80211_VSDB_PRIORITIZE_SCAN_REQUEST */
WL_DBG(("Listen DONE for ramain on channel expired\n"));
- wl_clr_drv_status(wl, REMAINING_ON_CHANNEL, netdev);
+ wl_clr_drv_status(cfg, REMAINING_ON_CHANNEL, ndev);
#ifdef WL_CFG80211_VSDB_PRIORITIZE_SCAN_REQUEST
- wl_clr_drv_status(wl, FAKE_REMAINING_ON_CHANNEL, netdev);
+ wl_clr_drv_status(cfg, FAKE_REMAINING_ON_CHANNEL, ndev);
#endif /* WL_CFG80211_VSDB_PRIORITIZE_SCAN_REQUEST */
if (ndev && (ndev->ieee80211_ptr != NULL)) {
- cfg80211_remain_on_channel_expired(ndev, wl->last_roc_id,
- &wl->remain_on_chan, wl->remain_on_chan_type, GFP_KERNEL);
+#if defined(WL_CFG80211_P2P_DEV_IF)
+ cfg80211_remain_on_channel_expired(cfgdev, cfg->last_roc_id,
+ &cfg->remain_on_chan, GFP_KERNEL);
+#else
+ cfg80211_remain_on_channel_expired(cfgdev, cfg->last_roc_id,
+ &cfg->remain_on_chan, cfg->remain_on_chan_type, GFP_KERNEL);
+#endif /* WL_CFG80211_P2P_DEV_IF */
}
}
- if (wl_add_remove_eventmsg(wl_to_prmry_ndev(wl),
+ if (wl_add_remove_eventmsg(bcmcfg_to_prmry_ndev(cfg),
WLC_E_P2P_PROBREQ_MSG, false) != BCME_OK) {
CFGP2P_ERR((" failed to unset WLC_E_P2P_PROPREQ_MSG\n"));
}
} else
- wl_clr_p2p_status(wl, LISTEN_EXPIRED);
+ wl_clr_p2p_status(cfg, LISTEN_EXPIRED);
return ret;
@@ -1600,35 +1661,44 @@ void
wl_cfgp2p_listen_expired(unsigned long data)
{
wl_event_msg_t msg;
- struct wl_priv *wl = (struct wl_priv *) data;
+ struct bcm_cfg80211 *cfg = (struct bcm_cfg80211 *) data;
CFGP2P_DBG((" Enter\n"));
bzero(&msg, sizeof(wl_event_msg_t));
msg.event_type = hton32(WLC_E_P2P_DISC_LISTEN_COMPLETE);
- wl_cfg80211_event(wl->p2p_net ? wl->p2p_net :
- wl_to_p2p_bss_ndev(wl, P2PAPI_BSSCFG_DEVICE), &msg, NULL);
+#if defined(WL_ENABLE_P2P_IF)
+ wl_cfg80211_event(cfg->p2p_net ? cfg->p2p_net :
+ wl_to_p2p_bss_ndev(cfg, P2PAPI_BSSCFG_DEVICE), &msg, NULL);
+#else
+ wl_cfg80211_event(wl_to_p2p_bss_ndev(cfg, P2PAPI_BSSCFG_DEVICE), &msg,
+ NULL);
+#endif /* WL_ENABLE_P2P_IF */
}
/*
* Routine for cancelling the P2P LISTEN
*/
static s32
-wl_cfgp2p_cancel_listen(struct wl_priv *wl, struct net_device *ndev,
- bool notify)
+wl_cfgp2p_cancel_listen(struct bcm_cfg80211 *cfg, struct net_device *ndev,
+ struct wireless_dev *wdev, bool notify)
{
WL_DBG(("Enter \n"));
/* Irrespective of whether timer is running or not, reset
* the LISTEN state.
*/
#ifdef NOT_YET
- wl_cfgp2p_set_p2p_mode(wl, WL_P2P_DISC_ST_SCAN, 0, 0,
- wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_DEVICE));
+ wl_cfgp2p_set_p2p_mode(cfg, WL_P2P_DISC_ST_SCAN, 0, 0,
+ wl_to_p2p_bss_bssidx(cfg, P2PAPI_BSSCFG_DEVICE));
#endif /* NOT_YET */
- if (timer_pending(&wl->p2p->listen_timer)) {
- del_timer_sync(&wl->p2p->listen_timer);
+ if (timer_pending(&cfg->p2p->listen_timer)) {
+ del_timer_sync(&cfg->p2p->listen_timer);
if (notify)
if (ndev && ndev->ieee80211_ptr) {
- cfg80211_remain_on_channel_expired(ndev, wl->last_roc_id,
- &wl->remain_on_chan, wl->remain_on_chan_type,
- GFP_KERNEL);
+#if defined(WL_CFG80211_P2P_DEV_IF)
+ cfg80211_remain_on_channel_expired(wdev, cfg->last_roc_id,
+ &cfg->remain_on_chan, GFP_KERNEL);
+#else
+ cfg80211_remain_on_channel_expired(ndev, cfg->last_roc_id,
+ &cfg->remain_on_chan, cfg->remain_on_chan_type, GFP_KERNEL);
+#endif /* WL_CFG80211_P2P_DEV_IF */
}
}
return 0;
@@ -1640,43 +1710,43 @@ wl_cfgp2p_cancel_listen(struct wl_priv *wl, struct net_device *ndev,
*
* This fn assumes dongle p2p device discovery is already enabled.
* Parameters :
- * @wl : wl_private data
+ * @cfg : wl_private data
* @channel : channel to listen
* @duration_ms : the time (milli seconds) to wait
*/
s32
-wl_cfgp2p_discover_listen(struct wl_priv *wl, s32 channel, u32 duration_ms)
+wl_cfgp2p_discover_listen(struct bcm_cfg80211 *cfg, s32 channel, u32 duration_ms)
{
#define EXTRA_DELAY_TIME 100
s32 ret = BCME_OK;
struct timer_list *_timer;
s32 extra_delay;
- struct net_device *netdev = wl_to_prmry_ndev(wl);
+ struct net_device *netdev = bcmcfg_to_prmry_ndev(cfg);
CFGP2P_DBG((" Enter Listen Channel : %d, Duration : %d\n", channel, duration_ms));
- if (unlikely(wl_get_p2p_status(wl, DISCOVERY_ON) == 0)) {
+ if (unlikely(wl_get_p2p_status(cfg, DISCOVERY_ON) == 0)) {
CFGP2P_ERR((" Discovery is not set, so we have noting to do\n"));
ret = BCME_NOTREADY;
goto exit;
}
- if (timer_pending(&wl->p2p->listen_timer)) {
+ if (timer_pending(&cfg->p2p->listen_timer)) {
CFGP2P_DBG(("previous LISTEN is not completed yet\n"));
goto exit;
}
#ifndef WL_CFG80211_VSDB_PRIORITIZE_SCAN_REQUEST
else
- wl_clr_p2p_status(wl, LISTEN_EXPIRED);
+ wl_clr_p2p_status(cfg, LISTEN_EXPIRED);
#endif /* not WL_CFG80211_VSDB_PRIORITIZE_SCAN_REQUEST */
if (wl_add_remove_eventmsg(netdev, WLC_E_P2P_PROBREQ_MSG, true) != BCME_OK) {
CFGP2P_ERR((" failed to set WLC_E_P2P_PROPREQ_MSG\n"));
}
- ret = wl_cfgp2p_set_p2p_mode(wl, WL_P2P_DISC_ST_LISTEN, channel, (u16) duration_ms,
- wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_DEVICE));
- _timer = &wl->p2p->listen_timer;
+ ret = wl_cfgp2p_set_p2p_mode(cfg, WL_P2P_DISC_ST_LISTEN, channel, (u16) duration_ms,
+ wl_to_p2p_bss_bssidx(cfg, P2PAPI_BSSCFG_DEVICE));
+ _timer = &cfg->p2p->listen_timer;
/* We will wait to receive WLC_E_P2P_DISC_LISTEN_COMPLETE from dongle ,
* otherwise we will wait up to duration_ms + 100ms + duration / 10
@@ -1691,7 +1761,7 @@ wl_cfgp2p_discover_listen(struct wl_priv *wl, s32 channel, u32 duration_ms)
INIT_TIMER(_timer, wl_cfgp2p_listen_expired, duration_ms, extra_delay);
#ifdef WL_CFG80211_VSDB_PRIORITIZE_SCAN_REQUEST
- wl_clr_p2p_status(wl, LISTEN_EXPIRED);
+ wl_clr_p2p_status(cfg, LISTEN_EXPIRED);
#endif /* WL_CFG80211_VSDB_PRIORITIZE_SCAN_REQUEST */
#undef EXTRA_DELAY_TIME
@@ -1701,28 +1771,28 @@ exit:
s32
-wl_cfgp2p_discover_enable_search(struct wl_priv *wl, u8 enable)
+wl_cfgp2p_discover_enable_search(struct bcm_cfg80211 *cfg, u8 enable)
{
s32 ret = BCME_OK;
CFGP2P_DBG((" Enter\n"));
- if (!wl_get_p2p_status(wl, DISCOVERY_ON)) {
+ if (!wl_get_p2p_status(cfg, DISCOVERY_ON)) {
CFGP2P_DBG((" do nothing, discovery is off\n"));
return ret;
}
- if (wl_get_p2p_status(wl, SEARCH_ENABLED) == enable) {
+ if (wl_get_p2p_status(cfg, SEARCH_ENABLED) == enable) {
CFGP2P_DBG(("already : %d\n", enable));
return ret;
}
- wl_chg_p2p_status(wl, SEARCH_ENABLED);
+ wl_chg_p2p_status(cfg, SEARCH_ENABLED);
/* When disabling Search, reset the WL driver's p2p discovery state to
* WL_P2P_DISC_ST_SCAN.
*/
if (!enable) {
- wl_clr_p2p_status(wl, SCANNING);
- ret = wl_cfgp2p_set_p2p_mode(wl, WL_P2P_DISC_ST_SCAN, 0, 0,
- wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_DEVICE));
+ wl_clr_p2p_status(cfg, SCANNING);
+ ret = wl_cfgp2p_set_p2p_mode(cfg, WL_P2P_DISC_ST_SCAN, 0, 0,
+ wl_to_p2p_bss_bssidx(cfg, P2PAPI_BSSCFG_DEVICE));
}
return ret;
@@ -1732,35 +1802,36 @@ wl_cfgp2p_discover_enable_search(struct wl_priv *wl, u8 enable)
* Callback function for WLC_E_ACTION_FRAME_COMPLETE, WLC_E_ACTION_FRAME_OFF_CHAN_COMPLETE
*/
s32
-wl_cfgp2p_action_tx_complete(struct wl_priv *wl, struct net_device *ndev,
+wl_cfgp2p_action_tx_complete(struct bcm_cfg80211 *cfg, bcm_struct_cfgdev *cfgdev,
const wl_event_msg_t *e, void *data)
{
s32 ret = BCME_OK;
u32 event_type = ntoh32(e->event_type);
u32 status = ntoh32(e->status);
+ struct net_device *ndev = NULL;
CFGP2P_DBG((" Enter\n"));
- if (wl_get_drv_status_all(wl, SENDING_ACT_FRM)) {
+
+ ndev = cfgdev_to_wlc_ndev(cfgdev, cfg);
+
+ if (wl_get_drv_status_all(cfg, SENDING_ACT_FRM)) {
if (event_type == WLC_E_ACTION_FRAME_COMPLETE) {
CFGP2P_INFO((" WLC_E_ACTION_FRAME_COMPLETE is received : %d\n", status));
if (status == WLC_E_STATUS_SUCCESS) {
- wl_set_p2p_status(wl, ACTION_TX_COMPLETED);
+ wl_set_p2p_status(cfg, ACTION_TX_COMPLETED);
CFGP2P_DBG(("WLC_E_ACTION_FRAME_COMPLETE : ACK\n"));
-
}
- else {
- if (!wl_get_p2p_status(wl, ACTION_TX_COMPLETED)) {
- wl_set_p2p_status(wl, ACTION_TX_NOACK);
- CFGP2P_INFO(("WLC_E_ACTION_FRAME_COMPLETE : NO ACK\n"));
- wl_stop_wait_next_action_frame(wl, ndev);
- }
+ else if (!wl_get_p2p_status(cfg, ACTION_TX_COMPLETED)) {
+ wl_set_p2p_status(cfg, ACTION_TX_NOACK);
+ CFGP2P_INFO(("WLC_E_ACTION_FRAME_COMPLETE : NO ACK\n"));
+ wl_stop_wait_next_action_frame(cfg, ndev);
}
} else {
CFGP2P_INFO((" WLC_E_ACTION_FRAME_OFFCHAN_COMPLETE is received,"
"status : %d\n", status));
- if (wl_get_drv_status_all(wl, SENDING_ACT_FRM))
- complete(&wl->send_af_done);
+ if (wl_get_drv_status_all(cfg, SENDING_ACT_FRM))
+ complete(&cfg->send_af_done);
}
}
return ret;
@@ -1774,40 +1845,45 @@ wl_cfgp2p_action_tx_complete(struct wl_priv *wl, struct net_device *ndev,
* 802.11 ack has been received for the sent action frame.
*/
s32
-wl_cfgp2p_tx_action_frame(struct wl_priv *wl, struct net_device *dev,
+wl_cfgp2p_tx_action_frame(struct bcm_cfg80211 *cfg, struct net_device *dev,
wl_af_params_t *af_params, s32 bssidx)
{
s32 ret = BCME_OK;
+ s32 evt_ret = BCME_OK;
s32 timeout = 0;
+ wl_eventmsg_buf_t buf;
CFGP2P_INFO(("\n"));
CFGP2P_INFO(("channel : %u , dwell time : %u\n",
af_params->channel, af_params->dwell_time));
- wl_clr_p2p_status(wl, ACTION_TX_COMPLETED);
- wl_clr_p2p_status(wl, ACTION_TX_NOACK);
- if (bssidx == P2PAPI_BSSCFG_PRIMARY)
- bssidx = wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_DEVICE);
+ wl_clr_p2p_status(cfg, ACTION_TX_COMPLETED);
+ wl_clr_p2p_status(cfg, ACTION_TX_NOACK);
+
+ bzero(&buf, sizeof(wl_eventmsg_buf_t));
+ wl_cfg80211_add_to_eventbuffer(&buf, WLC_E_ACTION_FRAME_OFF_CHAN_COMPLETE, true);
+ wl_cfg80211_add_to_eventbuffer(&buf, WLC_E_ACTION_FRAME_COMPLETE, true);
+ if ((evt_ret = wl_cfg80211_apply_eventbuffer(bcmcfg_to_prmry_ndev(cfg), cfg, &buf)) < 0)
+ return evt_ret;
- wl->af_sent_channel = af_params->channel;
+ cfg->af_sent_channel = af_params->channel;
#ifdef WL_CFG80211_SYNC_GON
- wl->af_tx_sent_jiffies = jiffies;
+ cfg->af_tx_sent_jiffies = jiffies;
#endif /* WL_CFG80211_SYNC_GON */
ret = wldev_iovar_setbuf_bsscfg(dev, "actframe", af_params, sizeof(*af_params),
- wl->ioctl_buf, WLC_IOCTL_MAXLEN, bssidx, &wl->ioctl_buf_sync);
+ cfg->ioctl_buf, WLC_IOCTL_MAXLEN, bssidx, &cfg->ioctl_buf_sync);
if (ret < 0) {
-
CFGP2P_ERR((" sending action frame is failed\n"));
goto exit;
}
- timeout = wait_for_completion_timeout(&wl->send_af_done,
+ timeout = wait_for_completion_timeout(&cfg->send_af_done,
msecs_to_jiffies(af_params->dwell_time + WL_AF_TX_EXTRA_TIME_MAX));
- if (timeout > 0 && wl_get_p2p_status(wl, ACTION_TX_COMPLETED)) {
+ if (timeout >= 0 && wl_get_p2p_status(cfg, ACTION_TX_COMPLETED)) {
CFGP2P_INFO(("tx action frame operation is completed\n"));
ret = BCME_OK;
} else {
@@ -1815,11 +1891,20 @@ wl_cfgp2p_tx_action_frame(struct wl_priv *wl, struct net_device *dev,
CFGP2P_INFO(("tx action frame operation is failed\n"));
}
/* clear status bit for action tx */
- wl_clr_p2p_status(wl, ACTION_TX_COMPLETED);
- wl_clr_p2p_status(wl, ACTION_TX_NOACK);
+ wl_clr_p2p_status(cfg, ACTION_TX_COMPLETED);
+ wl_clr_p2p_status(cfg, ACTION_TX_NOACK);
exit:
CFGP2P_INFO((" via act frame iovar : status = %d\n", ret));
+
+ bzero(&buf, sizeof(wl_eventmsg_buf_t));
+ wl_cfg80211_add_to_eventbuffer(&buf, WLC_E_ACTION_FRAME_OFF_CHAN_COMPLETE, false);
+ wl_cfg80211_add_to_eventbuffer(&buf, WLC_E_ACTION_FRAME_COMPLETE, false);
+ if ((evt_ret = wl_cfg80211_apply_eventbuffer(bcmcfg_to_prmry_ndev(cfg), cfg, &buf)) < 0) {
+ WL_ERR(("TX frame events revert back failed \n"));
+ return evt_ret;
+ }
+
return ret;
}
@@ -1917,13 +2002,13 @@ wl_cfgp2p_bss_isup(struct net_device *ndev, int bsscfg_idx)
result = wldev_iovar_getbuf_bsscfg(ndev, "bss", &bsscfg_idx,
sizeof(bsscfg_idx), getbuf, sizeof(getbuf), 0, NULL);
if (result != 0) {
- CFGP2P_ERR(("'wl bss -C %d' failed: %d\n", bsscfg_idx, result));
+ CFGP2P_ERR(("'cfg bss -C %d' failed: %d\n", bsscfg_idx, result));
CFGP2P_ERR(("NOTE: this ioctl error is normal "
"when the BSS has not been created yet.\n"));
} else {
val = *(int*)getbuf;
val = dtoh32(val);
- CFGP2P_INFO(("---wl bss -C %d ==> %d\n", bsscfg_idx, val));
+ CFGP2P_INFO(("---cfg bss -C %d ==> %d\n", bsscfg_idx, val));
isup = (val ? TRUE : FALSE);
}
return isup;
@@ -1932,7 +2017,7 @@ wl_cfgp2p_bss_isup(struct net_device *ndev, int bsscfg_idx)
/* Bring up or down a BSS */
s32
-wl_cfgp2p_bss(struct wl_priv *wl, struct net_device *ndev, s32 bsscfg_idx, s32 up)
+wl_cfgp2p_bss(struct bcm_cfg80211 *cfg, struct net_device *ndev, s32 bsscfg_idx, s32 up)
{
s32 ret = BCME_OK;
s32 val = up ? 1 : 0;
@@ -1944,9 +2029,9 @@ wl_cfgp2p_bss(struct wl_priv *wl, struct net_device *ndev, s32 bsscfg_idx, s32 u
bss_setbuf.cfg = htod32(bsscfg_idx);
bss_setbuf.val = htod32(val);
- CFGP2P_INFO(("---wl bss -C %d %s\n", bsscfg_idx, up ? "up" : "down"));
+ CFGP2P_INFO(("---cfg bss -C %d %s\n", bsscfg_idx, up ? "up" : "down"));
ret = wldev_iovar_setbuf(ndev, "bss", &bss_setbuf, sizeof(bss_setbuf),
- wl->ioctl_buf, WLC_IOCTL_MAXLEN, &wl->ioctl_buf_sync);
+ cfg->ioctl_buf, WLC_IOCTL_MAXLEN, &cfg->ioctl_buf_sync);
if (ret != 0) {
CFGP2P_ERR(("'bss %d' failed with %d\n", up, ret));
@@ -1957,15 +2042,20 @@ wl_cfgp2p_bss(struct wl_priv *wl, struct net_device *ndev, s32 bsscfg_idx, s32 u
/* Check if 'p2p' is supported in the driver */
s32
-wl_cfgp2p_supported(struct wl_priv *wl, struct net_device *ndev)
+wl_cfgp2p_supported(struct bcm_cfg80211 *cfg, struct net_device *ndev)
{
s32 ret = BCME_OK;
s32 p2p_supported = 0;
ret = wldev_iovar_getint(ndev, "p2p",
&p2p_supported);
if (ret < 0) {
- CFGP2P_ERR(("wl p2p error %d\n", ret));
- return 0;
+ if (ret == BCME_UNSUPPORTED) {
+ CFGP2P_INFO(("p2p is unsupported\n"));
+ return 0;
+ } else {
+ CFGP2P_ERR(("cfg p2p error %d\n", ret));
+ return ret;
+ }
}
if (p2p_supported == 1) {
CFGP2P_INFO(("p2p is supported\n"));
@@ -1977,21 +2067,34 @@ wl_cfgp2p_supported(struct wl_priv *wl, struct net_device *ndev)
}
/* Cleanup P2P resources */
s32
-wl_cfgp2p_down(struct wl_priv *wl)
+wl_cfgp2p_down(struct bcm_cfg80211 *cfg)
{
+ struct net_device *ndev = NULL;
+ struct wireless_dev *wdev = NULL;
s32 i = 0, index = -1;
- wl_cfgp2p_cancel_listen(wl,
- wl->p2p_net ? wl->p2p_net : wl_to_prmry_ndev(wl), TRUE);
+
+#if defined(WL_CFG80211_P2P_DEV_IF)
+ ndev = bcmcfg_to_prmry_ndev(cfg);
+ wdev = bcmcfg_to_p2p_wdev(cfg);
+#elif defined(WL_ENABLE_P2P_IF)
+ ndev = cfg->p2p_net ? cfg->p2p_net : bcmcfg_to_prmry_ndev(cfg);
+ wdev = ndev_to_wdev(ndev);
+#endif /* WL_CFG80211_P2P_DEV_IF */
+
+ wl_cfgp2p_cancel_listen(cfg, ndev, wdev, TRUE);
for (i = 0; i < P2PAPI_BSSCFG_MAX; i++) {
- index = wl_to_p2p_bss_bssidx(wl, i);
+ index = wl_to_p2p_bss_bssidx(cfg, i);
if (index != WL_INVALID)
- wl_cfgp2p_clear_management_ie(wl, index);
+ wl_cfgp2p_clear_management_ie(cfg, index);
}
- wl_cfgp2p_deinit_priv(wl);
+#if defined(WL_CFG80211_P2P_DEV_IF)
+ wl_cfgp2p_del_p2p_disc_if(wdev, cfg);
+#endif /* WL_CFG80211_P2P_DEV_IF */
+ wl_cfgp2p_deinit_priv(cfg);
return 0;
}
s32
-wl_cfgp2p_set_p2p_noa(struct wl_priv *wl, struct net_device *ndev, char* buf, int len)
+wl_cfgp2p_set_p2p_noa(struct bcm_cfg80211 *cfg, struct net_device *ndev, char* buf, int len)
{
s32 ret = -1;
int count, start, duration;
@@ -2001,37 +2104,47 @@ wl_cfgp2p_set_p2p_noa(struct wl_priv *wl, struct net_device *ndev, char* buf, in
memset(&dongle_noa, 0, sizeof(dongle_noa));
- if (wl->p2p && wl->p2p->vif_created) {
+ if (cfg->p2p && cfg->p2p->vif_created) {
- wl->p2p->noa.desc[0].start = 0;
+ cfg->p2p->noa.desc[0].start = 0;
sscanf(buf, "%10d %10d %10d", &count, &start, &duration);
CFGP2P_DBG(("set_p2p_noa count %d start %d duration %d\n",
count, start, duration));
if (count != -1)
- wl->p2p->noa.desc[0].count = count;
+ cfg->p2p->noa.desc[0].count = count;
/* supplicant gives interval as start */
if (start != -1)
- wl->p2p->noa.desc[0].interval = start;
+ cfg->p2p->noa.desc[0].interval = start;
if (duration != -1)
- wl->p2p->noa.desc[0].duration = duration;
+ cfg->p2p->noa.desc[0].duration = duration;
- if (wl->p2p->noa.desc[0].count != 255) {
- wl->p2p->noa.desc[0].start = 200;
+ if (cfg->p2p->noa.desc[0].count < 255 && cfg->p2p->noa.desc[0].count > 1) {
+ cfg->p2p->noa.desc[0].start = 0;
+ dongle_noa.type = WL_P2P_SCHED_TYPE_ABS;
+ dongle_noa.action = WL_P2P_SCHED_ACTION_NONE;
+ dongle_noa.option = WL_P2P_SCHED_OPTION_TSFOFS;
+ }
+ else if (cfg->p2p->noa.desc[0].count == 1) {
+ cfg->p2p->noa.desc[0].start = 200;
dongle_noa.type = WL_P2P_SCHED_TYPE_REQ_ABS;
dongle_noa.action = WL_P2P_SCHED_ACTION_GOOFF;
dongle_noa.option = WL_P2P_SCHED_OPTION_TSFOFS;
}
+ else if (cfg->p2p->noa.desc[0].count == 0) {
+ cfg->p2p->noa.desc[0].start = 0;
+ dongle_noa.action = WL_P2P_SCHED_ACTION_RESET;
+ }
else {
/* Continuous NoA interval. */
dongle_noa.action = WL_P2P_SCHED_ACTION_NONE;
dongle_noa.type = WL_P2P_SCHED_TYPE_ABS;
- if ((wl->p2p->noa.desc[0].interval == 102) ||
- (wl->p2p->noa.desc[0].interval == 100)) {
- wl->p2p->noa.desc[0].start = 100 -
- wl->p2p->noa.desc[0].duration;
+ if ((cfg->p2p->noa.desc[0].interval == 102) ||
+ (cfg->p2p->noa.desc[0].interval == 100)) {
+ cfg->p2p->noa.desc[0].start = 100 -
+ cfg->p2p->noa.desc[0].duration;
dongle_noa.option = WL_P2P_SCHED_OPTION_BCNPCT;
}
else {
@@ -2039,20 +2152,20 @@ wl_cfgp2p_set_p2p_noa(struct wl_priv *wl, struct net_device *ndev, char* buf, in
}
}
/* Put the noa descriptor in dongle format for dongle */
- dongle_noa.desc[0].count = htod32(wl->p2p->noa.desc[0].count);
+ dongle_noa.desc[0].count = htod32(cfg->p2p->noa.desc[0].count);
if (dongle_noa.option == WL_P2P_SCHED_OPTION_BCNPCT) {
- dongle_noa.desc[0].start = htod32(wl->p2p->noa.desc[0].start);
- dongle_noa.desc[0].duration = htod32(wl->p2p->noa.desc[0].duration);
+ dongle_noa.desc[0].start = htod32(cfg->p2p->noa.desc[0].start);
+ dongle_noa.desc[0].duration = htod32(cfg->p2p->noa.desc[0].duration);
}
else {
- dongle_noa.desc[0].start = htod32(wl->p2p->noa.desc[0].start*1000);
- dongle_noa.desc[0].duration = htod32(wl->p2p->noa.desc[0].duration*1000);
+ dongle_noa.desc[0].start = htod32(cfg->p2p->noa.desc[0].start*1000);
+ dongle_noa.desc[0].duration = htod32(cfg->p2p->noa.desc[0].duration*1000);
}
- dongle_noa.desc[0].interval = htod32(wl->p2p->noa.desc[0].interval*1000);
+ dongle_noa.desc[0].interval = htod32(cfg->p2p->noa.desc[0].interval*1000);
- ret = wldev_iovar_setbuf(wl_to_p2p_bss_ndev(wl, P2PAPI_BSSCFG_CONNECTION),
- "p2p_noa", &dongle_noa, sizeof(dongle_noa), wl->ioctl_buf, WLC_IOCTL_MAXLEN,
- &wl->ioctl_buf_sync);
+ ret = wldev_iovar_setbuf(wl_to_p2p_bss_ndev(cfg, P2PAPI_BSSCFG_CONNECTION),
+ "p2p_noa", &dongle_noa, sizeof(dongle_noa), cfg->ioctl_buf,
+ WLC_IOCTL_MAXLEN, &cfg->ioctl_buf_sync);
if (ret < 0) {
CFGP2P_ERR(("fw set p2p_noa failed %d\n", ret));
@@ -2064,7 +2177,7 @@ wl_cfgp2p_set_p2p_noa(struct wl_priv *wl, struct net_device *ndev, char* buf, in
return ret;
}
s32
-wl_cfgp2p_get_p2p_noa(struct wl_priv *wl, struct net_device *ndev, char* buf, int buf_len)
+wl_cfgp2p_get_p2p_noa(struct bcm_cfg80211 *cfg, struct net_device *ndev, char* buf, int buf_len)
{
wifi_p2p_noa_desc_t *noa_desc;
@@ -2073,18 +2186,18 @@ wl_cfgp2p_get_p2p_noa(struct wl_priv *wl, struct net_device *ndev, char* buf, in
CFGP2P_DBG((" Enter\n"));
buf[0] = '\0';
- if (wl->p2p && wl->p2p->vif_created) {
- if (wl->p2p->noa.desc[0].count || wl->p2p->ops.ops) {
+ if (cfg->p2p && cfg->p2p->vif_created) {
+ if (cfg->p2p->noa.desc[0].count || cfg->p2p->ops.ops) {
_buf[0] = 1; /* noa index */
- _buf[1] = (wl->p2p->ops.ops ? 0x80: 0) |
- (wl->p2p->ops.ctw & 0x7f); /* ops + ctw */
+ _buf[1] = (cfg->p2p->ops.ops ? 0x80: 0) |
+ (cfg->p2p->ops.ctw & 0x7f); /* ops + ctw */
len += 2;
- if (wl->p2p->noa.desc[0].count) {
+ if (cfg->p2p->noa.desc[0].count) {
noa_desc = (wifi_p2p_noa_desc_t*)&_buf[len];
- noa_desc->cnt_type = wl->p2p->noa.desc[0].count;
- noa_desc->duration = wl->p2p->noa.desc[0].duration;
- noa_desc->interval = wl->p2p->noa.desc[0].interval;
- noa_desc->start = wl->p2p->noa.desc[0].start;
+ noa_desc->cnt_type = cfg->p2p->noa.desc[0].count;
+ noa_desc->duration = cfg->p2p->noa.desc[0].duration;
+ noa_desc->interval = cfg->p2p->noa.desc[0].interval;
+ noa_desc->start = cfg->p2p->noa.desc[0].start;
len += sizeof(wifi_p2p_noa_desc_t);
}
if (buf_len <= len * 2) {
@@ -2107,36 +2220,38 @@ wl_cfgp2p_get_p2p_noa(struct wl_priv *wl, struct net_device *ndev, char* buf, in
return len * 2;
}
s32
-wl_cfgp2p_set_p2p_ps(struct wl_priv *wl, struct net_device *ndev, char* buf, int len)
+wl_cfgp2p_set_p2p_ps(struct bcm_cfg80211 *cfg, struct net_device *ndev, char* buf, int len)
{
int ps, ctw;
int ret = -1;
s32 legacy_ps;
+ struct net_device *dev;
CFGP2P_DBG((" Enter\n"));
- if (wl->p2p && wl->p2p->vif_created) {
+ if (cfg->p2p && cfg->p2p->vif_created) {
sscanf(buf, "%10d %10d %10d", &legacy_ps, &ps, &ctw);
CFGP2P_DBG((" Enter legacy_ps %d ps %d ctw %d\n", legacy_ps, ps, ctw));
+ dev = wl_to_p2p_bss_ndev(cfg, P2PAPI_BSSCFG_CONNECTION);
if (ctw != -1) {
- wl->p2p->ops.ctw = ctw;
+ cfg->p2p->ops.ctw = ctw;
ret = 0;
}
if (ps != -1) {
- wl->p2p->ops.ops = ps;
- ret = wldev_iovar_setbuf(wl_to_p2p_bss_ndev(wl, P2PAPI_BSSCFG_CONNECTION),
- "p2p_ops", &wl->p2p->ops, sizeof(wl->p2p->ops),
- wl->ioctl_buf, WLC_IOCTL_MAXLEN, &wl->ioctl_buf_sync);
+ cfg->p2p->ops.ops = ps;
+ ret = wldev_iovar_setbuf(dev,
+ "p2p_ops", &cfg->p2p->ops, sizeof(cfg->p2p->ops),
+ cfg->ioctl_buf, WLC_IOCTL_MAXLEN, &cfg->ioctl_buf_sync);
if (ret < 0) {
CFGP2P_ERR(("fw set p2p_ops failed %d\n", ret));
}
}
if ((legacy_ps != -1) && ((legacy_ps == PM_MAX) || (legacy_ps == PM_OFF))) {
- ret = wldev_ioctl(wl_to_p2p_bss_ndev(wl, P2PAPI_BSSCFG_CONNECTION),
+ ret = wldev_ioctl(dev,
WLC_SET_PM, &legacy_ps, sizeof(legacy_ps), true);
- if (unlikely(ret)) {
+ if (unlikely(ret))
CFGP2P_ERR(("error (%d)\n", ret));
- }
+ wl_cfg80211_update_power_mode(dev);
}
else
CFGP2P_ERR(("ilegal setting\n"));
@@ -2200,20 +2315,47 @@ wl_cfgp2p_retreive_p2pattrib(void *buf, u8 element_id)
}
#define P2P_GROUP_CAPAB_GO_BIT 0x01
+
+u8*
+wl_cfgp2p_find_attrib_in_all_p2p_Ies(u8 *parse, u32 len, u32 attrib)
+{
+ bcm_tlv_t *ie;
+ u8* pAttrib;
+
+ CFGP2P_INFO(("Starting parsing parse %p attrib %d remaining len %d ", parse, attrib, len));
+ while ((ie = bcm_parse_tlvs(parse, (int)len, DOT11_MNG_VS_ID))) {
+ if (wl_cfgp2p_is_p2p_ie((uint8*)ie, &parse, &len) == TRUE) {
+ /* Have the P2p ie. Now check for attribute */
+ if ((pAttrib = wl_cfgp2p_retreive_p2pattrib(parse, attrib)) != NULL) {
+ CFGP2P_INFO(("P2P attribute %d was found at parse %p",
+ attrib, parse));
+ return pAttrib;
+ }
+ else {
+ parse += (ie->len + TLV_HDR_LEN);
+ len -= (ie->len + TLV_HDR_LEN);
+ CFGP2P_INFO(("P2P Attribute %d not found Moving parse"
+ " to %p len to %d", attrib, parse, len));
+ }
+ }
+ else {
+ /* It was not p2p IE. parse will get updated automatically to next TLV */
+ CFGP2P_INFO(("IT was NOT P2P IE parse %p len %d", parse, len));
+ }
+ }
+ CFGP2P_ERR(("P2P attribute %d was NOT found", attrib));
+ return NULL;
+}
+
u8 *
wl_cfgp2p_retreive_p2p_dev_addr(wl_bss_info_t *bi, u32 bi_length)
{
- wifi_p2p_ie_t * p2p_ie = NULL;
u8 *capability = NULL;
bool p2p_go = 0;
u8 *ptr = NULL;
- if (!(p2p_ie = wl_cfgp2p_find_p2pie(((u8 *) bi) + bi->ie_offset, bi->ie_length))) {
- WL_ERR(("P2P IE not found"));
- return NULL;
- }
-
- if (!(capability = wl_cfgp2p_retreive_p2pattrib(p2p_ie, P2P_SEID_P2P_INFO))) {
+ if ((capability = wl_cfgp2p_find_attrib_in_all_p2p_Ies(((u8 *) bi) + bi->ie_offset,
+ bi->ie_length, P2P_SEID_P2P_INFO)) == NULL) {
WL_ERR(("P2P Capability attribute not found"));
return NULL;
}
@@ -2225,11 +2367,13 @@ wl_cfgp2p_retreive_p2p_dev_addr(wl_bss_info_t *bi, u32 bi_length)
}
/* In probe responses, DEVICE INFO attribute will be present */
- if (!(ptr = wl_cfgp2p_retreive_p2pattrib(p2p_ie, P2P_SEID_DEV_INFO))) {
+ if (!(ptr = wl_cfgp2p_find_attrib_in_all_p2p_Ies(((u8 *) bi) + bi->ie_offset,
+ bi->ie_length, P2P_SEID_DEV_INFO))) {
/* If DEVICE_INFO is not found, this might be a beacon frame.
* check for DEVICE_ID in the beacon frame.
*/
- ptr = wl_cfgp2p_retreive_p2pattrib(p2p_ie, P2P_SEID_DEV_ID);
+ ptr = wl_cfgp2p_find_attrib_in_all_p2p_Ies(((u8 *) bi) + bi->ie_offset,
+ bi->ie_length, P2P_SEID_DEV_ID);
}
if (!ptr)
@@ -2251,37 +2395,42 @@ struct ethtool_ops cfgp2p_ethtool_ops = {
};
#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24) */
+#if defined(WL_ENABLE_P2P_IF) || defined(WL_NEWCFG_PRIVCMD_SUPPORT)
s32
-wl_cfgp2p_register_ndev(struct wl_priv *wl)
+wl_cfgp2p_register_ndev(struct bcm_cfg80211 *cfg)
{
int ret = 0;
struct net_device* net = NULL;
+#ifndef WL_NEWCFG_PRIVCMD_SUPPORT
struct wireless_dev *wdev = NULL;
+#endif /* WL_NEWCFG_PRIVCMD_SUPPORT */
uint8 temp_addr[ETHER_ADDR_LEN] = { 0x00, 0x90, 0x4c, 0x33, 0x22, 0x11 };
- if (wl->p2p_net) {
+ if (cfg->p2p_net) {
CFGP2P_ERR(("p2p_net defined already.\n"));
return -EINVAL;
}
/* Allocate etherdev, including space for private structure */
- if (!(net = alloc_etherdev(sizeof(struct wl_priv *)))) {
+ if (!(net = alloc_etherdev(sizeof(struct bcm_cfg80211 *)))) {
CFGP2P_ERR(("%s: OOM - alloc_etherdev\n", __FUNCTION__));
return -ENODEV;
}
+#ifndef WL_NEWCFG_PRIVCMD_SUPPORT
wdev = kzalloc(sizeof(*wdev), GFP_KERNEL);
if (unlikely(!wdev)) {
WL_ERR(("Could not allocate wireless device\n"));
free_netdev(net);
return -ENOMEM;
}
+#endif /* WL_NEWCFG_PRIVCMD_SUPPORT */
strncpy(net->name, "p2p%d", sizeof(net->name) - 1);
net->name[IFNAMSIZ - 1] = '\0';
- /* Copy the reference to wl_priv */
- memcpy((void *)netdev_priv(net), &wl, sizeof(struct wl_priv *));
+ /* Copy the reference to bcm_cfg80211 */
+ memcpy((void *)netdev_priv(net), &cfg, sizeof(struct bcm_cfg80211 *));
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 31))
ASSERT(!net->open);
@@ -2297,34 +2446,42 @@ wl_cfgp2p_register_ndev(struct wl_priv *wl)
/* Register with a dummy MAC addr */
memcpy(net->dev_addr, temp_addr, ETHER_ADDR_LEN);
- wdev->wiphy = wl->wdev->wiphy;
+#ifndef WL_NEWCFG_PRIVCMD_SUPPORT
+ wdev->wiphy = cfg->wdev->wiphy;
wdev->iftype = wl_mode_to_nl80211_iftype(WL_MODE_BSS);
net->ieee80211_ptr = wdev;
+#endif /* WL_NEWCFG_PRIVCMD_SUPPORT */
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24)
net->ethtool_ops = &cfgp2p_ethtool_ops;
#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24) */
+#ifndef WL_NEWCFG_PRIVCMD_SUPPORT
SET_NETDEV_DEV(net, wiphy_dev(wdev->wiphy));
/* Associate p2p0 network interface with new wdev */
wdev->netdev = net;
+#endif /* WL_NEWCFG_PRIVCMD_SUPPORT */
ret = register_netdev(net);
if (ret) {
CFGP2P_ERR((" register_netdevice failed (%d)\n", ret));
free_netdev(net);
+#ifndef WL_NEWCFG_PRIVCMD_SUPPORT
kfree(wdev);
+#endif /* WL_NEWCFG_PRIVCMD_SUPPORT */
return -ENODEV;
}
/* store p2p net ptr for further reference. Note that iflist won't have this
* entry as there corresponding firmware interface is a "Hidden" interface.
*/
- wl->p2p_wdev = wdev;
- wl->p2p_net = net;
+#ifndef WL_NEWCFG_PRIVCMD_SUPPORT
+ cfg->p2p_wdev = wdev;
+#endif /* WL_NEWCFG_PRIVCMD_SUPPORT */
+ cfg->p2p_net = net;
printk("%s: P2P Interface Registered\n", net->name);
@@ -2332,35 +2489,38 @@ wl_cfgp2p_register_ndev(struct wl_priv *wl)
}
s32
-wl_cfgp2p_unregister_ndev(struct wl_priv *wl)
+wl_cfgp2p_unregister_ndev(struct bcm_cfg80211 *cfg)
{
- if (!wl || !wl->p2p_net) {
+ if (!cfg || !cfg->p2p_net) {
CFGP2P_ERR(("Invalid Ptr\n"));
return -EINVAL;
}
- unregister_netdev(wl->p2p_net);
- free_netdev(wl->p2p_net);
+ unregister_netdev(cfg->p2p_net);
+ free_netdev(cfg->p2p_net);
return 0;
}
+
static int wl_cfgp2p_start_xmit(struct sk_buff *skb, struct net_device *ndev)
{
+
if (skb)
{
CFGP2P_DBG(("(%s) is not used for data operations.Droping the packet.\n",
ndev->name));
dev_kfree_skb_any(skb);
}
+
return 0;
}
static int wl_cfgp2p_do_ioctl(struct net_device *net, struct ifreq *ifr, int cmd)
{
int ret = 0;
- struct wl_priv *wl = *(struct wl_priv **)netdev_priv(net);
- struct net_device *ndev = wl_to_prmry_ndev(wl);
+ struct bcm_cfg80211 *cfg = *(struct bcm_cfg80211 **)netdev_priv(net);
+ struct net_device *ndev = bcmcfg_to_prmry_ndev(cfg);
/* There is no ifidx corresponding to p2p0 in our firmware. So we should
* not Handle any IOCTL cmds on p2p0 other than ANDROID PRIVATE CMDs.
@@ -2377,16 +2537,17 @@ static int wl_cfgp2p_do_ioctl(struct net_device *net, struct ifreq *ifr, int cmd
return ret;
}
+#endif /* WL_ENABLE_P2P_IF || WL_NEWCFG_PRIVCMD_SUPPORT */
+#if defined(WL_ENABLE_P2P_IF)
static int wl_cfgp2p_if_open(struct net_device *net)
{
- extern struct wl_priv *wlcfg_drv_priv;
struct wireless_dev *wdev = net->ieee80211_ptr;
- struct wl_priv *wl = NULL;
- wl = wlcfg_drv_priv;
- if (!wdev || !wl || !wl->p2p)
+
+ if (!wdev || !wl_cfg80211_is_p2p_active())
return -EINVAL;
WL_TRACE(("Enter\n"));
+#if !defined(WL_IFACE_COMB_NUM_CHANNELS)
/* If suppose F/W download (ifconfig wlan0 up) hasn't been done by now,
* do it here. This will make sure that in concurrent mode, supplicant
* is not dependent on a particular order of interface initialization.
@@ -2395,6 +2556,7 @@ static int wl_cfgp2p_if_open(struct net_device *net)
*/
wdev->wiphy->interface_modes |= (BIT(NL80211_IFTYPE_P2P_CLIENT)
| BIT(NL80211_IFTYPE_P2P_GO));
+#endif /* !WL_IFACE_COMB_NUM_CHANNELS */
wl_cfg80211_do_driver_init(net);
return 0;
@@ -2402,30 +2564,18 @@ static int wl_cfgp2p_if_open(struct net_device *net)
static int wl_cfgp2p_if_stop(struct net_device *net)
{
- extern struct wl_priv *wlcfg_drv_priv;
- struct wl_priv *wl = NULL;
- unsigned long flags;
struct wireless_dev *wdev = net->ieee80211_ptr;
- int clear_flag = 0;
+
if (!wdev)
return -EINVAL;
- WL_TRACE(("Enter\n"));
- wl = wlcfg_drv_priv;
- if (!wl)
- return -EINVAL;
- spin_lock_irqsave(&wl->cfgdrv_lock, flags);
- if (wl->scan_request && wl->scan_request->dev == net) {
- cfg80211_scan_done(wl->scan_request, true);
- wl->scan_request = NULL;
- clear_flag = 1;
- }
- spin_unlock_irqrestore(&wl->cfgdrv_lock, flags);
- if (clear_flag)
- wl_clr_drv_status(wl, SCANNING, net);
+ wl_cfg80211_scan_stop(net);
+
+#if !defined(WL_IFACE_COMB_NUM_CHANNELS)
wdev->wiphy->interface_modes = (wdev->wiphy->interface_modes)
& (~(BIT(NL80211_IFTYPE_P2P_CLIENT)|
BIT(NL80211_IFTYPE_P2P_GO)));
+#endif /* !WL_IFACE_COMB_NUM_CHANNELS */
return 0;
}
@@ -2433,3 +2583,129 @@ bool wl_cfgp2p_is_ifops(const struct net_device_ops *if_ops)
{
return (if_ops == &wl_cfgp2p_if_ops);
}
+#endif /* WL_ENABLE_P2P_IF */
+
+#if defined(WL_CFG80211_P2P_DEV_IF)
+struct wireless_dev *
+wl_cfgp2p_add_p2p_disc_if(struct bcm_cfg80211 *cfg)
+{
+ struct wireless_dev *wdev = NULL;
+ struct ether_addr primary_mac;
+
+ if (!cfg)
+ return ERR_PTR(-EINVAL);
+
+ WL_TRACE(("Enter\n"));
+
+ if (cfg->p2p_wdev) {
+ CFGP2P_ERR(("p2p_wdev defined already.\n"));
+ return ERR_PTR(-ENFILE);
+ }
+
+ wdev = kzalloc(sizeof(*wdev), GFP_KERNEL);
+ if (unlikely(!wdev)) {
+ WL_ERR(("Could not allocate wireless device\n"));
+ return ERR_PTR(-ENOMEM);
+ }
+
+ memset(&primary_mac, 0, sizeof(primary_mac));
+ get_primary_mac(cfg, &primary_mac);
+ wl_cfgp2p_generate_bss_mac(&primary_mac,
+ &cfg->p2p->dev_addr, &cfg->p2p->int_addr);
+
+ wdev->wiphy = cfg->wdev->wiphy;
+ wdev->iftype = NL80211_IFTYPE_P2P_DEVICE;
+ memcpy(wdev->address, &cfg->p2p->dev_addr, ETHER_ADDR_LEN);
+
+#if defined(WL_NEWCFG_PRIVCMD_SUPPORT)
+ if (cfg->p2p_net)
+ memcpy(cfg->p2p_net->dev_addr, &cfg->p2p->dev_addr, ETHER_ADDR_LEN);
+#endif /* WL_NEWCFG_PRIVCMD_SUPPORT */
+
+ /* store p2p wdev ptr for further reference. */
+ cfg->p2p_wdev = wdev;
+
+ CFGP2P_ERR(("P2P interface registered\n"));
+
+ return wdev;
+}
+
+int
+wl_cfgp2p_start_p2p_device(struct wiphy *wiphy, struct wireless_dev *wdev)
+{
+ int ret = 0;
+ struct bcm_cfg80211 *cfg = wiphy_priv(wiphy);
+
+ if (!cfg)
+ return -EINVAL;
+
+ WL_TRACE(("Enter\n"));
+
+ ret = wl_cfgp2p_set_firm_p2p(cfg);
+ if (unlikely(ret < 0)) {
+ CFGP2P_ERR(("Set P2P in firmware failed, ret=%d\n", ret));
+ goto exit;
+ }
+
+ ret = wl_cfgp2p_enable_discovery(cfg, bcmcfg_to_prmry_ndev(cfg), NULL, 0);
+ if (unlikely(ret < 0)) {
+ CFGP2P_ERR(("P2P enable discovery failed, ret=%d\n", ret));
+ goto exit;
+ }
+
+ p2p_on(cfg) = true;
+
+ CFGP2P_DBG(("P2P interface started\n"));
+
+exit:
+ return ret;
+}
+
+void
+wl_cfgp2p_stop_p2p_device(struct wiphy *wiphy, struct wireless_dev *wdev)
+{
+ int ret = 0;
+ struct bcm_cfg80211 *cfg = wiphy_priv(wiphy);
+
+ if (!cfg)
+ return;
+
+ WL_TRACE(("Enter\n"));
+
+ ret = wl_cfg80211_scan_stop(wdev);
+ if (unlikely(ret < 0)) {
+ CFGP2P_ERR(("P2P scan stop failed, ret=%d\n", ret));
+ }
+
+ ret = wl_cfgp2p_disable_discovery(cfg);
+ if (unlikely(ret < 0)) {
+ CFGP2P_ERR(("P2P disable discovery failed, ret=%d\n", ret));
+ }
+
+ p2p_on(cfg) = false;
+
+ CFGP2P_DBG(("P2P interface stopped\n"));
+
+ return;
+}
+
+int
+wl_cfgp2p_del_p2p_disc_if(struct wireless_dev *wdev, struct bcm_cfg80211 *cfg)
+{
+ if (!wdev)
+ return -EINVAL;
+
+ WL_TRACE(("Enter\n"));
+
+ cfg80211_unregister_wdev(wdev);
+
+ kfree(wdev);
+
+ if (cfg)
+ cfg->p2p_wdev = NULL;
+
+ CFGP2P_ERR(("P2P interface unregistered\n"));
+
+ return 0;
+}
+#endif /* WL_CFG80211_P2P_DEV_IF */