Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit be0418ad authored by Sujith's avatar Sujith Committed by John W. Linville
Browse files

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: default avatarSujith <Sujith.Manoharan@atheros.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 2b406f1e
Loading
Loading
Loading
Loading
+3 −50
Original line number Original line Diff line number Diff line
@@ -279,13 +279,6 @@ struct ath_descdma {
	dma_addr_t dd_dmacontext;
	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,
int ath_descdma_setup(struct ath_softc *sc,
		      struct ath_descdma *dd,
		      struct ath_descdma *dd,
		      struct list_head *head,
		      struct list_head *head,
@@ -298,61 +291,21 @@ void ath_descdma_cleanup(struct ath_softc *sc,
			 struct ath_descdma *dd,
			 struct ath_descdma *dd,
			 struct list_head *head);
			 struct list_head *head);


/******/
/***********/
/* RX */
/* RX / TX */
/******/
/***********/


#define ATH_MAX_ANTENNA          3
#define ATH_MAX_ANTENNA          3
#define ATH_RXBUF                512
#define ATH_RXBUF                512
#define WME_NUM_TID              16
#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);
int ath_startrecv(struct ath_softc *sc);
bool ath_stoprecv(struct ath_softc *sc);
bool ath_stoprecv(struct ath_softc *sc);
void ath_flushrecv(struct ath_softc *sc);
void ath_flushrecv(struct ath_softc *sc);
u32 ath_calcrxfilter(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);
int ath_rx_init(struct ath_softc *sc, int nbufs);
void ath_rx_cleanup(struct ath_softc *sc);
void ath_rx_cleanup(struct ath_softc *sc);
int ath_rx_tasklet(struct ath_softc *sc, int flush);
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
#define ATH_TXBUF               512
/* max number of transmit attempts (tries) */
/* max number of transmit attempts (tries) */
+0 −100
Original line number Original line Diff line number Diff line
@@ -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;
	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,
static void ath9k_ht_conf(struct ath_softc *sc,
			  struct ieee80211_bss_conf *bss_conf)
			  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);
	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		*/
/*	 LED functions		*/
/********************************/
/********************************/
+206 −369

File changed.

Preview size limit exceeded, changes collapsed.