diff options
Diffstat (limited to 'drivers/net/wireless/ti/wl18xx/tx.c')
| -rw-r--r-- | drivers/net/wireless/ti/wl18xx/tx.c | 56 |
1 files changed, 33 insertions, 23 deletions
diff --git a/drivers/net/wireless/ti/wl18xx/tx.c b/drivers/net/wireless/ti/wl18xx/tx.c index 57c694396647..beef393853ef 100644 --- a/drivers/net/wireless/ti/wl18xx/tx.c +++ b/drivers/net/wireless/ti/wl18xx/tx.c @@ -1,22 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * This file is part of wl18xx * * Copyright (C) 2011 Texas Instruments Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA - * */ #include "../wlcore/wlcore.h" @@ -30,9 +16,9 @@ static void wl18xx_get_last_tx_rate(struct wl1271 *wl, struct ieee80211_vif *vif, - struct ieee80211_tx_rate *rate) + u8 band, struct ieee80211_tx_rate *rate, u8 hlid) { - u8 fw_rate = wl->fw_status_2->counters.tx_last_rate; + u8 fw_rate = wl->links[hlid].fw_rate_idx; if (fw_rate > CONF_HW_RATE_INDEX_MAX) { wl1271_error("last Tx rate invalid: %d", fw_rate); @@ -43,6 +29,8 @@ void wl18xx_get_last_tx_rate(struct wl1271 *wl, struct ieee80211_vif *vif, if (fw_rate <= CONF_HW_RATE_INDEX_54MBPS) { rate->idx = fw_rate; + if (band == NL80211_BAND_5GHZ) + rate->idx -= CONF_HW_RATE_INDEX_6MBPS; rate->flags = 0; } else { rate->flags = IEEE80211_TX_RC_MCS; @@ -77,6 +65,7 @@ static void wl18xx_tx_complete_packet(struct wl1271 *wl, u8 tx_stat_byte) struct sk_buff *skb; int id = tx_stat_byte & WL18XX_TX_STATUS_DESC_ID_MASK; bool tx_success; + struct wl1271_tx_hw_descr *tx_desc; /* check for id legality */ if (unlikely(id >= wl->num_tx_desc || wl->tx_frames[id] == NULL)) { @@ -89,6 +78,7 @@ static void wl18xx_tx_complete_packet(struct wl1271 *wl, u8 tx_stat_byte) skb = wl->tx_frames[id]; info = IEEE80211_SKB_CB(skb); + tx_desc = (struct wl1271_tx_hw_descr *)skb->data; if (wl12xx_is_dummy_packet(wl, skb)) { wl1271_free_tx_id(wl, id); @@ -102,7 +92,10 @@ static void wl18xx_tx_complete_packet(struct wl1271 *wl, u8 tx_stat_byte) * 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]); + wl18xx_get_last_tx_rate(wl, info->control.vif, + info->band, + &info->status.rates[0], + tx_desc->hlid); info->status.rates[0].count = 1; /* no data about retries */ info->status.ack_signal = -1; @@ -136,17 +129,35 @@ static void wl18xx_tx_complete_packet(struct wl1271 *wl, u8 tx_stat_byte) wl1271_free_tx_id(wl, id); } +static u8 wl18xx_next_tx_idx(u8 idx) +{ + if (++idx >= WL18XX_FW_MAX_TX_STATUS_DESC) + idx = 0; + + return idx; +} + void wl18xx_tx_immediate_complete(struct wl1271 *wl) { struct wl18xx_fw_status_priv *status_priv = - (struct wl18xx_fw_status_priv *)wl->fw_status_2->priv; + (struct wl18xx_fw_status_priv *)wl->fw_status->priv; struct wl18xx_priv *priv = wl->priv; - u8 i; + u8 i, hlid; /* nothing to do here */ if (priv->last_fw_rls_idx == status_priv->fw_release_idx) return; + /* update rates per link */ + hlid = wl->fw_status->counters.hlid; + + if (hlid < WLCORE_MAX_LINKS) { + wl->links[hlid].fw_rate_idx = + wl->fw_status->counters.tx_last_rate; + wl->links[hlid].fw_rate_mbps = + wl->fw_status->counters.tx_last_rate_mbps; + } + /* freed Tx descriptors */ wl1271_debug(DEBUG_TX, "last released desc = %d, current idx = %d", priv->last_fw_rls_idx, status_priv->fw_release_idx); @@ -158,9 +169,8 @@ void wl18xx_tx_immediate_complete(struct wl1271 *wl) return; } - for (i = priv->last_fw_rls_idx; - i != status_priv->fw_release_idx; - i = (i + 1) % WL18XX_FW_MAX_TX_STATUS_DESC) { + for (i = priv->last_fw_rls_idx; i != status_priv->fw_release_idx; + i = wl18xx_next_tx_idx(i)) { wl18xx_tx_complete_packet(wl, status_priv->released_tx_desc[i]); |
