|
@@ -1,5 +1,5 @@
|
|
|
/*
|
|
|
- * Copyright (c) 2012-2016 Qualcomm Atheros, Inc.
|
|
|
+ * Copyright (c) 2012-2017 Qualcomm Atheros, Inc.
|
|
|
*
|
|
|
* Permission to use, copy, modify, and/or distribute this software for any
|
|
|
* purpose with or without fee is hereby granted, provided that the above
|
|
@@ -20,6 +20,10 @@
|
|
|
|
|
|
#define WIL_MAX_ROC_DURATION_MS 5000
|
|
|
|
|
|
+bool disable_ap_sme;
|
|
|
+module_param(disable_ap_sme, bool, 0444);
|
|
|
+MODULE_PARM_DESC(disable_ap_sme, " let user space handle AP mode SME");
|
|
|
+
|
|
|
#define CHAN60G(_channel, _flags) { \
|
|
|
.band = NL80211_BAND_60GHZ, \
|
|
|
.center_freq = 56160 + (2160 * (_channel)), \
|
|
@@ -62,9 +66,16 @@ wil_mgmt_stypes[NUM_NL80211_IFTYPES] = {
|
|
|
},
|
|
|
[NL80211_IFTYPE_AP] = {
|
|
|
.tx = BIT(IEEE80211_STYPE_ACTION >> 4) |
|
|
|
- BIT(IEEE80211_STYPE_PROBE_RESP >> 4),
|
|
|
+ BIT(IEEE80211_STYPE_PROBE_RESP >> 4) |
|
|
|
+ BIT(IEEE80211_STYPE_ASSOC_RESP >> 4) |
|
|
|
+ BIT(IEEE80211_STYPE_DISASSOC >> 4),
|
|
|
.rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
|
|
|
- BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
|
|
|
+ BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
|
|
|
+ BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
|
|
|
+ BIT(IEEE80211_STYPE_DISASSOC >> 4) |
|
|
|
+ BIT(IEEE80211_STYPE_AUTH >> 4) |
|
|
|
+ BIT(IEEE80211_STYPE_DEAUTH >> 4) |
|
|
|
+ BIT(IEEE80211_STYPE_REASSOC_REQ >> 4)
|
|
|
},
|
|
|
[NL80211_IFTYPE_P2P_CLIENT] = {
|
|
|
.tx = BIT(IEEE80211_STYPE_ACTION >> 4) |
|
|
@@ -194,7 +205,7 @@ static int wil_cfg80211_get_station(struct wiphy *wiphy,
|
|
|
|
|
|
int cid = wil_find_cid(wil, mac);
|
|
|
|
|
|
- wil_dbg_misc(wil, "%s(%pM) CID %d\n", __func__, mac, cid);
|
|
|
+ wil_dbg_misc(wil, "get_station: %pM CID %d\n", mac, cid);
|
|
|
if (cid < 0)
|
|
|
return cid;
|
|
|
|
|
@@ -233,7 +244,7 @@ static int wil_cfg80211_dump_station(struct wiphy *wiphy,
|
|
|
return -ENOENT;
|
|
|
|
|
|
ether_addr_copy(mac, wil->sta[cid].addr);
|
|
|
- wil_dbg_misc(wil, "%s(%pM) CID %d\n", __func__, mac, cid);
|
|
|
+ wil_dbg_misc(wil, "dump_station: %pM CID %d\n", mac, cid);
|
|
|
|
|
|
rc = wil_cid_fill_sinfo(wil, cid, sinfo);
|
|
|
|
|
@@ -250,16 +261,15 @@ wil_cfg80211_add_iface(struct wiphy *wiphy, const char *name,
|
|
|
struct net_device *ndev = wil_to_ndev(wil);
|
|
|
struct wireless_dev *p2p_wdev;
|
|
|
|
|
|
- wil_dbg_misc(wil, "%s()\n", __func__);
|
|
|
+ wil_dbg_misc(wil, "add_iface\n");
|
|
|
|
|
|
if (type != NL80211_IFTYPE_P2P_DEVICE) {
|
|
|
- wil_err(wil, "%s: unsupported iftype %d\n", __func__, type);
|
|
|
+ wil_err(wil, "unsupported iftype %d\n", type);
|
|
|
return ERR_PTR(-EINVAL);
|
|
|
}
|
|
|
|
|
|
if (wil->p2p_wdev) {
|
|
|
- wil_err(wil, "%s: P2P_DEVICE interface already created\n",
|
|
|
- __func__);
|
|
|
+ wil_err(wil, "P2P_DEVICE interface already created\n");
|
|
|
return ERR_PTR(-EINVAL);
|
|
|
}
|
|
|
|
|
@@ -282,11 +292,10 @@ static int wil_cfg80211_del_iface(struct wiphy *wiphy,
|
|
|
{
|
|
|
struct wil6210_priv *wil = wiphy_to_wil(wiphy);
|
|
|
|
|
|
- wil_dbg_misc(wil, "%s()\n", __func__);
|
|
|
+ wil_dbg_misc(wil, "del_iface\n");
|
|
|
|
|
|
if (wdev != wil->p2p_wdev) {
|
|
|
- wil_err(wil, "%s: delete of incorrect interface 0x%p\n",
|
|
|
- __func__, wdev);
|
|
|
+ wil_err(wil, "delete of incorrect interface 0x%p\n", wdev);
|
|
|
return -EINVAL;
|
|
|
}
|
|
|
|
|
@@ -304,7 +313,7 @@ static int wil_cfg80211_change_iface(struct wiphy *wiphy,
|
|
|
struct wireless_dev *wdev = wil_to_wdev(wil);
|
|
|
int rc;
|
|
|
|
|
|
- wil_dbg_misc(wil, "%s() type=%d\n", __func__, type);
|
|
|
+ wil_dbg_misc(wil, "change_iface: type=%d\n", type);
|
|
|
|
|
|
if (netif_running(wil_to_ndev(wil)) && !wil_is_recovery_blocked(wil)) {
|
|
|
wil_dbg_misc(wil, "interface is up. resetting...\n");
|
|
@@ -351,8 +360,7 @@ static int wil_cfg80211_scan(struct wiphy *wiphy,
|
|
|
uint i, n;
|
|
|
int rc;
|
|
|
|
|
|
- wil_dbg_misc(wil, "%s(), wdev=0x%p iftype=%d\n",
|
|
|
- __func__, wdev, wdev->iftype);
|
|
|
+ wil_dbg_misc(wil, "scan: wdev=0x%p iftype=%d\n", wdev, wdev->iftype);
|
|
|
|
|
|
/* check we are client side */
|
|
|
switch (wdev->iftype) {
|
|
@@ -557,7 +565,7 @@ static int wil_cfg80211_connect(struct wiphy *wiphy,
|
|
|
int rc = 0;
|
|
|
enum ieee80211_bss_type bss_type = IEEE80211_BSS_TYPE_ESS;
|
|
|
|
|
|
- wil_dbg_misc(wil, "%s()\n", __func__);
|
|
|
+ wil_dbg_misc(wil, "connect\n");
|
|
|
wil_print_connect_params(wil, sme);
|
|
|
|
|
|
if (test_bit(wil_status_fwconnecting, wil->status) ||
|
|
@@ -593,6 +601,7 @@ static int wil_cfg80211_connect(struct wiphy *wiphy,
|
|
|
goto out;
|
|
|
}
|
|
|
wil->privacy = sme->privacy;
|
|
|
+ wil->pbss = sme->pbss;
|
|
|
|
|
|
if (wil->privacy) {
|
|
|
/* For secure assoc, remove old keys */
|
|
@@ -689,12 +698,11 @@ static int wil_cfg80211_disconnect(struct wiphy *wiphy,
|
|
|
int rc;
|
|
|
struct wil6210_priv *wil = wiphy_to_wil(wiphy);
|
|
|
|
|
|
- wil_dbg_misc(wil, "%s(reason=%d)\n", __func__, reason_code);
|
|
|
+ wil_dbg_misc(wil, "disconnect: reason=%d\n", reason_code);
|
|
|
|
|
|
if (!(test_bit(wil_status_fwconnecting, wil->status) ||
|
|
|
test_bit(wil_status_fwconnected, wil->status))) {
|
|
|
- wil_err(wil, "%s: Disconnect was called while disconnected\n",
|
|
|
- __func__);
|
|
|
+ wil_err(wil, "Disconnect was called while disconnected\n");
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
@@ -702,7 +710,7 @@ static int wil_cfg80211_disconnect(struct wiphy *wiphy,
|
|
|
WMI_DISCONNECT_EVENTID, NULL, 0,
|
|
|
WIL6210_DISCONNECT_TO_MS);
|
|
|
if (rc)
|
|
|
- wil_err(wil, "%s: disconnect error %d\n", __func__, rc);
|
|
|
+ wil_err(wil, "disconnect error %d\n", rc);
|
|
|
|
|
|
return rc;
|
|
|
}
|
|
@@ -750,7 +758,7 @@ int wil_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
|
|
|
* different from currently "listened" channel and fail if it is.
|
|
|
*/
|
|
|
|
|
|
- wil_dbg_misc(wil, "%s()\n", __func__);
|
|
|
+ wil_dbg_misc(wil, "mgmt_tx\n");
|
|
|
print_hex_dump_bytes("mgmt tx frame ", DUMP_PREFIX_OFFSET, buf, len);
|
|
|
|
|
|
cmd = kmalloc(sizeof(*cmd) + len, GFP_KERNEL);
|
|
@@ -811,7 +819,7 @@ static enum wmi_key_usage wil_detect_key_usage(struct wil6210_priv *wil,
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
- wil_dbg_misc(wil, "%s() -> %s\n", __func__, key_usage_str[rc]);
|
|
|
+ wil_dbg_misc(wil, "detect_key_usage: -> %s\n", key_usage_str[rc]);
|
|
|
|
|
|
return rc;
|
|
|
}
|
|
@@ -916,13 +924,13 @@ static int wil_cfg80211_add_key(struct wiphy *wiphy,
|
|
|
return -EINVAL;
|
|
|
}
|
|
|
|
|
|
- wil_dbg_misc(wil, "%s(%pM %s[%d] PN %*phN)\n", __func__,
|
|
|
+ wil_dbg_misc(wil, "add_key: %pM %s[%d] PN %*phN\n",
|
|
|
mac_addr, key_usage_str[key_usage], key_index,
|
|
|
params->seq_len, params->seq);
|
|
|
|
|
|
if (IS_ERR(cs)) {
|
|
|
- wil_err(wil, "Not connected, %s(%pM %s[%d] PN %*phN)\n",
|
|
|
- __func__, mac_addr, key_usage_str[key_usage], key_index,
|
|
|
+ wil_err(wil, "Not connected, %pM %s[%d] PN %*phN\n",
|
|
|
+ mac_addr, key_usage_str[key_usage], key_index,
|
|
|
params->seq_len, params->seq);
|
|
|
return -EINVAL;
|
|
|
}
|
|
@@ -931,8 +939,8 @@ static int wil_cfg80211_add_key(struct wiphy *wiphy,
|
|
|
|
|
|
if (params->seq && params->seq_len != IEEE80211_GCMP_PN_LEN) {
|
|
|
wil_err(wil,
|
|
|
- "Wrong PN len %d, %s(%pM %s[%d] PN %*phN)\n",
|
|
|
- params->seq_len, __func__, mac_addr,
|
|
|
+ "Wrong PN len %d, %pM %s[%d] PN %*phN\n",
|
|
|
+ params->seq_len, mac_addr,
|
|
|
key_usage_str[key_usage], key_index,
|
|
|
params->seq_len, params->seq);
|
|
|
return -EINVAL;
|
|
@@ -956,11 +964,11 @@ static int wil_cfg80211_del_key(struct wiphy *wiphy,
|
|
|
struct wil_sta_info *cs = wil_find_sta_by_key_usage(wil, key_usage,
|
|
|
mac_addr);
|
|
|
|
|
|
- wil_dbg_misc(wil, "%s(%pM %s[%d])\n", __func__, mac_addr,
|
|
|
+ wil_dbg_misc(wil, "del_key: %pM %s[%d]\n", mac_addr,
|
|
|
key_usage_str[key_usage], key_index);
|
|
|
|
|
|
if (IS_ERR(cs))
|
|
|
- wil_info(wil, "Not connected, %s(%pM %s[%d])\n", __func__,
|
|
|
+ wil_info(wil, "Not connected, %pM %s[%d]\n",
|
|
|
mac_addr, key_usage_str[key_usage], key_index);
|
|
|
|
|
|
if (!IS_ERR_OR_NULL(cs))
|
|
@@ -977,7 +985,7 @@ static int wil_cfg80211_set_default_key(struct wiphy *wiphy,
|
|
|
{
|
|
|
struct wil6210_priv *wil = wiphy_to_wil(wiphy);
|
|
|
|
|
|
- wil_dbg_misc(wil, "%s: entered\n", __func__);
|
|
|
+ wil_dbg_misc(wil, "set_default_key: entered\n");
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
@@ -990,8 +998,9 @@ static int wil_remain_on_channel(struct wiphy *wiphy,
|
|
|
struct wil6210_priv *wil = wiphy_to_wil(wiphy);
|
|
|
int rc;
|
|
|
|
|
|
- wil_dbg_misc(wil, "%s() center_freq=%d, duration=%d iftype=%d\n",
|
|
|
- __func__, chan->center_freq, duration, wdev->iftype);
|
|
|
+ wil_dbg_misc(wil,
|
|
|
+ "remain_on_channel: center_freq=%d, duration=%d iftype=%d\n",
|
|
|
+ chan->center_freq, duration, wdev->iftype);
|
|
|
|
|
|
rc = wil_p2p_listen(wil, wdev, duration, chan, cookie);
|
|
|
return rc;
|
|
@@ -1003,7 +1012,7 @@ static int wil_cancel_remain_on_channel(struct wiphy *wiphy,
|
|
|
{
|
|
|
struct wil6210_priv *wil = wiphy_to_wil(wiphy);
|
|
|
|
|
|
- wil_dbg_misc(wil, "%s()\n", __func__);
|
|
|
+ wil_dbg_misc(wil, "cancel_remain_on_channel\n");
|
|
|
|
|
|
return wil_p2p_cancel_listen(wil, cookie);
|
|
|
}
|
|
@@ -1159,9 +1168,9 @@ static int _wil_cfg80211_start_ap(struct wiphy *wiphy,
|
|
|
if (pbss)
|
|
|
wmi_nettype = WMI_NETTYPE_P2P;
|
|
|
|
|
|
- wil_dbg_misc(wil, "%s: is_go=%d\n", __func__, is_go);
|
|
|
+ wil_dbg_misc(wil, "start_ap: is_go=%d\n", is_go);
|
|
|
if (is_go && !pbss) {
|
|
|
- wil_err(wil, "%s: P2P GO must be in PBSS\n", __func__);
|
|
|
+ wil_err(wil, "P2P GO must be in PBSS\n");
|
|
|
return -ENOTSUPP;
|
|
|
}
|
|
|
|
|
@@ -1216,7 +1225,7 @@ static int wil_cfg80211_change_beacon(struct wiphy *wiphy,
|
|
|
int rc;
|
|
|
u32 privacy = 0;
|
|
|
|
|
|
- wil_dbg_misc(wil, "%s()\n", __func__);
|
|
|
+ wil_dbg_misc(wil, "change_beacon\n");
|
|
|
wil_print_bcon_data(bcon);
|
|
|
|
|
|
if (bcon->tail &&
|
|
@@ -1255,7 +1264,7 @@ static int wil_cfg80211_start_ap(struct wiphy *wiphy,
|
|
|
struct cfg80211_crypto_settings *crypto = &info->crypto;
|
|
|
u8 hidden_ssid;
|
|
|
|
|
|
- wil_dbg_misc(wil, "%s()\n", __func__);
|
|
|
+ wil_dbg_misc(wil, "start_ap\n");
|
|
|
|
|
|
if (!channel) {
|
|
|
wil_err(wil, "AP: No channel???\n");
|
|
@@ -1306,7 +1315,7 @@ static int wil_cfg80211_stop_ap(struct wiphy *wiphy,
|
|
|
{
|
|
|
struct wil6210_priv *wil = wiphy_to_wil(wiphy);
|
|
|
|
|
|
- wil_dbg_misc(wil, "%s()\n", __func__);
|
|
|
+ wil_dbg_misc(wil, "stop_ap\n");
|
|
|
|
|
|
netif_carrier_off(ndev);
|
|
|
wil_set_recovery_state(wil, fw_recovery_idle);
|
|
@@ -1322,13 +1331,35 @@ static int wil_cfg80211_stop_ap(struct wiphy *wiphy,
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
+static int wil_cfg80211_add_station(struct wiphy *wiphy,
|
|
|
+ struct net_device *dev,
|
|
|
+ const u8 *mac,
|
|
|
+ struct station_parameters *params)
|
|
|
+{
|
|
|
+ struct wil6210_priv *wil = wiphy_to_wil(wiphy);
|
|
|
+
|
|
|
+ wil_dbg_misc(wil, "add station %pM aid %d\n", mac, params->aid);
|
|
|
+
|
|
|
+ if (!disable_ap_sme) {
|
|
|
+ wil_err(wil, "not supported with AP SME enabled\n");
|
|
|
+ return -EOPNOTSUPP;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (params->aid > WIL_MAX_DMG_AID) {
|
|
|
+ wil_err(wil, "invalid aid\n");
|
|
|
+ return -EINVAL;
|
|
|
+ }
|
|
|
+
|
|
|
+ return wmi_new_sta(wil, mac, params->aid);
|
|
|
+}
|
|
|
+
|
|
|
static int wil_cfg80211_del_station(struct wiphy *wiphy,
|
|
|
struct net_device *dev,
|
|
|
struct station_del_parameters *params)
|
|
|
{
|
|
|
struct wil6210_priv *wil = wiphy_to_wil(wiphy);
|
|
|
|
|
|
- wil_dbg_misc(wil, "%s(%pM, reason=%d)\n", __func__, params->mac,
|
|
|
+ wil_dbg_misc(wil, "del_station: %pM, reason=%d\n", params->mac,
|
|
|
params->reason_code);
|
|
|
|
|
|
mutex_lock(&wil->mutex);
|
|
@@ -1338,6 +1369,52 @@ static int wil_cfg80211_del_station(struct wiphy *wiphy,
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
+static int wil_cfg80211_change_station(struct wiphy *wiphy,
|
|
|
+ struct net_device *dev,
|
|
|
+ const u8 *mac,
|
|
|
+ struct station_parameters *params)
|
|
|
+{
|
|
|
+ struct wil6210_priv *wil = wiphy_to_wil(wiphy);
|
|
|
+ int authorize;
|
|
|
+ int cid, i;
|
|
|
+ struct vring_tx_data *txdata = NULL;
|
|
|
+
|
|
|
+ wil_dbg_misc(wil, "change station %pM mask 0x%x set 0x%x\n", mac,
|
|
|
+ params->sta_flags_mask, params->sta_flags_set);
|
|
|
+
|
|
|
+ if (!disable_ap_sme) {
|
|
|
+ wil_dbg_misc(wil, "not supported with AP SME enabled\n");
|
|
|
+ return -EOPNOTSUPP;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!(params->sta_flags_mask & BIT(NL80211_STA_FLAG_AUTHORIZED)))
|
|
|
+ return 0;
|
|
|
+
|
|
|
+ cid = wil_find_cid(wil, mac);
|
|
|
+ if (cid < 0) {
|
|
|
+ wil_err(wil, "station not found\n");
|
|
|
+ return -ENOLINK;
|
|
|
+ }
|
|
|
+
|
|
|
+ for (i = 0; i < ARRAY_SIZE(wil->vring2cid_tid); i++)
|
|
|
+ if (wil->vring2cid_tid[i][0] == cid) {
|
|
|
+ txdata = &wil->vring_tx_data[i];
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!txdata) {
|
|
|
+ wil_err(wil, "vring data not found\n");
|
|
|
+ return -ENOLINK;
|
|
|
+ }
|
|
|
+
|
|
|
+ authorize = params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED);
|
|
|
+ txdata->dot1x_open = authorize ? 1 : 0;
|
|
|
+ wil_dbg_misc(wil, "cid %d vring %d authorize %d\n", cid, i,
|
|
|
+ txdata->dot1x_open);
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
/* probe_client handling */
|
|
|
static void wil_probe_client_handle(struct wil6210_priv *wil,
|
|
|
struct wil_probe_client_req *req)
|
|
@@ -1387,7 +1464,7 @@ void wil_probe_client_flush(struct wil6210_priv *wil)
|
|
|
{
|
|
|
struct wil_probe_client_req *req, *t;
|
|
|
|
|
|
- wil_dbg_misc(wil, "%s()\n", __func__);
|
|
|
+ wil_dbg_misc(wil, "probe_client_flush\n");
|
|
|
|
|
|
mutex_lock(&wil->probe_client_mutex);
|
|
|
|
|
@@ -1407,7 +1484,7 @@ static int wil_cfg80211_probe_client(struct wiphy *wiphy,
|
|
|
struct wil_probe_client_req *req;
|
|
|
int cid = wil_find_cid(wil, peer);
|
|
|
|
|
|
- wil_dbg_misc(wil, "%s(%pM => CID %d)\n", __func__, peer, cid);
|
|
|
+ wil_dbg_misc(wil, "probe_client: %pM => CID %d\n", peer, cid);
|
|
|
|
|
|
if (cid < 0)
|
|
|
return -ENOLINK;
|
|
@@ -1435,7 +1512,7 @@ static int wil_cfg80211_change_bss(struct wiphy *wiphy,
|
|
|
struct wil6210_priv *wil = wiphy_to_wil(wiphy);
|
|
|
|
|
|
if (params->ap_isolate >= 0) {
|
|
|
- wil_dbg_misc(wil, "%s(ap_isolate %d => %d)\n", __func__,
|
|
|
+ wil_dbg_misc(wil, "change_bss: ap_isolate %d => %d\n",
|
|
|
wil->ap_isolate, params->ap_isolate);
|
|
|
wil->ap_isolate = params->ap_isolate;
|
|
|
}
|
|
@@ -1448,7 +1525,7 @@ static int wil_cfg80211_start_p2p_device(struct wiphy *wiphy,
|
|
|
{
|
|
|
struct wil6210_priv *wil = wiphy_to_wil(wiphy);
|
|
|
|
|
|
- wil_dbg_misc(wil, "%s: entered\n", __func__);
|
|
|
+ wil_dbg_misc(wil, "start_p2p_device: entered\n");
|
|
|
wil->p2p.p2p_dev_started = 1;
|
|
|
return 0;
|
|
|
}
|
|
@@ -1462,7 +1539,7 @@ static void wil_cfg80211_stop_p2p_device(struct wiphy *wiphy,
|
|
|
if (!p2p->p2p_dev_started)
|
|
|
return;
|
|
|
|
|
|
- wil_dbg_misc(wil, "%s: entered\n", __func__);
|
|
|
+ wil_dbg_misc(wil, "stop_p2p_device: entered\n");
|
|
|
mutex_lock(&wil->mutex);
|
|
|
mutex_lock(&wil->p2p_wdev_mutex);
|
|
|
wil_p2p_stop_radio_operations(wil);
|
|
@@ -1499,7 +1576,7 @@ static int wil_cfg80211_set_power_mgmt(struct wiphy *wiphy,
|
|
|
return rc;
|
|
|
}
|
|
|
|
|
|
-static struct cfg80211_ops wil_cfg80211_ops = {
|
|
|
+static const struct cfg80211_ops wil_cfg80211_ops = {
|
|
|
.add_virtual_intf = wil_cfg80211_add_iface,
|
|
|
.del_virtual_intf = wil_cfg80211_del_iface,
|
|
|
.scan = wil_cfg80211_scan,
|
|
@@ -1521,7 +1598,9 @@ static struct cfg80211_ops wil_cfg80211_ops = {
|
|
|
.change_beacon = wil_cfg80211_change_beacon,
|
|
|
.start_ap = wil_cfg80211_start_ap,
|
|
|
.stop_ap = wil_cfg80211_stop_ap,
|
|
|
+ .add_station = wil_cfg80211_add_station,
|
|
|
.del_station = wil_cfg80211_del_station,
|
|
|
+ .change_station = wil_cfg80211_change_station,
|
|
|
.probe_client = wil_cfg80211_probe_client,
|
|
|
.change_bss = wil_cfg80211_change_bss,
|
|
|
/* P2P device */
|
|
@@ -1542,10 +1621,11 @@ static void wil_wiphy_init(struct wiphy *wiphy)
|
|
|
BIT(NL80211_IFTYPE_P2P_GO) |
|
|
|
BIT(NL80211_IFTYPE_P2P_DEVICE) |
|
|
|
BIT(NL80211_IFTYPE_MONITOR);
|
|
|
- wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME |
|
|
|
- WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL |
|
|
|
+ wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL |
|
|
|
WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD |
|
|
|
WIPHY_FLAG_PS_ON_BY_DEFAULT;
|
|
|
+ if (!disable_ap_sme)
|
|
|
+ wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME;
|
|
|
dev_dbg(wiphy_dev(wiphy), "%s : flags = 0x%08x\n",
|
|
|
__func__, wiphy->flags);
|
|
|
wiphy->probe_resp_offload =
|