summaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/marvell
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/marvell')
-rw-r--r--drivers/net/wireless/marvell/mwifiex/11n_aggr.c2
-rw-r--r--drivers/net/wireless/marvell/mwifiex/11n_rxreorder.c10
-rw-r--r--drivers/net/wireless/marvell/mwifiex/cfg80211.c62
-rw-r--r--drivers/net/wireless/marvell/mwifiex/cfp.c6
-rw-r--r--drivers/net/wireless/marvell/mwifiex/cmdevt.c4
-rw-r--r--drivers/net/wireless/marvell/mwifiex/debugfs.c30
-rw-r--r--drivers/net/wireless/marvell/mwifiex/decl.h6
-rw-r--r--drivers/net/wireless/marvell/mwifiex/fw.h13
-rw-r--r--drivers/net/wireless/marvell/mwifiex/ie.c2
-rw-r--r--drivers/net/wireless/marvell/mwifiex/init.c2
-rw-r--r--drivers/net/wireless/marvell/mwifiex/join.c20
-rw-r--r--drivers/net/wireless/marvell/mwifiex/main.h50
-rw-r--r--drivers/net/wireless/marvell/mwifiex/pcie.c33
-rw-r--r--drivers/net/wireless/marvell/mwifiex/pcie.h10
-rw-r--r--drivers/net/wireless/marvell/mwifiex/sta_ioctl.c85
-rw-r--r--drivers/net/wireless/marvell/mwifiex/sta_rx.c2
-rw-r--r--drivers/net/wireless/marvell/mwifiex/uap_cmd.c6
-rw-r--r--drivers/net/wireless/marvell/mwifiex/uap_txrx.c3
18 files changed, 249 insertions, 97 deletions
diff --git a/drivers/net/wireless/marvell/mwifiex/11n_aggr.c b/drivers/net/wireless/marvell/mwifiex/11n_aggr.c
index aa498e0d2204..1efef3b8273d 100644
--- a/drivers/net/wireless/marvell/mwifiex/11n_aggr.c
+++ b/drivers/net/wireless/marvell/mwifiex/11n_aggr.c
@@ -203,8 +203,6 @@ mwifiex_11n_aggregate_pkt(struct mwifiex_private *priv,
skb_aggr->priority = skb_src->priority;
skb_aggr->tstamp = skb_src->tstamp;
- skb_aggr->tstamp = ktime_get_real();
-
do {
/* Check if AMSDU can accommodate this MSDU */
if (skb_tailroom(skb_aggr) < (skb_src->len + LLC_SNAP_LEN))
diff --git a/drivers/net/wireless/marvell/mwifiex/11n_rxreorder.c b/drivers/net/wireless/marvell/mwifiex/11n_rxreorder.c
index b3970a8c9e48..09578c6cde59 100644
--- a/drivers/net/wireless/marvell/mwifiex/11n_rxreorder.c
+++ b/drivers/net/wireless/marvell/mwifiex/11n_rxreorder.c
@@ -48,7 +48,17 @@ static int mwifiex_11n_dispatch_amsdu_pkt(struct mwifiex_private *priv,
priv->wdev.iftype, 0, false);
while (!skb_queue_empty(&list)) {
+ struct rx_packet_hdr *rx_hdr;
+
rx_skb = __skb_dequeue(&list);
+ rx_hdr = (struct rx_packet_hdr *)rx_skb->data;
+ if (ISSUPP_TDLS_ENABLED(priv->adapter->fw_cap_info) &&
+ ntohs(rx_hdr->eth803_hdr.h_proto) == ETH_P_TDLS) {
+ mwifiex_process_tdls_action_frame(priv,
+ (u8 *)rx_hdr,
+ skb->len);
+ }
+
ret = mwifiex_recv_packet(priv, rx_skb);
if (ret == -1)
mwifiex_dbg(priv->adapter, ERROR,
diff --git a/drivers/net/wireless/marvell/mwifiex/cfg80211.c b/drivers/net/wireless/marvell/mwifiex/cfg80211.c
index 4073116e6e9f..e7adef72c05f 100644
--- a/drivers/net/wireless/marvell/mwifiex/cfg80211.c
+++ b/drivers/net/wireless/marvell/mwifiex/cfg80211.c
@@ -26,12 +26,10 @@ module_param(reg_alpha2, charp, 0);
static const struct ieee80211_iface_limit mwifiex_ap_sta_limits[] = {
{
- .max = 2, .types = BIT(NL80211_IFTYPE_STATION) |
+ .max = 3, .types = BIT(NL80211_IFTYPE_STATION) |
BIT(NL80211_IFTYPE_P2P_GO) |
- BIT(NL80211_IFTYPE_P2P_CLIENT),
- },
- {
- .max = 1, .types = BIT(NL80211_IFTYPE_AP),
+ BIT(NL80211_IFTYPE_P2P_CLIENT) |
+ BIT(NL80211_IFTYPE_AP),
},
};
@@ -827,18 +825,26 @@ mwifiex_init_new_priv_params(struct mwifiex_private *priv,
switch (type) {
case NL80211_IFTYPE_STATION:
case NL80211_IFTYPE_ADHOC:
+ priv->bss_num = mwifiex_get_unused_bss_num(adapter,
+ MWIFIEX_BSS_TYPE_STA);
priv->bss_role = MWIFIEX_BSS_ROLE_STA;
priv->bss_type = MWIFIEX_BSS_TYPE_STA;
break;
case NL80211_IFTYPE_P2P_CLIENT:
+ priv->bss_num = mwifiex_get_unused_bss_num(adapter,
+ MWIFIEX_BSS_TYPE_P2P);
priv->bss_role = MWIFIEX_BSS_ROLE_STA;
priv->bss_type = MWIFIEX_BSS_TYPE_P2P;
break;
case NL80211_IFTYPE_P2P_GO:
+ priv->bss_num = mwifiex_get_unused_bss_num(adapter,
+ MWIFIEX_BSS_TYPE_P2P);
priv->bss_role = MWIFIEX_BSS_ROLE_UAP;
priv->bss_type = MWIFIEX_BSS_TYPE_P2P;
break;
case NL80211_IFTYPE_AP:
+ priv->bss_num = mwifiex_get_unused_bss_num(adapter,
+ MWIFIEX_BSS_TYPE_UAP);
priv->bss_type = MWIFIEX_BSS_TYPE_UAP;
priv->bss_role = MWIFIEX_BSS_ROLE_UAP;
break;
@@ -1533,6 +1539,7 @@ static const u32 mwifiex_cipher_suites[] = {
WLAN_CIPHER_SUITE_WEP104,
WLAN_CIPHER_SUITE_TKIP,
WLAN_CIPHER_SUITE_CCMP,
+ WLAN_CIPHER_SUITE_SMS4,
WLAN_CIPHER_SUITE_AES_CMAC,
};
@@ -1701,6 +1708,11 @@ mwifiex_cfg80211_del_station(struct wiphy *wiphy, struct net_device *dev,
u8 deauth_mac[ETH_ALEN];
unsigned long flags;
+ if (!priv->bss_started && priv->wdev.cac_started) {
+ mwifiex_dbg(priv->adapter, INFO, "%s: abort CAC!\n", __func__);
+ mwifiex_abort_cac(priv);
+ }
+
if (list_empty(&priv->sta_list) || !priv->bss_started)
return 0;
@@ -2608,7 +2620,8 @@ struct wireless_dev *mwifiex_add_virtual_intf(struct wiphy *wiphy,
return ERR_PTR(-EINVAL);
}
- priv = mwifiex_get_unused_priv(adapter);
+ priv = mwifiex_get_unused_priv_by_bss_type(
+ adapter, MWIFIEX_BSS_TYPE_STA);
if (!priv) {
mwifiex_dbg(adapter, ERROR,
"could not get free private struct\n");
@@ -2627,7 +2640,6 @@ struct wireless_dev *mwifiex_add_virtual_intf(struct wiphy *wiphy,
priv->frame_type = MWIFIEX_DATA_FRAME_TYPE_ETH_II;
priv->bss_priority = 0;
priv->bss_role = MWIFIEX_BSS_ROLE_STA;
- priv->bss_num = adapter->curr_iface_comb.sta_intf;
break;
case NL80211_IFTYPE_AP:
@@ -2638,7 +2650,8 @@ struct wireless_dev *mwifiex_add_virtual_intf(struct wiphy *wiphy,
return ERR_PTR(-EINVAL);
}
- priv = mwifiex_get_unused_priv(adapter);
+ priv = mwifiex_get_unused_priv_by_bss_type(
+ adapter, MWIFIEX_BSS_TYPE_UAP);
if (!priv) {
mwifiex_dbg(adapter, ERROR,
"could not get free private struct\n");
@@ -2653,7 +2666,6 @@ struct wireless_dev *mwifiex_add_virtual_intf(struct wiphy *wiphy,
priv->bss_priority = 0;
priv->bss_role = MWIFIEX_BSS_ROLE_UAP;
priv->bss_started = 0;
- priv->bss_num = adapter->curr_iface_comb.uap_intf;
priv->bss_mode = type;
break;
@@ -2665,7 +2677,8 @@ struct wireless_dev *mwifiex_add_virtual_intf(struct wiphy *wiphy,
return ERR_PTR(-EINVAL);
}
- priv = mwifiex_get_unused_priv(adapter);
+ priv = mwifiex_get_unused_priv_by_bss_type(
+ adapter, MWIFIEX_BSS_TYPE_P2P);
if (!priv) {
mwifiex_dbg(adapter, ERROR,
"could not get free private struct\n");
@@ -2689,7 +2702,6 @@ struct wireless_dev *mwifiex_add_virtual_intf(struct wiphy *wiphy,
priv->bss_priority = MWIFIEX_BSS_ROLE_STA;
priv->bss_role = MWIFIEX_BSS_ROLE_STA;
priv->bss_started = 0;
- priv->bss_num = adapter->curr_iface_comb.p2p_intf;
if (mwifiex_cfg80211_init_p2p_client(priv)) {
memset(&priv->wdev, 0, sizeof(priv->wdev));
@@ -2914,6 +2926,12 @@ mwifiex_is_pattern_supported(struct cfg80211_pkt_pattern *pat, s8 *byte_seq,
dont_care_byte = true;
}
+ /* wildcard bytes record as the offset
+ * before the valid byte
+ */
+ if (!valid_byte_cnt && !dont_care_byte)
+ pat->pkt_offset++;
+
if (valid_byte_cnt > max_byte_seq)
return false;
}
@@ -3141,8 +3159,8 @@ static int mwifiex_cfg80211_suspend(struct wiphy *wiphy,
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;
+ hs_cfg.gpio = adapter->hs_cfg.gpio;
+ hs_cfg.gap = adapter->hs_cfg.gap;
ret = mwifiex_set_hs_params(priv, HostCmd_ACT_GEN_SET,
MWIFIEX_SYNC_CMD, &hs_cfg);
if (ret) {
@@ -3802,6 +3820,10 @@ int mwifiex_register_cfg80211(struct mwifiex_adapter *adapter)
wiphy->cipher_suites = mwifiex_cipher_suites;
wiphy->n_cipher_suites = ARRAY_SIZE(mwifiex_cipher_suites);
+ if (adapter->region_code)
+ wiphy->regulatory_flags |= REGULATORY_DISABLE_BEACON_HINTS |
+ REGULATORY_COUNTRY_IE_IGNORE;
+
ether_addr_copy(wiphy->perm_addr, adapter->perm_addr);
wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME |
@@ -3862,11 +3884,15 @@ int mwifiex_register_cfg80211(struct mwifiex_adapter *adapter)
"driver hint alpha2: %2.2s\n", reg_alpha2);
regulatory_hint(wiphy, reg_alpha2);
} else {
- country_code = mwifiex_11d_code_2_region(adapter->region_code);
- if (country_code)
- mwifiex_dbg(adapter, WARN,
- "ignoring F/W country code %2.2s\n",
- country_code);
+ if (adapter->region_code == 0x00) {
+ mwifiex_dbg(adapter, WARN, "Ignore world regulatory domain\n");
+ } else {
+ country_code =
+ mwifiex_11d_code_2_region(adapter->region_code);
+ if (country_code &&
+ regulatory_hint(wiphy, country_code))
+ mwifiex_dbg(priv->adapter, ERROR, "regulatory_hint() failed\n");
+ }
}
mwifiex_send_cmd(priv, HostCmd_CMD_802_11_SNMP_MIB,
diff --git a/drivers/net/wireless/marvell/mwifiex/cfp.c b/drivers/net/wireless/marvell/mwifiex/cfp.c
index 3ddb8ec676ed..09fae27140f7 100644
--- a/drivers/net/wireless/marvell/mwifiex/cfp.c
+++ b/drivers/net/wireless/marvell/mwifiex/cfp.c
@@ -66,8 +66,8 @@ static u8 supported_rates_bg[BG_SUPPORTED_RATES] = { 0x02, 0x04, 0x0b, 0x0c,
0x12, 0x16, 0x18, 0x24, 0x30, 0x48,
0x60, 0x6c, 0 };
-u16 region_code_index[MWIFIEX_MAX_REGION_CODE] = { 0x10, 0x20, 0x30,
- 0x32, 0x40, 0x41, 0xff };
+u16 region_code_index[MWIFIEX_MAX_REGION_CODE] = { 0x00, 0x10, 0x20, 0x30,
+ 0x31, 0x32, 0x40, 0x41, 0x50 };
static u8 supported_rates_n[N_SUPPORTED_RATES] = { 0x02, 0x04, 0 };
@@ -168,7 +168,7 @@ struct region_code_mapping {
static struct region_code_mapping region_code_mapping_t[] = {
{ 0x10, "US " }, /* US FCC */
{ 0x20, "CA " }, /* IC Canada */
- { 0x30, "EU " }, /* ETSI */
+ { 0x30, "FR " }, /* France */
{ 0x31, "ES " }, /* Spain */
{ 0x32, "FR " }, /* France */
{ 0x40, "JP " }, /* Japan */
diff --git a/drivers/net/wireless/marvell/mwifiex/cmdevt.c b/drivers/net/wireless/marvell/mwifiex/cmdevt.c
index 45ae38e32621..cb25aa7e90db 100644
--- a/drivers/net/wireless/marvell/mwifiex/cmdevt.c
+++ b/drivers/net/wireless/marvell/mwifiex/cmdevt.c
@@ -1637,9 +1637,9 @@ int mwifiex_ret_get_hw_spec(struct mwifiex_private *priv,
if (adapter->region_code == region_code_index[i])
break;
- /* If it's unidentified region code, use the default (USA) */
+ /* If it's unidentified region code, use the default (world) */
if (i >= MWIFIEX_MAX_REGION_CODE) {
- adapter->region_code = 0x10;
+ adapter->region_code = 0x00;
mwifiex_dbg(adapter, WARN,
"cmd: unknown region code, use default (USA)\n");
}
diff --git a/drivers/net/wireless/marvell/mwifiex/debugfs.c b/drivers/net/wireless/marvell/mwifiex/debugfs.c
index 9824d8dd2b44..5e5562909d9f 100644
--- a/drivers/net/wireless/marvell/mwifiex/debugfs.c
+++ b/drivers/net/wireless/marvell/mwifiex/debugfs.c
@@ -906,6 +906,34 @@ mwifiex_timeshare_coex_write(struct file *file, const char __user *ubuf,
return count;
}
+static ssize_t
+mwifiex_reset_write(struct file *file,
+ const char __user *ubuf, size_t count, loff_t *ppos)
+{
+ struct mwifiex_private *priv = file->private_data;
+ struct mwifiex_adapter *adapter = priv->adapter;
+ char cmd;
+ bool result;
+
+ if (copy_from_user(&cmd, ubuf, sizeof(cmd)))
+ return -EFAULT;
+
+ if (strtobool(&cmd, &result))
+ return -EINVAL;
+
+ if (!result)
+ return -EINVAL;
+
+ if (adapter->if_ops.card_reset) {
+ dev_info(adapter->dev, "Resetting per request\n");
+ adapter->hw_status = MWIFIEX_HW_STATUS_RESET;
+ mwifiex_cancel_all_pending_cmd(adapter);
+ adapter->if_ops.card_reset(adapter);
+ }
+
+ return count;
+}
+
#define MWIFIEX_DFS_ADD_FILE(name) do { \
if (!debugfs_create_file(#name, 0644, priv->dfs_dev_dir, \
priv, &mwifiex_dfs_##name##_fops)) \
@@ -943,6 +971,7 @@ MWIFIEX_DFS_FILE_OPS(hscfg);
MWIFIEX_DFS_FILE_OPS(histogram);
MWIFIEX_DFS_FILE_OPS(debug_mask);
MWIFIEX_DFS_FILE_OPS(timeshare_coex);
+MWIFIEX_DFS_FILE_WRITE_OPS(reset);
/*
* This function creates the debug FS directory structure and the files.
@@ -970,6 +999,7 @@ mwifiex_dev_debugfs_init(struct mwifiex_private *priv)
MWIFIEX_DFS_ADD_FILE(histogram);
MWIFIEX_DFS_ADD_FILE(debug_mask);
MWIFIEX_DFS_ADD_FILE(timeshare_coex);
+ MWIFIEX_DFS_ADD_FILE(reset);
}
/*
diff --git a/drivers/net/wireless/marvell/mwifiex/decl.h b/drivers/net/wireless/marvell/mwifiex/decl.h
index 098e1f14dc9a..d9c15cd36f12 100644
--- a/drivers/net/wireless/marvell/mwifiex/decl.h
+++ b/drivers/net/wireless/marvell/mwifiex/decl.h
@@ -111,9 +111,9 @@
/* Rate index for OFDM 0 */
#define MWIFIEX_RATE_INDEX_OFDM0 4
-#define MWIFIEX_MAX_STA_NUM 1
-#define MWIFIEX_MAX_UAP_NUM 1
-#define MWIFIEX_MAX_P2P_NUM 1
+#define MWIFIEX_MAX_STA_NUM 3
+#define MWIFIEX_MAX_UAP_NUM 3
+#define MWIFIEX_MAX_P2P_NUM 3
#define MWIFIEX_A_BAND_START_FREQ 5000
diff --git a/drivers/net/wireless/marvell/mwifiex/fw.h b/drivers/net/wireless/marvell/mwifiex/fw.h
index 1e1e81a0a8d4..ced7af2be29a 100644
--- a/drivers/net/wireless/marvell/mwifiex/fw.h
+++ b/drivers/net/wireless/marvell/mwifiex/fw.h
@@ -537,7 +537,7 @@ enum P2P_MODES {
#define EVENT_GET_BSS_TYPE(event_cause) \
(((event_cause) >> 24) & 0x00ff)
-#define MWIFIEX_MAX_PATTERN_LEN 20
+#define MWIFIEX_MAX_PATTERN_LEN 40
#define MWIFIEX_MAX_OFFSET_LEN 100
#define STACK_NBYTES 100
#define TYPE_DNUM 1
@@ -1092,9 +1092,15 @@ struct host_cmd_ds_802_11_ad_hoc_start {
u8 data_rate[HOSTCMD_SUPPORTED_RATES];
} __packed;
-struct host_cmd_ds_802_11_ad_hoc_result {
+struct host_cmd_ds_802_11_ad_hoc_start_result {
u8 pad[3];
u8 bssid[ETH_ALEN];
+ u8 pad2[2];
+ u8 result;
+} __packed;
+
+struct host_cmd_ds_802_11_ad_hoc_join_result {
+ u8 result;
} __packed;
struct adhoc_bss_desc {
@@ -2124,7 +2130,8 @@ struct host_cmd_ds_command {
struct host_cmd_ds_802_11_associate_rsp associate_rsp;
struct host_cmd_ds_802_11_deauthenticate deauth;
struct host_cmd_ds_802_11_ad_hoc_start adhoc_start;
- struct host_cmd_ds_802_11_ad_hoc_result adhoc_result;
+ struct host_cmd_ds_802_11_ad_hoc_start_result start_result;
+ struct host_cmd_ds_802_11_ad_hoc_join_result join_result;
struct host_cmd_ds_802_11_ad_hoc_join adhoc_join;
struct host_cmd_ds_802_11d_domain_info domain_info;
struct host_cmd_ds_802_11d_domain_info_rsp domain_info_resp;
diff --git a/drivers/net/wireless/marvell/mwifiex/ie.c b/drivers/net/wireless/marvell/mwifiex/ie.c
index abf52d25b981..c488c3068abc 100644
--- a/drivers/net/wireless/marvell/mwifiex/ie.c
+++ b/drivers/net/wireless/marvell/mwifiex/ie.c
@@ -140,7 +140,7 @@ mwifiex_update_autoindex_ies(struct mwifiex_private *priv,
if (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_UAP)
return mwifiex_send_cmd(priv, HostCmd_CMD_UAP_SYS_CONFIG,
HostCmd_ACT_GEN_SET,
- UAP_CUSTOM_IE_I, ie_list, false);
+ UAP_CUSTOM_IE_I, ie_list, true);
return 0;
}
diff --git a/drivers/net/wireless/marvell/mwifiex/init.c b/drivers/net/wireless/marvell/mwifiex/init.c
index de74a7773fb6..6f7876ec31b7 100644
--- a/drivers/net/wireless/marvell/mwifiex/init.c
+++ b/drivers/net/wireless/marvell/mwifiex/init.c
@@ -95,7 +95,7 @@ int mwifiex_init_priv(struct mwifiex_private *priv)
priv->curr_pkt_filter = HostCmd_ACT_MAC_RX_ON | HostCmd_ACT_MAC_TX_ON |
HostCmd_ACT_MAC_ETHERNETII_ENABLE;
- priv->beacon_period = 100; /* beacon interval */ ;
+ priv->beacon_period = 100; /* beacon interval */
priv->attempted_bss_desc = NULL;
memset(&priv->curr_bss_params, 0, sizeof(priv->curr_bss_params));
priv->listen_interval = MWIFIEX_DEFAULT_LISTEN_INTERVAL;
diff --git a/drivers/net/wireless/marvell/mwifiex/join.c b/drivers/net/wireless/marvell/mwifiex/join.c
index 3cda1f956f0b..cc09a81dbf6a 100644
--- a/drivers/net/wireless/marvell/mwifiex/join.c
+++ b/drivers/net/wireless/marvell/mwifiex/join.c
@@ -1247,20 +1247,26 @@ int mwifiex_ret_802_11_ad_hoc(struct mwifiex_private *priv,
{
int ret = 0;
struct mwifiex_adapter *adapter = priv->adapter;
- struct host_cmd_ds_802_11_ad_hoc_result *adhoc_result;
+ struct host_cmd_ds_802_11_ad_hoc_start_result *start_result =
+ &resp->params.start_result;
+ struct host_cmd_ds_802_11_ad_hoc_join_result *join_result =
+ &resp->params.join_result;
struct mwifiex_bssdescriptor *bss_desc;
- u16 reason_code;
+ u16 cmd = le16_to_cpu(resp->command);
+ u8 result;
- adhoc_result = &resp->params.adhoc_result;
+ if (cmd == HostCmd_CMD_802_11_AD_HOC_START)
+ result = start_result->result;
+ else
+ result = join_result->result;
bss_desc = priv->attempted_bss_desc;
/* Join result code 0 --> SUCCESS */
- reason_code = le16_to_cpu(resp->result);
- if (reason_code) {
+ if (result) {
mwifiex_dbg(priv->adapter, ERROR, "ADHOC_RESP: failed\n");
if (priv->media_connected)
- mwifiex_reset_connect_state(priv, reason_code);
+ mwifiex_reset_connect_state(priv, result);
memset(&priv->curr_bss_params.bss_descriptor,
0x00, sizeof(struct mwifiex_bssdescriptor));
@@ -1278,7 +1284,7 @@ int mwifiex_ret_802_11_ad_hoc(struct mwifiex_private *priv,
/* Update the created network descriptor with the new BSSID */
memcpy(bss_desc->mac_address,
- adhoc_result->bssid, ETH_ALEN);
+ start_result->bssid, ETH_ALEN);
priv->adhoc_state = ADHOC_STARTED;
} else {
diff --git a/drivers/net/wireless/marvell/mwifiex/main.h b/drivers/net/wireless/marvell/mwifiex/main.h
index 3959f1c97f4e..2f7f478ce04b 100644
--- a/drivers/net/wireless/marvell/mwifiex/main.h
+++ b/drivers/net/wireless/marvell/mwifiex/main.h
@@ -84,7 +84,7 @@ enum {
#define MWIFIEX_KEY_BUFFER_SIZE 16
#define MWIFIEX_DEFAULT_LISTEN_INTERVAL 10
-#define MWIFIEX_MAX_REGION_CODE 7
+#define MWIFIEX_MAX_REGION_CODE 9
#define DEFAULT_BCN_AVG_FACTOR 8
#define DEFAULT_DATA_AVG_FACTOR 8
@@ -564,14 +564,14 @@ struct mwifiex_private {
struct mwifiex_wep_key wep_key[NUM_WEP_KEYS];
u16 wep_key_curr_index;
u8 wpa_ie[256];
- u8 wpa_ie_len;
+ u16 wpa_ie_len;
u8 wpa_is_gtk_set;
struct host_cmd_ds_802_11_key_material aes_key;
struct host_cmd_ds_802_11_key_material_v2 aes_key_v2;
u8 wapi_ie[256];
- u8 wapi_ie_len;
+ u16 wapi_ie_len;
u8 *wps_ie;
- u8 wps_ie_len;
+ u16 wps_ie_len;
u8 wmm_required;
u8 wmm_enabled;
u8 wmm_qosinfo;
@@ -1273,20 +1273,46 @@ mwifiex_get_priv(struct mwifiex_adapter *adapter,
}
/*
+ * This function checks available bss_num when adding new interface or
+ * changing interface type.
+ */
+static inline u8
+mwifiex_get_unused_bss_num(struct mwifiex_adapter *adapter, u8 bss_type)
+{
+ u8 i, j;
+ int index[MWIFIEX_MAX_BSS_NUM];
+
+ memset(index, 0, sizeof(index));
+ for (i = 0; i < adapter->priv_num; i++)
+ if (adapter->priv[i]) {
+ if (adapter->priv[i]->bss_type == bss_type &&
+ !(adapter->priv[i]->bss_mode ==
+ NL80211_IFTYPE_UNSPECIFIED)) {
+ index[adapter->priv[i]->bss_num] = 1;
+ }
+ }
+ for (j = 0; j < MWIFIEX_MAX_BSS_NUM; j++)
+ if (!index[j])
+ return j;
+ return -1;
+}
+
+/*
* This function returns the first available unused private structure pointer.
*/
static inline struct mwifiex_private *
-mwifiex_get_unused_priv(struct mwifiex_adapter *adapter)
+mwifiex_get_unused_priv_by_bss_type(struct mwifiex_adapter *adapter,
+ u8 bss_type)
{
- int i;
+ u8 i;
- for (i = 0; i < adapter->priv_num; i++) {
- if (adapter->priv[i]) {
- if (adapter->priv[i]->bss_mode ==
- NL80211_IFTYPE_UNSPECIFIED)
- break;
+ for (i = 0; i < adapter->priv_num; i++)
+ if (adapter->priv[i]->bss_mode ==
+ NL80211_IFTYPE_UNSPECIFIED) {
+ adapter->priv[i]->bss_num =
+ mwifiex_get_unused_bss_num(adapter, bss_type);
+ break;
}
- }
return ((i < adapter->priv_num) ? adapter->priv[i] : NULL);
}
diff --git a/drivers/net/wireless/marvell/mwifiex/pcie.c b/drivers/net/wireless/marvell/mwifiex/pcie.c
index 21192b6f9c64..9703848ba9f8 100644
--- a/drivers/net/wireless/marvell/mwifiex/pcie.c
+++ b/drivers/net/wireless/marvell/mwifiex/pcie.c
@@ -2599,6 +2599,30 @@ static void mwifiex_pcie_cleanup(struct mwifiex_adapter *adapter)
kfree(card);
}
+static int mwifiex_pcie_request_irq(struct mwifiex_adapter *adapter)
+{
+ int ret;
+ struct pcie_service_card *card = adapter->card;
+ struct pci_dev *pdev = card->dev;
+
+ if (pci_enable_msi(pdev) != 0)
+ pci_disable_msi(pdev);
+ else
+ card->msi_enable = 1;
+
+ mwifiex_dbg(adapter, INFO, "msi_enable = %d\n", card->msi_enable);
+
+ ret = request_irq(pdev->irq, mwifiex_pcie_interrupt, IRQF_SHARED,
+ "MRVL_PCIE", pdev);
+ if (ret) {
+ pr_err("request_irq failed: ret=%d\n", ret);
+ adapter->card = NULL;
+ return -1;
+ }
+
+ return 0;
+}
+
/*
* This function registers the PCIE device.
*
@@ -2606,21 +2630,14 @@ static void mwifiex_pcie_cleanup(struct mwifiex_adapter *adapter)
*/
static int mwifiex_register_dev(struct mwifiex_adapter *adapter)
{
- int ret;
struct pcie_service_card *card = adapter->card;
struct pci_dev *pdev = card->dev;
/* save adapter pointer in card */
card->adapter = adapter;
- ret = request_irq(pdev->irq, mwifiex_pcie_interrupt, IRQF_SHARED,
- "MRVL_PCIE", pdev);
- if (ret) {
- mwifiex_dbg(adapter, ERROR,
- "request_irq failed: ret=%d\n", ret);
- adapter->card = NULL;
+ if (mwifiex_pcie_request_irq(adapter))
return -1;
- }
adapter->dev = &pdev->dev;
adapter->tx_buf_size = card->pcie.tx_buf_size;
diff --git a/drivers/net/wireless/marvell/mwifiex/pcie.h b/drivers/net/wireless/marvell/mwifiex/pcie.h
index 48e549c3b285..6fc28737b576 100644
--- a/drivers/net/wireless/marvell/mwifiex/pcie.h
+++ b/drivers/net/wireless/marvell/mwifiex/pcie.h
@@ -210,17 +210,17 @@ static const struct mwifiex_pcie_card_reg mwifiex_reg_8997 = {
.cmdrsp_addr_lo = PCIE_SCRATCH_4_REG,
.cmdrsp_addr_hi = PCIE_SCRATCH_5_REG,
.tx_rdptr = 0xC1A4,
- .tx_wrptr = 0xC1A8,
- .rx_rdptr = 0xC1A8,
+ .tx_wrptr = 0xC174,
+ .rx_rdptr = 0xC174,
.rx_wrptr = 0xC1A4,
.evt_rdptr = PCIE_SCRATCH_10_REG,
.evt_wrptr = PCIE_SCRATCH_11_REG,
.drv_rdy = PCIE_SCRATCH_12_REG,
.tx_start_ptr = 16,
.tx_mask = 0x0FFF0000,
- .tx_wrap_mask = 0x01FF0000,
+ .tx_wrap_mask = 0x1FFF0000,
.rx_mask = 0x00000FFF,
- .rx_wrap_mask = 0x000001FF,
+ .rx_wrap_mask = 0x00001FFF,
.tx_rollover_ind = BIT(28),
.rx_rollover_ind = BIT(12),
.evt_rollover_ind = MWIFIEX_BD_FLAG_EVT_ROLLOVER_IND,
@@ -326,6 +326,7 @@ struct pcie_service_card {
dma_addr_t sleep_cookie_pbase;
void __iomem *pci_mmap;
void __iomem *pci_mmap1;
+ int msi_enable;
};
static inline int
@@ -342,6 +343,7 @@ mwifiex_pcie_txbd_empty(struct pcie_service_card *card, u32 rdptr)
return 1;
break;
case PCIE_DEVICE_ID_MARVELL_88W8897:
+ case PCIE_DEVICE_ID_MARVELL_88W8997:
if (((card->txbd_wrptr & reg->tx_mask) ==
(rdptr & reg->tx_mask)) &&
((card->txbd_wrptr & reg->tx_rollover_ind) ==
diff --git a/drivers/net/wireless/marvell/mwifiex/sta_ioctl.c b/drivers/net/wireless/marvell/mwifiex/sta_ioctl.c
index a6c8a4f7bfe9..6a4fc5d183cf 100644
--- a/drivers/net/wireless/marvell/mwifiex/sta_ioctl.c
+++ b/drivers/net/wireless/marvell/mwifiex/sta_ioctl.c
@@ -272,7 +272,8 @@ int mwifiex_bss_start(struct mwifiex_private *priv, struct cfg80211_bss *bss,
priv->scan_block = false;
if (bss) {
- mwifiex_process_country_ie(priv, bss);
+ if (adapter->region_code == 0x00)
+ mwifiex_process_country_ie(priv, bss);
/* Allocate and fill new bss descriptor */
bss_desc = kzalloc(sizeof(struct mwifiex_bssdescriptor),
@@ -758,7 +759,7 @@ static int mwifiex_set_wpa_ie_helper(struct mwifiex_private *priv,
return -1;
}
memcpy(priv->wpa_ie, ie_data_ptr, ie_len);
- priv->wpa_ie_len = (u8) ie_len;
+ priv->wpa_ie_len = ie_len;
mwifiex_dbg(priv->adapter, CMD,
"cmd: Set Wpa_ie_len=%d IE=%#x\n",
priv->wpa_ie_len, priv->wpa_ie[0]);
@@ -923,9 +924,8 @@ static int mwifiex_sec_ioctl_set_wep_key(struct mwifiex_private *priv,
if (encrypt_key->key_disable) {
memset(&priv->wep_key[index], 0,
sizeof(struct mwifiex_wep_key));
- if (wep_key->key_length)
- goto done;
- }
+ goto done;
+ }
if (adapter->key_api_major_ver == KEY_API_VER_MAJOR_V2)
enc_key = encrypt_key;
@@ -1293,6 +1293,8 @@ mwifiex_set_gen_ie_helper(struct mwifiex_private *priv, u8 *ie_data_ptr,
struct ieee_types_vendor_header *pvendor_ie;
const u8 wpa_oui[] = { 0x00, 0x50, 0xf2, 0x01 };
const u8 wps_oui[] = { 0x00, 0x50, 0xf2, 0x04 };
+ u16 unparsed_len = ie_len;
+ int find_wpa_ie = 0;
/* If the passed length is zero, reset the buffer */
if (!ie_len) {
@@ -1304,40 +1306,69 @@ mwifiex_set_gen_ie_helper(struct mwifiex_private *priv, u8 *ie_data_ptr,
return -1;
}
pvendor_ie = (struct ieee_types_vendor_header *) ie_data_ptr;
- /* Test to see if it is a WPA IE, if not, then it is a gen IE */
- if (((pvendor_ie->element_id == WLAN_EID_VENDOR_SPECIFIC) &&
- (!memcmp(pvendor_ie->oui, wpa_oui, sizeof(wpa_oui)))) ||
- (pvendor_ie->element_id == WLAN_EID_RSN)) {
- /* IE is a WPA/WPA2 IE so call set_wpa function */
- ret = mwifiex_set_wpa_ie_helper(priv, ie_data_ptr, ie_len);
- priv->wps.session_enable = false;
+ while (pvendor_ie) {
+ if (pvendor_ie->element_id == WLAN_EID_VENDOR_SPECIFIC) {
+ /* Test to see if it is a WPA IE, if not, then it is a
+ * gen IE
+ */
+ if (!memcmp(pvendor_ie->oui, wpa_oui,
+ sizeof(wpa_oui))) {
+ find_wpa_ie = 1;
+ break;
+ }
- return ret;
- } else if (pvendor_ie->element_id == WLAN_EID_BSS_AC_ACCESS_DELAY) {
+ /* Test to see if it is a WPS IE, if so, enable
+ * wps session flag
+ */
+ if (!memcmp(pvendor_ie->oui, wps_oui,
+ sizeof(wps_oui))) {
+ priv->wps.session_enable = true;
+ mwifiex_dbg(priv->adapter, MSG,
+ "info: WPS Session Enabled.\n");
+ ret = mwifiex_set_wps_ie(priv,
+ (u8 *)pvendor_ie,
+ unparsed_len);
+ }
+ }
+
+ if (pvendor_ie->element_id == WLAN_EID_RSN) {
+ find_wpa_ie = 1;
+ break;
+ }
+
+ if (pvendor_ie->element_id == WLAN_EID_BSS_AC_ACCESS_DELAY) {
/* IE is a WAPI IE so call set_wapi function */
- ret = mwifiex_set_wapi_ie(priv, ie_data_ptr, ie_len);
+ ret = mwifiex_set_wapi_ie(priv, (u8 *)pvendor_ie,
+ unparsed_len);
+ return ret;
+ }
+ unparsed_len -= (pvendor_ie->len +
+ sizeof(struct ieee_types_header));
+
+ if (unparsed_len <= sizeof(struct ieee_types_header))
+ pvendor_ie = NULL;
+ else
+ pvendor_ie = (struct ieee_types_vendor_header *)
+ (((u8 *)pvendor_ie) + pvendor_ie->len +
+ sizeof(struct ieee_types_header));
+ }
+
+ if (find_wpa_ie) {
+ /* IE is a WPA/WPA2 IE so call set_wpa function */
+ ret = mwifiex_set_wpa_ie_helper(priv, (u8 *)pvendor_ie,
+ unparsed_len);
+ priv->wps.session_enable = false;
return ret;
}
+
/*
* Verify that the passed length is not larger than the
* available space remaining in the buffer
*/
if (ie_len < (sizeof(priv->gen_ie_buf) - priv->gen_ie_buf_len)) {
- /* Test to see if it is a WPS IE, if so, enable
- * wps session flag
- */
- pvendor_ie = (struct ieee_types_vendor_header *) ie_data_ptr;
- if ((pvendor_ie->element_id == WLAN_EID_VENDOR_SPECIFIC) &&
- (!memcmp(pvendor_ie->oui, wps_oui, sizeof(wps_oui)))) {
- priv->wps.session_enable = true;
- mwifiex_dbg(priv->adapter, INFO,
- "info: WPS Session Enabled.\n");
- ret = mwifiex_set_wps_ie(priv, ie_data_ptr, ie_len);
- }
-
/* Append the passed data to the end of the
genIeBuffer */
memcpy(priv->gen_ie_buf + priv->gen_ie_buf_len, ie_data_ptr,
diff --git a/drivers/net/wireless/marvell/mwifiex/sta_rx.c b/drivers/net/wireless/marvell/mwifiex/sta_rx.c
index d4d4cb1ce95b..00fcbda09349 100644
--- a/drivers/net/wireless/marvell/mwifiex/sta_rx.c
+++ b/drivers/net/wireless/marvell/mwifiex/sta_rx.c
@@ -215,7 +215,7 @@ int mwifiex_process_sta_rx_packet(struct mwifiex_private *priv,
if (rx_pkt_type == PKT_TYPE_MGMT) {
ret = mwifiex_process_mgmt_packet(priv, skb);
if (ret)
- mwifiex_dbg(adapter, ERROR, "Rx of mgmt packet failed");
+ mwifiex_dbg(adapter, DATA, "Rx of mgmt packet failed");
dev_kfree_skb_any(skb);
return ret;
}
diff --git a/drivers/net/wireless/marvell/mwifiex/uap_cmd.c b/drivers/net/wireless/marvell/mwifiex/uap_cmd.c
index 759a6ada5b0f..e791166d90c4 100644
--- a/drivers/net/wireless/marvell/mwifiex/uap_cmd.c
+++ b/drivers/net/wireless/marvell/mwifiex/uap_cmd.c
@@ -848,9 +848,9 @@ int mwifiex_config_start_uap(struct mwifiex_private *priv,
if (mwifiex_send_cmd(priv, HostCmd_CMD_UAP_SYS_CONFIG,
HostCmd_ACT_GEN_SET,
- UAP_BSS_PARAMS_I, bss_cfg, false)) {
+ UAP_BSS_PARAMS_I, bss_cfg, true)) {
mwifiex_dbg(priv->adapter, ERROR,
- "Failed to set the SSID\n");
+ "Failed to set AP configuration\n");
return -1;
}
@@ -865,7 +865,7 @@ int mwifiex_config_start_uap(struct mwifiex_private *priv,
}
if (mwifiex_send_cmd(priv, HostCmd_CMD_UAP_BSS_START,
- HostCmd_ACT_GEN_SET, 0, NULL, false)) {
+ HostCmd_ACT_GEN_SET, 0, NULL, true)) {
mwifiex_dbg(priv->adapter, ERROR,
"Failed to start the BSS\n");
return -1;
diff --git a/drivers/net/wireless/marvell/mwifiex/uap_txrx.c b/drivers/net/wireless/marvell/mwifiex/uap_txrx.c
index 74d5d7238633..52f7981a8afc 100644
--- a/drivers/net/wireless/marvell/mwifiex/uap_txrx.c
+++ b/drivers/net/wireless/marvell/mwifiex/uap_txrx.c
@@ -310,8 +310,7 @@ int mwifiex_process_uap_rx_packet(struct mwifiex_private *priv,
if (rx_pkt_type == PKT_TYPE_MGMT) {
ret = mwifiex_process_mgmt_packet(priv, skb);
if (ret)
- mwifiex_dbg(adapter, ERROR,
- "Rx of mgmt packet failed");
+ mwifiex_dbg(adapter, DATA, "Rx of mgmt packet failed");
dev_kfree_skb_any(skb);
return ret;
}