Skip to content

Commit

Permalink
wl18xx: set last Tx rate from FW status
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
ariknem committed Nov 29, 2012
1 parent b002bb4 commit e0f876e
Show file tree
Hide file tree
Showing 3 changed files with 96 additions and 20 deletions.
54 changes: 49 additions & 5 deletions drivers/net/wireless/ti/wl18xx/tx.c
Expand Up @@ -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;
Expand All @@ -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);

Expand All @@ -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)
Expand Down
57 changes: 43 additions & 14 deletions drivers/net/wireless/ti/wlcore/conf.h
Expand Up @@ -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
Expand Down
5 changes: 4 additions & 1 deletion drivers/net/wireless/ti/wlcore/wlcore_i.h
Expand Up @@ -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 */
Expand Down

0 comments on commit e0f876e

Please sign in to comment.