Commit 4fd6c476 authored by Prameela Rani Garnepudi's avatar Prameela Rani Garnepudi Committed by Kalle Valo

rsi: roaming enhancements

To support roaming below changes are done:
* Station notify frame is send to firmware after sending assoc
  request. This will avoid dropping of first EAPOL frame due to
  delay in creation of station control block in firmware.
* Data queues are unblocked after sending station notify in open
  mode, after configuring key in WEP mode, and after receiving
  EAPOL4 confirm in WPA mode.
* Initial EAPOL frames priority is chaged to MGMT, rekey EAPOL
  frames priority changed to VO.
Signed-off-by: default avatarPrameela Rani Garnepudi <prameela.j04cs@gmail.com>
Signed-off-by: default avatarAmitkumar Karwar <amit.karwar@redpinesignals.com>
Signed-off-by: default avatarKalle Valo <kvalo@codeaurora.org>
parent 62dc108d
...@@ -411,6 +411,18 @@ void rsi_core_xmit(struct rsi_common *common, struct sk_buff *skb) ...@@ -411,6 +411,18 @@ void rsi_core_xmit(struct rsi_common *common, struct sk_buff *skb)
if ((ieee80211_is_mgmt(wh->frame_control)) || if ((ieee80211_is_mgmt(wh->frame_control)) ||
(ieee80211_is_ctl(wh->frame_control)) || (ieee80211_is_ctl(wh->frame_control)) ||
(ieee80211_is_qos_nullfunc(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; q_num = MGMT_SOFT_Q;
skb->priority = q_num; skb->priority = q_num;
...@@ -450,6 +462,10 @@ void rsi_core_xmit(struct rsi_common *common, struct sk_buff *skb) ...@@ -450,6 +462,10 @@ void rsi_core_xmit(struct rsi_common *common, struct sk_buff *skb)
tid, 0); 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)) { if (rsi_prepare_data_desc(common, skb)) {
rsi_dbg(ERR_ZONE, "Failed to prepare data desc\n"); rsi_dbg(ERR_ZONE, "Failed to prepare data desc\n");
goto xmit_fail; goto xmit_fail;
......
...@@ -232,6 +232,18 @@ int rsi_prepare_data_desc(struct rsi_common *common, struct sk_buff *skb) ...@@ -232,6 +232,18 @@ int rsi_prepare_data_desc(struct rsi_common *common, struct sk_buff *skb)
data_desc->misc_flags |= RSI_FETCH_RETRY_CNT_FRM_HST; data_desc->misc_flags |= RSI_FETCH_RETRY_CNT_FRM_HST;
#define EAPOL_RETRY_CNT 15 #define EAPOL_RETRY_CNT 15
xtend_desc->retry_cnt = EAPOL_RETRY_CNT; 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); data_desc->mac_flags = cpu_to_le16(seq_num & 0xfff);
...@@ -271,8 +283,11 @@ int rsi_send_data_pkt(struct rsi_common *common, struct sk_buff *skb) ...@@ -271,8 +283,11 @@ int rsi_send_data_pkt(struct rsi_common *common, struct sk_buff *skb)
struct rsi_hw *adapter = common->priv; struct rsi_hw *adapter = common->priv;
struct ieee80211_vif *vif; struct ieee80211_vif *vif;
struct ieee80211_tx_info *info; struct ieee80211_tx_info *info;
struct skb_info *tx_params;
struct ieee80211_bss_conf *bss; struct ieee80211_bss_conf *bss;
struct ieee80211_hdr *wh;
int status = -EINVAL; int status = -EINVAL;
u8 header_size;
if (!skb) if (!skb)
return 0; return 0;
...@@ -284,6 +299,9 @@ int rsi_send_data_pkt(struct rsi_common *common, struct sk_buff *skb) ...@@ -284,6 +299,9 @@ int rsi_send_data_pkt(struct rsi_common *common, struct sk_buff *skb)
goto err; goto err;
vif = info->control.vif; vif = info->control.vif;
bss = &vif->bss_conf; 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) || if (((vif->type == NL80211_IFTYPE_STATION) ||
(vif->type == NL80211_IFTYPE_P2P_CLIENT)) && (vif->type == NL80211_IFTYPE_P2P_CLIENT)) &&
......
...@@ -737,7 +737,8 @@ static void rsi_mac80211_bss_info_changed(struct ieee80211_hw *hw, ...@@ -737,7 +737,8 @@ static void rsi_mac80211_bss_info_changed(struct ieee80211_hw *hw,
bss_conf->bssid, bss_conf->bssid,
bss_conf->qos, bss_conf->qos,
bss_conf->aid, 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.dtim_interval_duration = bss->dtim_period;
adapter->ps_info.listen_interval = conf->listen_interval; adapter->ps_info.listen_interval = conf->listen_interval;
...@@ -914,6 +915,17 @@ static int rsi_hal_key_config(struct ieee80211_hw *hw, ...@@ -914,6 +915,17 @@ static int rsi_hal_key_config(struct ieee80211_hw *hw,
key->cipher, key->cipher,
sta_id, sta_id,
vif); 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;
} }
/** /**
...@@ -1391,7 +1403,7 @@ static int rsi_mac80211_sta_add(struct ieee80211_hw *hw, ...@@ -1391,7 +1403,7 @@ static int rsi_mac80211_sta_add(struct ieee80211_hw *hw,
rsi_dbg(INFO_ZONE, "Indicate bss status to device\n"); rsi_dbg(INFO_ZONE, "Indicate bss status to device\n");
rsi_inform_bss_status(common, RSI_OPMODE_AP, 1, rsi_inform_bss_status(common, RSI_OPMODE_AP, 1,
sta->addr, sta->wme, sta->aid, sta->addr, sta->wme, sta->aid,
sta, sta_idx, vif); sta, sta_idx, 0, vif);
if (common->key) { if (common->key) {
struct ieee80211_key_conf *key = common->key; struct ieee80211_key_conf *key = common->key;
...@@ -1469,7 +1481,7 @@ static int rsi_mac80211_sta_remove(struct ieee80211_hw *hw, ...@@ -1469,7 +1481,7 @@ static int rsi_mac80211_sta_remove(struct ieee80211_hw *hw,
rsi_inform_bss_status(common, RSI_OPMODE_AP, 0, rsi_inform_bss_status(common, RSI_OPMODE_AP, 0,
sta->addr, sta->wme, sta->addr, sta->wme,
sta->aid, sta, sta_idx, sta->aid, sta, sta_idx,
vif); 0, vif);
rsta->sta = NULL; rsta->sta = NULL;
rsta->sta_id = -1; rsta->sta_id = -1;
for (cnt = 0; cnt < IEEE80211_NUM_TIDS; cnt++) for (cnt = 0; cnt < IEEE80211_NUM_TIDS; cnt++)
......
...@@ -454,14 +454,10 @@ static int rsi_mgmt_pkt_to_core(struct rsi_common *common, ...@@ -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. * Return: status: 0 on success, corresponding negative error code on failure.
*/ */
static int rsi_hal_send_sta_notify_frame(struct rsi_common *common, int rsi_hal_send_sta_notify_frame(struct rsi_common *common, enum opmode opmode,
enum opmode opmode, u8 notify_event, const unsigned char *bssid,
u8 notify_event, u8 qos_enable, u16 aid, u16 sta_id,
const unsigned char *bssid, struct ieee80211_vif *vif)
u8 qos_enable,
u16 aid,
u16 sta_id,
struct ieee80211_vif *vif)
{ {
struct sk_buff *skb = NULL; struct sk_buff *skb = NULL;
struct rsi_peer_notify *peer_notify; struct rsi_peer_notify *peer_notify;
...@@ -1328,6 +1324,7 @@ void rsi_inform_bss_status(struct rsi_common *common, ...@@ -1328,6 +1324,7 @@ void rsi_inform_bss_status(struct rsi_common *common,
u16 aid, u16 aid,
struct ieee80211_sta *sta, struct ieee80211_sta *sta,
u16 sta_id, u16 sta_id,
u16 assoc_cap,
struct ieee80211_vif *vif) struct ieee80211_vif *vif)
{ {
if (status) { if (status) {
...@@ -1342,10 +1339,10 @@ void rsi_inform_bss_status(struct rsi_common *common, ...@@ -1342,10 +1339,10 @@ void rsi_inform_bss_status(struct rsi_common *common,
vif); vif);
if (common->min_rate == 0xffff) if (common->min_rate == 0xffff)
rsi_send_auto_rate_request(common, sta, sta_id, vif); rsi_send_auto_rate_request(common, sta, sta_id, vif);
if (opmode == RSI_OPMODE_STA) { if (opmode == RSI_OPMODE_STA &&
if (!rsi_send_block_unblock_frame(common, false)) !(assoc_cap & WLAN_CAPABILITY_PRIVACY) &&
common->hw_data_qs_blocked = false; !rsi_send_block_unblock_frame(common, false))
} common->hw_data_qs_blocked = false;
} else { } else {
if (opmode == RSI_OPMODE_STA) if (opmode == RSI_OPMODE_STA)
common->hw_data_qs_blocked = true; common->hw_data_qs_blocked = true;
...@@ -1850,10 +1847,19 @@ int rsi_mgmt_pkt_recv(struct rsi_common *common, u8 *msg) ...@@ -1850,10 +1847,19 @@ int rsi_mgmt_pkt_recv(struct rsi_common *common, u8 *msg)
__func__); __func__);
return rsi_handle_card_ready(common, msg); return rsi_handle_card_ready(common, msg);
case TX_STATUS_IND: case TX_STATUS_IND:
if (msg[15] == PROBEREQ_CONFIRM) { switch (msg[RSI_TX_STATUS_TYPE]) {
case PROBEREQ_CONFIRM:
common->mgmt_q_block = false; common->mgmt_q_block = false;
rsi_dbg(FSM_ZONE, "%s: Probe confirm received\n", rsi_dbg(FSM_ZONE, "%s: Probe confirm received\n",
__func__); __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; break;
case BEACON_EVENT_IND: case BEACON_EVENT_IND:
......
...@@ -287,6 +287,7 @@ struct rsi_common { ...@@ -287,6 +287,7 @@ struct rsi_common {
struct timer_list roc_timer; struct timer_list roc_timer;
struct ieee80211_vif *roc_vif; struct ieee80211_vif *roc_vif;
bool eapol4_confirm;
void *bt_adapter; void *bt_adapter;
}; };
......
...@@ -33,6 +33,7 @@ ...@@ -33,6 +33,7 @@
#define WMM_SHORT_SLOT_TIME 9 #define WMM_SHORT_SLOT_TIME 9
#define SIFS_DURATION 16 #define SIFS_DURATION 16
#define EAPOL4_PACKET_LEN 0x85
#define KEY_TYPE_CLEAR 0 #define KEY_TYPE_CLEAR 0
#define RSI_PAIRWISE_KEY 1 #define RSI_PAIRWISE_KEY 1
#define RSI_GROUP_KEY 2 #define RSI_GROUP_KEY 2
...@@ -62,9 +63,12 @@ ...@@ -62,9 +63,12 @@
#define RX_DOT11_MGMT 0x02 #define RX_DOT11_MGMT 0x02
#define TX_STATUS_IND 0x04 #define TX_STATUS_IND 0x04
#define BEACON_EVENT_IND 0x08 #define BEACON_EVENT_IND 0x08
#define EAPOL4_CONFIRM 1
#define PROBEREQ_CONFIRM 2 #define PROBEREQ_CONFIRM 2
#define CARD_READY_IND 0x00 #define CARD_READY_IND 0x00
#define SLEEP_NOTIFY_IND 0x06 #define SLEEP_NOTIFY_IND 0x06
#define RSI_TX_STATUS_TYPE 15
#define RSI_TX_STATUS 12
#define RSI_DELETE_PEER 0x0 #define RSI_DELETE_PEER 0x0
#define RSI_ADD_PEER 0x1 #define RSI_ADD_PEER 0x1
...@@ -660,10 +664,14 @@ int rsi_set_channel(struct rsi_common *common, ...@@ -660,10 +664,14 @@ int rsi_set_channel(struct rsi_common *common,
struct ieee80211_channel *channel); struct ieee80211_channel *channel);
int rsi_send_vap_dynamic_update(struct rsi_common *common); int rsi_send_vap_dynamic_update(struct rsi_common *common);
int rsi_send_block_unblock_frame(struct rsi_common *common, bool event); 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, void rsi_inform_bss_status(struct rsi_common *common, enum opmode opmode,
u8 status, const u8 *addr, u8 qos_enable, u16 aid, u8 status, const u8 *addr, u8 qos_enable, u16 aid,
struct ieee80211_sta *sta, u16 sta_id, 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); void rsi_indicate_pkt_to_os(struct rsi_common *common, struct sk_buff *skb);
int rsi_mac80211_attach(struct rsi_common *common); int rsi_mac80211_attach(struct rsi_common *common);
void rsi_indicate_tx_status(struct rsi_hw *common, struct sk_buff *skb, void rsi_indicate_tx_status(struct rsi_hw *common, struct sk_buff *skb,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment