rsi: data and managemet path changes for AP mode

Station id needs to be get for data and management frames
to fill in the descruptor for AP mode. Few other changes
related to AP mode are covered here.

Signed-off-by: Prameela Rani Garnepudi <prameela.j04cs@gmail.com>
Signed-off-by: Amitkumar Karwar <amit.karwar@redpinesignals.com>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
This commit is contained in:
Prameela Rani Garnepudi 2017-08-16 18:43:14 +05:30 committed by Kalle Valo
parent 571b050b42
commit 19844c0a9a
5 changed files with 96 additions and 27 deletions

View File

@ -320,6 +320,20 @@ void rsi_core_qos_processor(struct rsi_common *common)
}
}
struct rsi_sta *rsi_find_sta(struct rsi_common *common, u8 *mac_addr)
{
int i;
for (i = 0; i < common->max_stations; i++) {
if (!common->stations[i].sta)
continue;
if (!(memcmp(common->stations[i].sta->addr,
mac_addr, ETH_ALEN)))
return &common->stations[i];
}
return NULL;
}
/**
* rsi_core_xmit() - This function transmits the packets received from mac80211
* @common: Pointer to the driver private structure.
@ -332,39 +346,60 @@ void rsi_core_xmit(struct rsi_common *common, struct sk_buff *skb)
struct rsi_hw *adapter = common->priv;
struct ieee80211_tx_info *info;
struct skb_info *tx_params;
struct ieee80211_hdr *tmp_hdr = NULL;
struct ieee80211_hdr *wh;
struct ieee80211_vif *vif = adapter->vifs[0];
u8 q_num, tid = 0;
struct rsi_sta *rsta = NULL;
if ((!skb) || (!skb->len)) {
rsi_dbg(ERR_ZONE, "%s: Null skb/zero Length packet\n",
__func__);
goto xmit_fail;
}
info = IEEE80211_SKB_CB(skb);
tx_params = (struct skb_info *)info->driver_data;
tmp_hdr = (struct ieee80211_hdr *)&skb->data[0];
if (common->fsm_state != FSM_MAC_INIT_DONE) {
rsi_dbg(ERR_ZONE, "%s: FSM state not open\n", __func__);
goto xmit_fail;
}
if ((ieee80211_is_mgmt(tmp_hdr->frame_control)) ||
(ieee80211_is_ctl(tmp_hdr->frame_control)) ||
(ieee80211_is_qos_nullfunc(tmp_hdr->frame_control))) {
info = IEEE80211_SKB_CB(skb);
tx_params = (struct skb_info *)info->driver_data;
wh = (struct ieee80211_hdr *)&skb->data[0];
tx_params->sta_id = 0;
if ((ieee80211_is_mgmt(wh->frame_control)) ||
(ieee80211_is_ctl(wh->frame_control)) ||
(ieee80211_is_qos_nullfunc(wh->frame_control))) {
q_num = MGMT_SOFT_Q;
skb->priority = q_num;
} else {
if (ieee80211_is_data_qos(tmp_hdr->frame_control)) {
if (ieee80211_is_data_qos(wh->frame_control)) {
tid = (skb->data[24] & IEEE80211_QOS_TID);
skb->priority = TID_TO_WME_AC(tid);
} else {
tid = IEEE80211_NONQOS_TID;
skb->priority = BE_Q;
}
q_num = skb->priority;
tx_params->tid = tid;
tx_params->sta_id = 0;
if ((vif->type == NL80211_IFTYPE_AP) &&
(!is_broadcast_ether_addr(wh->addr1)) &&
(!is_multicast_ether_addr(wh->addr1))) {
rsta = rsi_find_sta(common, wh->addr1);
if (!rsta)
goto xmit_fail;
tx_params->sta_id = rsta->sta_id;
}
if (rsta) {
/* Start aggregation if not done for this tid */
if (!rsta->start_tx_aggr[tid]) {
rsta->start_tx_aggr[tid] = true;
ieee80211_start_tx_ba_session(rsta->sta,
tid, 0);
}
}
}
if ((q_num < MGMT_SOFT_Q) &&

View File

@ -18,6 +18,7 @@
#include "rsi_mgmt.h"
#include "rsi_hal.h"
#include "rsi_sdio.h"
#include "rsi_common.h"
/* FLASH Firmware */
static struct ta_metadata metadata_flash_content[] = {
@ -41,7 +42,7 @@ static int rsi_prepare_mgmt_desc(struct rsi_common *common, struct sk_buff *skb)
struct ieee80211_hdr *wh = NULL;
struct ieee80211_tx_info *info;
struct ieee80211_conf *conf = &adapter->hw->conf;
struct ieee80211_vif *vif = NULL;
struct ieee80211_vif *vif = adapter->vifs[0];
struct rsi_mgmt_desc *mgmt_desc;
struct skb_info *tx_params;
struct ieee80211_bss_conf *bss = NULL;
@ -49,6 +50,11 @@ static int rsi_prepare_mgmt_desc(struct rsi_common *common, struct sk_buff *skb)
u8 header_size;
u32 dword_align_bytes = 0;
if (skb->len > MAX_MGMT_PKT_SIZE) {
rsi_dbg(INFO_ZONE, "%s: Dropping mgmt pkt > 512\n", __func__);
return -EINVAL;
}
info = IEEE80211_SKB_CB(skb);
tx_params = (struct skb_info *)info->driver_data;
@ -74,15 +80,10 @@ static int rsi_prepare_mgmt_desc(struct rsi_common *common, struct sk_buff *skb)
memset(&skb->data[0], 0, header_size);
bss = &info->control.vif->bss_conf;
wh = (struct ieee80211_hdr *)&skb->data[header_size];
vif = adapter->vifs[0];
mgmt_desc = (struct rsi_mgmt_desc *)skb->data;
xtend_desc = (struct xtended_desc *)&skb->data[FRAME_DESC_SZ];
if (skb->len > MAX_MGMT_PKT_SIZE) {
rsi_dbg(INFO_ZONE, "%s: Dropping mgmt pkt > 512\n", __func__);
return -EINVAL;
}
rsi_set_len_qno(&mgmt_desc->len_qno, (skb->len - FRAME_DESC_SZ),
RSI_WIFI_MGMT_Q);
mgmt_desc->frame_type = TX_DOT11_MGMT;
@ -113,6 +114,22 @@ static int rsi_prepare_mgmt_desc(struct rsi_common *common, struct sk_buff *skb)
}
}
if (ieee80211_is_probe_resp(wh->frame_control)) {
mgmt_desc->misc_flags |= (RSI_ADD_DELTA_TSF_VAP_ID |
RSI_FETCH_RETRY_CNT_FRM_HST);
#define PROBE_RESP_RETRY_CNT 3
xtend_desc->retry_cnt = PROBE_RESP_RETRY_CNT;
}
if ((vif->type == NL80211_IFTYPE_AP) &&
(ieee80211_is_action(wh->frame_control))) {
struct rsi_sta *rsta = rsi_find_sta(common, wh->addr1);
if (rsta)
mgmt_desc->sta_id = tx_params->sta_id;
else
return -EINVAL;
}
return 0;
}
@ -157,7 +174,7 @@ static int rsi_prepare_data_desc(struct rsi_common *common, struct sk_buff *skb)
xtend_desc = (struct xtended_desc *)&skb->data[FRAME_DESC_SZ];
wh = (struct ieee80211_hdr *)&skb->data[header_size];
seq_num = (le16_to_cpu(wh->seq_ctrl) >> 4);
seq_num = IEEE80211_SEQ_TO_SN(le16_to_cpu(wh->seq_ctrl));
vif = adapter->vifs[0];
data_desc->xtend_desc_size = header_size - FRAME_DESC_SZ;
@ -191,12 +208,11 @@ static int rsi_prepare_data_desc(struct rsi_common *common, struct sk_buff *skb)
if (conf_is_ht40(&common->priv->hw->conf))
data_desc->bbp_info = cpu_to_le16(FULL40M_ENABLE);
if (common->vif_info[0].sgi) {
if (common->min_rate & 0x100) /* Only MCS rates */
data_desc->rate_info |=
cpu_to_le16(ENABLE_SHORTGI_RATE);
if ((common->vif_info[0].sgi) && (common->min_rate & 0x100)) {
/* Only MCS rates */
data_desc->rate_info |=
cpu_to_le16(ENABLE_SHORTGI_RATE);
}
}
if (skb->protocol == cpu_to_be16(ETH_P_PAE)) {
@ -223,7 +239,17 @@ static int rsi_prepare_data_desc(struct rsi_common *common, struct sk_buff *skb)
data_desc->frame_info = cpu_to_le16(RATE_INFO_ENABLE);
data_desc->frame_info |= cpu_to_le16(RSI_BROADCAST_PKT);
data_desc->sta_id = vap_id;
if (vif->type == NL80211_IFTYPE_AP) {
if (common->band == NL80211_BAND_5GHZ)
data_desc->rate_info = cpu_to_le16(RSI_RATE_6);
else
data_desc->rate_info = cpu_to_le16(RSI_RATE_1);
}
}
if ((vif->type == NL80211_IFTYPE_AP) &&
(ieee80211_has_moredata(wh->frame_control)))
data_desc->frame_info |= cpu_to_le16(MORE_DATA_PRESENT);
return 0;
}
@ -232,17 +258,23 @@ static int rsi_prepare_data_desc(struct rsi_common *common, struct sk_buff *skb)
int rsi_send_data_pkt(struct rsi_common *common, struct sk_buff *skb)
{
struct rsi_hw *adapter = common->priv;
struct ieee80211_vif *vif = adapter->vifs[0];
struct ieee80211_tx_info *info;
struct ieee80211_bss_conf *bss;
int status = -EIO;
int status = -EINVAL;
if (!skb)
return 0;
if (common->iface_down)
goto err;
info = IEEE80211_SKB_CB(skb);
if (!info->control.vif)
goto err;
bss = &info->control.vif->bss_conf;
if (!bss->assoc) {
status = -EINVAL;
if ((vif->type == NL80211_IFTYPE_STATION) && (!bss->assoc))
goto err;
}
status = rsi_prepare_data_desc(common, skb);
if (status)

View File

@ -83,4 +83,5 @@ u16 rsi_get_connected_channel(struct rsi_hw *adapter);
struct rsi_hw *rsi_91x_init(void);
void rsi_91x_deinit(struct rsi_hw *adapter);
int rsi_read_pkt(struct rsi_common *common, s32 rcv_pkt_len);
struct rsi_sta *rsi_find_sta(struct rsi_common *common, u8 *mac_addr);
#endif

View File

@ -126,7 +126,7 @@ struct rsi_mgmt_desc {
__le16 bbp_info;
__le16 seq_ctrl;
u8 reserved2;
u8 vap_info;
u8 sta_id;
} __packed;
struct rsi_data_desc {

View File

@ -63,6 +63,7 @@
#define BBP_REG_WRITE 0
#define RF_RESET_ENABLE BIT(3)
#define RATE_INFO_ENABLE BIT(0)
#define MORE_DATA_PRESENT BIT(1)
#define RSI_BROADCAST_PKT BIT(9)
#define RSI_DESC_REQUIRE_CFM_TO_HOST BIT(2)
#define RSI_ADD_DELTA_TSF_VAP_ID BIT(3)