summaryrefslogtreecommitdiff
path: root/drivers/net/wireless/rsi
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2018-06-07 04:39:49 +0300
committerLinus Torvalds <torvalds@linux-foundation.org>2018-06-07 04:39:49 +0300
commit1c8c5a9d38f607c0b6fd12c91cbe1a4418762a21 (patch)
treedcc97181d4d187252e0cc8fdf29d9b365fa3ffd0 /drivers/net/wireless/rsi
parent285767604576148fc1be7fcd112e4a90eb0d6ad2 (diff)
parent7170e6045a6a8b33f4fa5753589dc77b16198e2d (diff)
downloadlinux-1c8c5a9d38f607c0b6fd12c91cbe1a4418762a21.tar.xz
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next
Pull networking updates from David Miller: 1) Add Maglev hashing scheduler to IPVS, from Inju Song. 2) Lots of new TC subsystem tests from Roman Mashak. 3) Add TCP zero copy receive and fix delayed acks and autotuning with SO_RCVLOWAT, from Eric Dumazet. 4) Add XDP_REDIRECT support to mlx5 driver, from Jesper Dangaard Brouer. 5) Add ttl inherit support to vxlan, from Hangbin Liu. 6) Properly separate ipv6 routes into their logically independant components. fib6_info for the routing table, and fib6_nh for sets of nexthops, which thus can be shared. From David Ahern. 7) Add bpf_xdp_adjust_tail helper, which can be used to generate ICMP messages from XDP programs. From Nikita V. Shirokov. 8) Lots of long overdue cleanups to the r8169 driver, from Heiner Kallweit. 9) Add BTF ("BPF Type Format"), from Martin KaFai Lau. 10) Add traffic condition monitoring to iwlwifi, from Luca Coelho. 11) Plumb extack down into fib_rules, from Roopa Prabhu. 12) Add Flower classifier offload support to igb, from Vinicius Costa Gomes. 13) Add UDP GSO support, from Willem de Bruijn. 14) Add documentation for eBPF helpers, from Quentin Monnet. 15) Add TLS tx offload to mlx5, from Ilya Lesokhin. 16) Allow applications to be given the number of bytes available to read on a socket via a control message returned from recvmsg(), from Soheil Hassas Yeganeh. 17) Add x86_32 eBPF JIT compiler, from Wang YanQing. 18) Add AF_XDP sockets, with zerocopy support infrastructure as well. From Björn Töpel. 19) Remove indirect load support from all of the BPF JITs and handle these operations in the verifier by translating them into native BPF instead. From Daniel Borkmann. 20) Add GRO support to ipv6 gre tunnels, from Eran Ben Elisha. 21) Allow XDP programs to do lookups in the main kernel routing tables for forwarding. From David Ahern. 22) Allow drivers to store hardware state into an ELF section of kernel dump vmcore files, and use it in cxgb4. From Rahul Lakkireddy. 23) Various RACK and loss detection improvements in TCP, from Yuchung Cheng. 24) Add TCP SACK compression, from Eric Dumazet. 25) Add User Mode Helper support and basic bpfilter infrastructure, from Alexei Starovoitov. 26) Support ports and protocol values in RTM_GETROUTE, from Roopa Prabhu. 27) Support bulking in ->ndo_xdp_xmit() API, from Jesper Dangaard Brouer. 28) Add lots of forwarding selftests, from Petr Machata. 29) Add generic network device failover driver, from Sridhar Samudrala. * ra.kernel.org:/pub/scm/linux/kernel/git/davem/net-next: (1959 commits) strparser: Add __strp_unpause and use it in ktls. rxrpc: Fix terminal retransmission connection ID to include the channel net: hns3: Optimize PF CMDQ interrupt switching process net: hns3: Fix for VF mailbox receiving unknown message net: hns3: Fix for VF mailbox cannot receiving PF response bnx2x: use the right constant Revert "net: sched: cls: Fix offloading when ingress dev is vxlan" net: dsa: b53: Fix for brcm tag issue in Cygnus SoC enic: fix UDP rss bits netdev-FAQ: clarify DaveM's position for stable backports rtnetlink: validate attributes in do_setlink() mlxsw: Add extack messages for port_{un, }split failures netdevsim: Add extack error message for devlink reload devlink: Add extack to reload and port_{un, }split operations net: metrics: add proper netlink validation ipmr: fix error path when ipmr_new_table fails ip6mr: only set ip6mr_table from setsockopt when ip6mr_new_table succeeds net: hns3: remove unused hclgevf_cfg_func_mta_filter netfilter: provide udp*_lib_lookup for nf_tproxy qed*: Utilize FW 8.37.2.0 ...
Diffstat (limited to 'drivers/net/wireless/rsi')
-rw-r--r--drivers/net/wireless/rsi/rsi_91x_coex.c1
-rw-r--r--drivers/net/wireless/rsi/rsi_91x_core.c33
-rw-r--r--drivers/net/wireless/rsi/rsi_91x_hal.c108
-rw-r--r--drivers/net/wireless/rsi/rsi_91x_mac80211.c75
-rw-r--r--drivers/net/wireless/rsi/rsi_91x_mgmt.c35
-rw-r--r--drivers/net/wireless/rsi/rsi_91x_sdio.c27
-rw-r--r--drivers/net/wireless/rsi/rsi_91x_usb.c8
-rw-r--r--drivers/net/wireless/rsi/rsi_boot_params.h3
-rw-r--r--drivers/net/wireless/rsi/rsi_hal.h3
-rw-r--r--drivers/net/wireless/rsi/rsi_main.h7
-rw-r--r--drivers/net/wireless/rsi/rsi_mgmt.h19
-rw-r--r--drivers/net/wireless/rsi/rsi_sdio.h2
-rw-r--r--drivers/net/wireless/rsi/rsi_usb.h1
13 files changed, 220 insertions, 102 deletions
diff --git a/drivers/net/wireless/rsi/rsi_91x_coex.c b/drivers/net/wireless/rsi/rsi_91x_coex.c
index d055099dadf1..c8ba148f8c6c 100644
--- a/drivers/net/wireless/rsi/rsi_91x_coex.c
+++ b/drivers/net/wireless/rsi/rsi_91x_coex.c
@@ -73,6 +73,7 @@ int rsi_coex_recv_pkt(struct rsi_common *common, u8 *msg)
switch (msg_type) {
case COMMON_CARD_READY_IND:
rsi_dbg(INFO_ZONE, "common card ready received\n");
+ common->hibernate_resume = false;
rsi_handle_card_ready(common, msg);
break;
case SLEEP_NOTIFY_IND:
diff --git a/drivers/net/wireless/rsi/rsi_91x_core.c b/drivers/net/wireless/rsi/rsi_91x_core.c
index 5dafd2e1306c..3644d7d99463 100644
--- a/drivers/net/wireless/rsi/rsi_91x_core.c
+++ b/drivers/net/wireless/rsi/rsi_91x_core.c
@@ -411,11 +411,30 @@ void rsi_core_xmit(struct rsi_common *common, struct sk_buff *skb)
if ((ieee80211_is_mgmt(wh->frame_control)) ||
(ieee80211_is_ctl(wh->frame_control)) ||
(ieee80211_is_qos_nullfunc(wh->frame_control))) {
+ if (ieee80211_is_assoc_req(wh->frame_control) ||
+ ieee80211_is_reassoc_req(wh->frame_control)) {
+ struct ieee80211_bss_conf *bss = &vif->bss_conf;
+
+ common->eapol4_confirm = false;
+ rsi_hal_send_sta_notify_frame(common,
+ RSI_IFTYPE_STATION,
+ STA_CONNECTED, bss->bssid,
+ bss->qos, bss->aid, 0,
+ vif);
+ }
+
q_num = MGMT_SOFT_Q;
skb->priority = q_num;
+
+ if (rsi_prepare_mgmt_desc(common, skb)) {
+ rsi_dbg(ERR_ZONE, "Failed to prepare desc\n");
+ goto xmit_fail;
+ }
} else {
if (ieee80211_is_data_qos(wh->frame_control)) {
- tid = (skb->data[24] & IEEE80211_QOS_TID);
+ u8 *qos = ieee80211_get_qos_ctl(wh);
+
+ tid = *qos & IEEE80211_QOS_CTL_TID_MASK;
skb->priority = TID_TO_WME_AC(tid);
} else {
tid = IEEE80211_NONQOS_TID;
@@ -433,6 +452,8 @@ void rsi_core_xmit(struct rsi_common *common, struct sk_buff *skb)
if (!rsta)
goto xmit_fail;
tx_params->sta_id = rsta->sta_id;
+ } else {
+ tx_params->sta_id = 0;
}
if (rsta) {
@@ -443,6 +464,14 @@ void rsi_core_xmit(struct rsi_common *common, struct sk_buff *skb)
tid, 0);
}
}
+ if (skb->protocol == cpu_to_be16(ETH_P_PAE)) {
+ q_num = MGMT_SOFT_Q;
+ skb->priority = q_num;
+ }
+ if (rsi_prepare_data_desc(common, skb)) {
+ rsi_dbg(ERR_ZONE, "Failed to prepare data desc\n");
+ goto xmit_fail;
+ }
}
if ((q_num < MGMT_SOFT_Q) &&
@@ -456,7 +485,7 @@ void rsi_core_xmit(struct rsi_common *common, struct sk_buff *skb)
}
rsi_core_queue_pkt(common, skb);
- rsi_dbg(DATA_TX_ZONE, "%s: ===> Scheduling TX thead <===\n", __func__);
+ rsi_dbg(DATA_TX_ZONE, "%s: ===> Scheduling TX thread <===\n", __func__);
rsi_set_event(&common->tx_thread.event);
return;
diff --git a/drivers/net/wireless/rsi/rsi_91x_hal.c b/drivers/net/wireless/rsi/rsi_91x_hal.c
index de608ae365a4..0761e61591bd 100644
--- a/drivers/net/wireless/rsi/rsi_91x_hal.c
+++ b/drivers/net/wireless/rsi/rsi_91x_hal.c
@@ -45,7 +45,7 @@ int rsi_send_pkt_to_bus(struct rsi_common *common, struct sk_buff *skb)
return status;
}
-static int rsi_prepare_mgmt_desc(struct rsi_common *common, struct sk_buff *skb)
+int rsi_prepare_mgmt_desc(struct rsi_common *common, struct sk_buff *skb)
{
struct rsi_hw *adapter = common->priv;
struct ieee80211_hdr *wh = NULL;
@@ -55,7 +55,7 @@ static int rsi_prepare_mgmt_desc(struct rsi_common *common, struct sk_buff *skb)
struct rsi_mgmt_desc *mgmt_desc;
struct skb_info *tx_params;
struct ieee80211_bss_conf *bss = NULL;
- struct xtended_desc *xtend_desc = NULL;
+ struct rsi_xtended_desc *xtend_desc = NULL;
u8 header_size;
u32 dword_align_bytes = 0;
@@ -69,7 +69,7 @@ static int rsi_prepare_mgmt_desc(struct rsi_common *common, struct sk_buff *skb)
vif = tx_params->vif;
/* Update header size */
- header_size = FRAME_DESC_SZ + sizeof(struct xtended_desc);
+ header_size = FRAME_DESC_SZ + sizeof(struct rsi_xtended_desc);
if (header_size > skb_headroom(skb)) {
rsi_dbg(ERR_ZONE,
"%s: Failed to add extended descriptor\n",
@@ -92,7 +92,7 @@ static int rsi_prepare_mgmt_desc(struct rsi_common *common, struct sk_buff *skb)
wh = (struct ieee80211_hdr *)&skb->data[header_size];
mgmt_desc = (struct rsi_mgmt_desc *)skb->data;
- xtend_desc = (struct xtended_desc *)&skb->data[FRAME_DESC_SZ];
+ xtend_desc = (struct rsi_xtended_desc *)&skb->data[FRAME_DESC_SZ];
rsi_set_len_qno(&mgmt_desc->len_qno, (skb->len - FRAME_DESC_SZ),
RSI_WIFI_MGMT_Q);
@@ -113,17 +113,6 @@ static int rsi_prepare_mgmt_desc(struct rsi_common *common, struct sk_buff *skb)
if (conf_is_ht40(conf))
mgmt_desc->bbp_info = cpu_to_le16(FULL40M_ENABLE);
- if (ieee80211_is_probe_req(wh->frame_control)) {
- if (!bss->assoc) {
- rsi_dbg(INFO_ZONE,
- "%s: blocking mgmt queue\n", __func__);
- mgmt_desc->misc_flags = RSI_DESC_REQUIRE_CFM_TO_HOST;
- xtend_desc->confirm_frame_type = PROBEREQ_CONFIRM;
- common->mgmt_q_block = true;
- rsi_dbg(INFO_ZONE, "Mgmt queue blocked\n");
- }
- }
-
if (ieee80211_is_probe_resp(wh->frame_control)) {
mgmt_desc->misc_flags |= (RSI_ADD_DELTA_TSF_VAP_ID |
RSI_FETCH_RETRY_CNT_FRM_HST);
@@ -149,7 +138,7 @@ static int rsi_prepare_mgmt_desc(struct rsi_common *common, struct sk_buff *skb)
}
/* This function prepares descriptor for given data packet */
-static int rsi_prepare_data_desc(struct rsi_common *common, struct sk_buff *skb)
+int rsi_prepare_data_desc(struct rsi_common *common, struct sk_buff *skb)
{
struct rsi_hw *adapter = common->priv;
struct ieee80211_vif *vif;
@@ -158,7 +147,7 @@ static int rsi_prepare_data_desc(struct rsi_common *common, struct sk_buff *skb)
struct skb_info *tx_params;
struct ieee80211_bss_conf *bss;
struct rsi_data_desc *data_desc;
- struct xtended_desc *xtend_desc;
+ struct rsi_xtended_desc *xtend_desc;
u8 ieee80211_size = MIN_802_11_HDR_LEN;
u8 header_size;
u8 vap_id = 0;
@@ -170,7 +159,7 @@ static int rsi_prepare_data_desc(struct rsi_common *common, struct sk_buff *skb)
bss = &vif->bss_conf;
tx_params = (struct skb_info *)info->driver_data;
- header_size = FRAME_DESC_SZ + sizeof(struct xtended_desc);
+ header_size = FRAME_DESC_SZ + sizeof(struct rsi_xtended_desc);
if (header_size > skb_headroom(skb)) {
rsi_dbg(ERR_ZONE, "%s: Unable to send pkt\n", __func__);
return -ENOSPC;
@@ -188,7 +177,7 @@ static int rsi_prepare_data_desc(struct rsi_common *common, struct sk_buff *skb)
data_desc = (struct rsi_data_desc *)skb->data;
memset(data_desc, 0, header_size);
- xtend_desc = (struct xtended_desc *)&skb->data[FRAME_DESC_SZ];
+ xtend_desc = (struct rsi_xtended_desc *)&skb->data[FRAME_DESC_SZ];
wh = (struct ieee80211_hdr *)&skb->data[header_size];
seq_num = IEEE80211_SEQ_TO_SN(le16_to_cpu(wh->seq_ctrl));
@@ -243,6 +232,18 @@ static int rsi_prepare_data_desc(struct rsi_common *common, struct sk_buff *skb)
data_desc->misc_flags |= RSI_FETCH_RETRY_CNT_FRM_HST;
#define EAPOL_RETRY_CNT 15
xtend_desc->retry_cnt = EAPOL_RETRY_CNT;
+
+ if (common->eapol4_confirm)
+ skb->priority = VO_Q;
+ else
+ rsi_set_len_qno(&data_desc->len_qno,
+ (skb->len - FRAME_DESC_SZ),
+ RSI_WIFI_MGMT_Q);
+ if ((skb->len - header_size) == EAPOL4_PACKET_LEN) {
+ data_desc->misc_flags |=
+ RSI_DESC_REQUIRE_CFM_TO_HOST;
+ xtend_desc->confirm_frame_type = EAPOL4_CONFIRM;
+ }
}
data_desc->mac_flags = cpu_to_le16(seq_num & 0xfff);
@@ -282,8 +283,11 @@ int rsi_send_data_pkt(struct rsi_common *common, struct sk_buff *skb)
struct rsi_hw *adapter = common->priv;
struct ieee80211_vif *vif;
struct ieee80211_tx_info *info;
+ struct skb_info *tx_params;
struct ieee80211_bss_conf *bss;
+ struct ieee80211_hdr *wh;
int status = -EINVAL;
+ u8 header_size;
if (!skb)
return 0;
@@ -295,16 +299,15 @@ int rsi_send_data_pkt(struct rsi_common *common, struct sk_buff *skb)
goto err;
vif = info->control.vif;
bss = &vif->bss_conf;
+ tx_params = (struct skb_info *)info->driver_data;
+ header_size = tx_params->internal_hdr_size;
+ wh = (struct ieee80211_hdr *)&skb->data[header_size];
if (((vif->type == NL80211_IFTYPE_STATION) ||
(vif->type == NL80211_IFTYPE_P2P_CLIENT)) &&
(!bss->assoc))
goto err;
- status = rsi_prepare_data_desc(common, skb);
- if (status)
- goto err;
-
status = rsi_send_pkt_to_bus(common, skb);
if (status)
rsi_dbg(ERR_ZONE, "%s: Failed to write pkt\n", __func__);
@@ -327,12 +330,18 @@ int rsi_send_mgmt_pkt(struct rsi_common *common,
struct sk_buff *skb)
{
struct rsi_hw *adapter = common->priv;
+ struct ieee80211_bss_conf *bss;
+ struct ieee80211_hdr *wh;
struct ieee80211_tx_info *info;
struct skb_info *tx_params;
+ struct rsi_mgmt_desc *mgmt_desc;
+ struct rsi_xtended_desc *xtend_desc;
int status = -E2BIG;
+ u8 header_size;
info = IEEE80211_SKB_CB(skb);
tx_params = (struct skb_info *)info->driver_data;
+ header_size = tx_params->internal_hdr_size;
if (tx_params->flags & INTERNAL_MGMT_PKT) {
status = adapter->host_intf_ops->write_pkt(common->priv,
@@ -346,15 +355,25 @@ int rsi_send_mgmt_pkt(struct rsi_common *common,
return status;
}
- if (FRAME_DESC_SZ > skb_headroom(skb))
- goto err;
+ bss = &info->control.vif->bss_conf;
+ wh = (struct ieee80211_hdr *)&skb->data[header_size];
+ mgmt_desc = (struct rsi_mgmt_desc *)skb->data;
+ xtend_desc = (struct rsi_xtended_desc *)&skb->data[FRAME_DESC_SZ];
+
+ /* Indicate to firmware to give cfm for probe */
+ if (ieee80211_is_probe_req(wh->frame_control) && !bss->assoc) {
+ rsi_dbg(INFO_ZONE,
+ "%s: blocking mgmt queue\n", __func__);
+ mgmt_desc->misc_flags = RSI_DESC_REQUIRE_CFM_TO_HOST;
+ xtend_desc->confirm_frame_type = PROBEREQ_CONFIRM;
+ common->mgmt_q_block = true;
+ rsi_dbg(INFO_ZONE, "Mgmt queue blocked\n");
+ }
- rsi_prepare_mgmt_desc(common, skb);
status = rsi_send_pkt_to_bus(common, skb);
if (status)
rsi_dbg(ERR_ZONE, "%s: Failed to write the packet\n", __func__);
-err:
rsi_indicate_tx_status(common->priv, skb, status);
return status;
}
@@ -616,28 +635,32 @@ static int bl_write_header(struct rsi_hw *adapter, u8 *flash_content,
u32 content_size)
{
struct rsi_host_intf_ops *hif_ops = adapter->host_intf_ops;
- struct bl_header bl_hdr;
+ struct bl_header *bl_hdr;
u32 write_addr, write_len;
int status;
- bl_hdr.flags = 0;
- bl_hdr.image_no = cpu_to_le32(adapter->priv->coex_mode);
- bl_hdr.check_sum = cpu_to_le32(
- *(u32 *)&flash_content[CHECK_SUM_OFFSET]);
- bl_hdr.flash_start_address = cpu_to_le32(
- *(u32 *)&flash_content[ADDR_OFFSET]);
- bl_hdr.flash_len = cpu_to_le32(*(u32 *)&flash_content[LEN_OFFSET]);
+ bl_hdr = kzalloc(sizeof(*bl_hdr), GFP_KERNEL);
+ if (!bl_hdr)
+ return -ENOMEM;
+
+ bl_hdr->flags = 0;
+ bl_hdr->image_no = cpu_to_le32(adapter->priv->coex_mode);
+ bl_hdr->check_sum =
+ cpu_to_le32(*(u32 *)&flash_content[CHECK_SUM_OFFSET]);
+ bl_hdr->flash_start_address =
+ cpu_to_le32(*(u32 *)&flash_content[ADDR_OFFSET]);
+ bl_hdr->flash_len = cpu_to_le32(*(u32 *)&flash_content[LEN_OFFSET]);
write_len = sizeof(struct bl_header);
if (adapter->rsi_host_intf == RSI_HOST_INTF_USB) {
write_addr = PING_BUFFER_ADDRESS;
status = hif_ops->write_reg_multiple(adapter, write_addr,
- (u8 *)&bl_hdr, write_len);
+ (u8 *)bl_hdr, write_len);
if (status < 0) {
rsi_dbg(ERR_ZONE,
"%s: Failed to load Version/CRC structure\n",
__func__);
- return status;
+ goto fail;
}
} else {
write_addr = PING_BUFFER_ADDRESS >> 16;
@@ -646,20 +669,23 @@ static int bl_write_header(struct rsi_hw *adapter, u8 *flash_content,
rsi_dbg(ERR_ZONE,
"%s: Unable to set ms word to common reg\n",
__func__);
- return status;
+ goto fail;
}
write_addr = RSI_SD_REQUEST_MASTER |
(PING_BUFFER_ADDRESS & 0xFFFF);
status = hif_ops->write_reg_multiple(adapter, write_addr,
- (u8 *)&bl_hdr, write_len);
+ (u8 *)bl_hdr, write_len);
if (status < 0) {
rsi_dbg(ERR_ZONE,
"%s: Failed to load Version/CRC structure\n",
__func__);
- return status;
+ goto fail;
}
}
- return 0;
+ status = 0;
+fail:
+ kfree(bl_hdr);
+ return status;
}
static u32 read_flash_capacity(struct rsi_hw *adapter)
diff --git a/drivers/net/wireless/rsi/rsi_91x_mac80211.c b/drivers/net/wireless/rsi/rsi_91x_mac80211.c
index 32f5cb46fd4f..2ca7464b7fa3 100644
--- a/drivers/net/wireless/rsi/rsi_91x_mac80211.c
+++ b/drivers/net/wireless/rsi/rsi_91x_mac80211.c
@@ -245,6 +245,7 @@ void rsi_mac80211_detach(struct rsi_hw *adapter)
ieee80211_stop_queues(hw);
ieee80211_unregister_hw(hw);
ieee80211_free_hw(hw);
+ adapter->hw = NULL;
}
for (band = 0; band < NUM_NL80211_BANDS; band++) {
@@ -614,7 +615,7 @@ static int rsi_mac80211_config(struct ieee80211_hw *hw,
/* Power save parameters */
if (changed & IEEE80211_CONF_CHANGE_PS) {
- struct ieee80211_vif *vif;
+ struct ieee80211_vif *vif, *sta_vif = NULL;
unsigned long flags;
int i, set_ps = 1;
@@ -628,13 +629,17 @@ static int rsi_mac80211_config(struct ieee80211_hw *hw,
set_ps = 0;
break;
}
+ if ((vif->type == NL80211_IFTYPE_STATION ||
+ vif->type == NL80211_IFTYPE_P2P_CLIENT) &&
+ (!sta_vif || vif->bss_conf.assoc))
+ sta_vif = vif;
}
- if (set_ps) {
+ if (set_ps && sta_vif) {
spin_lock_irqsave(&adapter->ps_lock, flags);
if (conf->flags & IEEE80211_CONF_PS)
- rsi_enable_ps(adapter, vif);
+ rsi_enable_ps(adapter, sta_vif);
else
- rsi_disable_ps(adapter, vif);
+ rsi_disable_ps(adapter, sta_vif);
spin_unlock_irqrestore(&adapter->ps_lock, flags);
}
}
@@ -737,7 +742,8 @@ static void rsi_mac80211_bss_info_changed(struct ieee80211_hw *hw,
bss_conf->bssid,
bss_conf->qos,
bss_conf->aid,
- NULL, 0, vif);
+ NULL, 0,
+ bss_conf->assoc_capability, vif);
adapter->ps_info.dtim_interval_duration = bss->dtim_period;
adapter->ps_info.listen_interval = conf->listen_interval;
@@ -906,14 +912,25 @@ static int rsi_hal_key_config(struct ieee80211_hw *hw,
}
}
- return rsi_hal_load_key(adapter->priv,
- key->key,
- key->keylen,
- key_type,
- key->keyidx,
- key->cipher,
- sta_id,
- vif);
+ status = rsi_hal_load_key(adapter->priv,
+ key->key,
+ key->keylen,
+ key_type,
+ key->keyidx,
+ key->cipher,
+ sta_id,
+ vif);
+ if (status)
+ return status;
+
+ if (vif->type == NL80211_IFTYPE_STATION && key->key &&
+ (key->cipher == WLAN_CIPHER_SUITE_WEP104 ||
+ key->cipher == WLAN_CIPHER_SUITE_WEP40)) {
+ if (!rsi_send_block_unblock_frame(adapter->priv, false))
+ adapter->priv->hw_data_qs_blocked = false;
+ }
+
+ return 0;
}
/**
@@ -1086,7 +1103,7 @@ static int rsi_mac80211_ampdu_action(struct ieee80211_hw *hw,
break;
default:
- rsi_dbg(ERR_ZONE, "%s: Uknown AMPDU action\n", __func__);
+ rsi_dbg(ERR_ZONE, "%s: Unknown AMPDU action\n", __func__);
break;
}
@@ -1391,7 +1408,7 @@ static int rsi_mac80211_sta_add(struct ieee80211_hw *hw,
rsi_dbg(INFO_ZONE, "Indicate bss status to device\n");
rsi_inform_bss_status(common, RSI_OPMODE_AP, 1,
sta->addr, sta->wme, sta->aid,
- sta, sta_idx, vif);
+ sta, sta_idx, 0, vif);
if (common->key) {
struct ieee80211_key_conf *key = common->key;
@@ -1469,7 +1486,7 @@ static int rsi_mac80211_sta_remove(struct ieee80211_hw *hw,
rsi_inform_bss_status(common, RSI_OPMODE_AP, 0,
sta->addr, sta->wme,
sta->aid, sta, sta_idx,
- vif);
+ 0, vif);
rsta->sta = NULL;
rsta->sta_id = -1;
for (cnt = 0; cnt < IEEE80211_NUM_TIDS; cnt++)
@@ -1788,15 +1805,21 @@ int rsi_config_wowlan(struct rsi_hw *adapter, struct cfg80211_wowlan *wowlan)
struct rsi_common *common = adapter->priv;
u16 triggers = 0;
u16 rx_filter_word = 0;
- struct ieee80211_bss_conf *bss = &adapter->vifs[0]->bss_conf;
+ struct ieee80211_bss_conf *bss = NULL;
rsi_dbg(INFO_ZONE, "Config WoWLAN to device\n");
+ if (!adapter->vifs[0])
+ return -EINVAL;
+
+ bss = &adapter->vifs[0]->bss_conf;
+
if (WARN_ON(!wowlan)) {
rsi_dbg(ERR_ZONE, "WoW triggers not enabled\n");
return -EINVAL;
}
+ common->wow_flags |= RSI_WOW_ENABLED;
triggers = rsi_wow_map_triggers(common, wowlan);
if (!triggers) {
rsi_dbg(ERR_ZONE, "%s:No valid WoW triggers\n", __func__);
@@ -1819,7 +1842,6 @@ int rsi_config_wowlan(struct rsi_hw *adapter, struct cfg80211_wowlan *wowlan)
rx_filter_word = (ALLOW_DATA_ASSOC_PEER | DISALLOW_BEACONS);
rsi_send_rx_filter_frame(common, rx_filter_word);
- common->wow_flags |= RSI_WOW_ENABLED;
return 0;
}
@@ -1939,9 +1961,8 @@ int rsi_mac80211_attach(struct rsi_common *common)
hw->uapsd_queues = RSI_IEEE80211_UAPSD_QUEUES;
hw->uapsd_max_sp_len = IEEE80211_WMM_IE_STA_QOSINFO_SP_ALL;
- hw->max_tx_aggregation_subframes = 6;
- rsi_register_rates_channels(adapter, NL80211_BAND_2GHZ);
- rsi_register_rates_channels(adapter, NL80211_BAND_5GHZ);
+ hw->max_tx_aggregation_subframes = RSI_MAX_TX_AGGR_FRMS;
+ hw->max_rx_aggregation_subframes = RSI_MAX_RX_AGGR_FRMS;
hw->rate_control_algorithm = "AARF";
SET_IEEE80211_PERM_ADDR(hw, common->mac_addr);
@@ -1962,10 +1983,15 @@ int rsi_mac80211_attach(struct rsi_common *common)
wiphy->available_antennas_rx = 1;
wiphy->available_antennas_tx = 1;
+
+ rsi_register_rates_channels(adapter, NL80211_BAND_2GHZ);
wiphy->bands[NL80211_BAND_2GHZ] =
&adapter->sbands[NL80211_BAND_2GHZ];
- wiphy->bands[NL80211_BAND_5GHZ] =
- &adapter->sbands[NL80211_BAND_5GHZ];
+ if (common->num_supp_bands > 1) {
+ rsi_register_rates_channels(adapter, NL80211_BAND_5GHZ);
+ wiphy->bands[NL80211_BAND_5GHZ] =
+ &adapter->sbands[NL80211_BAND_5GHZ];
+ }
/* AP Parameters */
wiphy->max_ap_assoc_sta = rsi_max_ap_stas[common->oper_mode - 1];
@@ -1991,6 +2017,9 @@ int rsi_mac80211_attach(struct rsi_common *common)
wiphy->iface_combinations = rsi_iface_combinations;
wiphy->n_iface_combinations = ARRAY_SIZE(rsi_iface_combinations);
+ if (common->coex_mode > 1)
+ wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT;
+
status = ieee80211_register_hw(hw);
if (status)
return status;
diff --git a/drivers/net/wireless/rsi/rsi_91x_mgmt.c b/drivers/net/wireless/rsi/rsi_91x_mgmt.c
index c21fca750fd4..d0e5937cad6d 100644
--- a/drivers/net/wireless/rsi/rsi_91x_mgmt.c
+++ b/drivers/net/wireless/rsi/rsi_91x_mgmt.c
@@ -325,8 +325,8 @@ static int rsi_load_radio_caps(struct rsi_common *common)
radio_caps->channel_num = common->channel;
radio_caps->rf_model = RSI_RF_TYPE;
+ radio_caps->radio_cfg_info = RSI_LMAC_CLOCK_80MHZ;
if (common->channel_width == BW_40MHZ) {
- radio_caps->radio_cfg_info = RSI_LMAC_CLOCK_80MHZ;
radio_caps->radio_cfg_info |= RSI_ENABLE_40MHZ;
if (common->fsm_state == FSM_MAC_INIT_DONE) {
@@ -454,14 +454,10 @@ static int rsi_mgmt_pkt_to_core(struct rsi_common *common,
*
* Return: status: 0 on success, corresponding negative error code on failure.
*/
-static int rsi_hal_send_sta_notify_frame(struct rsi_common *common,
- enum opmode opmode,
- u8 notify_event,
- const unsigned char *bssid,
- u8 qos_enable,
- u16 aid,
- u16 sta_id,
- struct ieee80211_vif *vif)
+int rsi_hal_send_sta_notify_frame(struct rsi_common *common, enum opmode opmode,
+ u8 notify_event, const unsigned char *bssid,
+ u8 qos_enable, u16 aid, u16 sta_id,
+ struct ieee80211_vif *vif)
{
struct sk_buff *skb = NULL;
struct rsi_peer_notify *peer_notify;
@@ -1194,6 +1190,7 @@ static int rsi_send_auto_rate_request(struct rsi_common *common,
return -ENOMEM;
}
+ memset(skb->data, 0, frame_len);
selected_rates = kzalloc(2 * RSI_TBL_SZ, GFP_KERNEL);
if (!selected_rates) {
rsi_dbg(ERR_ZONE, "%s: Failed in allocation of mem\n",
@@ -1328,6 +1325,7 @@ void rsi_inform_bss_status(struct rsi_common *common,
u16 aid,
struct ieee80211_sta *sta,
u16 sta_id,
+ u16 assoc_cap,
struct ieee80211_vif *vif)
{
if (status) {
@@ -1342,10 +1340,10 @@ void rsi_inform_bss_status(struct rsi_common *common,
vif);
if (common->min_rate == 0xffff)
rsi_send_auto_rate_request(common, sta, sta_id, vif);
- if (opmode == RSI_OPMODE_STA) {
- if (!rsi_send_block_unblock_frame(common, false))
- common->hw_data_qs_blocked = false;
- }
+ if (opmode == RSI_OPMODE_STA &&
+ !(assoc_cap & WLAN_CAPABILITY_PRIVACY) &&
+ !rsi_send_block_unblock_frame(common, false))
+ common->hw_data_qs_blocked = false;
} else {
if (opmode == RSI_OPMODE_STA)
common->hw_data_qs_blocked = true;
@@ -1850,10 +1848,19 @@ int rsi_mgmt_pkt_recv(struct rsi_common *common, u8 *msg)
__func__);
return rsi_handle_card_ready(common, msg);
case TX_STATUS_IND:
- if (msg[15] == PROBEREQ_CONFIRM) {
+ switch (msg[RSI_TX_STATUS_TYPE]) {
+ case PROBEREQ_CONFIRM:
common->mgmt_q_block = false;
rsi_dbg(FSM_ZONE, "%s: Probe confirm received\n",
__func__);
+ break;
+ case EAPOL4_CONFIRM:
+ if (msg[RSI_TX_STATUS]) {
+ common->eapol4_confirm = true;
+ if (!rsi_send_block_unblock_frame(common,
+ false))
+ common->hw_data_qs_blocked = false;
+ }
}
break;
case BEACON_EVENT_IND:
diff --git a/drivers/net/wireless/rsi/rsi_91x_sdio.c b/drivers/net/wireless/rsi/rsi_91x_sdio.c
index d76e69c0beaa..416981d99229 100644
--- a/drivers/net/wireless/rsi/rsi_91x_sdio.c
+++ b/drivers/net/wireless/rsi/rsi_91x_sdio.c
@@ -170,7 +170,6 @@ static void rsi_reset_card(struct sdio_func *pfunction)
int err;
struct mmc_card *card = pfunction->card;
struct mmc_host *host = card->host;
- s32 bit = (fls(host->ocr_avail) - 1);
u8 cmd52_resp;
u32 clock, resp, i;
u16 rca;
@@ -190,7 +189,6 @@ static void rsi_reset_card(struct sdio_func *pfunction)
msleep(20);
/* Initialize the SDIO card */
- host->ios.vdd = bit;
host->ios.chip_select = MMC_CS_DONTCARE;
host->ios.bus_mode = MMC_BUSMODE_OPENDRAIN;
host->ios.power_mode = MMC_POWER_UP;
@@ -660,8 +658,6 @@ static int rsi_sdio_master_reg_read(struct rsi_hw *adapter, u32 addr,
if (!data)
return -ENOMEM;
- data = PTR_ALIGN(data, 8);
-
ms_addr = (addr >> 16);
status = rsi_sdio_master_access_msword(adapter, ms_addr);
if (status < 0) {
@@ -724,8 +720,6 @@ static int rsi_sdio_master_reg_write(struct rsi_hw *adapter,
if (!data_aligned)
return -ENOMEM;
- data_aligned = PTR_ALIGN(data_aligned, 8);
-
if (size == 2) {
*data_aligned = ((data << 16) | (data & 0xFFFF));
} else if (size == 1) {
@@ -1042,17 +1036,21 @@ static void ulp_read_write(struct rsi_hw *adapter, u16 addr, u32 data,
/*This function resets and re-initializes the chip.*/
static void rsi_reset_chip(struct rsi_hw *adapter)
{
- __le32 data;
+ u8 *data;
u8 sdio_interrupt_status = 0;
u8 request = 1;
int ret;
+ data = kzalloc(sizeof(u32), GFP_KERNEL);
+ if (!data)
+ return;
+
rsi_dbg(INFO_ZONE, "Writing disable to wakeup register\n");
ret = rsi_sdio_write_register(adapter, 0, SDIO_WAKEUP_REG, &request);
if (ret < 0) {
rsi_dbg(ERR_ZONE,
"%s: Failed to write SDIO wakeup register\n", __func__);
- return;
+ goto err;
}
msleep(20);
ret = rsi_sdio_read_register(adapter, RSI_FN1_INT_REGISTER,
@@ -1060,7 +1058,7 @@ static void rsi_reset_chip(struct rsi_hw *adapter)
if (ret < 0) {
rsi_dbg(ERR_ZONE, "%s: Failed to Read Intr Status Register\n",
__func__);
- return;
+ goto err;
}
rsi_dbg(INFO_ZONE, "%s: Intr Status Register value = %d\n",
__func__, sdio_interrupt_status);
@@ -1070,17 +1068,17 @@ static void rsi_reset_chip(struct rsi_hw *adapter)
rsi_dbg(ERR_ZONE,
"%s: Unable to set ms word to common reg\n",
__func__);
- return;
+ goto err;
}
- data = TA_HOLD_THREAD_VALUE;
+ put_unaligned_le32(TA_HOLD_THREAD_VALUE, data);
if (rsi_sdio_write_register_multiple(adapter, TA_HOLD_THREAD_REG |
RSI_SD_REQUEST_MASTER,
- (u8 *)&data, 4)) {
+ data, 4)) {
rsi_dbg(ERR_ZONE,
"%s: Unable to hold Thread-Arch processor threads\n",
__func__);
- return;
+ goto err;
}
/* This msleep will ensure Thread-Arch processor to go to hold
@@ -1101,6 +1099,9 @@ static void rsi_reset_chip(struct rsi_hw *adapter)
* read write operations to complete for chip reset.
*/
msleep(500);
+err:
+ kfree(data);
+ return;
}
/**
diff --git a/drivers/net/wireless/rsi/rsi_91x_usb.c b/drivers/net/wireless/rsi/rsi_91x_usb.c
index 7b8bae313aa9..6ce6b754df12 100644
--- a/drivers/net/wireless/rsi/rsi_91x_usb.c
+++ b/drivers/net/wireless/rsi/rsi_91x_usb.c
@@ -687,6 +687,14 @@ static int rsi_reset_card(struct rsi_hw *adapter)
*/
msleep(100);
+ ret = rsi_usb_master_reg_write(adapter, SWBL_REGOUT,
+ RSI_FW_WDT_DISABLE_REQ,
+ RSI_COMMON_REG_SIZE);
+ if (ret < 0) {
+ rsi_dbg(ERR_ZONE, "Disabling firmware watchdog timer failed\n");
+ goto fail;
+ }
+
ret = usb_ulp_read_write(adapter, RSI_WATCH_DOG_TIMER_1,
RSI_ULP_WRITE_2, 32);
if (ret < 0)
diff --git a/drivers/net/wireless/rsi/rsi_boot_params.h b/drivers/net/wireless/rsi/rsi_boot_params.h
index 238ee96434ec..ad903b22440e 100644
--- a/drivers/net/wireless/rsi/rsi_boot_params.h
+++ b/drivers/net/wireless/rsi/rsi_boot_params.h
@@ -46,7 +46,8 @@
(((TA_PLL_M_VAL_20 + 1) * 40) / \
((TA_PLL_N_VAL_20 + 1) * (TA_PLL_P_VAL_20 + 1)))
#define VALID_20 \
- (WIFI_PLL960_CONFIGS | WIFI_AFEPLL_CONFIGS | WIFI_SWITCH_CLK_CONFIGS)
+ (WIFI_TAPLL_CONFIGS | WIFI_PLL960_CONFIGS | WIFI_AFEPLL_CONFIGS | \
+ WIFI_SWITCH_CLK_CONFIGS | BOOTUP_MODE_INFO | CRYSTAL_GOOD_TIME)
#define UMAC_CLK_40BW \
(((TA_PLL_M_VAL_40 + 1) * 40) / \
((TA_PLL_N_VAL_40 + 1) * (TA_PLL_P_VAL_40 + 1)))
diff --git a/drivers/net/wireless/rsi/rsi_hal.h b/drivers/net/wireless/rsi/rsi_hal.h
index 786dccd0b732..327638cdd30b 100644
--- a/drivers/net/wireless/rsi/rsi_hal.h
+++ b/drivers/net/wireless/rsi/rsi_hal.h
@@ -115,6 +115,7 @@
#define FW_FLASH_OFFSET 0x820
#define LMAC_VER_OFFSET (FW_FLASH_OFFSET + 0x200)
#define MAX_DWORD_ALIGN_BYTES 64
+#define RSI_COMMON_REG_SIZE 2
struct bl_header {
__le32 flags;
@@ -167,6 +168,8 @@ struct rsi_bt_desc {
} __packed;
int rsi_hal_device_init(struct rsi_hw *adapter);
+int rsi_prepare_mgmt_desc(struct rsi_common *common, struct sk_buff *skb);
+int rsi_prepare_data_desc(struct rsi_common *common, struct sk_buff *skb);
int rsi_prepare_beacon(struct rsi_common *common, struct sk_buff *skb);
int rsi_send_pkt_to_bus(struct rsi_common *common, struct sk_buff *skb);
int rsi_send_bt_pkt(struct rsi_common *common, struct sk_buff *skb);
diff --git a/drivers/net/wireless/rsi/rsi_main.h b/drivers/net/wireless/rsi/rsi_main.h
index ef4fa323694b..a084f224bb03 100644
--- a/drivers/net/wireless/rsi/rsi_main.h
+++ b/drivers/net/wireless/rsi/rsi_main.h
@@ -190,12 +190,6 @@ struct cqm_info {
u32 rssi_hyst;
};
-struct xtended_desc {
- u8 confirm_frame_type;
- u8 retry_cnt;
- u16 reserved;
-};
-
enum rsi_dfs_regions {
RSI_REGION_FCC = 0,
RSI_REGION_ETSI,
@@ -293,6 +287,7 @@ struct rsi_common {
struct timer_list roc_timer;
struct ieee80211_vif *roc_vif;
+ bool eapol4_confirm;
void *bt_adapter;
};
diff --git a/drivers/net/wireless/rsi/rsi_mgmt.h b/drivers/net/wireless/rsi/rsi_mgmt.h
index cf6567ae5bbe..14620935c925 100644
--- a/drivers/net/wireless/rsi/rsi_mgmt.h
+++ b/drivers/net/wireless/rsi/rsi_mgmt.h
@@ -33,6 +33,7 @@
#define WMM_SHORT_SLOT_TIME 9
#define SIFS_DURATION 16
+#define EAPOL4_PACKET_LEN 0x85
#define KEY_TYPE_CLEAR 0
#define RSI_PAIRWISE_KEY 1
#define RSI_GROUP_KEY 2
@@ -62,9 +63,12 @@
#define RX_DOT11_MGMT 0x02
#define TX_STATUS_IND 0x04
#define BEACON_EVENT_IND 0x08
+#define EAPOL4_CONFIRM 1
#define PROBEREQ_CONFIRM 2
#define CARD_READY_IND 0x00
#define SLEEP_NOTIFY_IND 0x06
+#define RSI_TX_STATUS_TYPE 15
+#define RSI_TX_STATUS 12
#define RSI_DELETE_PEER 0x0
#define RSI_ADD_PEER 0x1
@@ -221,6 +225,9 @@
#define RSI_WOW_DISCONNECT BIT(5)
#endif
+#define RSI_MAX_TX_AGGR_FRMS 8
+#define RSI_MAX_RX_AGGR_FRMS 8
+
enum opmode {
RSI_OPMODE_UNSUPPORTED = -1,
RSI_OPMODE_AP = 0,
@@ -301,6 +308,12 @@ struct rsi_mac_frame {
#define ENCAP_MGMT_PKT BIT(7)
#define DESC_IMMEDIATE_WAKEUP BIT(15)
+struct rsi_xtended_desc {
+ u8 confirm_frame_type;
+ u8 retry_cnt;
+ u16 reserved;
+};
+
struct rsi_cmd_desc_dword0 {
__le16 len_qno;
u8 frame_type;
@@ -654,10 +667,14 @@ int rsi_set_channel(struct rsi_common *common,
struct ieee80211_channel *channel);
int rsi_send_vap_dynamic_update(struct rsi_common *common);
int rsi_send_block_unblock_frame(struct rsi_common *common, bool event);
+int rsi_hal_send_sta_notify_frame(struct rsi_common *common, enum opmode opmode,
+ u8 notify_event, const unsigned char *bssid,
+ u8 qos_enable, u16 aid, u16 sta_id,
+ struct ieee80211_vif *vif);
void rsi_inform_bss_status(struct rsi_common *common, enum opmode opmode,
u8 status, const u8 *addr, u8 qos_enable, u16 aid,
struct ieee80211_sta *sta, u16 sta_id,
- struct ieee80211_vif *vif);
+ u16 assoc_cap, struct ieee80211_vif *vif);
void rsi_indicate_pkt_to_os(struct rsi_common *common, struct sk_buff *skb);
int rsi_mac80211_attach(struct rsi_common *common);
void rsi_indicate_tx_status(struct rsi_hw *common, struct sk_buff *skb,
diff --git a/drivers/net/wireless/rsi/rsi_sdio.h b/drivers/net/wireless/rsi/rsi_sdio.h
index ead8e7c4df3a..353dbdf31e75 100644
--- a/drivers/net/wireless/rsi/rsi_sdio.h
+++ b/drivers/net/wireless/rsi/rsi_sdio.h
@@ -87,7 +87,7 @@ enum sdio_interrupt_type {
#define TA_SOFT_RST_CLR 0
#define TA_SOFT_RST_SET BIT(0)
#define TA_PC_ZERO 0
-#define TA_HOLD_THREAD_VALUE cpu_to_le32(0xF)
+#define TA_HOLD_THREAD_VALUE 0xF
#define TA_RELEASE_THREAD_VALUE cpu_to_le32(0xF)
#define TA_BASE_ADDR 0x2200
#define MISC_CFG_BASE_ADDR 0x4105
diff --git a/drivers/net/wireless/rsi/rsi_usb.h b/drivers/net/wireless/rsi/rsi_usb.h
index a88d59295a98..b6fe79f0a513 100644
--- a/drivers/net/wireless/rsi/rsi_usb.h
+++ b/drivers/net/wireless/rsi/rsi_usb.h
@@ -26,6 +26,7 @@
#define RSI_USB_READY_MAGIC_NUM 0xab
#define FW_STATUS_REG 0x41050012
#define RSI_TA_HOLD_REG 0x22000844
+#define RSI_FW_WDT_DISABLE_REQ 0x69
#define USB_VENDOR_REGISTER_READ 0x15
#define USB_VENDOR_REGISTER_WRITE 0x16