#include <osl.h>
#include <linux/kernel.h>
+#ifdef CONFIG_SYSCTL
+#include <linux/sysctl.h>
+#endif
+
#include <bcmutils.h>
#include <bcmwifi.h>
#include <bcmendian.h>
#include <bcmsdbus.h>
#include <wlioctl.h>
+#include <wldev_common.h>
#include <wl_cfg80211.h>
#include <wl_cfgp2p.h>
static struct sdio_func *cfg80211_sdio_func;
static struct wl_dev *wl_cfg80211_dev;
-u32 wl_dbg_level = WL_DBG_ERR | WL_DBG_INFO;
+u32 wl_dbg_level = WL_DBG_ERR;
#define WL_4329_FW_FILE "brcm/bcm4329-fullmac-4-218-248-5.bin"
#define WL_4329_NVRAM_FILE "brcm/bcm4329-fullmac-4-218-248-5.txt"
#define MAC2STR(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5]
#define MACSTR "%02x:%02x:%02x:%02x:%02x:%02x"
#define MAX_WAIT_TIME 3000
+static s8 ioctlbuf[WLC_IOCTL_MAXLEN];
+
+#ifdef CONFIG_SYSCTL
+#define MAC_STRING_LEN (sizeof(u8) * 17)
+u8 wl_sysctl_macstring[2][MAC_STRING_LEN];
+static ctl_table wl_sysctl_child[] = {
+ {
+ .procname = "p2p_dev_addr",
+ .data = &wl_sysctl_macstring[0],
+ .maxlen = MAC_STRING_LEN,
+ .mode = 0444,
+ .child = NULL,
+ .proc_handler = proc_dostring,
+ },
+ {
+ .procname = "p2p_int_addr",
+ .data = &wl_sysctl_macstring[1],
+ .maxlen = MAC_STRING_LEN,
+ .mode = 0444,
+ .child = NULL,
+ .proc_handler = proc_dostring,
+ },
+ {0}
+};
+static ctl_table wl_sysctl_table[] = {
+ {
+ .procname = "wifi",
+ .data = NULL,
+ .maxlen = 0,
+ .mode = 0555,
+ .child = wl_sysctl_child,
+ .proc_handler = proc_dostring,
+ },
+ {0}
+};
+static struct ctl_table_header *wl_sysctl_hdr;
+#endif /* CONFIG_SYSCTL */
/* Data Element Definitions */
#define WPS_ID_CONFIG_METHODS 0x1008
/*
* cfg80211_ops api/callback list
*/
-
+static s32 wl_frame_get_mgmt(u16 fc, const struct ether_addr *da,
+ const struct ether_addr *sa, const struct ether_addr *bssid,
+ u8 **pheader, u32 *body_len, u8 *pbody);
static s32 __wl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
struct cfg80211_scan_request *request,
struct cfg80211_ssid *this_ssid);
enum nl80211_tx_power_setting type,
s32 dbm);
static s32 wl_cfg80211_get_tx_power(struct wiphy *wiphy, s32 *dbm);
-#ifdef NEW_COMPAT_WIRELESS
static s32 wl_cfg80211_config_default_key(struct wiphy *wiphy,
struct net_device *dev,
u8 key_idx, bool unicast, bool multicast);
-#else
-static s32 wl_cfg80211_config_default_key(struct wiphy *wiphy,
- struct net_device *dev,
- u8 key_idx);
-#endif /* NEW_COMPAT_WIRELESS */
static s32 wl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *dev,
u8 key_idx, bool pairwise, const u8 *mac_addr,
struct key_params *params);
static void wl_init_event_handler(struct wl_priv *wl);
static struct wl_event_q *wl_deq_event(struct wl_priv *wl);
static s32 wl_enq_event(struct wl_priv *wl, struct net_device *ndev, u32 type,
- const wl_event_msg_t *msg, void *data);
+ const wl_event_msg_t *msg, void *data, gfp_t gfp);
static void wl_put_event(struct wl_event_q *e);
static void wl_wakeup_event(struct wl_priv *wl);
static s32 wl_notify_connect_status(struct wl_priv *wl,
static s32 wl_dev_intvar_set(struct net_device *dev, s8 *name, s32 val);
static s32 wl_dev_intvar_get(struct net_device *dev, s8 *name,
s32 *retval);
-static s32 wl_dev_ioctl(struct net_device *dev, u32 cmd, void *arg,
- u32 len);
/*
* cfg80211 set_wiphy_params utilities
/*
* ibss mode utilities
*/
-static bool wl_is_ibssmode(struct wl_priv *wl);
+static bool wl_is_ibssmode(struct wl_priv *wl, struct net_device *ndev);
static __used bool wl_is_ibssstarter(struct wl_priv *wl);
/*
* dongle up/down , default configuration utilities
*/
static bool wl_is_linkdown(struct wl_priv *wl, const wl_event_msg_t *e);
-static bool wl_is_linkup(struct wl_priv *wl, const wl_event_msg_t *e);
+static bool wl_is_linkup(struct wl_priv *wl, const wl_event_msg_t *e, struct net_device *ndev);
static bool wl_is_nonetwork(struct wl_priv *wl, const wl_event_msg_t *e);
static void wl_link_up(struct wl_priv *wl);
static void wl_link_down(struct wl_priv *wl);
-static s32 wl_dongle_mode(struct net_device *ndev, s32 iftype);
+static s32 wl_dongle_mode(struct wl_priv *wl, struct net_device *ndev, s32 iftype);
static s32 __wl_cfg80211_up(struct wl_priv *wl);
static s32 __wl_cfg80211_down(struct wl_priv *wl);
static s32 wl_dongle_probecap(struct wl_priv *wl);
* dongle configuration utilities
*/
#ifndef EMBEDDED_PLATFORM
-/* static s32 wl_dongle_mode(struct net_device *ndev, s32 iftype); */
static s32 wl_dongle_country(struct net_device *ndev, u8 ccode);
static s32 wl_dongle_up(struct net_device *ndev, u32 up);
static s32 wl_dongle_power(struct net_device *ndev, u32 power_mode);
static void wl_term_iscan(struct wl_priv *wl);
static s32 wl_init_iscan(struct wl_priv *wl);
static s32 wl_iscan_thread(void *data);
-static s32 wl_dev_iovar_setbuf(struct net_device *dev, s8 *iovar,
- void *param, s32 paramlen, void *bufptr,
- s32 buflen);
-static s32 wl_dev_iovar_getbuf(struct net_device *dev, s8 *iovar,
- void *param, s32 paramlen, void *bufptr,
- s32 buflen);
static s32 wl_run_iscan(struct wl_iscan_ctrl *iscan, struct wlc_ssid *ssid,
u16 action);
static s32 wl_do_iscan(struct wl_priv *wl);
static s32 wl_iscan_pending(struct wl_priv *wl);
static s32 wl_iscan_inprogress(struct wl_priv *wl);
static s32 wl_iscan_aborted(struct wl_priv *wl);
-#ifdef NOT_YET
-static s32 wl_dongle_save_eventmsg(struct wl_priv *wl);
-static s32 wl_dongle_disable_eventmsg(struct wl_priv *wl);
-static s32 wl_dongle_restore_eventmsg(struct wl_priv *wl);
-#endif /* NOT_YET */
+
/*
* fw/nvram downloading handler
*/
static __used s32 wl_update_pmklist(struct net_device *dev,
struct wl_pmk_list *pmk_list, s32 err);
-static void wl_set_mpc(struct net_device *ndev, int mpc);
+static void wl_set_mpc(struct net_device *ndev, s32 mpc);
/*
* debufs support
RATETAB_ENT(WLC_RATE_24M, 0),
RATETAB_ENT(WLC_RATE_36M, 0),
RATETAB_ENT(WLC_RATE_48M, 0),
- RATETAB_ENT(WLC_RATE_54M, 0),
+ RATETAB_ENT(WLC_RATE_54M, 0)
};
#define wl_a_rates (__wl_rates + 4)
CHAN2G(11, 2462, 0),
CHAN2G(12, 2467, 0),
CHAN2G(13, 2472, 0),
- CHAN2G(14, 2484, 0),
+ CHAN2G(14, 2484, 0)
};
static struct ieee80211_channel __wl_5ghz_a_channels[] = {
CHAN5G(192, 0), CHAN5G(196, 0),
CHAN5G(200, 0), CHAN5G(204, 0),
CHAN5G(208, 0), CHAN5G(212, 0),
- CHAN5G(216, 0),
+ CHAN5G(216, 0)
};
static struct ieee80211_channel __wl_5ghz_n_channels[] = {
CHAN5G(214, 0), CHAN5G(216, 0),
CHAN5G(218, 0), CHAN5G(220, 0),
CHAN5G(222, 0), CHAN5G(224, 0),
- CHAN5G(226, 0), CHAN5G(228, 0),
+ CHAN5G(226, 0), CHAN5G(228, 0)
};
static struct ieee80211_supported_band __wl_band_2ghz = {
.channels = __wl_2ghz_channels,
.n_channels = ARRAY_SIZE(__wl_2ghz_channels),
.bitrates = wl_g_rates,
- .n_bitrates = wl_g_rates_size,
+ .n_bitrates = wl_g_rates_size
};
static struct ieee80211_supported_band __wl_band_5ghz_a = {
.channels = __wl_5ghz_a_channels,
.n_channels = ARRAY_SIZE(__wl_5ghz_a_channels),
.bitrates = wl_a_rates,
- .n_bitrates = wl_a_rates_size,
+ .n_bitrates = wl_a_rates_size
};
static struct ieee80211_supported_band __wl_band_5ghz_n = {
.channels = __wl_5ghz_n_channels,
.n_channels = ARRAY_SIZE(__wl_5ghz_n_channels),
.bitrates = wl_a_rates,
- .n_bitrates = wl_a_rates_size,
+ .n_bitrates = wl_a_rates_size
};
static const u32 __wl_cipher_suites[] = {
WLAN_CIPHER_SUITE_WEP104,
WLAN_CIPHER_SUITE_TKIP,
WLAN_CIPHER_SUITE_CCMP,
- WLAN_CIPHER_SUITE_AES_CMAC,
+ WLAN_CIPHER_SUITE_AES_CMAC
};
/* There isn't a lot of sense in it, but you can transmit anything you like */
BIT(IEEE80211_STYPE_AUTH >> 4) |
BIT(IEEE80211_STYPE_DEAUTH >> 4) |
BIT(IEEE80211_STYPE_ACTION >> 4)
- },
+ }
};
static void swap_key_from_BE(struct wl_wsec_key *key)
key->iv_initialized = dtoh32(key->iv_initialized);
}
-static s32
-wl_dev_ioctl(struct net_device *dev, u32 cmd, void *arg, u32 len)
-{
- struct ifreq ifr;
- struct wl_ioctl ioc;
- mm_segment_t fs;
- s32 err = 0;
-
- memset(&ioc, 0, sizeof(ioc));
- ioc.cmd = cmd;
- ioc.buf = arg;
- ioc.len = len;
- strcpy(ifr.ifr_name, dev->name);
- ifr.ifr_data = (caddr_t)&ioc;
-
- fs = get_fs();
- set_fs(get_ds());
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 31)
- err = dev->do_ioctl(dev, &ifr, SIOCDEVPRIVATE);
-#else
- err = dev->netdev_ops->ndo_do_ioctl(dev, &ifr, SIOCDEVPRIVATE);
-#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 31) */
- set_fs(fs);
-
- return err;
-}
-
/* For debug: Dump the contents of the encoded wps ie buffe */
static void
wl_dbg_dump_wps_ie(char *wps_ie)
static struct net_device *
wl_cfg80211_add_virtual_iface(struct wiphy *wiphy, char *name,
- enum nl80211_iftype type, u32 *flags,
- struct vif_params *params)
+ enum nl80211_iftype type, u32 *flags,
+ struct vif_params *params)
{
s32 err;
s32 timeout = -1;
s32 wlif_type;
s32 index = 0;
+ s32 mode = 0;
chanspec_t chspec;
struct wl_priv *wl = WL_PRIV_GET();
struct net_device *_ndev;
case NL80211_IFTYPE_WDS:
case NL80211_IFTYPE_MESH_POINT:
WL_ERR(("Unsupported interface type\n"));
- wl->conf->mode = WL_MODE_IBSS;
+ mode = WL_MODE_IBSS;
return NULL;
case NL80211_IFTYPE_MONITOR:
return wl_to_p2p_bss_ndev(wl, P2PAPI_BSSCFG_CONNECTION);
case NL80211_IFTYPE_P2P_CLIENT:
case NL80211_IFTYPE_STATION:
- wlif_type = WL_P2P_IF_CLIENT;
- wl->conf->mode = WL_MODE_BSS;
+ wlif_type = WL_P2P_IF_CLIENT;
+ mode = WL_MODE_BSS;
break;
case NL80211_IFTYPE_P2P_GO:
case NL80211_IFTYPE_AP:
wlif_type = WL_P2P_IF_GO;
- wl->conf->mode = WL_MODE_AP;
+ mode = WL_MODE_AP;
break;
default:
WL_ERR(("Unsupported interface type\n"));
return NULL;
}
+ if (test_bit(WLP2P_STATUS_IF_DELETING, &wl->p2p_status) == 1) {
+ /* wait till IF_DEL is complete
+ * release the lock for the unregister to proceed
+ */
+ rtnl_unlock();
+ WL_INFO(("%s: Released the lock and wait till IF_DEL is complete\n", __func__));
+ timeout = wait_event_interruptible_timeout(wl->dongle_event_wait,
+ (test_bit(WLP2P_STATUS_IF_DELETING, &wl->p2p_status) == FALSE),
+ msecs_to_jiffies(MAX_WAIT_TIME));
+
+ /* put back the rtnl_lock again */
+ rtnl_lock();
+ if (timeout > 0) {
+ WL_ERR(("IF DEL is Success\n"));
+
+ } else {
+ WL_ERR(("%s: timeount < 0, return -EAGAIN\n", __func__));
+ return ERR_PTR(-EAGAIN);
+ }
+ }
if (!wl->p2p_on && strstr(name, WL_P2P_INTERFACE_PREFIX)) {
wl->p2p_on = true;
wl_cfgp2p_init_discovery(wl);
/* For P2P mode, use P2P-specific driver features to create the
* bss: "wl p2p_ifadd"
*/
- clear_bit(WLP2P_STATUS_IF_ADD, &wl->p2p_status);
+ set_bit(WLP2P_STATUS_IF_ADD, &wl->p2p_status);
err = wl_cfgp2p_ifadd(wl, &wl->p2p_int_addr, htod32(wlif_type), chspec);
if (unlikely(err))
return ERR_PTR(-ENOMEM);
timeout = wait_event_interruptible_timeout(wl->dongle_event_wait,
- (test_bit(WLP2P_STATUS_IF_ADD, &wl->p2p_status) == TRUE),
+ (test_bit(WLP2P_STATUS_IF_ADD, &wl->p2p_status) == FALSE),
msecs_to_jiffies(MAX_WAIT_TIME));
- if (timeout > 0 && test_bit(WLP2P_STATUS_IF_ADD, &wl->p2p_status)) {
+ if (timeout > 0 && (!test_bit(WLP2P_STATUS_IF_ADD, &wl->p2p_status))) {
struct wireless_dev *vwdev;
vwdev = kzalloc(sizeof(*vwdev), GFP_KERNEL);
wl->vwdev[index] = vwdev;
vwdev->iftype =
(wlif_type == WL_P2P_IF_CLIENT) ? NL80211_IFTYPE_STATION
- : NL80211_IFTYPE_AP;
+ : NL80211_IFTYPE_AP;
_ndev = wl_to_p2p_bss_ndev(wl, P2PAPI_BSSCFG_CONNECTION);
_ndev->ieee80211_ptr = vwdev;
SET_NETDEV_DEV(_ndev, wiphy_dev(vwdev->wiphy));
vwdev->netdev = _ndev;
set_bit(WL_STATUS_READY, &wl->status);
wl->p2p_vif_created = TRUE;
+ set_mode_by_netdev(wl, _ndev, mode);
wl = wdev_to_wl(vwdev);
return _ndev;
-
} else {
clear_bit(WLP2P_STATUS_IF_ADD, &wl->p2p_status);
WL_ERR((" virtual interface(%s) is not created \n", wl->p2p_vir_ifname));
wl_cfg80211_scan_abort(wl, dev);
}
wl_cfgp2p_ifdel(wl, &p2p_mac);
+ WL_ERR(("ifdel command sent to Firmware.. "
+ "and we just come out without waiting.."));
+ set_bit(WLP2P_STATUS_IF_DELETING, &wl->p2p_status);
}
static s32
wl_cfg80211_change_virtual_iface(struct wiphy *wiphy, struct net_device *ndev,
- enum nl80211_iftype type, u32 *flags,
- struct vif_params *params)
+ enum nl80211_iftype type, u32 *flags,
+ struct vif_params *params)
{
s32 ap = 0;
s32 infra = 0;
s32 err = BCME_OK;
- chanspec_t chspec;
s32 timeout = -1;
s32 wlif_type;
+ s32 mode = 0;
+ chanspec_t chspec;
struct wl_priv *wl = WL_PRIV_GET();
CHECK_SYS_UP();
switch (type) {
type));
break;
case NL80211_IFTYPE_ADHOC:
- wl->conf->mode = WL_MODE_IBSS;
+ mode = WL_MODE_IBSS;
break;
case NL80211_IFTYPE_STATION:
case NL80211_IFTYPE_P2P_CLIENT:
- wl->conf->mode = WL_MODE_BSS;
+ mode = WL_MODE_BSS;
infra = 1;
break;
case NL80211_IFTYPE_AP:
case NL80211_IFTYPE_AP_VLAN:
case NL80211_IFTYPE_P2P_GO:
- wl->conf->mode = WL_MODE_AP;
+ mode = WL_MODE_AP;
ap = 1;
break;
default:
timeout = wait_event_interruptible_timeout(wl->dongle_event_wait,
(test_bit(WLP2P_STATUS_IF_CHANGED, &wl->p2p_status) == TRUE),
msecs_to_jiffies(MAX_WAIT_TIME));
-
+ set_mode_by_netdev(wl, ndev, mode);
clear_bit(WLP2P_STATUS_IF_CHANGING, &wl->p2p_status);
clear_bit(WLP2P_STATUS_IF_CHANGED, &wl->p2p_status);
}
}
WL_DBG(("IF_ADD event called from dongle, old interface name: %s, new name: %s\n",
- net->name, wl->p2p_vir_ifname));
+ net->name, wl->p2p_vir_ifname));
/* Assign the net device to CONNECT BSSCFG */
strncpy(net->name, wl->p2p_vir_ifname, IFNAMSIZ - 1);
wl_to_p2p_bss_ndev(wl, P2PAPI_BSSCFG_CONNECTION) = net;
wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_CONNECTION) = P2PAPI_BSSCFG_CONNECTION;
- set_bit(WLP2P_STATUS_IF_ADD, &wl->p2p_status);
+ clear_bit(WLP2P_STATUS_IF_ADD, &wl->p2p_status);
wake_up_interruptible(&wl->dongle_event_wait);
return ret;
}
}
WL_DBG(("IF_DEL event called from dongle, _net name: %s, vif name: %s\n",
- net->name, wl->p2p_vir_ifname));
+ net->name, wl->p2p_vir_ifname));
if (wl->p2p_vif_created) {
s32 index = 0;
memset(wl->p2p_vir_ifname, '\0', IFNAMSIZ);
wl_to_p2p_bss_ndev(wl, index) = NULL;
wl_to_p2p_bss_bssidx(wl, index) = 0;
wl->p2p_vif_created = FALSE;
+ set_mode_by_netdev(wl, net, -1);
wl_cfgp2p_clear_management_ie(wl,
index);
index = get_idx_vwdev_by_netdev(wl, net);
if (index >= 0) {
free_vwdev_by_index(wl, index);
}
+ /* Another option.. Make the IF_ADD wait, if the IF_DEL is not complete.. */
+ clear_bit(WLP2P_STATUS_IF_DELETING, &wl->p2p_status);
+ WL_ERR(("Cleared IF_DELETING status bit\n"));
+ wake_up_interruptible(&wl->dongle_event_wait);
+ WL_ERR(("Cleared IF_DELETING status bit DONE WAKEUP Interruptible\n"));
}
return 0;
}
+s32
+wl_cfg80211_is_progress_ifadd(void)
+{
+ s32 is_progress = 0;
+ struct wl_priv *wl = WL_PRIV_GET();
+ if (test_bit(WLP2P_STATUS_IF_ADD, &wl->p2p_status))
+ is_progress = 1;
+ return is_progress;
+}
s32
wl_cfg80211_is_progress_ifchange(void)
}
-static s32
-wl_dev_iovar_setbuf(struct net_device *dev, s8 * iovar, void *param,
- s32 paramlen, void *bufptr, s32 buflen)
-{
- s32 iolen;
-
- iolen = bcm_mkiovar(iovar, param, paramlen, bufptr, buflen);
- BUG_ON(unlikely(!iolen));
-
- return wl_dev_ioctl(dev, WLC_SET_VAR, bufptr, iolen);
-}
-
-static s32
-wl_dev_iovar_getbuf(struct net_device *dev, s8 * iovar, void *param,
- s32 paramlen, void *bufptr, s32 buflen)
-{
- s32 iolen;
-
- iolen = bcm_mkiovar(iovar, param, paramlen, bufptr, buflen);
- BUG_ON(unlikely(!iolen));
-
- return wl_dev_ioctl(dev, WLC_GET_VAR, bufptr, buflen);
-}
-
static s32
wl_run_iscan(struct wl_iscan_ctrl *iscan, struct wlc_ssid *ssid, u16 action)
{
s32 params_size =
- (WL_SCAN_PARAMS_FIXED_SIZE + offsetof(wl_iscan_params_t, params));
+ (WL_SCAN_PARAMS_FIXED_SIZE + offsetof(wl_iscan_params_t, params));
struct wl_iscan_params *params;
s32 err = 0;
if (ssid && ssid->SSID_len)
- params_size += sizeof(struct wlc_ssid);
+ params_size += sizeof(struct wlc_ssid);
params = (struct wl_iscan_params *)kzalloc(params_size, GFP_KERNEL);
if (unlikely(!params))
- return -ENOMEM;
+ return -ENOMEM;
memset(params, 0, params_size);
BUG_ON(unlikely(params_size >= WLC_IOCTL_SMLEN));
params->scan_duration = htod16(0);
/* params_size += offsetof(wl_iscan_params_t, params); */
- err = wl_dev_iovar_setbuf(iscan->dev, "iscan", params, params_size,
+ err = wldev_iovar_setbuf(iscan->dev, "iscan", params, params_size,
iscan->ioctl_buf, WLC_IOCTL_SMLEN);
if (unlikely(err)) {
- if (err == -EBUSY) {
+ if (err == -EBUSY) {
WL_INFO(("system busy : iscan canceled\n"));
} else {
- WL_ERR(("error (%d)\n", err));
+ WL_ERR(("error (%d)\n", err));
}
}
kfree(params);
iscan->state = WL_ISCAN_STATE_SCANING;
passive_scan = wl->active_scan ? 0 : 1;
- err = wl_dev_ioctl(ndev, WLC_SET_PASSIVE_SCAN,
- &passive_scan, sizeof(passive_scan));
+ err = wldev_ioctl(ndev, WLC_SET_PASSIVE_SCAN,
+ &passive_scan, sizeof(passive_scan), FALSE);
if (unlikely(err)) {
WL_DBG(("error (%d)\n", err));
return err;
params->version = htod32(ESCAN_REQ_VERSION);
params->action = htod16(action);
params->sync_id = htod16(0x1234);
- wl_dev_iovar_setbuf(ndev, "escan", params, params_size,
- wl->escan_ioctl_buf, WLC_IOCTL_MEDLEN);
+ wldev_iovar_setbuf(ndev, "escan", params, params_size,
+ wl->escan_ioctl_buf, WLC_IOCTL_MEDLEN);
kfree(params);
}
else if (wl->p2p_on && wl->p2p_scan) {
num_chans = scan_request->n_channels;
WL_INFO((" chann number : %d\n", num_chans));
default_chan_list = kzalloc(num_chans * sizeof(*default_chan_list),
- GFP_KERNEL);
+ GFP_KERNEL);
if (default_chan_list == NULL) {
WL_ERR(("channel list allocation failed \n"));
err = -ENOMEM;
{
default_chan_list[i] =
ieee80211_frequency_to_channel(
- scan_request->channels[i]->center_freq);
+ scan_request->channels[i]->center_freq);
}
if (num_chans == 3 && (
(default_chan_list[0] == SOCIAL_CHAN_1) &&
}
}
- err = wl_cfgp2p_escan(wl, wl->active_scan, num_chans, default_chan_list,
- search_state, action,
+ err = wl_cfgp2p_escan(wl, ndev, wl->active_scan, num_chans, default_chan_list,
+ search_state, action,
wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_DEVICE));
kfree(default_chan_list);
}
wl->escan_info.wiphy = wiphy;
wl->escan_info.escan_state = WL_ESCAN_STATE_SCANING;
passive_scan = wl->active_scan ? 0 : 1;
- err = wl_dev_ioctl(ndev, WLC_SET_PASSIVE_SCAN,
- &passive_scan, sizeof(passive_scan));
+ err = wldev_ioctl(ndev, WLC_SET_PASSIVE_SCAN,
+ &passive_scan, sizeof(passive_scan), FALSE);
if (unlikely(err)) {
WL_DBG(("error (%d)\n", err));
return err;
if (wl->p2p_on && wl->p2p_scan) {
- err = wl_cfgp2p_enable_discovery(wl, request->ie, request->ie_len);
+ err = wl_cfgp2p_enable_discovery(wl, ndev, request->ie, request->ie_len);
if (unlikely(err)) {
goto scan_out;
}
WL_DBG(("sr->ssid.SSID_len (%d)\n", sr->ssid.SSID_len));
passive_scan = wl->active_scan ? 0 : 1;
- err = wl_dev_ioctl(ndev, WLC_SET_PASSIVE_SCAN,
- &passive_scan, sizeof(passive_scan));
+ err = wldev_ioctl(ndev, WLC_SET_PASSIVE_SCAN,
+ &passive_scan, sizeof(passive_scan), FALSE);
if (unlikely(err)) {
WL_ERR(("WLC_SET_PASSIVE_SCAN error (%d)\n", err));
goto scan_out;
}
wl_set_mpc(ndev, 0);
- err = wl_dev_ioctl(ndev, WLC_SCAN, &sr->ssid,
- sizeof(sr->ssid));
+ err = wldev_ioctl(ndev, WLC_SCAN, &sr->ssid,
+ sizeof(sr->ssid), FALSE);
if (err) {
if (err == -EBUSY) {
WL_INFO(("system busy : scan for \"%s\" "
len = bcm_mkiovar(name, (char *)(&val), sizeof(val), buf, sizeof(buf));
BUG_ON(unlikely(!len));
- err = wl_dev_ioctl(dev, WLC_SET_VAR, buf, len);
+ err = wldev_ioctl(dev, WLC_SET_VAR, buf, len, FALSE);
if (unlikely(err)) {
WL_ERR(("error (%d)\n", err));
}
len = bcm_mkiovar(name, (char *)(&data_null), 0,
(char *)(&var), sizeof(var.buf));
BUG_ON(unlikely(!len));
- err = wl_dev_ioctl(dev, WLC_GET_VAR, &var, len);
+ err = wldev_ioctl(dev, WLC_GET_VAR, &var, len, FALSE);
if (unlikely(err)) {
WL_ERR(("error (%d)\n", err));
}
u32 cmd = (l ? WLC_SET_LRL : WLC_SET_SRL);
retry = htod32(retry);
- err = wl_dev_ioctl(dev, cmd, &retry, sizeof(retry));
+ err = wldev_ioctl(dev, cmd, &retry, sizeof(retry), FALSE);
if (unlikely(err)) {
WL_ERR(("cmd (%d) , error (%d)\n", cmd, err));
return err;
CHECK_SYS_UP();
if (changed & WIPHY_PARAM_RTS_THRESHOLD &&
- (wl->conf->rts_threshold != wiphy->rts_threshold)) {
+ (wl->conf->rts_threshold != wiphy->rts_threshold)) {
wl->conf->rts_threshold = wiphy->rts_threshold;
err = wl_set_rts(ndev, wl->conf->rts_threshold);
if (!err)
return err;
}
if (changed & WIPHY_PARAM_FRAG_THRESHOLD &&
- (wl->conf->frag_threshold != wiphy->frag_threshold)) {
+ (wl->conf->frag_threshold != wiphy->frag_threshold)) {
wl->conf->frag_threshold = wiphy->frag_threshold;
err = wl_set_frag(ndev, wl->conf->frag_threshold);
if (!err)
ssid.ssid_len = params->ssid_len;
do {
if (unlikely
- (__wl_cfg80211_scan(wiphy, dev, NULL, &ssid) ==
- -EBUSY)) {
+ (__wl_cfg80211_scan(wiphy, dev, NULL, &ssid) ==
+ -EBUSY)) {
wl_delay(150);
} else {
break;
}
} while (++scan_retry < WL_SCAN_RETRY_MAX);
- /* to allow scan_inform to paropagate to cfg80211 plane */
+ /* to allow scan_inform to propagate to cfg80211 plane */
rtnl_unlock();
/* wait 4 secons till scan done.... */
else
memset(&join_params.params.bssid, 0, ETHER_ADDR_LEN);
- err = wl_dev_ioctl(dev, WLC_SET_SSID, &join_params,
- sizeof(join_params));
+ err = wldev_ioctl(dev, WLC_SET_SSID, &join_params,
+ sizeof(join_params), FALSE);
if (unlikely(err)) {
WL_ERR(("Error (%d)\n", err));
return err;
val = WPA_AUTH_DISABLED;
WL_DBG(("setting wpa_auth to 0x%0x\n", val));
- err = wl_cfgp2p_bssiovar_setint(dev, "wpa_auth", bssidx, val);
+ err = wldev_iovar_setint_bsscfg(dev, "wpa_auth", val, bssidx);
if (unlikely(err)) {
WL_ERR(("set wpa_auth failed (%d)\n", err));
return err;
break;
}
- err = wl_cfgp2p_bssiovar_setint(dev, "auth", bssidx, val);
+ err = wldev_iovar_setint_bsscfg(dev, "auth", val, bssidx);
if (unlikely(err)) {
WL_ERR(("set auth failed (%d)\n", err));
return err;
WL_DBG(("pval (%d) gval (%d)\n", pval, gval));
if (is_wps_conn(sme)) {
- err = wl_cfgp2p_bssiovar_setint(dev, "wsec", bssidx, 4);
+ err = wldev_iovar_setint_bsscfg(dev, "wsec", 4, bssidx);
} else {
- err = wl_cfgp2p_bssiovar_setint(dev, "wsec", bssidx, pval | gval);
+ err = wldev_iovar_setint_bsscfg(dev, "wsec", pval | gval, bssidx);
}
if (unlikely(err)) {
WL_ERR(("error (%d)\n", err));
WL_DBG(("setting wpa_auth to %d\n", val));
- err = wl_cfgp2p_bssiovar_setint(dev, "wpa_auth", bssidx, val);
+ err = wldev_iovar_setint_bsscfg(dev, "wpa_auth", val, bssidx);
if (unlikely(err)) {
WL_ERR(("could not set wpa_auth (%d)\n", err));
return err;
key.len, key.index, key.algo));
WL_DBG(("key \"%s\"\n", key.data));
swap_key_from_BE(&key);
- err = wl_cfgp2p_bssiovar_set(dev, "wsec_key", bssidx, &key, sizeof(key));
+ err = wldev_iovar_setbuf_bsscfg(dev, "wsec_key", &key, sizeof(key),
+ ioctlbuf, sizeof(ioctlbuf), bssidx);
if (unlikely(err)) {
WL_ERR(("WLC_SET_KEY error (%d)\n", err));
return err;
if (sec->auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM) {
WL_DBG(("set auth_type to shared key\n"));
val = 1; /* shared key */
- err = wl_cfgp2p_bssiovar_setint(dev, "auth", bssidx, val);
+ err = wldev_iovar_setint_bsscfg(dev, "auth", val, bssidx);
if (unlikely(err)) {
WL_ERR(("set auth failed (%d)\n", err));
return err;
s32 err = 0;
WL_TRACE(("In\n"));
+ CHECK_SYS_UP();
if (IS_P2P_SSID(sme->ssid) && (dev != wl_to_prmry_ndev(wl))) {
/* we only allow to connect using virtual interface in case of P2P */
if (wl->p2p_on && is_wps_conn(sme)) {
-
WL_DBG(("p2p index : %d\n", wl_cfgp2p_find_idx(wl, dev)));
/* Have to apply WPS IE + P2P IE in assoc req frame */
wl_cfgp2p_set_managment_ie(wl, dev,
P2PAPI_BSSCFG_DEVICE).p2p_probe_req_ie_len);
wl_cfgp2p_set_managment_ie(wl, dev, wl_cfgp2p_find_idx(wl, dev),
VNDR_IE_ASSOCREQ_FLAG, sme->ie, sme->ie_len);
+ } else if (wl->p2p_on && (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2)) {
+ /* This is the connect req after WPS is done [credentials exchanged]
+ * currently identified with WPA_VERSION_2 .
+ * Update the previously set IEs with
+ * the newly received IEs from Supplicant. This will remove the WPS IE from
+ * the Assoc Req.
+ */
+ wl_cfgp2p_set_managment_ie(wl, dev, wl_cfgp2p_find_idx(wl, dev),
+ VNDR_IE_ASSOCREQ_FLAG, sme->ie, sme->ie_len);
}
+
} else {
WL_ERR(("No P2PIE in beacon \n"));
}
-
- CHECK_SYS_UP();
if (unlikely(!sme->ssid)) {
WL_ERR(("Invalid ssid\n"));
return -EOPNOTSUPP;
WL_ERR(("ssid \"%s\", len (%d)\n", join_params.ssid.SSID,
join_params.ssid.SSID_len));
}
- err = wl_dev_ioctl(dev, WLC_SET_SSID, &join_params, join_params_size);
+ err = wldev_ioctl(dev, WLC_SET_SSID, &join_params, join_params_size, FALSE);
if (unlikely(err)) {
WL_ERR(("error (%d)\n", err));
return err;
scbval.val = reason_code;
memcpy(&scbval.ea, &wl->bssid, ETHER_ADDR_LEN);
scbval.val = htod32(scbval.val);
- err = wl_dev_ioctl(dev, WLC_DISASSOC, &scbval,
- sizeof(scb_val_t));
+ err = wldev_ioctl(dev, WLC_DISASSOC, &scbval,
+ sizeof(scb_val_t), FALSE);
if (unlikely(err)) {
WL_ERR(("error (%d)\n", err));
return err;
/* Make sure radio is off or on as far as software is concerned */
disable = WL_RADIO_SW_DISABLE << 16;
disable = htod32(disable);
- err = wl_dev_ioctl(ndev, WLC_SET_RADIO, &disable, sizeof(disable));
+ err = wldev_ioctl(ndev, WLC_SET_RADIO, &disable, sizeof(disable), FALSE);
if (unlikely(err)) {
WL_ERR(("WLC_SET_RADIO error (%d)\n", err));
return err;
return err;
}
-#ifdef NEW_COMPAT_WIRELESS
-static s32 wl_cfg80211_config_default_key(struct wiphy *wiphy,
- struct net_device *dev,
+static s32
+wl_cfg80211_config_default_key(struct wiphy *wiphy, struct net_device *dev,
u8 key_idx, bool unicast, bool multicast)
-#else
-static s32 wl_cfg80211_config_default_key(struct wiphy *wiphy,
- struct net_device *dev,
- u8 key_idx)
-#endif /* NEW_COMPAT_WIRELESS */
{
struct wl_priv *wl = WL_PRIV_GET();
u32 index;
WL_DBG(("key index (%d)\n", key_idx));
CHECK_SYS_UP();
- /* TODO: wl_cfgp2p_bssiovar_get seems to have a problem here
- * roll back to old way
- err = wl_cfgp2p_bssiovar_get(dev, "wsec", bssidx, &wsec, sizeof(wsec));
- */
- UNUSED_PARAMETER(bssidx);
- err = wl_dev_ioctl(dev, WLC_GET_WSEC, &wsec, sizeof(wsec));
+ err = wldev_iovar_getint_bsscfg(dev, "wsec", &wsec, bssidx);
if (unlikely(err)) {
WL_ERR(("WLC_GET_WSEC error (%d)\n", err));
return err;
}
- wsec = dtoh32(wsec);
if (wsec & WEP_ENABLED) {
/* Just select a new current key */
index = (u32) key_idx;
index = htod32(index);
- err = wl_dev_ioctl(dev, WLC_SET_KEY_PRIMARY, &index,
- sizeof(index));
+ err = wldev_ioctl(dev, WLC_SET_KEY_PRIMARY, &index,
+ sizeof(index), FALSE);
if (unlikely(err)) {
WL_ERR(("error (%d)\n", err));
}
if (key.len == 0) {
/* key delete */
swap_key_from_BE(&key);
- wl_cfgp2p_bssiovar_set(dev, "wsec_key", bssidx, &key, sizeof(key));
+ wldev_iovar_setbuf_bsscfg(dev, "wsec_key", &key, sizeof(key), ioctlbuf,
+ sizeof(ioctlbuf), bssidx);
if (unlikely(err)) {
WL_ERR(("key delete error (%d)\n", err));
return err;
u8 *ivptr;
ivptr = (u8 *) params->seq;
key.rxiv.hi = (ivptr[5] << 24) | (ivptr[4] << 16) |
- (ivptr[3] << 8) | ivptr[2];
+ (ivptr[3] << 8) | ivptr[2];
key.rxiv.lo = (ivptr[1] << 8) | ivptr[0];
key.iv_initialized = true;
}
#ifdef CONFIG_WIRELESS_EXT
dhd_wait_pend8021x(dev);
#endif
- wl_cfgp2p_bssiovar_set(dev, "wsec_key", bssidx, &key, sizeof(key));
+ wldev_iovar_setbuf_bsscfg(dev, "wsec_key", &key, sizeof(key), ioctlbuf,
+ sizeof(ioctlbuf), bssidx);
if (unlikely(err)) {
WL_ERR(("WLC_SET_KEY error (%d)\n", err));
return err;
bssidx = wl_cfgp2p_find_idx(wl, dev);
if (mac_addr) {
-#if defined(P2P_CONFLICT_GONE)
wl_add_keyext(wiphy, dev, key_idx, mac_addr, params);
goto exit;
-#else
- return wl_add_keyext(wiphy, dev, key_idx, mac_addr, params);
-#endif /* defined(P2P_CONFLICT_GONE) */
}
memset(&key, 0, sizeof(key));
/* Set the new key/index */
swap_key_from_BE(&key);
- err = wl_cfgp2p_bssiovar_set(dev, "wsec_key", bssidx, &key, sizeof(key));
+ err = wldev_iovar_setbuf_bsscfg(dev, "wsec_key", &key, sizeof(key), ioctlbuf,
+ sizeof(ioctlbuf), bssidx);
if (unlikely(err)) {
WL_ERR(("WLC_SET_KEY error (%d)\n", err));
return err;
}
-#if defined(P2P_CONFLICT_GONE)
+
exit:
-#endif
- val = WEP_ENABLED;
- err = wl_cfgp2p_bssiovar_get(dev, "wsec", bssidx, &wsec, sizeof(wsec));
+ err = wldev_iovar_getint_bsscfg(dev, "wsec", &wsec, bssidx);
if (unlikely(err)) {
WL_ERR(("get wsec error (%d)\n", err));
return err;
}
- wsec &= ~(WEP_ENABLED);
+
wsec |= val;
- err = wl_cfgp2p_bssiovar_setint(dev, "wsec", bssidx, wsec);
+ err = wldev_iovar_setint_bsscfg(dev, "wsec", wsec, bssidx);
if (unlikely(err)) {
WL_ERR(("set wsec error (%d)\n", err));
return err;
/* TODO: Removed in P2P, check later --lm */
val = 1; /* assume shared key. otherwise 0 */
val = htod32(val);
- err = wl_dev_ioctl(dev, WLC_SET_AUTH, &val, sizeof(val));
+ err = wldev_ioctl(dev, WLC_SET_AUTH, &val, sizeof(val), FALSE);
if (unlikely(err)) {
WL_ERR(("WLC_SET_AUTH error (%d)\n", err));
return err;
struct wl_wsec_key key;
struct wl_priv *wl = WL_PRIV_GET();
s32 err = 0;
- s32 val;
- s32 wsec = 0;
s32 bssidx = wl_cfgp2p_find_idx(wl, dev);
WL_DBG(("Enter\n"));
WL_DBG(("key index (%d)\n", key_idx));
/* Set the new key/index */
swap_key_from_BE(&key);
- wl_cfgp2p_bssiovar_set(dev, "wsec_key", bssidx, &key, sizeof(key));
+ wldev_iovar_setbuf_bsscfg(dev, "wsec_key", &key, sizeof(key), ioctlbuf,
+ sizeof(ioctlbuf), bssidx);
if (unlikely(err)) {
if (err == -EINVAL) {
if (key.index >= DOT11_MAX_DEFAULT_KEYS) {
return err;
}
- val = 0;
- err = wl_cfgp2p_bssiovar_get(dev, "wsec", bssidx, &wsec, sizeof(wsec));
- if (unlikely(err)) {
- WL_ERR(("get wsec error (%d)\n", err));
- return err;
- }
-
- wsec &= ~(WEP_ENABLED);
- wsec |= val;
- err = wl_cfgp2p_bssiovar_setint(dev, "wsec", bssidx, wsec);
- if (unlikely(err)) {
- WL_ERR(("set wsec error (%d)\n", err));
- return err;
- }
-
#ifdef NOT_YET
/* TODO: Removed in P2P twig, check later --lin */
val = 0; /* assume open key. otherwise 1 */
val = htod32(val);
- err = wl_dev_ioctl(dev, WLC_SET_AUTH, &val, sizeof(val));
+ err = wldev_ioctl(dev, WLC_SET_AUTH, &val, sizeof(val), FALSE);
if (unlikely(err)) {
WL_ERR(("WLC_SET_AUTH error (%d)\n", err));
return err;
params.key_len = (u8) min_t(u8, DOT11_MAX_KEY_SIZE, key.len);
memcpy(params.key, key.data, params.key_len);
- wl_cfgp2p_bssiovar_get(dev, "wsec", bssidx, &wsec, sizeof(wsec));
+ wldev_iovar_getint_bsscfg(dev, "wsec", &wsec, bssidx);
if (unlikely(err)) {
WL_ERR(("WLC_GET_WSEC error (%d)\n", err));
return err;
}
- wsec = dtoh32(wsec);
switch (wsec) {
case WEP_ENABLED:
sec = wl_read_prof(wl, WL_PROF_SEC);
CHECK_SYS_UP();
if (unlikely
- (memcmp(mac, wl_read_prof(wl, WL_PROF_BSSID), ETHER_ADDR_LEN))) {
+ (memcmp(mac, wl_read_prof(wl, WL_PROF_BSSID), ETHER_ADDR_LEN))) {
WL_ERR(("Wrong Mac address\n"));
return -ENOENT;
}
/* Report the current tx rate */
- err = wl_dev_ioctl(dev, WLC_GET_RATE, &rate, sizeof(rate));
+ err = wldev_ioctl(dev, WLC_GET_RATE, &rate, sizeof(rate), FALSE);
if (err) {
WL_ERR(("Could not get rate (%d)\n", err));
} else {
if (test_bit(WL_STATUS_CONNECTED, &wl->status)) {
memset(&scb_val, 0, sizeof(scb_val));
scb_val.val = 0;
- err = wl_dev_ioctl(dev, WLC_GET_RSSI, &scb_val,
- sizeof(scb_val_t));
+ err = wldev_ioctl(dev, WLC_GET_RSSI, &scb_val,
+ sizeof(scb_val_t), FALSE);
if (unlikely(err)) {
WL_ERR(("Could not get rssi (%d)\n", err));
return err;
}
#if defined(ANDROID_WIRELESS_PATCH)
- err = wl_dev_ioctl(dev, WLC_GET_RATE, &sinfo->link_speed, sizeof(sinfo->link_speed));
+ err = wldev_ioctl(dev, WLC_GET_RATE, &sinfo->link_speed, sizeof(sinfo->link_speed), FALSE);
sinfo->link_speed = sinfo->link_speed / 2; /* Convert internal 500Kbps to Mpbs */
if (!err)
sinfo->filled |= STATION_LINK_SPEED;
pm = enabled ? PM_FAST : PM_OFF;
pm = htod32(pm);
WL_DBG(("power save %s\n", (pm ? "enabled" : "disabled")));
- err = wl_dev_ioctl(dev, WLC_SET_PM, &pm, sizeof(pm));
+ err = wldev_ioctl(dev, WLC_SET_PM, &pm, sizeof(pm), FALSE);
if (unlikely(err)) {
if (err == -ENODEV)
WL_DBG(("net_device is not ready yet\n"));
CHECK_SYS_UP();
/* addr param is always NULL. ignore it */
/* Get current rateset */
- err = wl_dev_ioctl(dev, WLC_GET_CURR_RATESET, &rateset,
- sizeof(rateset));
+ err = wldev_ioctl(dev, WLC_GET_CURR_RATESET, &rateset,
+ sizeof(rateset), FALSE);
if (unlikely(err)) {
WL_ERR(("could not get current rateset (%d)\n", err));
return err;
err = -ENOMEM;
}
/* Do a scan abort to stop the driver's scan engine */
- err = wl_dev_ioctl(ndev, WLC_SCAN, params, params_size);
+ err = wldev_ioctl(ndev, WLC_SCAN, params, params_size, FALSE);
if (err < 0) {
WL_ERR(("scan abort failed \n"));
}
- clear_bit(WL_STATUS_SCANNING, &wl->status);
+ /* Report the scan abort to CFG driver too
+ * We will report it from the thread context, not from this context.
+ */
- if (wl->p2p_on && test_bit(WLP2P_STATUS_SCANNING, &wl->p2p_status))
- clear_bit(WLP2P_STATUS_SCANNING, &wl->p2p_status);
+ {
+ wl_event_msg_t msg;
+ msg.event_type = hton32(WLC_E_ESCAN_RESULT);
+ msg.status = WLC_E_STATUS_ABORT;
+ wl_cfg80211_event(ndev, &msg, NULL, GFP_ATOMIC);
+ }
return err;
}
static s32
* without turning on P2P
*/
- err = wl_cfgp2p_enable_discovery(wl, NULL, 0);
+ err = wl_cfgp2p_enable_discovery(wl, dev, NULL, 0);
if (unlikely(err)) {
goto exit;
u32 p2pie_len = 0;
u32 wpsie_len = 0;
u16 fc;
+ bool ack = FALSE;
WL_DBG(("Enter \n"));
/* find bssidx based on ndev */
bssidx = wl_cfgp2p_find_idx(wl, dev);
+ /* cookie generation */
+ *cookie = (unsigned long) buf;
if (bssidx == -1) {
* channel.
*/
wl_cfgp2p_discover_enable_search(wl, FALSE);
+ /* Abort the dwell time of any previous off-channel action frame that may
+ * be still in effect. Sending off-channel action frames relies on the
+ * driver's scan engine. If a previous off-channel action frame tx is
+ * still in progress (including the dwell time), then this new action
+ * frame will not be sent out.
+ */
+ wl_cfg80211_scan_abort(wl, dev);
}
mgmt = (const struct ieee80211_mgmt *) buf;
fc = mgmt->frame_control;
- switch (fc & IEEE80211_FCTL_STYPE) {
- case IEEE80211_STYPE_ASSOC_REQ:
- WL_DBG(("packet type: IEEE80211_STYPE_ASSOC_REQ, bssidx : %d\n", bssidx));
- break;
- case IEEE80211_STYPE_ASSOC_RESP:
- WL_DBG(("packet type: IEEE80211_STYPE_ASSOC_RESP, bssidx : %d\n", bssidx));
- break;
- case IEEE80211_STYPE_REASSOC_REQ:
- WL_DBG(("packet type: IEEE80211_STYPE_REASSOC_REQ, bssidx : %d\n", bssidx));
- break;
- case IEEE80211_STYPE_REASSOC_RESP:
- WL_DBG(("packet type: IEEE80211_STYPE_REASSOC_RESP, bssidx : %d\n", bssidx));
- break;
- case IEEE80211_STYPE_PROBE_REQ:
- WL_DBG(("packet type: IEEE80211_STYPE_PROBE_REQ, bssidx : %d\n", bssidx));
- break;
- case IEEE80211_STYPE_PROBE_RESP:
- WL_DBG(("packet type: IEEE80211_STYPE_PROBE_RESP, bssidx : %d\n", bssidx));
- break;
- case IEEE80211_STYPE_BEACON:
- WL_DBG(("packet type: IEEE80211_STYPE_BEACON, bssidx : %d\n", bssidx));
- break;
- case IEEE80211_STYPE_ATIM:
- WL_DBG(("packet type: IEEE80211_STYPE_ATIM, bssidx : %d\n", bssidx));
- break;
- case IEEE80211_STYPE_DISASSOC:
- WL_DBG(("packet type: IEEE80211_STYPE_DISASSOC, bssidx : %d\n", bssidx));
- break;
- case IEEE80211_STYPE_AUTH:
- WL_DBG(("packet type: IEEE80211_STYPE_AUTH, bssidx : %d\n", bssidx));
- break;
- case IEEE80211_STYPE_DEAUTH:
- WL_DBG(("packet type: IEEE80211_STYPE_DEAUTH, bssidx : %d\n", bssidx));
- break;
- case IEEE80211_STYPE_ACTION:
- WL_DBG(("packet type: IEEE80211_STYPE_ACTION, bssidx : %d\n", bssidx));
- break;
- }
if (fc != IEEE80211_STYPE_ACTION) {
if (wl->p2p_on && (fc == IEEE80211_STYPE_PROBE_RESP)) {
s32 ie_offset = DOT11_MGMT_HDR_LEN + DOT11_BCN_PRB_FIXED_LEN;
/* Have to change p2p device address in dev_info attribute
* because Supplicant use primary eth0 address
*/
+ #ifdef ENABLE_DRIVER_CHANGE_IFADDR /* We are now doing this in supplicant */
wl_cfg80211_change_ifaddr((u8 *)p2p_ie,
&wl->p2p_dev_addr, P2P_SEID_DEV_INFO);
+ #endif
}
if ((wps_ie = wl_cfgp2p_find_wpsie((u8 *)(buf + ie_offset), ie_len))
!= NULL) {
* Dwell time to stay off-channel to wait for a response action frame
* after transmitting an GO Negotiation action frame
*/
- af_params->dwell_time = 200;
+ af_params->dwell_time = WL_DWELL_TIME;
memcpy(action_frame->data, &buf[DOT11_MGMT_HDR_LEN], action_frame->len);
wifi_p2p_pub_act_frame_t *act_frm =
(wifi_p2p_pub_act_frame_t *) (action_frame->data);
/*
- * Have to change intented address from GO REQ or GO RSP
+ * Have to change intented address from GO REQ or GO RSP and INVITE REQ
* because wpa-supplicant use eth0 primary address
*/
- if (act_frm->subtype == P2P_PAF_GON_REQ || act_frm->subtype == P2P_PAF_GON_RSP) {
+ if ((act_frm->subtype == P2P_PAF_GON_REQ)||
+ (act_frm->subtype == P2P_PAF_GON_RSP)||
+ (act_frm->subtype == P2P_PAF_GON_CONF)||
+ (act_frm->subtype == P2P_PAF_INVITE_REQ)) {
p2p_ie = wl_cfgp2p_find_p2pie(act_frm->elts,
action_frame->len - P2P_PUB_AF_FIXED_LEN);
+ #ifdef ENABLE_DRIVER_CHANGE_IFADDR /* We are now doing this in supplicant */
wl_cfg80211_change_ifaddr((u8 *)p2p_ie, &wl->p2p_int_addr,
P2P_SEID_INTINTADDR);
wl_cfg80211_change_ifaddr((u8 *)p2p_ie, &wl->p2p_dev_addr,
P2P_SEID_DEV_INFO);
+ wl_cfg80211_change_ifaddr((u8 *)p2p_ie, &wl->p2p_dev_addr,
+ P2P_SEID_GROUP_ID);
+ #endif
}
}
- err = wl_cfgp2p_tx_action_frame(wl, af_params, bssidx);
- cfg80211_mgmt_tx_status(dev, *cookie, buf, len, true, GFP_KERNEL);
+ ack = (wl_cfgp2p_tx_action_frame(wl, dev, af_params, bssidx)) ? FALSE : TRUE;
+ cfg80211_mgmt_tx_status(dev, *cookie, buf, len, ack, GFP_KERNEL);
kfree(af_params);
exit:
channel = ieee80211_frequency_to_channel(chan->center_freq);
WL_DBG(("netdev_ifidx(%d), chan_type(%d) target channel(%d) \n",
dev->ifindex, channel_type, channel));
- wl_dev_ioctl(dev, WLC_SET_CHANNEL, &channel, sizeof(channel));
+ wldev_ioctl(dev, WLC_SET_CHANNEL, &channel, sizeof(channel), FALSE);
return err;
}
break;
}
/* set auth */
- err = wl_cfgp2p_bssiovar_setint(dev, "auth", bssidx, auth);
+ err = wldev_iovar_setint_bsscfg(dev, "auth", auth, bssidx);
if (err < 0) {
WL_ERR(("auth error %d\n", err));
}
/* set wsec */
- err = wl_cfgp2p_bssiovar_setint(dev, "wsec", bssidx, wsec);
+ err = wldev_iovar_setint_bsscfg(dev, "wsec", wsec, bssidx);
if (err < 0) {
WL_ERR(("wsec error %d\n", err));
}
/* set upper-layer auth */
- err = wl_cfgp2p_bssiovar_setint(dev, "wpa_auth", bssidx, wpa_auth);
+ err = wldev_iovar_setint_bsscfg(dev, "wpa_auth", wpa_auth, bssidx);
if (err < 0) {
WL_ERR(("wpa_auth error %d\n", err));
}
WL_DBG(("interval (%d) dtim_period (%d) head_len (%d) tail_len (%d)\n",
info->interval, info->dtim_period, info->head_len, info->tail_len));
+
+ /*
+ * !!! The following code was NOT indented properly, PLEASE merge your code
+ * to SVN verion becuase your merger tool may IGNORE tabs/spaces
+ */
if (wl->p2p_on && (bssidx >= wl_to_p2p_bss_bssidx(wl,
P2PAPI_BSSCFG_CONNECTION))) {
- /* We don't need to set beacon for P2P_GO,
- * but need to parse ssid from beacon_parameters
- * because there is no way to set ssid
- */
- ie_offset = DOT11_MGMT_HDR_LEN + DOT11_BCN_PRB_FIXED_LEN;
- /* find the SSID */
- if ((ssid_ie = bcm_parse_tlvs((u8 *)&info->head[ie_offset], info->head_len - ie_offset,
- DOT11_MNG_SSID_ID)) != NULL) {
- memcpy(wl->p2p_ssid.SSID, ssid_ie->data, ssid_ie->len);
- wl->p2p_ssid.SSID_len = ssid_ie->len;
- WL_DBG(("SSID (%s) in Head \n", ssid_ie->data));
+ /* We don't need to set beacon for P2P_GO,
+ * but need to parse ssid from beacon_parameters
+ * because there is no way to set ssid
+ */
+ ie_offset = DOT11_MGMT_HDR_LEN + DOT11_BCN_PRB_FIXED_LEN;
+ /* find the SSID */
+ if ((ssid_ie = bcm_parse_tlvs((u8 *)&info->head[ie_offset],
+ info->head_len - ie_offset,
+ DOT11_MNG_SSID_ID)) != NULL) {
+ memcpy(wl->p2p_ssid.SSID, ssid_ie->data, ssid_ie->len);
+ wl->p2p_ssid.SSID_len = ssid_ie->len;
+ WL_DBG(("SSID (%s) in Head \n", ssid_ie->data));
- } else {
- WL_ERR(("No SSID in beacon \n"));
- }
+ } else {
+ WL_ERR(("No SSID in beacon \n"));
+ }
- /* find the WPSIE */
- if ((wps_ie = wl_cfgp2p_find_wpsie((u8 *)info->tail, info->tail_len)) != NULL) {
- wpsie_len = wps_ie->length + sizeof(wps_ie->tag) + sizeof(wps_ie->length);
- /*
- * Should be compared with saved ie before saving it
- */
+ /* find the WPSIE */
+ if ((wps_ie = wl_cfgp2p_find_wpsie((u8 *)info->tail, info->tail_len)) != NULL) {
+ wpsie_len = wps_ie->length + sizeof(wps_ie->tag) + sizeof(wps_ie->length);
+ /*
+ * Should be compared with saved ie before saving it
+ */
if (wl_dbg_level & WL_DBG_INFO)
wl_dbg_dump_wps_ie((char *) wps_ie);
- memcpy(beacon_ie, wps_ie, wpsie_len);
- } else {
- WL_ERR(("No WPSIE in beacon \n"));
- }
+ memcpy(beacon_ie, wps_ie, wpsie_len);
+ } else {
+ WL_ERR(("No WPSIE in beacon \n"));
+ }
- /* find the P2PIE */
- if ((p2p_ie = wl_cfgp2p_find_p2pie((u8 *)info->tail, info->tail_len)) != NULL) {
- /* Total length of P2P Information Element */
- p2pie_len = p2p_ie->len + sizeof(p2p_ie->len) + sizeof(p2p_ie->id);
- /* Have to change device address in dev_id attribute because Supplicant
- * use primary eth0 address
- */
- wl_cfg80211_change_ifaddr((u8 *)p2p_ie, &wl->p2p_dev_addr, P2P_SEID_DEV_ID);
- memcpy(&beacon_ie[wpsie_len], p2p_ie, p2pie_len);
+ /* find the P2PIE */
+ if ((p2p_ie = wl_cfgp2p_find_p2pie((u8 *)info->tail, info->tail_len)) != NULL) {
+ /* Total length of P2P Information Element */
+ p2pie_len = p2p_ie->len + sizeof(p2p_ie->len) + sizeof(p2p_ie->id);
+ #ifdef ENABLE_DRIVER_CHANGE_IFADDR /* We are now doing this in supplicant */
+ /* Have to change device address in dev_id attribute because Supplicant
+ * use primary eth0 address
+ */
+ wl_cfg80211_change_ifaddr((u8 *)p2p_ie, &wl->p2p_dev_addr, P2P_SEID_DEV_ID);
+ #endif
+ memcpy(&beacon_ie[wpsie_len], p2p_ie, p2pie_len);
- } else {
- WL_ERR(("No P2PIE in beacon \n"));
- }
+ } else {
+ WL_ERR(("No P2PIE in beacon \n"));
+ }
wl_cfgp2p_set_managment_ie(wl, dev, bssidx, VNDR_IE_BEACON_FLAG,
- beacon_ie, wpsie_len + p2pie_len);
+ beacon_ie, wpsie_len + p2pie_len);
wl_cfgp2p_set_managment_ie(wl, dev, bssidx, VNDR_IE_ASSOCRSP_FLAG,
- beacon_ie, wpsie_len + p2pie_len);
+ beacon_ie, wpsie_len + p2pie_len);
/* find the WPA_IE */
if ((wpa_ie = wl_cfgp2p_find_wpaie((u8 *)info->tail, info->tail_len)) != NULL) {
WL_DBG((" WPA IE is found\n"));
}
/* find the RSN_IE */
if ((wpa2_ie = bcm_parse_tlvs((u8 *)info->tail, info->tail_len,
- DOT11_MNG_RSN_ID)) != NULL) {
+ DOT11_MNG_RSN_ID)) != NULL) {
WL_DBG((" WPA2 IE is found\n"));
}
is_bssup = wl_cfgp2p_bss_isup(dev, bssidx);
wl_check_wpa2ie(dev, wpa2_ie, bssidx);
wl_check_wpaie(dev, (bcm_tlv_t *)wpa_ie, bssidx);
- err = wl_dev_ioctl(dev, WLC_SET_INFRA, &infra, sizeof(s32));
- if (err < 0) {
+ err = wldev_ioctl(dev, WLC_SET_INFRA, &infra, sizeof(s32), FALSE);
+ if (err < 0) {
WL_ERR(("SET INFRA error %d\n", err));
- }
+ }
- err = wl_cfgp2p_bssiovar_set(dev, "ssid", bssidx, &wl->p2p_ssid,
- sizeof(wl->p2p_ssid));
+ err = wldev_iovar_setbuf_bsscfg(dev, "ssid", &wl->p2p_ssid,
+ sizeof(wl->p2p_ssid), ioctlbuf, sizeof(ioctlbuf), bssidx);
- wl_cfgp2p_bss(dev, bssidx, 1);
- }
+ wl_cfgp2p_bss(dev, bssidx, 1);
+ }
}
return 0;
}
.set_beacon = wl_cfg80211_set_beacon,
#if defined(ANDROID_WIRELESS_PATCH)
.drv_start = wl_cfg80211_drv_start,
- .drv_stop = wl_cfg80211_drv_stop,
+ .drv_stop = wl_cfg80211_drv_stop
#endif
};
wdev->wiphy->max_scan_ssids = WL_NUM_SCAN_MAX;
wdev->wiphy->max_num_pmkids = WL_NUM_PMKIDS_MAX;
wdev->wiphy->interface_modes =
- BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_ADHOC) | BIT(NL80211_IFTYPE_AP) |
- (BIT(NL80211_IFTYPE_P2P_CLIENT) | BIT(NL80211_IFTYPE_P2P_GO));
+ BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_ADHOC) | BIT(NL80211_IFTYPE_AP);
+
wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &__wl_band_2ghz;
wdev->wiphy->bands[IEEE80211_BAND_5GHZ] = &__wl_band_5ghz_a;
wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
wdev->wiphy->cipher_suites = __wl_cipher_suites;
wdev->wiphy->n_cipher_suites = ARRAY_SIZE(__wl_cipher_suites);
-#ifdef NEW_COMPAT_WIRELESS
wdev->wiphy->max_remain_on_channel_duration = 5000;
-#endif
wdev->wiphy->mgmt_stypes = wl_cfg80211_default_mgmt_stypes;
#ifndef WL_POWERSAVE_DISABLED
wdev->wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT;
#else
wdev->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
#endif /* !WL_POWERSAVE_DISABLED */
-
+ wdev->wiphy->flags |= WIPHY_FLAG_NETNS_OK |
+ WIPHY_FLAG_4ADDR_AP |
+ WIPHY_FLAG_4ADDR_STATION |
+ WIPHY_FLAG_SUPPORTS_SEPARATE_DEFAULT_KEYS;
err = wiphy_register(wdev->wiphy);
if (unlikely(err < 0)) {
WL_ERR(("Couldn not register wiphy device (%d)\n", err));
static s32 wl_inform_single_bss(struct wl_priv *wl, struct wl_bss_info *bi)
{
- struct wiphy *wiphy = wl_to_wiphy(wl);
+ struct wiphy *wiphy = wiphy_from_scan(wl);
struct ieee80211_mgmt *mgmt;
struct ieee80211_channel *channel;
struct ieee80211_supported_band *band;
offsetof(struct wl_cfg80211_bss_info, frame_buf));
notif_bss_info->frame_len = offsetof(struct ieee80211_mgmt,
u.beacon.variable) + wl_get_ielen(wl);
+#if LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 38) && !defined(COMPAT_WIRELESS)
+ freq = ieee80211_channel_to_frequency(notif_bss_info->channel);
+#else
freq = ieee80211_channel_to_frequency(notif_bss_info->channel, band->band);
+#endif
channel = ieee80211_get_channel(wiphy, freq);
WL_DBG(("SSID : \"%s\", rssi %d, channel %d, capability : 0x04%x, bssid %pM\n",
return err;
}
-static bool wl_is_linkup(struct wl_priv *wl, const wl_event_msg_t *e)
+static bool wl_is_linkup(struct wl_priv *wl, const wl_event_msg_t *e, struct net_device *ndev)
{
- /* To SK, chagne NOT_YET to 1 if you don't like this
- * But in general WLC_E_SET_SSID is more reliable --lin
- */
-#ifdef NOT_YET
- u32 event = ntoh32(e->event_type);
- u16 flags = ntoh16(e->flags);
-
- if (event == WLC_E_LINK) {
- if (flags & WLC_EVENT_MSG_LINK) {
- if (wl_is_ibssmode(wl)) {
- if (wl_is_ibssstarter(wl)) {
- }
- } else {
- return true;
- }
- }
- }
- return false;
-#else
u32 event = ntoh32(e->event_type);
uint32 status = ntoh32(e->status);
- WL_DBG(("event %d\n", event));
- /* was WLC_E_LINK here, changed as WLC_E_SET_SSID is more reliable -- lin */
+ WL_DBG(("event %d, status %d\n", event, status));
if (event == WLC_E_SET_SSID) {
if (status == WLC_E_STATUS_SUCCESS) {
- if (!wl_is_ibssmode(wl))
+ if (!wl_is_ibssmode(wl, ndev))
return true;
}
}
WL_DBG(("wl_is_linkup false\n"));
return false;
-#endif /* NOT_YET */
}
static bool wl_is_linkdown(struct wl_priv *wl, const wl_event_msg_t *e)
return false;
}
-static bool wl_is_newsta(struct wl_priv *wl, const wl_event_msg_t *e)
-{
- u32 event = ntoh32(e->event_type);
- u32 status = ntoh32(e->status);
-
- if (event == WLC_E_ASSOC_IND && (status == WLC_E_STATUS_SUCCESS)) {
- return true;
- }
- return false;
-}
-
static s32
wl_notify_connect_status(struct wl_priv *wl, struct net_device *ndev,
const wl_event_msg_t *e, void *data)
{
bool act;
+ bool isfree = FALSE;
s32 err = 0;
+ s32 freq;
+ s32 channel;
u8 body[200];
+ u32 event = ntoh32(e->event_type);
+ u32 reason = ntoh32(e->reason);
+ u32 len = ntoh32(e->datalen);
+ u16 fc = 0;
+ u8 *mgmt_frame;
+ u8 bsscfgidx = e->bsscfgidx;
+ struct ieee80211_supported_band *band;
+ struct ether_addr da;
+ struct ether_addr bssid;
+ struct wiphy *wiphy = wl_to_wiphy(wl);
+ channel_info_t ci;
+ memset(body, 0, sizeof(body));
WL_DBG(("Enter \n"));
- if (wl->conf->mode == WL_MODE_AP) {
- if (wl_is_newsta(wl, e)) {
- u32 len = ntoh32(e->datalen);
- memcpy(body, e->addr.octet, ETHER_ADDR_LEN);
- memcpy(&body[ETHER_ADDR_LEN], data, len);
- cfg80211_send_rx_assoc(ndev, body, len + ETHER_ADDR_LEN);
+ if (get_mode_by_netdev(wl, ndev) == WL_MODE_AP) {
+ memcpy(body, data, len);
+ wldev_iovar_getbuf_bsscfg(ndev, "cur_etheraddr",
+ &da, sizeof(struct ether_addr), ioctlbuf, sizeof(ioctlbuf), bsscfgidx);
+ wldev_ioctl(ndev, WLC_GET_BSSID, &bssid, ETHER_ADDR_LEN, FALSE);
+ switch (event) {
+ case WLC_E_ASSOC_IND:
+ fc = FC_ASSOC_REQ;
+ break;
+ case WLC_E_REASSOC_IND:
+ fc = FC_REASSOC_REQ;
+ break;
+ case WLC_E_DISASSOC_IND:
+ fc = FC_DISASSOC;
+ break;
+ case WLC_E_DEAUTH_IND:
+ fc = FC_DEAUTH;
+ break;
+ case WLC_E_DEAUTH:
+ fc = FC_DEAUTH;
+ break;
+ default:
+ fc = 0;
+ goto exit;
}
+ if ((err = wldev_ioctl(ndev, WLC_GET_CHANNEL, &ci, sizeof(ci), FALSE)))
+ return err;
+
+ channel = dtoh32(ci.hw_channel);
+ if (channel <= CH_MAX_2G_CHANNEL)
+ band = wiphy->bands[IEEE80211_BAND_2GHZ];
+ else
+ band = wiphy->bands[IEEE80211_BAND_5GHZ];
+
+#if LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 38) && !defined(COMPAT_WIRELESS)
+ freq = ieee80211_channel_to_frequency(channel);
+#else
+ freq = ieee80211_channel_to_frequency(channel, band->band);
+#endif
+
+ err = wl_frame_get_mgmt(fc, &da, &e->addr, &bssid,
+ &mgmt_frame, &len, body);
+ if (err < 0)
+ goto exit;
+ isfree = TRUE;
+
+ if (event == WLC_E_ASSOC_IND && reason == DOT11_SC_SUCCESS) {
+ cfg80211_rx_mgmt(ndev, freq, mgmt_frame, len, GFP_ATOMIC);
+ } else if (event == WLC_E_DISASSOC_IND) {
+ cfg80211_rx_mgmt(ndev, freq, mgmt_frame, len, GFP_ATOMIC);
+ } else if ((event == WLC_E_DEAUTH_IND) || (event == WLC_E_DEAUTH)) {
+ cfg80211_rx_mgmt(ndev, freq, mgmt_frame, len, GFP_ATOMIC);
+ }
+
} else {
- WL_ERR(("event %d ", ntoh32(e->event_type)));
- if (wl_is_linkup(wl, e)) {
+ WL_DBG(("wl_notify_connect_status : event %d status : %d \n",
+ ntoh32(e->event_type), ntoh32(e->status)));
+ if (wl_is_linkup(wl, e, ndev)) {
wl_link_up(wl);
- if (wl_is_ibssmode(wl)) {
+ if (wl_is_ibssmode(wl, ndev)) {
printk("cfg80211_ibss_joined");
cfg80211_ibss_joined(ndev, (s8 *)&e->addr,
GFP_KERNEL);
wl_update_prof(wl, e, &act, WL_PROF_ACT);
} else if (wl_is_linkdown(wl, e)) {
if (test_bit(WL_STATUS_CONNECTED, &wl->status)) {
- printk("link down, call cfg80211_disconnected");
+ printk("link down, call cfg80211_disconnected ");
cfg80211_disconnected(ndev, 0, NULL, 0, GFP_KERNEL);
clear_bit(WL_STATUS_CONNECTED, &wl->status);
wl_link_down(wl);
wl_init_prof(wl->profile);
}
} else if (wl_is_nonetwork(wl, e)) {
- printk("connect failed wl->status 0x%x", (int)wl->status);
+ printk("connect failed e->status 0x%x", (int)ntoh32(e->status));
if (test_bit(WL_STATUS_CONNECTING, &wl->status))
wl_bss_connect_done(wl, ndev, e, data, false);
} else {
}
printk("\n");
}
+exit:
+ if (isfree)
+ kfree(mgmt_frame);
return err;
}
buflen = bcm_mkiovar(name, buf, len, wl->ioctl_buf, WL_IOCTL_LEN_MAX);
BUG_ON(unlikely(!buflen));
- return wl_dev_ioctl(dev, WLC_SET_VAR, wl->ioctl_buf, buflen);
+ return wldev_ioctl(dev, WLC_SET_VAR, wl->ioctl_buf, buflen, FALSE);
}
static s32
len = bcm_mkiovar(name, NULL, 0, wl->ioctl_buf, WL_IOCTL_LEN_MAX);
BUG_ON(unlikely(!len));
- err = wl_dev_ioctl(dev, WLC_GET_VAR, (void *)wl->ioctl_buf,
- WL_IOCTL_LEN_MAX);
+ err = wldev_ioctl(dev, WLC_GET_VAR, (void *)wl->ioctl_buf,
+ WL_IOCTL_LEN_MAX, FALSE);
if (unlikely(err)) {
WL_ERR(("error (%d)\n", err));
return err;
static s32 wl_get_assoc_ies(struct wl_priv *wl, struct net_device *ndev)
{
- struct wl_assoc_ielen *assoc_info;
+ wl_assoc_info_t assoc_info;
struct wl_connect_info *conn_info = wl_to_conn(wl);
- u32 req_len;
- u32 resp_len;
s32 err = 0;
WL_DBG(("Enter \n"));
WL_ERR(("could not get assoc info (%d)\n", err));
return err;
}
- assoc_info = (struct wl_assoc_ielen *)wl->extra_buf;
- req_len = assoc_info->req_len;
- resp_len = assoc_info->resp_len;
- if (req_len) {
+ memcpy(&assoc_info, wl->extra_buf, sizeof(wl_assoc_info_t));
+ assoc_info.req_len = htod32(assoc_info.req_len);
+ assoc_info.resp_len = htod32(assoc_info.resp_len);
+ assoc_info.flags = htod32(assoc_info.flags);
+ if (assoc_info.req_len) {
err = wl_dev_bufvar_get(ndev, "assoc_req_ies", wl->extra_buf,
WL_ASSOC_INFO_MAX);
if (unlikely(err)) {
WL_ERR(("could not get assoc req (%d)\n", err));
return err;
}
- conn_info->req_ie_len = req_len;
+ conn_info->req_ie_len = assoc_info.req_len - sizeof(struct dot11_assoc_req);
+ if (assoc_info.flags & WLC_ASSOC_REQ_IS_REASSOC) {
+ conn_info->req_ie_len -= ETHER_ADDR_LEN;
+ }
conn_info->req_ie =
kmemdup(wl->extra_buf, conn_info->req_ie_len, GFP_KERNEL);
} else {
conn_info->req_ie_len = 0;
conn_info->req_ie = NULL;
}
- if (resp_len) {
+ if (assoc_info.resp_len) {
err = wl_dev_bufvar_get(ndev, "assoc_resp_ies", wl->extra_buf,
WL_ASSOC_INFO_MAX);
if (unlikely(err)) {
WL_ERR(("could not get assoc resp (%d)\n", err));
return err;
}
- conn_info->resp_ie_len = resp_len;
+ conn_info->resp_ie_len = assoc_info.resp_len -sizeof(struct dot11_assoc_resp);
conn_info->resp_ie =
kmemdup(wl->extra_buf, conn_info->resp_ie_len, GFP_KERNEL);
} else {
}
static void wl_ch_to_chanspec(int ch, struct wl_join_params *join_params,
- size_t *join_params_size)
+ size_t *join_params_size)
{
chanspec_t chanspec = 0;
WL_DBG(("%s join_params->params.chanspec_list[0]= %X\n",
__FUNCTION__, join_params->params.chanspec_list[0]));
+
}
}
struct wiphy *wiphy;
wiphy = wl_to_wiphy(wl);
- if (wl_is_ibssmode(wl))
+ if (wl_is_ibssmode(wl, ndev))
return err;
ssid = (struct wlc_ssid *)wl_read_prof(wl, WL_PROF_SSID);
if (unlikely(!bss)) {
WL_DBG(("Could not find the AP\n"));
*(u32 *) wl->extra_buf = htod32(WL_EXTRA_BUF_MAX);
- err = wl_dev_ioctl(wl_to_prmry_ndev(wl), WLC_GET_BSS_INFO,
- wl->extra_buf, WL_EXTRA_BUF_MAX);
+ err = wldev_ioctl(wl_to_prmry_ndev(wl), WLC_GET_BSS_INFO,
+ wl->extra_buf, WL_EXTRA_BUF_MAX, FALSE);
if (unlikely(err)) {
WL_ERR(("Could not get bss info %d\n", err));
goto update_bss_info_out;
* information out of probe response.
* so we speficially query dtim information to dongle.
*/
- err = wl_dev_ioctl(wl_to_prmry_ndev(wl), WLC_GET_DTIMPRD,
- &dtim_period, sizeof(dtim_period));
+ err = wldev_ioctl(wl_to_prmry_ndev(wl), WLC_GET_DTIMPRD,
+ &dtim_period, sizeof(dtim_period), FALSE);
if (unlikely(err)) {
WL_ERR(("WLC_GET_DTIMPRD error (%d)\n", err));
goto update_bss_info_out;
if (unlikely(!wl->scan_request)) {
}
rtnl_lock();
- err = wl_dev_ioctl(ndev, WLC_GET_CHANNEL, &channel_inform,
- sizeof(channel_inform));
+ err = wldev_ioctl(ndev, WLC_GET_CHANNEL, &channel_inform,
+ sizeof(channel_inform), FALSE);
if (unlikely(err)) {
WL_ERR(("scan busy (%d)\n", err));
goto scan_done_out;
bss_list = wl->bss_list;
memset(bss_list, 0, len);
bss_list->buflen = htod32(len);
- err = wl_dev_ioctl(ndev, WLC_SCAN_RESULTS, bss_list, len);
+ err = wldev_ioctl(ndev, WLC_SCAN_RESULTS, bss_list, len, FALSE);
if (unlikely(err)) {
WL_ERR(("%s Scan_results error (%d)\n", ndev->name, err));
err = -EINVAL;
rtnl_unlock();
return err;
}
+static s32
+wl_frame_get_mgmt(u16 fc, const struct ether_addr *da,
+ const struct ether_addr *sa, const struct ether_addr *bssid,
+ u8 **pheader, u32 *body_len, u8 *pbody)
+{
+ struct dot11_management_header *hdr;
+ u32 totlen = 0;
+ s32 err = 0;
+ u8 *offset;
+ u32 prebody_len = *body_len;
+ switch (fc) {
+ case FC_ASSOC_REQ:
+ /* capability , listen interval */
+ totlen = DOT11_ASSOC_REQ_FIXED_LEN;
+ *body_len += DOT11_ASSOC_REQ_FIXED_LEN;
+ break;
+ case FC_REASSOC_REQ:
+ /* capability, listen inteval, ap address */
+ totlen = DOT11_REASSOC_REQ_FIXED_LEN;
+ *body_len += DOT11_REASSOC_REQ_FIXED_LEN;
+ break;
+ }
+ totlen += DOT11_MGMT_HDR_LEN + prebody_len;
+ *pheader = kzalloc(totlen, GFP_KERNEL);
+ if (*pheader == NULL) {
+ WL_ERR(("memory alloc failed \n"));
+ return -ENOMEM;
+ }
+ hdr = (struct dot11_management_header *) (*pheader);
+ hdr->fc = htol16(fc);
+ hdr->durid = 0;
+ hdr->seq = 0;
+ offset = (u8*)(hdr + 1) + (totlen - DOT11_MGMT_HDR_LEN - prebody_len);
+ bcopy((const char*)da, (u8*)&hdr->da, ETHER_ADDR_LEN);
+ bcopy((const char*)sa, (u8*)&hdr->sa, ETHER_ADDR_LEN);
+ bcopy((const char*)bssid, (u8*)&hdr->bssid, ETHER_ADDR_LEN);
+ bcopy((const char*)pbody, offset, prebody_len);
+ *body_len = totlen;
+ return err;
+}
static s32
wl_notify_rx_mgmt_frame(struct wl_priv *wl, struct net_device *ndev,
const wl_event_msg_t *e, void *data)
{
struct ieee80211_supported_band *band;
- s32 freq;
struct wiphy *wiphy = wl_to_wiphy(wl);
-
+ struct ether_addr da;
+ struct ether_addr bssid;
+ bool isfree = FALSE;
+ s32 err = 0;
+ s32 freq;
wl_event_rx_frame_data_t *rxframe =
(wl_event_rx_frame_data_t*)data;
-
- u8 *mgmt_frame = (u8 *)((wl_event_rx_frame_data_t *)rxframe + 1);
+ u32 event = ntoh32(e->event_type);
+ u8 *mgmt_frame;
+ u8 bsscfgidx = e->bsscfgidx;
u32 mgmt_frame_len = ntoh32(e->datalen) - sizeof(wl_event_rx_frame_data_t);
-
u16 channel = ((ntoh16(rxframe->channel) & WL_CHANSPEC_CHAN_MASK) & 0x0f);
-
if (channel <= CH_MAX_2G_CHANNEL)
band = wiphy->bands[IEEE80211_BAND_2GHZ];
else
band = wiphy->bands[IEEE80211_BAND_5GHZ];
+
+#if LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 38) && !defined(COMPAT_WIRELESS)
+ freq = ieee80211_channel_to_frequency(channel);
+#else
freq = ieee80211_channel_to_frequency(channel, band->band);
+#endif
+ if (event == WLC_E_ACTION_FRAME_RX) {
+ wldev_iovar_getbuf_bsscfg(ndev, "cur_etheraddr",
+ &da, sizeof(struct ether_addr), ioctlbuf, sizeof(ioctlbuf), bsscfgidx);
+ wldev_ioctl(ndev, WLC_GET_BSSID, &bssid, ETHER_ADDR_LEN, FALSE);
+ err = wl_frame_get_mgmt(FC_ACTION, &da, &e->addr, &bssid,
+ &mgmt_frame, &mgmt_frame_len,
+ (u8 *)((wl_event_rx_frame_data_t *)rxframe + 1));
+ if (err < 0) {
+ WL_ERR(("%s: Error in receiving action frame len %d channel %d freq %d\n",
+ __func__, mgmt_frame_len, channel, freq));
+ goto exit;
+ }
+ isfree = TRUE;
+ } else {
+ mgmt_frame = (u8 *)((wl_event_rx_frame_data_t *)rxframe + 1);
+ }
cfg80211_rx_mgmt(ndev, freq, mgmt_frame, mgmt_frame_len, GFP_ATOMIC);
WL_DBG(("%s: mgmt_frame_len (%d) , e->datalen (%d), channel (%d), freq (%d)\n", __func__,
mgmt_frame_len, ntoh32(e->datalen), channel, freq));
+
+ if (isfree)
+ kfree(mgmt_frame);
+exit:
return 0;
}
static void wl_init_conf(struct wl_conf *conf)
{
+ s32 i = 0;
WL_DBG(("Enter \n"));
- conf->mode = (u32)-1;
+ for (i = 0; i <= VWDEV_CNT; i++) {
+ conf->mode[i].type = -1;
+ conf->mode[i].ndev = NULL;
+ }
conf->frag_threshold = (u32)-1;
conf->rts_threshold = (u32)-1;
conf->retry_short = (u32)-1;
memset(wl->evt_handler, 0, sizeof(wl->evt_handler));
wl->evt_handler[WLC_E_SCAN_COMPLETE] = wl_notify_scan_status;
- wl->evt_handler[WLC_E_JOIN] = wl_notify_connect_status;
+ /* wl->evt_handler[WLC_E_JOIN] = wl_notify_connect_status; */
wl->evt_handler[WLC_E_LINK] = wl_notify_connect_status;
wl->evt_handler[WLC_E_DEAUTH_IND] = wl_notify_connect_status;
+ wl->evt_handler[WLC_E_DEAUTH] = wl_notify_connect_status;
wl->evt_handler[WLC_E_DISASSOC_IND] = wl_notify_connect_status;
wl->evt_handler[WLC_E_ASSOC_IND] = wl_notify_connect_status;
wl->evt_handler[WLC_E_REASSOC_IND] = wl_notify_connect_status;
wl->evt_handler[WLC_E_ACTION_FRAME_COMPLETE] = wl_cfgp2p_action_tx_complete;
wl->evt_handler[WLC_E_ACTION_FRAME_OFF_CHAN_COMPLETE] = wl_cfgp2p_action_tx_complete;
- /* Used to be like this...
- el->handler[WLC_E_SCAN_COMPLETE] = wl_notify_scan_status;
- el->handler[WLC_E_JOIN] = wl_notify_connect_status;
- el->handler[WLC_E_LINK] = wl_notify_connect_status;
- el->handler[WLC_E_DEAUTH_IND] = wl_notify_connect_status;
- el->handler[WLC_E_DISASSOC_IND] = wl_notify_connect_status;
- el->handler[WLC_E_ASSOC_IND] = wl_notify_connect_status;
- el->handler[WLC_E_REASSOC_IND] = wl_notify_connect_status;
- el->handler[WLC_E_ROAM] = wl_notify_roaming_status;
- el->handler[WLC_E_MIC_ERROR] = wl_notify_mic_status;
- el->handler[WLC_E_SET_SSID] = wl_notify_connect_status;
- */
}
static s32 wl_init_priv_mem(struct wl_priv *wl)
memset(&list, 0, sizeof(list));
list.results.buflen = htod32(WL_ISCAN_BUF_MAX);
- err = wl_dev_iovar_getbuf(iscan->dev, "iscanresults", &list,
+ err = wldev_iovar_getbuf(iscan->dev, "iscanresults", &list,
WL_ISCAN_RESULTS_FIXED_SIZE, iscan->scan_buf,
WL_ISCAN_BUF_MAX);
if (unlikely(err)) {
rtnl_unlock();
}
}
+ else if (status == WLC_E_STATUS_ABORT) {
+ wl->escan_info.escan_state = WL_ESCAN_STATE_IDLE;
+ if (likely(wl->scan_request)) {
+ rtnl_lock();
+ WL_INFO(("ESCAN COMPLETED\n"));
+ wl_notify_escan_complete(wl, true);
+ rtnl_unlock();
+ }
+ }
exit:
return err;
}
wl->scan_request = NULL;
wl->pwr_save = !!(wiphy->flags & WIPHY_FLAG_PS_ON_BY_DEFAULT);
- wl->iscan_on = true;
- wl->escan_on = false;
+ wl->iscan_on = false;
+ wl->escan_on = true;
wl->roam_on = false;
wl->iscan_kickstart = false;
wl->active_scan = true;
wl_deinit_priv_mem(wl);
}
+#ifdef CONFIG_SYSCTL
+s32 wl_cfg80211_sysctl_export_devaddr(void *data)
+{
+ /* Export the p2p_dev_addr via sysctl interface
+ * so that wpa_supplicant can access it
+ */
+ dhd_pub_t *dhd = (dhd_pub_t *)data;
+ struct wl_priv *wl = WL_PRIV_GET();
+
+ wl_cfgp2p_generate_bss_mac(&dhd->mac, &wl->p2p_dev_addr, &wl->p2p_int_addr);
+
+ sprintf((char *)&wl_sysctl_macstring[0], MACSTR, MAC2STR(wl->p2p_dev_addr.octet));
+ sprintf((char *)&wl_sysctl_macstring[1], MACSTR, MAC2STR(wl->p2p_int_addr.octet));
+
+ return 0;
+}
+#endif /* CONFIG_SYSCTL */
+
+s32 wl_cfg80211_attach_post(struct net_device *ndev)
+{
+ struct wl_priv * wl = NULL;
+ s32 err = 0;
+ WL_TRACE(("In\n"));
+ if (unlikely(!ndev)) {
+ WL_ERR(("ndev is invaild\n"));
+ return -ENODEV;
+ }
+ wl = WL_PRIV_GET();
+ if (wl && !test_bit(WL_STATUS_READY, &wl->status)) {
+ if (wl->wdev &&
+ wl_cfgp2p_is_p2p_supported(wl, ndev)) {
+ WL_INFO(("P2P is supported on Firmware \n"));
+ wl->wdev->wiphy->interface_modes |=
+ (BIT(NL80211_IFTYPE_P2P_CLIENT)|
+ BIT(NL80211_IFTYPE_P2P_GO));
+ }
+ } else
+ return -ENODEV;
+
+ set_bit(WL_STATUS_READY, &wl->status);
+ return err;
+}
s32 wl_cfg80211_attach(struct net_device *ndev, void *data)
{
struct wireless_dev *wdev;
goto cfg80211_attach_out;
}
+#ifdef CONFIG_SYSCTL
+ if (!(wl_sysctl_hdr = register_sysctl_table(wl_sysctl_table))) {
+ WL_ERR(("%s: sysctl register failed!! \n", __func__));
+ goto cfg80211_attach_out;
+ }
+#endif
wl_set_drvdata(wl_cfg80211_dev, ci);
- set_bit(WL_STATUS_READY, &wl->status);
-
return err;
cfg80211_attach_out:
WL_TRACE(("In\n"));
+#ifdef CONFIG_SYSCTL
+ if (wl_sysctl_hdr)
+ unregister_sysctl_table(wl_sysctl_hdr);
+#endif
rfkill_unregister(wl->rfkill);
rfkill_destroy(wl->rfkill);
}
void
-wl_cfg80211_event(struct net_device *ndev, const wl_event_msg_t * e, void *data)
+wl_cfg80211_event(struct net_device *ndev, const wl_event_msg_t * e, void *data, gfp_t gfp)
{
u32 event_type = ntoh32(e->event_type);
struct wl_priv *wl = WL_PRIV_GET();
WL_DBG(("event_type (%d):" "WLC_E_" "%s\n", event_type, estr));
#endif /* (WL_DBG_LEVEL > 0) */
- if (likely(!wl_enq_event(wl, ndev, event_type, e, data)))
+ if (likely(!wl_enq_event(wl, ndev, event_type, e, data, gfp)))
wl_wakeup_event(wl);
}
static s32
wl_enq_event(struct wl_priv *wl, struct net_device *ndev, u32 event, const wl_event_msg_t *msg,
- void *data)
+ void *data, gfp_t gfp)
{
struct wl_event_q *e;
s32 err = 0;
if (data)
data_len = ntoh32(msg->datalen);
evtq_size = sizeof(struct wl_event_q) + data_len;
- e = kzalloc(evtq_size, GFP_KERNEL);
+ e = kzalloc(evtq_size, gfp);
if (unlikely(!e)) {
WL_ERR(("event alloc failed\n"));
return -ENOMEM;
return cfg80211_sdio_func;
}
-static s32 wl_dongle_mode(struct net_device *ndev, s32 iftype)
+static s32 wl_dongle_mode(struct wl_priv *wl, struct net_device *ndev, s32 iftype)
{
s32 infra = 0;
- s32 ap = 0;
s32 err = 0;
-
+ s32 mode = 0;
switch (iftype) {
case NL80211_IFTYPE_MONITOR:
case NL80211_IFTYPE_WDS:
err = -EINVAL;
return err;
case NL80211_IFTYPE_ADHOC:
+ mode = WL_MODE_IBSS;
break;
case NL80211_IFTYPE_STATION:
+ mode = WL_MODE_BSS;
infra = 1;
break;
default:
return err;
}
infra = htod32(infra);
- ap = htod32(ap);
- WL_DBG(("%s ap (%d), infra (%d)\n", ndev->name, ap, infra));
- err = wl_dev_ioctl(ndev, WLC_SET_INFRA, &infra, sizeof(infra));
+ err = wldev_ioctl(ndev, WLC_SET_INFRA, &infra, sizeof(infra), FALSE);
if (unlikely(err)) {
WL_ERR(("WLC_SET_INFRA error (%d)\n", err));
return err;
}
- err = wl_dev_ioctl(ndev, WLC_SET_AP, &ap, sizeof(ap));
- if (unlikely(err)) {
- WL_ERR(("WLC_SET_AP error (%d)\n", err));
- return err;
- }
-
- return -EINPROGRESS;
-}
-#ifdef NOT_YET
-static s32 wl_dongle_save_eventmsg(struct wl_priv *wl)
-{
- s8 eventmask[WL_EVENTING_MASK_LEN];
- s32 err = 0;
- struct net_device *ndev = wl_to_prmry_ndev(wl);
- /* Room for "event_msgs" + '\0' + bitvec */
- err = wl_cfgp2p_bssiovar_get(ndev, "event_msgs", 0,
- eventmask, WL_EVENTING_MASK_LEN);
- if (unlikely(err)) {
- WL_ERR(("Get event_msgs error (%d)\n", err));
- } else {
- memcpy(wl->last_eventmask, eventmask, WL_EVENTING_MASK_LEN);
- }
- return err;
-}
-
-static s32 wl_dongle_disable_eventmsg(struct wl_priv *wl)
-{
- s8 eventmask[WL_EVENTING_MASK_LEN];
- s32 err = 0;
- struct net_device *ndev = wl_to_prmry_ndev(wl);
- /* Only Enable IF EVENT */
- setbit(eventmask, WLC_E_IF);
-
- err = wl_cfgp2p_bssiovar_set(ndev, "event_msgs", 0,
- eventmask, WL_EVENTING_MASK_LEN);
- if (unlikely(err)) {
- WL_ERR(("Get event_msgs error (%d)\n", err));
- }
- return err;
-}
+ set_mode_by_netdev(wl, ndev, mode);
-
-static s32 wl_dongle_restore_eventmsg(struct wl_priv *wl)
-{
- s32 err = 0;
- struct net_device *ndev = wl_to_prmry_ndev(wl);
- err = wl_cfgp2p_bssiovar_set(ndev, "event_msgs", 0,
- wl->last_eventmask, WL_EVENTING_MASK_LEN);
- if (unlikely(err)) {
- WL_ERR(("Get event_msgs error (%d)\n", err));
- }
-
- return err;
+ return 0;
}
-#endif /* NOT_YET */
static s32 wl_dongle_eventmsg(struct net_device *ndev)
{
/* Setup event_msgs */
bcm_mkiovar("event_msgs", eventmask, WL_EVENTING_MASK_LEN, iovbuf,
sizeof(iovbuf));
- err = wl_dev_ioctl(ndev, WLC_GET_VAR, iovbuf, sizeof(iovbuf));
+ err = wldev_ioctl(ndev, WLC_GET_VAR, iovbuf, sizeof(iovbuf), FALSE);
if (unlikely(err)) {
WL_ERR(("Get event_msgs error (%d)\n", err));
goto dongle_eventmsg_out;
setbit(eventmask, WLC_E_REASSOC);
setbit(eventmask, WLC_E_REASSOC_IND);
setbit(eventmask, WLC_E_DEAUTH_IND);
+ setbit(eventmask, WLC_E_DEAUTH);
setbit(eventmask, WLC_E_DISASSOC_IND);
setbit(eventmask, WLC_E_DISASSOC);
setbit(eventmask, WLC_E_JOIN);
setbit(eventmask, WLC_E_SCAN_COMPLETE);
setbit(eventmask, WLC_E_ACTION_FRAME_RX);
setbit(eventmask, WLC_E_ACTION_FRAME_COMPLETE);
+ setbit(eventmask, WLC_E_ACTION_FRAME_OFF_CHAN_COMPLETE);
setbit(eventmask, WLC_E_P2P_PROBREQ_MSG);
setbit(eventmask, WLC_E_P2P_DISC_LISTEN_COMPLETE);
setbit(eventmask, WLC_E_ESCAN_RESULT);
bcm_mkiovar("event_msgs", eventmask, WL_EVENTING_MASK_LEN, iovbuf,
sizeof(iovbuf));
- err = wl_dev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf));
+ err = wldev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf), FALSE);
if (unlikely(err)) {
WL_ERR(("Set event_msgs error (%d)\n", err));
goto dongle_eventmsg_out;
{
s32 err = 0;
- err = wl_dev_ioctl(ndev, WLC_UP, &up, sizeof(up));
+ err = wldev_ioctl(ndev, WLC_UP, &up, sizeof(up), FALSE);
if (unlikely(err)) {
WL_ERR(("WLC_UP error (%d)\n", err));
}
s32 err = 0;
WL_TRACE(("In\n"));
- err = wl_dev_ioctl(ndev, WLC_SET_PM, &power_mode, sizeof(power_mode));
+ err = wldev_ioctl(ndev, WLC_SET_PM, &power_mode, sizeof(power_mode), FALSE);
if (unlikely(err)) {
WL_ERR(("WLC_SET_PM error (%d)\n", err));
}
/* Match Host and Dongle rx alignment */
bcm_mkiovar("bus:txglomalign", (char *)&dongle_align, 4, iovbuf,
sizeof(iovbuf));
- err = wl_dev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf));
+ err = wldev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf), FALSE);
if (unlikely(err)) {
WL_ERR(("txglomalign error (%d)\n", err));
goto dongle_glom_out;
}
/* disable glom option per default */
bcm_mkiovar("bus:txglom", (char *)&glom, 4, iovbuf, sizeof(iovbuf));
- err = wl_dev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf));
+ err = wldev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf), FALSE);
if (unlikely(err)) {
WL_ERR(("txglom error (%d)\n", err));
goto dongle_glom_out;
if (roamvar) {
bcm_mkiovar("bcn_timeout", (char *)&bcn_timeout, 4, iovbuf,
sizeof(iovbuf));
- err = wl_dev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf));
+ err = wldev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf), FALSE);
if (unlikely(err)) {
WL_ERR(("bcn_timeout error (%d)\n", err));
goto dongle_rom_out;
}
/* Enable/Disable built-in roaming to allow supplicant to take care of roaming */
bcm_mkiovar("roam_off", (char *)&roamvar, 4, iovbuf, sizeof(iovbuf));
- err = wl_dev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf));
+ err = wldev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf), FALSE);
if (unlikely(err)) {
WL_ERR(("roam_off error (%d)\n", err));
goto dongle_rom_out;
{
s32 err = 0;
- err = wl_dev_ioctl(ndev, WLC_SET_SCAN_CHANNEL_TIME, &scan_assoc_time,
- sizeof(scan_assoc_time));
+ err = wldev_ioctl(ndev, WLC_SET_SCAN_CHANNEL_TIME, &scan_assoc_time,
+ sizeof(scan_assoc_time), FALSE);
if (err) {
if (err == -EOPNOTSUPP) {
WL_INFO(("Scan assoc time is not supported\n"));
}
goto dongle_scantime_out;
}
- err = wl_dev_ioctl(ndev, WLC_SET_SCAN_UNASSOC_TIME, &scan_unassoc_time,
- sizeof(scan_unassoc_time));
+ err = wldev_ioctl(ndev, WLC_SET_SCAN_UNASSOC_TIME, &scan_unassoc_time,
+ sizeof(scan_unassoc_time), FALSE);
if (err) {
if (err == -EOPNOTSUPP) {
WL_INFO(("Scan unassoc time is not supported\n"));
/* Set ARP offload */
bcm_mkiovar("arpoe", (char *)&arpoe, 4, iovbuf, sizeof(iovbuf));
- err = wl_dev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf));
+ err = wldev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf), FALSE);
if (err) {
if (err == -EOPNOTSUPP)
WL_INFO(("arpoe is not supported\n"));
goto dongle_offload_out;
}
bcm_mkiovar("arp_ol", (char *)&arp_ol, 4, iovbuf, sizeof(iovbuf));
- err = wl_dev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf));
+ err = wldev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf), FALSE);
if (err) {
if (err == -EOPNOTSUPP)
WL_INFO(("arp_ol is not supported\n"));
memcpy((char *)pkt_filterp, &pkt_filter,
WL_PKT_FILTER_FIXED_LEN + WL_PKT_FILTER_PATTERN_FIXED_LEN);
- err = wl_dev_ioctl(ndev, WLC_SET_VAR, buf, buf_len);
+ err = wldev_ioctl(ndev, WLC_SET_VAR, buf, buf_len, FALSE);
if (err) {
if (err == -EOPNOTSUPP) {
WL_INFO(("filter not supported\n"));
/* set mode to allow pattern */
bcm_mkiovar("pkt_filter_mode", (char *)&filter_mode, 4, iovbuf,
sizeof(iovbuf));
- err = wl_dev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf));
+ err = wldev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf), FALSE);
if (err) {
if (err == -EOPNOTSUPP) {
WL_INFO(("filter_mode not supported\n"));
wl_dongle_filter(ndev, 1);
#endif /* !EMBEDDED_PLATFORM */
- /* TODO: Check if this is ever needed */
- err = wl_dongle_mode(ndev, wdev->iftype);
+ err = wl_dongle_mode(wl, ndev, wdev->iftype);
if (unlikely(err && err != -EINPROGRESS))
goto default_conf_out;
err = wl_dongle_probecap(wl);
s8 phy;
s32 err = 0;
- err = wl_dev_ioctl(wl_to_prmry_ndev(wl), WLC_GET_PHYLIST, &phy_list,
- sizeof(phy_list));
+ err = wldev_ioctl(wl_to_prmry_ndev(wl), WLC_GET_PHYLIST, &phy_list,
+ sizeof(phy_list), FALSE);
if (unlikely(err)) {
WL_ERR(("error (%d)\n", err));
return err;
clear_bit(WL_STATUS_SCAN_ABORTING, &wl->status);
clear_bit(WL_STATUS_CONNECTED, &wl->status);
+ wl_cfgp2p_down(wl);
+
wl_debugfs_remove_netdev(wl);
return err;
/* wl_dbg_level = level; */
}
-static bool wl_is_ibssmode(struct wl_priv *wl)
+static bool wl_is_ibssmode(struct wl_priv *wl, struct net_device *ndev)
{
- return wl->conf->mode == WL_MODE_IBSS;
+ return get_mode_by_netdev(wl, ndev) == WL_MODE_IBSS;
}
static __used bool wl_is_ibssstarter(struct wl_priv *wl)
{
struct wl_connect_info *conn_info = wl_to_conn(wl);
+ WL_DBG(("In\n"));
wl->link_up = false;
kfree(conn_info->req_ie);
conn_info->req_ie = NULL;
return wl->fw->nvram_name;
}
-static void wl_set_mpc(struct net_device *ndev, int mpc)
+static void wl_set_mpc(struct net_device *ndev, s32 mpc)
{
+
+ s32 err = 0;
+
+ WL_TRACE(("In\n"));
+ err = wl_dev_intvar_set(ndev, "mpc", mpc);
+ if (unlikely(err)) {
+ WL_ERR(("fail to set mpc\n"));
+ return;
+ }
+ WL_DBG(("MPC : %d\n", mpc));
+
}
static int wl_debugfs_add_netdev_params(struct wl_priv *wl)
}
static const struct rfkill_ops wl_rfkill_ops = {
- .set_block = wl_rfkill_set,
+ .set_block = wl_rfkill_set
};
static int wl_rfkill_set(void *data, bool blocked)
* 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_cfg80211.c,v 1.1.4.1.2.14 2011-02-09 01:40:07 Exp $
* $Id$
*/
#include <wl_cfg80211.h>
#include <wl_cfgp2p.h>
+#include <wldev_common.h>
/* dword align allocation */
static s8 scanparambuf[WLC_IOCTL_SMLEN];
static s8 *smbuf = ioctlbuf;
+static bool
+wl_cfgp2p_has_ie(u8 *ie, u8 **tlvs, u32 *tlvs_len, const u8 *oui, u32 oui_len, u8 type);
static s32
wl_cfgp2p_vndr_ie(struct net_device *ndev, s32 bssidx, s32 pktflag,
s8 *oui, s32 ie_id, s8 *data, s32 data_len, s32 delete);
-static s32
-wl_dev_ioctl(struct net_device *dev, u32 cmd, void *arg, u32 len, u32 set)
-{
- struct ifreq ifr;
- struct wl_ioctl ioc;
- mm_segment_t fs;
- s32 err = 0;
-
- memset(&ioc, 0, sizeof(ioc));
- ioc.cmd = cmd;
- ioc.buf = arg;
- ioc.len = len;
- ioc.set = set;
- strcpy(ifr.ifr_name, dev->name);
- ifr.ifr_data = (caddr_t)&ioc;
- fs = get_fs();
- set_fs(get_ds());
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 31)
- err = dev->do_ioctl(dev, &ifr, SIOCDEVPRIVATE);
-#else
- err = dev->netdev_ops->ndo_do_ioctl(dev, &ifr, SIOCDEVPRIVATE);
-#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 31) */
- set_fs(fs);
-
- return err;
-}
-
-/*
- * Format an iovar buffer.
- * iovar name is converted to lower case
- */
-static s32
-wl_cfgp2p_iovar_mkbuf(const s8 *name, s8 *data, u32 datalen,
- s8 *iovar_buf, u32 buflen, u32 *perr)
-{
- u32 iovar_len;
- iovar_len = (u32) strlen(name) + 1;
-
- if ((iovar_len + datalen) > buflen) {
-
- CFGP2P_ERR(("buf too short, %u < %u\n", buflen, (iovar_len + datalen)));
- *perr = BCME_BUFTOOSHORT;
- return 0;
- }
-
- /* copy data to the buffer past the end of the iovar name string */
- if (datalen > 0) {
- memmove(&iovar_buf[iovar_len], data, datalen);
- }
-
- /* copy the name to the beginning of the buffer */
- strcpy(iovar_buf, name);
-
-
- *perr = 0;
- return (iovar_len + datalen);
-}
-
-/*
- * Format a bsscfg indexed iovar buffer.
- * This is a common implementation called by most OSL implementations of
- * p2posl_bssiovar_mkbuf(). DO NOT call this function directly from the
- * common code -- call p2posl_bssiovar_mkbuf() instead to allow the OSL to
- * override the common implementation if necessary.
- */
-static s32
-wl_cfgp2p_bssiovar_mkbuf(const s8 *iovar, s32 bssidx,
- void *param, s32 paramlen, void *bufptr, s32 buflen, s32 *perr)
-{
- const s8 *prefix = "bsscfg:";
- s8 *p;
- u32 prefixlen;
- u32 namelen;
- u32 iolen;
-
- if (bssidx == 0) {
- return wl_cfgp2p_iovar_mkbuf(iovar, (s8 *)param, paramlen,
- (s8 *) bufptr, buflen, perr);
- }
-
- prefixlen = (u32) strlen(prefix); /* lengh of bsscfg prefix */
- namelen = (u32) strlen(iovar) + 1; /* lengh of iovar name + null */
- iolen = prefixlen + namelen + sizeof(u32) + paramlen;
-
- if (buflen < 0 || iolen > (u32)buflen) {
- CFGP2P_ERR(("buf too short, %u < %u\n", buflen, iolen));
- *perr = BCME_BUFTOOSHORT;
- return 0;
- }
- p = (s8 *)bufptr;
-
- /* copy prefix, no null */
- memcpy(p, prefix, prefixlen);
- p += prefixlen;
-
- /* copy iovar name including null */
- memcpy(p, iovar, namelen);
- p += namelen;
-
- /* bss config index as first param */
- bssidx = htod32(bssidx);
- memcpy(p, &bssidx, sizeof(u32));
- p += sizeof(u32);
-
- /* parameter buffer follows */
- if (paramlen)
- memcpy(p, param, paramlen);
-
- *perr = 0;
-
- return iolen;
-
-}
-
-/*
- * Set a bss-indexed iovar on the primary ioctl interface, providing both
- * parameter and i/o buffers.
- */
-
-static s32
-wl_cfgp2p_bssiovar_setbuf(struct net_device *dev, const s8 *iovar, s32 bssidx,
- void *param, s32 paramlen, void *bufptr, s32 buflen)
-{
- s32 iolen;
- s32 err;
- iolen = wl_cfgp2p_bssiovar_mkbuf(iovar, bssidx, param, paramlen, bufptr,
- buflen, &err);
-
- if (err)
- return err;
-
- return wl_dev_ioctl(dev, WLC_SET_VAR, bufptr, iolen, TRUE);
-}
-/*
- * Get a named & bss indexed driver iovar using the primary ioctl interface.
- */
-static s32
-wl_cfgp2p_bssiovar_getbuf(struct net_device *dev, const s8 *iovar, int bssidx,
- void *param, s32 paramlen, void *bufptr, s32 buflen)
-{
- s32 err;
- s32 iolen;
- iolen = wl_cfgp2p_bssiovar_mkbuf(iovar, bssidx, param, paramlen, bufptr, buflen, &err);
-
- if (unlikely(err))
- return err;
-
- return wl_dev_ioctl(dev, WLC_GET_VAR, bufptr, iolen, FALSE);
-}
-
-
-/*
- * Get named & bss indexed driver variable to buffer value
- * using the primary ioctl interface.
- */
-s32
-wl_cfgp2p_bssiovar_get(struct net_device *dev, const s8 *iovar, s32 bssidx,
- void *outbuf, s32 len)
-{
- s32 err;
-
- if (len > (s32)sizeof(ioctlbuf)) {
- err = wl_cfgp2p_bssiovar_getbuf(dev, iovar, bssidx, NULL, 0,
- outbuf, len);
- } else {
- memset(smbuf, 0, sizeof(ioctlbuf));
-
- err = wl_cfgp2p_bssiovar_getbuf(dev, iovar, bssidx, NULL, 0,
- smbuf, sizeof(ioctlbuf));
-
- if (err == 0)
- memcpy(outbuf, smbuf, len);
- }
- return err;
-}
-/*
- * Set named & bss indexed driver variable to buffer value
- * on the primary ioctl interface.
- */
-s32
-wl_cfgp2p_bssiovar_set(struct net_device *dev, const s8 *iovar, s32 bssidx,
- void *param, s32 paramlen)
-{
-
- memset(smbuf, 0, sizeof(ioctlbuf));
-
- return wl_cfgp2p_bssiovar_setbuf(dev, iovar, bssidx, param, paramlen, smbuf,
- sizeof(ioctlbuf));
-}
-
-
-/*
- * Set named & bsscfg indexed driver variable to int value
- * on the primary ioctl interface.
- */
-
-s32
-wl_cfgp2p_bssiovar_setint(struct net_device *dev, const s8 *iovar, s32 bssidx,
- s32 val)
-{
-
- val = htod32(val);
-
- return wl_cfgp2p_bssiovar_set(dev, iovar, bssidx, &val, sizeof(int));
-}
-
-
-s32
-wl_cfgp2p_set_int_bss(struct net_device *dev, s32 ioctl_cmd, s32 val, s32 bssidx)
-{
- s32 setval = htod32(val);
- return wl_dev_ioctl(dev, WLC_SET_VAR, &setval, sizeof(setval), TRUE);
-}
-
-
-s32
-wl_cfgp2p_get_int_bss(struct net_device *dev, s32 ioctl_cmd, s32 *val, s32 bssidx)
-{
- s32 ret;
- ret = wl_dev_ioctl(dev, WLC_GET_VAR, val, sizeof(*val), FALSE);
- if (ret >= 0) {
- val = dtoh32(val);
- }
- return ret;
-}
-
-s32
-wl_cfgp2p_iovar_getbuf_bss(struct net_device *dev, const s8 *iovar, void *param,
- s32 paramlen, void *bufptr, s32 buflen, s32 bssidx)
-{
- s32 err;
-
- wl_cfgp2p_iovar_mkbuf(iovar, (s8 *)param, paramlen, (s8 *) bufptr, buflen,
- &err);
-
- if (unlikely(err)) {
- CFGP2P_ERR((" mkbuf err %d\n", err));
- }
-
- return wl_dev_ioctl(dev, WLC_GET_VAR, bufptr, buflen, FALSE);
-}
-/*
- * Set a named iovar on a specified BSS, providing both parameter and i/o
- * buffers. The iovar name is converted to lower case.
- */
-s32
-wl_cfgp2p_iovar_setbuf_bss(struct net_device *dev, const s8 *iovar,
- void *param, s32 paramlen, void *bufptr, s32 buflen)
-{
- s32 err = BCME_OK;
- s32 iolen;
- CFGP2P_DBG((" enter\n"));
-
- iolen = wl_cfgp2p_iovar_mkbuf(iovar, (char *) param, paramlen, (s8 *)bufptr,
- buflen, &err);
-
- if (unlikely(err)) {
- CFGP2P_ERR(("iovar = %s\n", iovar));
- return err;
- }
- err = wl_dev_ioctl(dev, WLC_SET_VAR, bufptr, iolen, TRUE);
- CFGP2P_DBG((" leave\n"));
- return err;
-}
-
-/*
- * Set a named iovar given the parameter buffer, on a specified BSS.
- * The iovar name is converted to lower case.
- */
-s32
-wl_cfgp2p_iovar_set_bss(struct net_device *dev, const s8 *iovar, void *param,
- s32 paramlen)
-{
-
- s32 ret;
- memset(smbuf, 0, sizeof(ioctlbuf));
- CFGP2P_DBG((" enter\n"));
- ret = wl_cfgp2p_iovar_setbuf_bss(dev, iovar, param, paramlen, smbuf,
- sizeof(ioctlbuf));
-
- if (unlikely(ret != 0)) {
- CFGP2P_ERR(("set iovar %s failed (%d)\n",
- iovar, ret));
- }
- CFGP2P_DBG((" leave\n"));
- return ret;
-}
-/*
- * Get a parameterless iovar into a given buffer.
- * iovar name is converted to lower case
- */
-s32
-wl_cfgp2p_iovar_get_bss(struct net_device *dev, const s8 *iovar, void *outbuf, s32 len,
- s32 bssidx)
-{
- s32 err;
-
- /* use the return buffer if it is bigger than what we have on the stack */
- if (len > (s32)sizeof(ioctlbuf)) {
- err = wl_cfgp2p_iovar_getbuf_bss(dev, iovar, NULL, 0, outbuf, len, bssidx);
- } else {
- memset(smbuf, 0, sizeof(ioctlbuf));
- err = wl_cfgp2p_iovar_getbuf_bss(dev, iovar, NULL, 0, smbuf, sizeof(ioctlbuf),
- bssidx);
- if (err == 0)
- memcpy(outbuf, smbuf, len);
- }
-
- return err;
-}
-
-/*
- * Set named iovar given an integer parameter, on the specified BSS.
- * iovar name is converted to lower case
- */
-s32
-wl_cfgp2p_iovar_setint_bss(struct net_device *dev, const s8 *iovar, s32 val)
-{
- CFGP2P_DBG((" enter\n"));
- val = htod32(val);
- return wl_cfgp2p_iovar_set_bss(dev, iovar, &val, sizeof(int));
-}
-
-/*
- * Get the named integer iovar on the specified BSS.
- * iovar name is converted to lower case
- */
-s32
-wl_cfgp2p_iovar_getint_bss(struct net_device *dev, const s8*iovar, s32 *pval, s32 bssidx)
-{
- s32 ret;
-
- ret = wl_cfgp2p_iovar_get_bss(dev, iovar, pval, sizeof(s32), bssidx);
- if (ret >= 0)
- {
- *pval = dtoh32(*pval);
- }
- return ret;
-}
-
/*
* Initialize variables related to P2P
*
(if_type == WL_P2P_IF_GO) ? "go" : "client",
(chspec & WL_CHANSPEC_CHAN_MASK) >> WL_CHANSPEC_CHAN_SHIFT));
- err = wl_cfgp2p_iovar_set_bss(netdev, "p2p_ifadd", &ifreq, sizeof(ifreq));
+ err = wldev_iovar_setbuf(netdev, "p2p_ifadd", &ifreq, sizeof(ifreq),
+ ioctlbuf, sizeof(ioctlbuf));
return err;
}
mac->octet[0], mac->octet[1], mac->octet[2],
mac->octet[3], mac->octet[4], mac->octet[5]));
- ret = wl_cfgp2p_iovar_set_bss(netdev, "p2p_ifdel", mac, sizeof(*mac));
+ ret = wldev_iovar_setbuf(netdev, "p2p_ifdel", mac, sizeof(*mac),
+ ioctlbuf, sizeof(ioctlbuf));
if (unlikely(ret < 0)) {
printk("'wl p2p_ifdel' error %d\n", ret);
(if_type == WL_P2P_IF_GO) ? "go" : "client",
(chspec & WL_CHANSPEC_CHAN_MASK) >> WL_CHANSPEC_CHAN_SHIFT));
- err = wl_cfgp2p_iovar_set_bss(netdev, "p2p_ifupd", &ifreq, sizeof(ifreq));
+ err = wldev_iovar_setbuf(netdev, "p2p_ifupd", &ifreq, sizeof(ifreq),
+ ioctlbuf, sizeof(ioctlbuf));
if (unlikely(err < 0)) {
printk("'wl p2p_ifupd' error %d\n", err);
mac->octet[0], mac->octet[1], mac->octet[2],
mac->octet[3], mac->octet[4], mac->octet[5]));
- ret = wl_cfgp2p_iovar_getbuf_bss(dev, "p2p_if", mac, sizeof(*mac),
+ ret = wldev_iovar_getbuf_bsscfg(dev, "p2p_if", mac, sizeof(*mac),
getbuf, sizeof(getbuf), wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_PRIMARY));
if (ret == 0) {
struct net_device *ndev = wl_to_prmry_ndev(wl);
CFGP2P_DBG(("enter\n"));
- ret = wl_cfgp2p_iovar_setint_bss(ndev, "p2p_disc", on);
+ ret = wldev_iovar_setint(ndev, "p2p_disc", on);
if (unlikely(ret < 0)) {
CFGP2P_ERR(("p2p_disc %d error %d\n", on, ret));
discovery_mode.state = mode;
discovery_mode.chspec = CH20MHZ_CHSPEC(channel);
discovery_mode.dwell = listen_ms;
- ret = wl_cfgp2p_bssiovar_set(dev, "p2p_state", bssidx, &discovery_mode,
- sizeof(discovery_mode));
+ ret = wldev_iovar_setbuf_bsscfg(dev, "p2p_state", &discovery_mode,
+ sizeof(discovery_mode), ioctlbuf, sizeof(ioctlbuf), bssidx);
return ret;
}
s32 ret;
struct net_device *dev = wl_to_p2p_bss_ndev(wl, P2PAPI_BSSCFG_PRIMARY);
- ret = wl_cfgp2p_iovar_getint_bss(dev, "p2p_dev", index, 0);
+ ret = wldev_iovar_getint(dev, "p2p_dev", index);
CFGP2P_INFO(("p2p_dev bsscfg_idx=%d ret=%d\n", *index, ret));
if (unlikely(ret < 0)) {
* Returns 0 if success.
*/
s32
-wl_cfgp2p_enable_discovery(struct wl_priv *wl, const u8 *ie, u32 ie_len)
+wl_cfgp2p_enable_discovery(struct wl_priv *wl, struct net_device *dev, const u8 *ie, u32 ie_len)
{
s32 ret = BCME_OK;
if (test_bit(WLP2P_STATUS_DISCOVERY_ON, &wl->p2p_status)) {
* 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 = wl_cfgp2p_bssiovar_setint(wl_to_p2p_bss_ndev(wl, P2PAPI_BSSCFG_DEVICE),
- "wsec", wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_DEVICE), AES_ENABLED);
+ 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));
if (unlikely(ret < 0)) {
CFGP2P_ERR((" wsec error %d\n", ret));
}
set_ie:
- ret = wl_cfgp2p_set_managment_ie(wl, wl_to_p2p_bss_ndev(wl, P2PAPI_BSSCFG_DEVICE),
+ ret = wl_cfgp2p_set_managment_ie(wl, dev,
wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_DEVICE),
VNDR_IE_PRBREQ_FLAG, ie, ie_len);
}
s32
-wl_cfgp2p_escan(struct wl_priv *wl, u16 active, u32 num_chans, u16 *channels,
+wl_cfgp2p_escan(struct wl_priv *wl, struct net_device *dev, u16 active,
+ u32 num_chans, u16 *channels,
s32 search_state, u16 action, u32 bssidx)
{
s32 ret = BCME_OK;
CFGP2P_INFO(("\n"));
- ret = wl_cfgp2p_bssiovar_setbuf(wl_to_p2p_bss_ndev(wl, bssidx), "p2p_scan", bssidx,
- memblk, memsize, smbuf, sizeof(ioctlbuf));
+ ret = wldev_iovar_setbuf_bsscfg(dev, "p2p_scan",
+ memblk, memsize, smbuf, sizeof(ioctlbuf), bssidx);
return ret;
}
+/* Check whether pointed-to IE looks like WPA. */
+#define wl_cfgp2p_is_wpa_ie(ie, tlvs, len) wl_cfgp2p_has_ie(ie, tlvs, len, \
+ (const uint8 *)WPS_OUI, WPS_OUI_LEN, WPA_OUI_TYPE)
+/* Check whether pointed-to IE looks like WPS. */
+#define wl_cfgp2p_is_wps_ie(ie, tlvs, len) wl_cfgp2p_has_ie(ie, tlvs, len, \
+ (const uint8 *)WPS_OUI, WPS_OUI_LEN, WPS_OUI_TYPE)
+/* Check whether the given IE looks like WFA P2P IE. */
+#define wl_cfgp2p_is_p2p_ie(ie, tlvs, len) wl_cfgp2p_has_ie(ie, tlvs, len, \
+ (const uint8 *)WFA_OUI, WFA_OUI_LEN, WFA_OUI_TYPE_P2P)
/* Delete and Set a management ie to firmware
* Parameters:
* @wl : wl_private data
u8 delete = 0;
#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)
-
+ if (bssidx == -1)
+ return BCME_BADARG;
if (bssidx == P2PAPI_BSSCFG_PRIMARY)
bssidx = wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_DEVICE);
switch (pktflag) {
while (pos < *mgmt_ie_len) {
ie_id = ie_buf[pos++];
ie_len = ie_buf[pos++];
- CFGP2P_INFO(("DELELED ID(%d), Len(%d),\
- OUI(%02x:%02x:%02x)\n",\
- ie_id, ie_len, ie_buf[pos],\
+ CFGP2P_INFO(("DELELED ID(%d), Len(%d),"
+ "OUI(%02x:%02x:%02x)\n",
+ ie_id, ie_len, ie_buf[pos],
ie_buf[pos+1], ie_buf[pos+2]));
ret = wl_cfgp2p_vndr_ie(ndev, bssidx, pktflag,
ie_buf+pos, VNDR_SPEC_ELEMENT_ID,
while (pos < p2p_ie_len) {
ie_id = ie_buf[pos++];
ie_len = ie_buf[pos++];
- CFGP2P_INFO(("ADDED ID : %d, Len : %d , OUI : %02x:%02x:%02x\n",
- ie_id, ie_len, ie_buf[pos], ie_buf[pos+1], ie_buf[pos+2]));
- ret = wl_cfgp2p_vndr_ie(ndev, bssidx, pktflag, ie_buf+pos,
- VNDR_SPEC_ELEMENT_ID, ie_buf+pos+3, ie_len-3, delete);
+ if ((ie_id == DOT11_MNG_VS_ID) &&
+ (wl_cfgp2p_is_wps_ie(&ie_buf[pos-2], NULL, 0) ||
+ wl_cfgp2p_is_p2p_ie(&ie_buf[pos-2], NULL, 0))) {
+ CFGP2P_INFO(("ADDED ID : %d, Len : %d , OUI :"
+ "%02x:%02x:%02x\n", ie_id, ie_len, ie_buf[pos],
+ ie_buf[pos+1], ie_buf[pos+2]));
+ ret = wl_cfgp2p_vndr_ie(ndev, bssidx, pktflag, ie_buf+pos,
+ VNDR_SPEC_ELEMENT_ID, ie_buf+pos+3, ie_len-3, delete);
+ }
pos += ie_len;
}
}
return BCME_OK;
}
-/* Check whether pointed-to IE looks like WPA. */
-#define wl_cfgp2p_is_wpa_ie(ie, tlvs, len) wl_cfgp2p_has_ie(ie, tlvs, len, \
- (const uint8 *)WPS_OUI, WPS_OUI_LEN, WPA_OUI_TYPE)
-/* Check whether pointed-to IE looks like WPS. */
-#define wl_cfgp2p_is_wps_ie(ie, tlvs, len) wl_cfgp2p_has_ie(ie, tlvs, len, \
- (const uint8 *)WPS_OUI, WPS_OUI_LEN, WPS_OUI_TYPE)
-/* Check whether the given IE looks like WFA P2P IE. */
-#define wl_cfgp2p_is_p2p_ie(ie, tlvs, len) wl_cfgp2p_has_ie(ie, tlvs, len, \
- (const uint8 *)WFA_OUI, WFA_OUI_LEN, WFA_OUI_TYPE_P2P)
+
/* Is any of the tlvs the expected entry? If
* not update the tlvs buffer pointer/length.
return TRUE;
}
+ if (tlvs == NULL)
+ return FALSE;
/* point to the next ie */
ie += ie[TLV_LEN_OFF] + TLV_HDR_LEN;
/* calculate the length of the rest of the buffer */
= (uchar)(data_len + VNDR_IE_MIN_LEN);
memcpy(ie_setbuf->vndr_ie_buffer.vndr_ie_list[0].vndr_ie_data.oui, oui, 3);
memcpy(ie_setbuf->vndr_ie_buffer.vndr_ie_list[0].vndr_ie_data.data, data, data_len);
- err = wl_cfgp2p_bssiovar_set(ndev, "vndr_ie", bssidx, ie_setbuf, buf_len);
+ err = wldev_iovar_setbuf_bsscfg(ndev, "vndr_ie", ie_setbuf, buf_len,
+ ioctlbuf, sizeof(ioctlbuf), bssidx);
+
CFGP2P_INFO(("vndr_ie iovar returns %d\n", err));
kfree(ie_setbuf);
return err;
/*
* Timer expire callback function for LISTEN
+ * We can't report cfg80211_remain_on_channel_expired from Timer ISR context,
+ * so lets do it from thread context.
*/
static void
wl_cfgp2p_listen_expired(unsigned long data)
{
+ wl_event_msg_t msg;
struct wl_priv *wl = (struct wl_priv *) data;
CFGP2P_DBG((" Enter\n"));
-
- if (test_bit(WLP2P_STATUS_LISTEN_EXPIRED, &wl->p2p_status) == 0) {
- CFGP2P_ERR((" WLC_E_P2P_DISC_LISTEN_COMPLETE does not occur\n"));
- set_bit(WLP2P_STATUS_LISTEN_EXPIRED, &wl->p2p_status);
-
- cfg80211_remain_on_channel_expired(
- wl_to_p2p_bss_ndev(wl, P2PAPI_BSSCFG_DEVICE),
- wl->cache_cookie, &wl->remain_on_chan,
- wl->remain_on_chan_type, GFP_KERNEL);
- }
-
+ msg.event_type = hton32(WLC_E_P2P_DISC_LISTEN_COMPLETE);
+ wl_cfg80211_event(wl_to_p2p_bss_ndev(wl, P2PAPI_BSSCFG_DEVICE), &msg, NULL, GFP_ATOMIC);
}
/*
s32 ret = BCME_OK;
CFGP2P_DBG((" Enter\n"));
+ CFGP2P_INFO(("Channel : %d, Duration : %d\n", channel, duration_ms));
if (unlikely(test_bit(WLP2P_STATUS_DISCOVERY_ON, &wl->p2p_status) == 0)) {
CFGP2P_ERR((" Discovery is not set, so we have noting to do\n"));
{
s32 ret = BCME_OK;
u32 event_type = ntoh32(e->event_type);
-
+ u32 status = ntoh32(e->status);
CFGP2P_DBG((" Enter\n"));
if (event_type == WLC_E_ACTION_FRAME_COMPLETE) {
- CFGP2P_INFO((" WLC_E_ACTION_FRAME_COMPLETE is received\n"));
+ CFGP2P_INFO((" WLC_E_ACTION_FRAME_COMPLETE is received : %d\n", status));
+ if (status == WLC_E_STATUS_SUCCESS)
+ set_bit(WLP2P_STATUS_ACTION_TX_COMPLETED, &wl->p2p_status);
+ else
+ CFGP2P_ERR(("WLC_E_ACTION_FRAME_COMPLETE : NO ACK\n"));
+ wake_up_interruptible(&wl->dongle_event_wait);
+ } else {
+ CFGP2P_INFO((" WLC_E_ACTION_FRAME_OFFCHAN_COMPLETE is received,"
+ "status : %d\n", status));
- }else {
- CFGP2P_INFO((" WLC_E_ACTION_FRAME_OFFCHAN_COMPLETE is received\n"));
}
- set_bit(WLP2P_STATUS_ACTION_TX_COMPLETED, &wl->p2p_status);
-
- wake_up_interruptible(&wl->dongle_event_wait);
-
return ret;
}
* 802.11 ack has been received for the sent action frame.
*/
s32
-wl_cfgp2p_tx_action_frame(struct wl_priv *wl, wl_af_params_t *af_params, s32 bssidx)
+wl_cfgp2p_tx_action_frame(struct wl_priv *wl, struct net_device *dev,
+ wl_af_params_t *af_params, s32 bssidx)
{
s32 ret = BCME_OK;
s32 timeout = 0;
if (bssidx == P2PAPI_BSSCFG_PRIMARY)
bssidx = wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_DEVICE);
- ret = wl_cfgp2p_bssiovar_setbuf(wl_to_p2p_bss_ndev(wl, bssidx), "actframe",
- bssidx, af_params, sizeof(*af_params), ioctlbuf, sizeof(ioctlbuf));
+ ret = wldev_iovar_setbuf_bsscfg(dev, "actframe",
+ af_params, sizeof(*af_params), ioctlbuf, sizeof(ioctlbuf), bssidx);
+
if (ret < 0) {
CFGP2P_ERR((" sending action frame is failed\n"));
CFGP2P_INFO(("Device ID ATTR FOUND\n"));
} else if (subelt_id == P2P_SEID_DEV_INFO) {
memcpy(subel, p2p_int_addr->octet, ETHER_ADDR_LEN);
- CFGP2P_INFO(("Device ID ATTR FOUND\n"));
- }
- return;
+ CFGP2P_INFO(("Device INFO ATTR FOUND\n"));
+ } else if (subelt_id == P2P_SEID_GROUP_ID) {
+ memcpy(subel, p2p_int_addr->octet, ETHER_ADDR_LEN);
+ CFGP2P_INFO(("GROUP ID ATTR FOUND\n"));
+ } return;
} else {
CFGP2P_DBG(("OTHER id : %d\n", subelt_id));
}
/* Check if the BSS is up */
*(int*)getbuf = -1;
- result = wl_cfgp2p_iovar_getbuf_bss(ndev, "bss", &bsscfg_idx,
+ result = wldev_iovar_getbuf_bsscfg(ndev, "bss", &bsscfg_idx,
sizeof(bsscfg_idx), getbuf, sizeof(getbuf), 0);
if (result != 0) {
CFGP2P_ERR(("'wl bss -C %d' failed: %d\n", bsscfg_idx, result));
bss_setbuf.cfg = htod32(bsscfg_idx);
bss_setbuf.val = htod32(val);
CFGP2P_INFO(("---wl bss -C %d %s\n", bsscfg_idx, up ? "up" : "down"));
- ret = wl_cfgp2p_iovar_set_bss(ndev, "bss", &bss_setbuf, sizeof(bss_setbuf));
+ ret = wldev_iovar_setbuf(ndev, "bss", &bss_setbuf, sizeof(bss_setbuf),
+ ioctlbuf, sizeof(ioctlbuf));
if (ret != 0) {
CFGP2P_ERR(("'bss %d' failed with %d\n", up, ret));
/* Check if 'p2p' is supported in the driver */
s32
-wl_cfgp2p_is_p2p_supported(struct wl_priv *wl)
+wl_cfgp2p_is_p2p_supported(struct wl_priv *wl, struct net_device *ndev)
{
s32 ret = BCME_OK;
s32 is_p2p_supported = 0;
- ret = wl_cfgp2p_iovar_getint_bss(wl_to_p2p_bss_ndev(wl, P2PAPI_BSSCFG_PRIMARY), "p2p",
- &is_p2p_supported, wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_PRIMARY));
+ ret = wldev_iovar_getint(ndev, "p2p",
+ &is_p2p_supported);
if (ret < 0) {
CFGP2P_ERR(("wl p2p error %d\n", ret));
return 0;
return is_p2p_supported;
}
+
+s32
+wl_cfgp2p_down(struct wl_priv *wl)
+{
+ if (wl->listen_timer)
+ del_timer_sync(wl->listen_timer);
+ return 0;
+}