summaryrefslogtreecommitdiff
path: root/drivers/net/wireless/mwifiex/cfg80211.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/mwifiex/cfg80211.c')
-rw-r--r--drivers/net/wireless/mwifiex/cfg80211.c107
1 files changed, 75 insertions, 32 deletions
diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c
index 1996a8b612d2..7be1e9b83fd0 100644
--- a/drivers/net/wireless/mwifiex/cfg80211.c
+++ b/drivers/net/wireless/mwifiex/cfg80211.c
@@ -1786,6 +1786,7 @@ mwifiex_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
struct cfg80211_connect_params *sme)
{
struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
+ struct mwifiex_adapter *adapter = priv->adapter;
int ret;
if (GET_BSS_ROLE(priv) != MWIFIEX_BSS_ROLE_STA) {
@@ -1800,6 +1801,13 @@ mwifiex_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
return -EALREADY;
}
+ if (adapter->surprise_removed || adapter->is_cmd_timedout) {
+ wiphy_err(wiphy,
+ "%s: Ignore connection. Card removed or FW in bad state\n",
+ dev->name);
+ return -EFAULT;
+ }
+
wiphy_dbg(wiphy, "info: Trying to associate to %s and bssid %pM\n",
(char *) sme->ssid, sme->bssid);
@@ -2388,6 +2396,10 @@ int mwifiex_del_virtual_intf(struct wiphy *wiphy, struct wireless_dev *wdev)
priv->bss_mode = NL80211_IFTYPE_UNSPECIFIED;
+ if (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA ||
+ GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_UAP)
+ kfree(priv->hist_data);
+
return 0;
}
EXPORT_SYMBOL_GPL(mwifiex_del_virtual_intf);
@@ -2423,30 +2435,16 @@ mwifiex_is_pattern_supported(struct cfg80211_pkt_pattern *pat, s8 *byte_seq,
}
#ifdef CONFIG_PM
-static int mwifiex_cfg80211_suspend(struct wiphy *wiphy,
- struct cfg80211_wowlan *wowlan)
+static int mwifiex_set_mef_filter(struct mwifiex_private *priv,
+ struct cfg80211_wowlan *wowlan)
{
- struct mwifiex_adapter *adapter = mwifiex_cfg80211_get_adapter(wiphy);
- struct mwifiex_ds_mef_cfg mef_cfg;
- struct mwifiex_mef_entry *mef_entry;
- int i, filt_num = 0, ret;
+ int i, filt_num = 0, ret = 0;
bool first_pat = true;
u8 byte_seq[MWIFIEX_MEF_MAX_BYTESEQ + 1];
const u8 ipv4_mc_mac[] = {0x33, 0x33};
const u8 ipv6_mc_mac[] = {0x01, 0x00, 0x5e};
- struct mwifiex_private *priv =
- mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_STA);
-
- if (!wowlan) {
- dev_warn(adapter->dev, "None of the WOWLAN triggers enabled\n");
- return 0;
- }
-
- if (!priv->media_connected) {
- dev_warn(adapter->dev,
- "Can not configure WOWLAN in disconnected state\n");
- return 0;
- }
+ struct mwifiex_ds_mef_cfg mef_cfg;
+ struct mwifiex_mef_entry *mef_entry;
mef_entry = kzalloc(sizeof(*mef_entry), GFP_KERNEL);
if (!mef_entry)
@@ -2461,9 +2459,9 @@ static int mwifiex_cfg80211_suspend(struct wiphy *wiphy,
for (i = 0; i < wowlan->n_patterns; i++) {
memset(byte_seq, 0, sizeof(byte_seq));
if (!mwifiex_is_pattern_supported(&wowlan->patterns[i],
- byte_seq,
- MWIFIEX_MEF_MAX_BYTESEQ)) {
- wiphy_err(wiphy, "Pattern not supported\n");
+ byte_seq,
+ MWIFIEX_MEF_MAX_BYTESEQ)) {
+ dev_err(priv->adapter->dev, "Pattern not supported\n");
kfree(mef_entry);
return -EOPNOTSUPP;
}
@@ -2487,9 +2485,9 @@ static int mwifiex_cfg80211_suspend(struct wiphy *wiphy,
mef_entry->filter[filt_num].repeat = 1;
mef_entry->filter[filt_num].offset =
- wowlan->patterns[i].pkt_offset;
+ wowlan->patterns[i].pkt_offset;
memcpy(mef_entry->filter[filt_num].byte_seq, byte_seq,
- sizeof(byte_seq));
+ sizeof(byte_seq));
mef_entry->filter[filt_num].filt_type = TYPE_EQ;
if (first_pat)
@@ -2504,9 +2502,9 @@ static int mwifiex_cfg80211_suspend(struct wiphy *wiphy,
mef_cfg.criteria |= MWIFIEX_CRITERIA_UNICAST;
mef_entry->filter[filt_num].repeat = 16;
memcpy(mef_entry->filter[filt_num].byte_seq, priv->curr_addr,
- ETH_ALEN);
+ ETH_ALEN);
mef_entry->filter[filt_num].byte_seq[MWIFIEX_MEF_MAX_BYTESEQ] =
- ETH_ALEN;
+ ETH_ALEN;
mef_entry->filter[filt_num].offset = 28;
mef_entry->filter[filt_num].filt_type = TYPE_EQ;
if (filt_num)
@@ -2515,9 +2513,9 @@ static int mwifiex_cfg80211_suspend(struct wiphy *wiphy,
filt_num++;
mef_entry->filter[filt_num].repeat = 16;
memcpy(mef_entry->filter[filt_num].byte_seq, priv->curr_addr,
- ETH_ALEN);
+ ETH_ALEN);
mef_entry->filter[filt_num].byte_seq[MWIFIEX_MEF_MAX_BYTESEQ] =
- ETH_ALEN;
+ ETH_ALEN;
mef_entry->filter[filt_num].offset = 56;
mef_entry->filter[filt_num].filt_type = TYPE_EQ;
mef_entry->filter[filt_num].filt_action = TYPE_OR;
@@ -2525,16 +2523,61 @@ static int mwifiex_cfg80211_suspend(struct wiphy *wiphy,
if (!mef_cfg.criteria)
mef_cfg.criteria = MWIFIEX_CRITERIA_BROADCAST |
- MWIFIEX_CRITERIA_UNICAST |
- MWIFIEX_CRITERIA_MULTICAST;
+ MWIFIEX_CRITERIA_UNICAST |
+ MWIFIEX_CRITERIA_MULTICAST;
ret = mwifiex_send_cmd(priv, HostCmd_CMD_MEF_CFG,
- HostCmd_ACT_GEN_SET, 0, &mef_cfg, true);
+ HostCmd_ACT_GEN_SET, 0, &mef_cfg, true);
kfree(mef_entry);
return ret;
}
+static int mwifiex_cfg80211_suspend(struct wiphy *wiphy,
+ struct cfg80211_wowlan *wowlan)
+{
+ struct mwifiex_adapter *adapter = mwifiex_cfg80211_get_adapter(wiphy);
+ struct mwifiex_ds_hs_cfg hs_cfg;
+ int ret = 0;
+ struct mwifiex_private *priv =
+ mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_STA);
+
+ if (!wowlan) {
+ dev_warn(adapter->dev, "None of the WOWLAN triggers enabled\n");
+ return 0;
+ }
+
+ if (!priv->media_connected) {
+ dev_warn(adapter->dev,
+ "Can not configure WOWLAN in disconnected state\n");
+ return 0;
+ }
+
+ if (wowlan->n_patterns || wowlan->magic_pkt) {
+ ret = mwifiex_set_mef_filter(priv, wowlan);
+ if (ret) {
+ dev_err(adapter->dev, "Failed to set MEF filter\n");
+ return ret;
+ }
+ }
+
+ if (wowlan->disconnect) {
+ memset(&hs_cfg, 0, sizeof(hs_cfg));
+ hs_cfg.is_invoke_hostcmd = false;
+ hs_cfg.conditions = HS_CFG_COND_MAC_EVENT;
+ hs_cfg.gpio = HS_CFG_GPIO_DEF;
+ hs_cfg.gap = HS_CFG_GAP_DEF;
+ ret = mwifiex_set_hs_params(priv, HostCmd_ACT_GEN_SET,
+ MWIFIEX_SYNC_CMD, &hs_cfg);
+ if (ret) {
+ dev_err(adapter->dev, "Failed to set HS params\n");
+ return ret;
+ }
+ }
+
+ return ret;
+}
+
static int mwifiex_cfg80211_resume(struct wiphy *wiphy)
{
return 0;
@@ -2872,7 +2915,7 @@ static struct cfg80211_ops mwifiex_cfg80211_ops = {
#ifdef CONFIG_PM
static const struct wiphy_wowlan_support mwifiex_wowlan_support = {
- .flags = WIPHY_WOWLAN_MAGIC_PKT,
+ .flags = WIPHY_WOWLAN_MAGIC_PKT | WIPHY_WOWLAN_DISCONNECT,
.n_patterns = MWIFIEX_MEF_MAX_FILTERS,
.pattern_min_len = 1,
.pattern_max_len = MWIFIEX_MAX_PATTERN_LEN,