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)
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;
......@@ -450,6 +462,10 @@ 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;
......
......@@ -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;
#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);
......@@ -271,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;
......@@ -284,6 +299,9 @@ 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)) &&
......
......@@ -737,7 +737,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;
......@@ -914,6 +915,17 @@ static int rsi_hal_key_config(struct ieee80211_hw *hw,
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;
}
/**
......@@ -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_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 +1481,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++)
......
......@@ -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;
......@@ -1328,6 +1324,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 +1339,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 +1847,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:
......
......@@ -287,6 +287,7 @@ struct rsi_common {
struct timer_list roc_timer;
struct ieee80211_vif *roc_vif;
bool eapol4_confirm;
void *bt_adapter;
};
......
......@@ -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
......@@ -660,10 +664,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,
......
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