You've already forked linux-apfs
mirror of
https://github.com/linux-apfs/linux-apfs.git
synced 2026-05-01 15:00:59 -07:00
ath9k: Revamp RX handling
Remove a lot of old, crufty code and make RX status reporting a bit sane and clean. Do not do anything to the RX skb before unmapping. So in ath_rx_tasklet(), move the skb_put() after PCI unmap. Signed-off-by: Sujith <Sujith.Manoharan@atheros.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
This commit is contained in:
@@ -279,13 +279,6 @@ struct ath_descdma {
|
||||
dma_addr_t dd_dmacontext;
|
||||
};
|
||||
|
||||
/* Abstraction of a received RX MPDU/MMPDU, or a RX fragment */
|
||||
|
||||
struct ath_rx_context {
|
||||
struct ath_buf *ctx_rxbuf; /* associated ath_buf for rx */
|
||||
};
|
||||
#define ATH_RX_CONTEXT(skb) ((struct ath_rx_context *)skb->cb)
|
||||
|
||||
int ath_descdma_setup(struct ath_softc *sc,
|
||||
struct ath_descdma *dd,
|
||||
struct list_head *head,
|
||||
@@ -298,61 +291,21 @@ void ath_descdma_cleanup(struct ath_softc *sc,
|
||||
struct ath_descdma *dd,
|
||||
struct list_head *head);
|
||||
|
||||
/******/
|
||||
/* RX */
|
||||
/******/
|
||||
/***********/
|
||||
/* RX / TX */
|
||||
/***********/
|
||||
|
||||
#define ATH_MAX_ANTENNA 3
|
||||
#define ATH_RXBUF 512
|
||||
#define WME_NUM_TID 16
|
||||
|
||||
/* per frame rx status block */
|
||||
struct ath_recv_status {
|
||||
u64 tsf; /* mac tsf */
|
||||
int8_t rssi; /* RSSI (noise floor ajusted) */
|
||||
int8_t rssictl[ATH_MAX_ANTENNA]; /* RSSI (noise floor ajusted) */
|
||||
int8_t rssiextn[ATH_MAX_ANTENNA]; /* RSSI (noise floor ajusted) */
|
||||
int8_t abs_rssi; /* absolute RSSI */
|
||||
u8 rateieee; /* data rate received (IEEE rate code) */
|
||||
u8 ratecode; /* phy rate code */
|
||||
int rateKbps; /* data rate received (Kbps) */
|
||||
int antenna; /* rx antenna */
|
||||
int flags; /* status of associated skb */
|
||||
#define ATH_RX_FCS_ERROR 0x01
|
||||
#define ATH_RX_MIC_ERROR 0x02
|
||||
#define ATH_RX_DECRYPT_ERROR 0x04
|
||||
#define ATH_RX_RSSI_VALID 0x08
|
||||
/* if any of ctl,extn chainrssis are valid */
|
||||
#define ATH_RX_CHAIN_RSSI_VALID 0x10
|
||||
/* if extn chain rssis are valid */
|
||||
#define ATH_RX_RSSI_EXTN_VALID 0x20
|
||||
/* set if 40Mhz, clear if 20Mhz */
|
||||
#define ATH_RX_40MHZ 0x40
|
||||
/* set if short GI, clear if full GI */
|
||||
#define ATH_RX_SHORT_GI 0x80
|
||||
};
|
||||
|
||||
struct ath_rxbuf {
|
||||
struct sk_buff *rx_wbuf;
|
||||
unsigned long rx_time; /* system time when received */
|
||||
struct ath_recv_status rx_status; /* cached rx status */
|
||||
};
|
||||
|
||||
int ath_startrecv(struct ath_softc *sc);
|
||||
bool ath_stoprecv(struct ath_softc *sc);
|
||||
void ath_flushrecv(struct ath_softc *sc);
|
||||
u32 ath_calcrxfilter(struct ath_softc *sc);
|
||||
void ath_handle_rx_intr(struct ath_softc *sc);
|
||||
int ath_rx_init(struct ath_softc *sc, int nbufs);
|
||||
void ath_rx_cleanup(struct ath_softc *sc);
|
||||
int ath_rx_tasklet(struct ath_softc *sc, int flush);
|
||||
int _ath_rx_indicate(struct ath_softc *sc,
|
||||
struct sk_buff *skb,
|
||||
struct ath_recv_status *status,
|
||||
u16 keyix);
|
||||
/******/
|
||||
/* TX */
|
||||
/******/
|
||||
|
||||
#define ATH_TXBUF 512
|
||||
/* max number of transmit attempts (tries) */
|
||||
|
||||
@@ -236,68 +236,6 @@ static void setup_ht_cap(struct ieee80211_sta_ht_cap *ht_info)
|
||||
ht_info->mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED;
|
||||
}
|
||||
|
||||
static int ath_rate2idx(struct ath_softc *sc, int rate)
|
||||
{
|
||||
int i = 0, cur_band, n_rates;
|
||||
struct ieee80211_hw *hw = sc->hw;
|
||||
|
||||
cur_band = hw->conf.channel->band;
|
||||
n_rates = sc->sbands[cur_band].n_bitrates;
|
||||
|
||||
for (i = 0; i < n_rates; i++) {
|
||||
if (sc->sbands[cur_band].bitrates[i].bitrate == rate)
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* NB:mac80211 validates rx rate index against the supported legacy rate
|
||||
* index only (should be done against ht rates also), return the highest
|
||||
* legacy rate index for rx rate which does not match any one of the
|
||||
* supported basic and extended rates to make mac80211 happy.
|
||||
* The following hack will be cleaned up once the issue with
|
||||
* the rx rate index validation in mac80211 is fixed.
|
||||
*/
|
||||
if (i == n_rates)
|
||||
return n_rates - 1;
|
||||
return i;
|
||||
}
|
||||
|
||||
static void ath9k_rx_prepare(struct ath_softc *sc,
|
||||
struct sk_buff *skb,
|
||||
struct ath_recv_status *status,
|
||||
struct ieee80211_rx_status *rx_status)
|
||||
{
|
||||
struct ieee80211_hw *hw = sc->hw;
|
||||
struct ieee80211_channel *curchan = hw->conf.channel;
|
||||
|
||||
memset(rx_status, 0, sizeof(struct ieee80211_rx_status));
|
||||
|
||||
rx_status->mactime = status->tsf;
|
||||
rx_status->band = curchan->band;
|
||||
rx_status->freq = curchan->center_freq;
|
||||
rx_status->noise = sc->sc_ani.sc_noise_floor;
|
||||
rx_status->signal = rx_status->noise + status->rssi;
|
||||
rx_status->rate_idx = ath_rate2idx(sc, (status->rateKbps / 100));
|
||||
rx_status->antenna = status->antenna;
|
||||
|
||||
/* at 45 you will be able to use MCS 15 reliably. A more elaborate
|
||||
* scheme can be used here but it requires tables of SNR/throughput for
|
||||
* each possible mode used. */
|
||||
rx_status->qual = status->rssi * 100 / 45;
|
||||
|
||||
/* rssi can be more than 45 though, anything above that
|
||||
* should be considered at 100% */
|
||||
if (rx_status->qual > 100)
|
||||
rx_status->qual = 100;
|
||||
|
||||
if (status->flags & ATH_RX_MIC_ERROR)
|
||||
rx_status->flag |= RX_FLAG_MMIC_ERROR;
|
||||
if (status->flags & ATH_RX_FCS_ERROR)
|
||||
rx_status->flag |= RX_FLAG_FAILED_FCS_CRC;
|
||||
|
||||
rx_status->flag |= RX_FLAG_TSFT;
|
||||
}
|
||||
|
||||
static void ath9k_ht_conf(struct ath_softc *sc,
|
||||
struct ieee80211_bss_conf *bss_conf)
|
||||
{
|
||||
@@ -440,44 +378,6 @@ void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb,
|
||||
ieee80211_tx_status(hw, skb);
|
||||
}
|
||||
|
||||
int _ath_rx_indicate(struct ath_softc *sc,
|
||||
struct sk_buff *skb,
|
||||
struct ath_recv_status *status,
|
||||
u16 keyix)
|
||||
{
|
||||
struct ieee80211_hw *hw = sc->hw;
|
||||
struct ieee80211_rx_status rx_status;
|
||||
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
|
||||
int hdrlen = ieee80211_get_hdrlen_from_skb(skb);
|
||||
int padsize;
|
||||
|
||||
/* see if any padding is done by the hw and remove it */
|
||||
if (hdrlen & 3) {
|
||||
padsize = hdrlen % 4;
|
||||
memmove(skb->data + padsize, skb->data, hdrlen);
|
||||
skb_pull(skb, padsize);
|
||||
}
|
||||
|
||||
/* Prepare rx status */
|
||||
ath9k_rx_prepare(sc, skb, status, &rx_status);
|
||||
|
||||
if (!(keyix == ATH9K_RXKEYIX_INVALID) &&
|
||||
!(status->flags & ATH_RX_DECRYPT_ERROR)) {
|
||||
rx_status.flag |= RX_FLAG_DECRYPTED;
|
||||
} else if ((le16_to_cpu(hdr->frame_control) & IEEE80211_FCTL_PROTECTED)
|
||||
&& !(status->flags & ATH_RX_DECRYPT_ERROR)
|
||||
&& skb->len >= hdrlen + 4) {
|
||||
keyix = skb->data[hdrlen + 3] >> 6;
|
||||
|
||||
if (test_bit(keyix, sc->sc_keymap))
|
||||
rx_status.flag |= RX_FLAG_DECRYPTED;
|
||||
}
|
||||
|
||||
__ieee80211_rx(hw, skb, &rx_status);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/********************************/
|
||||
/* LED functions */
|
||||
/********************************/
|
||||
|
||||
+203
-366
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user