wl18xx: set last Tx rate from FW status
Obtain the last Tx rate from the FW status and translate it to the mac80211 rate+flag format before sending it up via the Tx status. Signed-off-by: Arik Nemtsov <arik@wizery.com> Signed-off-by: Luciano Coelho <coelho@ti.com>
This commit is contained in:
parent
0e81047996
commit
4d70384761
@ -28,6 +28,49 @@
|
||||
#include "wl18xx.h"
|
||||
#include "tx.h"
|
||||
|
||||
static
|
||||
void wl18xx_get_last_tx_rate(struct wl1271 *wl, struct ieee80211_vif *vif,
|
||||
struct ieee80211_tx_rate *rate)
|
||||
{
|
||||
u8 fw_rate = wl->fw_status_2->counters.tx_last_rate;
|
||||
|
||||
if (fw_rate > CONF_HW_RATE_INDEX_MAX) {
|
||||
wl1271_error("last Tx rate invalid: %d", fw_rate);
|
||||
rate->idx = 0;
|
||||
rate->flags = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if (fw_rate <= CONF_HW_RATE_INDEX_54MBPS) {
|
||||
rate->idx = fw_rate;
|
||||
rate->flags = 0;
|
||||
} else {
|
||||
rate->flags = IEEE80211_TX_RC_MCS;
|
||||
rate->idx = fw_rate - CONF_HW_RATE_INDEX_MCS0;
|
||||
|
||||
/* SGI modifier is counted as a separate rate */
|
||||
if (fw_rate >= CONF_HW_RATE_INDEX_MCS7_SGI)
|
||||
(rate->idx)--;
|
||||
if (fw_rate == CONF_HW_RATE_INDEX_MCS15_SGI)
|
||||
(rate->idx)--;
|
||||
|
||||
/* this also covers the 40Mhz SGI case (= MCS15) */
|
||||
if (fw_rate == CONF_HW_RATE_INDEX_MCS7_SGI ||
|
||||
fw_rate == CONF_HW_RATE_INDEX_MCS15_SGI)
|
||||
rate->flags |= IEEE80211_TX_RC_SHORT_GI;
|
||||
|
||||
if (fw_rate > CONF_HW_RATE_INDEX_MCS7_SGI && vif) {
|
||||
struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif);
|
||||
if (wlvif->channel_type == NL80211_CHAN_HT40MINUS ||
|
||||
wlvif->channel_type == NL80211_CHAN_HT40PLUS) {
|
||||
/* adjustment needed for range 0-7 */
|
||||
rate->idx -= 8;
|
||||
rate->flags |= IEEE80211_TX_RC_40_MHZ_WIDTH;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void wl18xx_tx_complete_packet(struct wl1271 *wl, u8 tx_stat_byte)
|
||||
{
|
||||
struct ieee80211_tx_info *info;
|
||||
@ -44,7 +87,6 @@ static void wl18xx_tx_complete_packet(struct wl1271 *wl, u8 tx_stat_byte)
|
||||
/* a zero bit indicates Tx success */
|
||||
tx_success = !(tx_stat_byte & BIT(WL18XX_TX_STATUS_STAT_BIT_IDX));
|
||||
|
||||
|
||||
skb = wl->tx_frames[id];
|
||||
info = IEEE80211_SKB_CB(skb);
|
||||
|
||||
@ -56,11 +98,13 @@ static void wl18xx_tx_complete_packet(struct wl1271 *wl, u8 tx_stat_byte)
|
||||
/* update the TX status info */
|
||||
if (tx_success && !(info->flags & IEEE80211_TX_CTL_NO_ACK))
|
||||
info->flags |= IEEE80211_TX_STAT_ACK;
|
||||
/*
|
||||
* first pass info->control.vif while it's valid, and then fill out
|
||||
* the info->status structures
|
||||
*/
|
||||
wl18xx_get_last_tx_rate(wl, info->control.vif, &info->status.rates[0]);
|
||||
|
||||
/* no real data about Tx completion */
|
||||
info->status.rates[0].idx = -1;
|
||||
info->status.rates[0].count = 0;
|
||||
info->status.rates[0].flags = 0;
|
||||
info->status.rates[0].count = 1; /* no data about retries */
|
||||
info->status.ack_signal = -1;
|
||||
|
||||
if (!tx_success)
|
||||
|
@ -57,20 +57,49 @@ enum {
|
||||
};
|
||||
|
||||
enum {
|
||||
CONF_HW_RATE_INDEX_1MBPS = 0,
|
||||
CONF_HW_RATE_INDEX_2MBPS = 1,
|
||||
CONF_HW_RATE_INDEX_5_5MBPS = 2,
|
||||
CONF_HW_RATE_INDEX_6MBPS = 3,
|
||||
CONF_HW_RATE_INDEX_9MBPS = 4,
|
||||
CONF_HW_RATE_INDEX_11MBPS = 5,
|
||||
CONF_HW_RATE_INDEX_12MBPS = 6,
|
||||
CONF_HW_RATE_INDEX_18MBPS = 7,
|
||||
CONF_HW_RATE_INDEX_22MBPS = 8,
|
||||
CONF_HW_RATE_INDEX_24MBPS = 9,
|
||||
CONF_HW_RATE_INDEX_36MBPS = 10,
|
||||
CONF_HW_RATE_INDEX_48MBPS = 11,
|
||||
CONF_HW_RATE_INDEX_54MBPS = 12,
|
||||
CONF_HW_RATE_INDEX_MAX = CONF_HW_RATE_INDEX_54MBPS,
|
||||
CONF_HW_RATE_INDEX_1MBPS = 0,
|
||||
CONF_HW_RATE_INDEX_2MBPS = 1,
|
||||
CONF_HW_RATE_INDEX_5_5MBPS = 2,
|
||||
CONF_HW_RATE_INDEX_11MBPS = 3,
|
||||
CONF_HW_RATE_INDEX_6MBPS = 4,
|
||||
CONF_HW_RATE_INDEX_9MBPS = 5,
|
||||
CONF_HW_RATE_INDEX_12MBPS = 6,
|
||||
CONF_HW_RATE_INDEX_18MBPS = 7,
|
||||
CONF_HW_RATE_INDEX_24MBPS = 8,
|
||||
CONF_HW_RATE_INDEX_36MBPS = 9,
|
||||
CONF_HW_RATE_INDEX_48MBPS = 10,
|
||||
CONF_HW_RATE_INDEX_54MBPS = 11,
|
||||
CONF_HW_RATE_INDEX_MCS0 = 12,
|
||||
CONF_HW_RATE_INDEX_MCS1 = 13,
|
||||
CONF_HW_RATE_INDEX_MCS2 = 14,
|
||||
CONF_HW_RATE_INDEX_MCS3 = 15,
|
||||
CONF_HW_RATE_INDEX_MCS4 = 16,
|
||||
CONF_HW_RATE_INDEX_MCS5 = 17,
|
||||
CONF_HW_RATE_INDEX_MCS6 = 18,
|
||||
CONF_HW_RATE_INDEX_MCS7 = 19,
|
||||
CONF_HW_RATE_INDEX_MCS7_SGI = 20,
|
||||
CONF_HW_RATE_INDEX_MCS0_40MHZ = 21,
|
||||
CONF_HW_RATE_INDEX_MCS1_40MHZ = 22,
|
||||
CONF_HW_RATE_INDEX_MCS2_40MHZ = 23,
|
||||
CONF_HW_RATE_INDEX_MCS3_40MHZ = 24,
|
||||
CONF_HW_RATE_INDEX_MCS4_40MHZ = 25,
|
||||
CONF_HW_RATE_INDEX_MCS5_40MHZ = 26,
|
||||
CONF_HW_RATE_INDEX_MCS6_40MHZ = 27,
|
||||
CONF_HW_RATE_INDEX_MCS7_40MHZ = 28,
|
||||
CONF_HW_RATE_INDEX_MCS7_40MHZ_SGI = 29,
|
||||
|
||||
/* MCS8+ rates overlap with 40Mhz rates */
|
||||
CONF_HW_RATE_INDEX_MCS8 = 21,
|
||||
CONF_HW_RATE_INDEX_MCS9 = 22,
|
||||
CONF_HW_RATE_INDEX_MCS10 = 23,
|
||||
CONF_HW_RATE_INDEX_MCS11 = 24,
|
||||
CONF_HW_RATE_INDEX_MCS12 = 25,
|
||||
CONF_HW_RATE_INDEX_MCS13 = 26,
|
||||
CONF_HW_RATE_INDEX_MCS14 = 27,
|
||||
CONF_HW_RATE_INDEX_MCS15 = 28,
|
||||
CONF_HW_RATE_INDEX_MCS15_SGI = 29,
|
||||
|
||||
CONF_HW_RATE_INDEX_MAX = CONF_HW_RATE_INDEX_MCS7_40MHZ_SGI,
|
||||
};
|
||||
|
||||
#define CONF_HW_RXTX_RATE_UNSUPPORTED 0xff
|
||||
|
@ -130,7 +130,10 @@ struct wl_fw_packet_counters {
|
||||
/* Cumulative counter of released Voice memory blocks */
|
||||
u8 tx_voice_released_blks;
|
||||
|
||||
u8 padding[3];
|
||||
/* Tx rate of the last transmitted packet */
|
||||
u8 tx_last_rate;
|
||||
|
||||
u8 padding[2];
|
||||
} __packed;
|
||||
|
||||
/* FW status registers */
|
||||
|
Loading…
Reference in New Issue
Block a user