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

Commit e0d687bd authored by Pavel Roskin's avatar Pavel Roskin Committed by John W. Linville
Browse files

ath5k: merge ath5k_hw and ath5k_softc



Both ath5k_hw and ath5k_softc represent one instance of the hardware.
This duplication is historical and is not needed anymore.

Keep the name "ath5k_hw" for the merged structure and "ah" for the
variable pointing to it.  "ath5k_hw" is shorter than "ath5k_softc", more
descriptive and more widely used.

Put the combined structure to ath5k.h where the old ath5k_softc used to
be. Move some code from base.h to ath5k.h as needed.

Remove memory allocation for struct ath5k_hw and the corresponding error
handling.  Merge iobase and ah_iobase fields.

Signed-off-by: default avatarPavel Roskin <proski@gnu.org>
Acked-by: default avatarNick Kossifidis <mickflemm@gmail.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 49173592
Loading
Loading
Loading
Loading
+21 −23
Original line number Diff line number Diff line
@@ -35,8 +35,8 @@ static void ath5k_ahb_read_cachesize(struct ath_common *common, int *csz)
static bool
ath5k_ahb_eeprom_read(struct ath_common *common, u32 off, u16 *data)
{
	struct ath5k_softc *sc = common->priv;
	struct platform_device *pdev = to_platform_device(sc->dev);
	struct ath5k_hw *ah = common->priv;
	struct platform_device *pdev = to_platform_device(ah->dev);
	struct ar231x_board_config *bcfg = pdev->dev.platform_data;
	u16 *eeprom, *eeprom_end;

@@ -56,8 +56,7 @@ ath5k_ahb_eeprom_read(struct ath_common *common, u32 off, u16 *data)

int ath5k_hw_read_srev(struct ath5k_hw *ah)
{
	struct ath5k_softc *sc = ah->ah_sc;
	struct platform_device *pdev = to_platform_device(sc->dev);
	struct platform_device *pdev = to_platform_device(ah->dev);
	struct ar231x_board_config *bcfg = pdev->dev.platform_data;
	ah->ah_mac_srev = bcfg->devid;
	return 0;
@@ -65,12 +64,11 @@ int ath5k_hw_read_srev(struct ath5k_hw *ah)

static int ath5k_ahb_eeprom_read_mac(struct ath5k_hw *ah, u8 *mac)
{
	struct ath5k_softc *sc = ah->ah_sc;
	struct platform_device *pdev = to_platform_device(sc->dev);
	struct platform_device *pdev = to_platform_device(ah->dev);
	struct ar231x_board_config *bcfg = pdev->dev.platform_data;
	u8 *cfg_mac;

	if (to_platform_device(sc->dev)->id == 0)
	if (to_platform_device(ah->dev)->id == 0)
		cfg_mac = bcfg->config->wlan0_mac;
	else
		cfg_mac = bcfg->config->wlan1_mac;
@@ -90,7 +88,7 @@ static const struct ath_bus_ops ath_ahb_bus_ops = {
static int ath_ahb_probe(struct platform_device *pdev)
{
	struct ar231x_board_config *bcfg = pdev->dev.platform_data;
	struct ath5k_softc *sc;
	struct ath5k_hw *ah;
	struct ieee80211_hw *hw;
	struct resource *res;
	void __iomem *mem;
@@ -127,19 +125,19 @@ static int ath_ahb_probe(struct platform_device *pdev)

	irq = res->start;

	hw = ieee80211_alloc_hw(sizeof(struct ath5k_softc), &ath5k_hw_ops);
	hw = ieee80211_alloc_hw(sizeof(struct ath5k_hw), &ath5k_hw_ops);
	if (hw == NULL) {
		dev_err(&pdev->dev, "no memory for ieee80211_hw\n");
		ret = -ENOMEM;
		goto err_out;
	}

	sc = hw->priv;
	sc->hw = hw;
	sc->dev = &pdev->dev;
	sc->iobase = mem;
	sc->irq = irq;
	sc->devid = bcfg->devid;
	ah = hw->priv;
	ah->hw = hw;
	ah->dev = &pdev->dev;
	ah->iobase = mem;
	ah->irq = irq;
	ah->devid = bcfg->devid;

	if (bcfg->devid >= AR5K_SREV_AR2315_R6) {
		/* Enable WMAC AHB arbitration */
@@ -155,7 +153,7 @@ static int ath_ahb_probe(struct platform_device *pdev)
		/* Enable WMAC DMA access (assuming 5312 or 231x*/
		/* TODO: check other platforms */
		reg = __raw_readl((void __iomem *) AR5K_AR5312_ENABLE);
		if (to_platform_device(sc->dev)->id == 0)
		if (to_platform_device(ah->dev)->id == 0)
			reg |= AR5K_AR5312_ENABLE_WLAN0;
		else
			reg |= AR5K_AR5312_ENABLE_WLAN1;
@@ -166,13 +164,13 @@ static int ath_ahb_probe(struct platform_device *pdev)
		 * used as pass-through. Disable 2 GHz support in the
		 * driver for it
		 */
		if (to_platform_device(sc->dev)->id == 0 &&
		if (to_platform_device(ah->dev)->id == 0 &&
		    (bcfg->config->flags & (BD_WLAN0 | BD_WLAN1)) ==
		     (BD_WLAN1 | BD_WLAN0))
			__set_bit(ATH_STAT_2G_DISABLED, sc->status);
			__set_bit(ATH_STAT_2G_DISABLED, ah->status);
	}

	ret = ath5k_init_softc(sc, &ath_ahb_bus_ops);
	ret = ath5k_init_softc(ah, &ath_ahb_bus_ops);
	if (ret != 0) {
		dev_err(&pdev->dev, "failed to attach device, err=%d\n", ret);
		ret = -ENODEV;
@@ -194,13 +192,13 @@ static int ath_ahb_remove(struct platform_device *pdev)
{
	struct ar231x_board_config *bcfg = pdev->dev.platform_data;
	struct ieee80211_hw *hw = platform_get_drvdata(pdev);
	struct ath5k_softc *sc;
	struct ath5k_hw *ah;
	u32 reg;

	if (!hw)
		return 0;

	sc = hw->priv;
	ah = hw->priv;

	if (bcfg->devid >= AR5K_SREV_AR2315_R6) {
		/* Disable WMAC AHB arbitration */
@@ -210,14 +208,14 @@ static int ath_ahb_remove(struct platform_device *pdev)
	} else {
		/*Stop DMA access */
		reg = __raw_readl((void __iomem *) AR5K_AR5312_ENABLE);
		if (to_platform_device(sc->dev)->id == 0)
		if (to_platform_device(ah->dev)->id == 0)
			reg &= ~AR5K_AR5312_ENABLE_WLAN0;
		else
			reg &= ~AR5K_AR5312_ENABLE_WLAN1;
		__raw_writel(reg, (void __iomem *) AR5K_AR5312_ENABLE);
	}

	ath5k_deinit_softc(sc);
	ath5k_deinit_softc(ah);
	platform_set_drvdata(pdev, NULL);
	ieee80211_free_hw(hw);

+42 −42
Original line number Diff line number Diff line
@@ -74,7 +74,7 @@ ath5k_ani_set_noise_immunity_level(struct ath5k_hw *ah, int level)
	static const s8 fr[] = { -78, -80 };
#endif
	if (level < 0 || level >= ARRAY_SIZE(sz)) {
		ATH5K_ERR(ah->ah_sc, "noise immunity level %d out of range",
		ATH5K_ERR(ah, "noise immunity level %d out of range",
			  level);
		return;
	}
@@ -88,8 +88,8 @@ ath5k_ani_set_noise_immunity_level(struct ath5k_hw *ah, int level)
	AR5K_REG_WRITE_BITS(ah, AR5K_PHY_SIG,
				AR5K_PHY_SIG_FIRPWR, fr[level]);

	ah->ah_sc->ani_state.noise_imm_level = level;
	ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_ANI, "new level %d", level);
	ah->ani_state.noise_imm_level = level;
	ATH5K_DBG_UNLIMIT(ah, ATH5K_DEBUG_ANI, "new level %d", level);
}


@@ -105,8 +105,8 @@ ath5k_ani_set_spur_immunity_level(struct ath5k_hw *ah, int level)
	static const int val[] = { 2, 4, 6, 8, 10, 12, 14, 16 };

	if (level < 0 || level >= ARRAY_SIZE(val) ||
	    level > ah->ah_sc->ani_state.max_spur_level) {
		ATH5K_ERR(ah->ah_sc, "spur immunity level %d out of range",
	    level > ah->ani_state.max_spur_level) {
		ATH5K_ERR(ah, "spur immunity level %d out of range",
			  level);
		return;
	}
@@ -114,8 +114,8 @@ ath5k_ani_set_spur_immunity_level(struct ath5k_hw *ah, int level)
	AR5K_REG_WRITE_BITS(ah, AR5K_PHY_OFDM_SELFCORR,
		AR5K_PHY_OFDM_SELFCORR_CYPWR_THR1, val[level]);

	ah->ah_sc->ani_state.spur_level = level;
	ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_ANI, "new level %d", level);
	ah->ani_state.spur_level = level;
	ATH5K_DBG_UNLIMIT(ah, ATH5K_DEBUG_ANI, "new level %d", level);
}


@@ -130,15 +130,15 @@ ath5k_ani_set_firstep_level(struct ath5k_hw *ah, int level)
	static const int val[] = { 0, 4, 8 };

	if (level < 0 || level >= ARRAY_SIZE(val)) {
		ATH5K_ERR(ah->ah_sc, "firstep level %d out of range", level);
		ATH5K_ERR(ah, "firstep level %d out of range", level);
		return;
	}

	AR5K_REG_WRITE_BITS(ah, AR5K_PHY_SIG,
				AR5K_PHY_SIG_FIRSTEP, val[level]);

	ah->ah_sc->ani_state.firstep_level = level;
	ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_ANI, "new level %d", level);
	ah->ani_state.firstep_level = level;
	ATH5K_DBG_UNLIMIT(ah, ATH5K_DEBUG_ANI, "new level %d", level);
}


@@ -178,8 +178,8 @@ ath5k_ani_set_ofdm_weak_signal_detection(struct ath5k_hw *ah, bool on)
		AR5K_REG_DISABLE_BITS(ah, AR5K_PHY_WEAK_OFDM_LOW_THR,
				AR5K_PHY_WEAK_OFDM_LOW_THR_SELFCOR_EN);

	ah->ah_sc->ani_state.ofdm_weak_sig = on;
	ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_ANI, "turned %s",
	ah->ani_state.ofdm_weak_sig = on;
	ATH5K_DBG_UNLIMIT(ah, ATH5K_DEBUG_ANI, "turned %s",
			  on ? "on" : "off");
}

@@ -195,8 +195,8 @@ ath5k_ani_set_cck_weak_signal_detection(struct ath5k_hw *ah, bool on)
	static const int val[] = { 8, 6 };
	AR5K_REG_WRITE_BITS(ah, AR5K_PHY_CCK_CROSSCORR,
				AR5K_PHY_CCK_CROSSCORR_WEAK_SIG_THR, val[on]);
	ah->ah_sc->ani_state.cck_weak_sig = on;
	ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_ANI, "turned %s",
	ah->ani_state.cck_weak_sig = on;
	ATH5K_DBG_UNLIMIT(ah, ATH5K_DEBUG_ANI, "turned %s",
			  on ? "on" : "off");
}

@@ -218,7 +218,7 @@ ath5k_ani_raise_immunity(struct ath5k_hw *ah, struct ath5k_ani_state *as,
{
	int rssi = ewma_read(&ah->ah_beacon_rssi_avg);

	ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_ANI, "raise immunity (%s)",
	ATH5K_DBG_UNLIMIT(ah, ATH5K_DEBUG_ANI, "raise immunity (%s)",
		ofdm_trigger ? "ODFM" : "CCK");

	/* first: raise noise immunity */
@@ -229,13 +229,13 @@ ath5k_ani_raise_immunity(struct ath5k_hw *ah, struct ath5k_ani_state *as,

	/* only OFDM: raise spur immunity level */
	if (ofdm_trigger &&
	    as->spur_level < ah->ah_sc->ani_state.max_spur_level) {
	    as->spur_level < ah->ani_state.max_spur_level) {
		ath5k_ani_set_spur_immunity_level(ah, as->spur_level + 1);
		return;
	}

	/* AP mode */
	if (ah->ah_sc->opmode == NL80211_IFTYPE_AP) {
	if (ah->opmode == NL80211_IFTYPE_AP) {
		if (as->firstep_level < ATH5K_ANI_MAX_FIRSTEP_LVL)
			ath5k_ani_set_firstep_level(ah, as->firstep_level + 1);
		return;
@@ -248,7 +248,7 @@ ath5k_ani_raise_immunity(struct ath5k_hw *ah, struct ath5k_ani_state *as,
	 * don't shut out a remote node by raising immunity too high. */

	if (rssi > ATH5K_ANI_RSSI_THR_HIGH) {
		ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_ANI,
		ATH5K_DBG_UNLIMIT(ah, ATH5K_DEBUG_ANI,
				  "beacon RSSI high");
		/* only OFDM: beacon RSSI is high, we can disable ODFM weak
		 * signal detection */
@@ -265,7 +265,7 @@ ath5k_ani_raise_immunity(struct ath5k_hw *ah, struct ath5k_ani_state *as,
	} else if (rssi > ATH5K_ANI_RSSI_THR_LOW) {
		/* beacon RSSI in mid range, we need OFDM weak signal detect,
		 * but can raise firstep level */
		ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_ANI,
		ATH5K_DBG_UNLIMIT(ah, ATH5K_DEBUG_ANI,
				  "beacon RSSI mid");
		if (ofdm_trigger && as->ofdm_weak_sig == false)
			ath5k_ani_set_ofdm_weak_signal_detection(ah, true);
@@ -275,7 +275,7 @@ ath5k_ani_raise_immunity(struct ath5k_hw *ah, struct ath5k_ani_state *as,
	} else if (ah->ah_current_channel->band == IEEE80211_BAND_2GHZ) {
		/* beacon RSSI is low. in B/G mode turn of OFDM weak signal
		 * detect and zero firstep level to maximize CCK sensitivity */
		ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_ANI,
		ATH5K_DBG_UNLIMIT(ah, ATH5K_DEBUG_ANI,
				  "beacon RSSI low, 2GHz");
		if (ofdm_trigger && as->ofdm_weak_sig == true)
			ath5k_ani_set_ofdm_weak_signal_detection(ah, false);
@@ -303,9 +303,9 @@ ath5k_ani_lower_immunity(struct ath5k_hw *ah, struct ath5k_ani_state *as)
{
	int rssi = ewma_read(&ah->ah_beacon_rssi_avg);

	ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_ANI, "lower immunity");
	ATH5K_DBG_UNLIMIT(ah, ATH5K_DEBUG_ANI, "lower immunity");

	if (ah->ah_sc->opmode == NL80211_IFTYPE_AP) {
	if (ah->opmode == NL80211_IFTYPE_AP) {
		/* AP mode */
		if (as->firstep_level > 0) {
			ath5k_ani_set_firstep_level(ah, as->firstep_level - 1);
@@ -464,7 +464,7 @@ ath5k_ani_period_restart(struct ath5k_hw *ah, struct ath5k_ani_state *as)
void
ath5k_ani_calibration(struct ath5k_hw *ah)
{
	struct ath5k_ani_state *as = &ah->ah_sc->ani_state;
	struct ath5k_ani_state *as = &ah->ani_state;
	int listen, ofdm_high, ofdm_low, cck_high, cck_low;

	/* get listen time since last call and add it to the counter because we
@@ -483,9 +483,9 @@ ath5k_ani_calibration(struct ath5k_hw *ah)
	ofdm_low = as->listen_time * ATH5K_ANI_OFDM_TRIG_LOW / 1000;
	cck_low = as->listen_time * ATH5K_ANI_CCK_TRIG_LOW / 1000;

	ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_ANI,
	ATH5K_DBG_UNLIMIT(ah, ATH5K_DEBUG_ANI,
		"listen %d (now %d)", as->listen_time, listen);
	ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_ANI,
	ATH5K_DBG_UNLIMIT(ah, ATH5K_DEBUG_ANI,
		"check high ofdm %d/%d cck %d/%d",
		as->ofdm_errors, ofdm_high, as->cck_errors, cck_high);

@@ -498,7 +498,7 @@ ath5k_ani_calibration(struct ath5k_hw *ah)
	} else if (as->listen_time > 5 * ATH5K_ANI_LISTEN_PERIOD) {
		/* If more than 5 (TODO: why 5?) periods have passed and we got
		 * relatively little errors we can try to lower immunity */
		ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_ANI,
		ATH5K_DBG_UNLIMIT(ah, ATH5K_DEBUG_ANI,
			"check low ofdm %d/%d cck %d/%d",
			as->ofdm_errors, ofdm_low, as->cck_errors, cck_low);

@@ -525,7 +525,7 @@ ath5k_ani_calibration(struct ath5k_hw *ah)
void
ath5k_ani_mib_intr(struct ath5k_hw *ah)
{
	struct ath5k_ani_state *as = &ah->ah_sc->ani_state;
	struct ath5k_ani_state *as = &ah->ani_state;

	/* nothing to do here if HW does not have PHY error counters - they
	 * can't be the reason for the MIB interrupt then */
@@ -536,7 +536,7 @@ ath5k_ani_mib_intr(struct ath5k_hw *ah)
	ath5k_hw_reg_write(ah, 0, AR5K_OFDM_FIL_CNT);
	ath5k_hw_reg_write(ah, 0, AR5K_CCK_FIL_CNT);

	if (ah->ah_sc->ani_state.ani_mode != ATH5K_ANI_MODE_AUTO)
	if (ah->ani_state.ani_mode != ATH5K_ANI_MODE_AUTO)
		return;

	/* If one of the errors triggered, we can get a superfluous second
@@ -547,7 +547,7 @@ ath5k_ani_mib_intr(struct ath5k_hw *ah)

	if (as->ofdm_errors > ATH5K_ANI_OFDM_TRIG_HIGH ||
	    as->cck_errors > ATH5K_ANI_CCK_TRIG_HIGH)
		tasklet_schedule(&ah->ah_sc->ani_tasklet);
		tasklet_schedule(&ah->ani_tasklet);
}


@@ -561,16 +561,16 @@ void
ath5k_ani_phy_error_report(struct ath5k_hw *ah,
			   enum ath5k_phy_error_code phyerr)
{
	struct ath5k_ani_state *as = &ah->ah_sc->ani_state;
	struct ath5k_ani_state *as = &ah->ani_state;

	if (phyerr == AR5K_RX_PHY_ERROR_OFDM_TIMING) {
		as->ofdm_errors++;
		if (as->ofdm_errors > ATH5K_ANI_OFDM_TRIG_HIGH)
			tasklet_schedule(&ah->ah_sc->ani_tasklet);
			tasklet_schedule(&ah->ani_tasklet);
	} else if (phyerr == AR5K_RX_PHY_ERROR_CCK_TIMING) {
		as->cck_errors++;
		if (as->cck_errors > ATH5K_ANI_CCK_TRIG_HIGH)
			tasklet_schedule(&ah->ah_sc->ani_tasklet);
			tasklet_schedule(&ah->ani_tasklet);
	}
}

@@ -631,24 +631,24 @@ ath5k_ani_init(struct ath5k_hw *ah, enum ath5k_ani_mode mode)
		return;

	if (mode < ATH5K_ANI_MODE_OFF || mode > ATH5K_ANI_MODE_AUTO) {
		ATH5K_ERR(ah->ah_sc, "ANI mode %d out of range", mode);
		ATH5K_ERR(ah, "ANI mode %d out of range", mode);
		return;
	}

	/* clear old state information */
	memset(&ah->ah_sc->ani_state, 0, sizeof(ah->ah_sc->ani_state));
	memset(&ah->ani_state, 0, sizeof(ah->ani_state));

	/* older hardware has more spur levels than newer */
	if (ah->ah_mac_srev < AR5K_SREV_AR2414)
		ah->ah_sc->ani_state.max_spur_level = 7;
		ah->ani_state.max_spur_level = 7;
	else
		ah->ah_sc->ani_state.max_spur_level = 2;
		ah->ani_state.max_spur_level = 2;

	/* initial values for our ani parameters */
	if (mode == ATH5K_ANI_MODE_OFF) {
		ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_ANI, "ANI off\n");
		ATH5K_DBG_UNLIMIT(ah, ATH5K_DEBUG_ANI, "ANI off\n");
	} else if (mode == ATH5K_ANI_MODE_MANUAL_LOW) {
		ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_ANI,
		ATH5K_DBG_UNLIMIT(ah, ATH5K_DEBUG_ANI,
			"ANI manual low -> high sensitivity\n");
		ath5k_ani_set_noise_immunity_level(ah, 0);
		ath5k_ani_set_spur_immunity_level(ah, 0);
@@ -656,17 +656,17 @@ ath5k_ani_init(struct ath5k_hw *ah, enum ath5k_ani_mode mode)
		ath5k_ani_set_ofdm_weak_signal_detection(ah, true);
		ath5k_ani_set_cck_weak_signal_detection(ah, true);
	} else if (mode == ATH5K_ANI_MODE_MANUAL_HIGH) {
		ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_ANI,
		ATH5K_DBG_UNLIMIT(ah, ATH5K_DEBUG_ANI,
			"ANI manual high -> low sensitivity\n");
		ath5k_ani_set_noise_immunity_level(ah,
					ATH5K_ANI_MAX_NOISE_IMM_LVL);
		ath5k_ani_set_spur_immunity_level(ah,
					ah->ah_sc->ani_state.max_spur_level);
					ah->ani_state.max_spur_level);
		ath5k_ani_set_firstep_level(ah, ATH5K_ANI_MAX_FIRSTEP_LVL);
		ath5k_ani_set_ofdm_weak_signal_detection(ah, false);
		ath5k_ani_set_cck_weak_signal_detection(ah, false);
	} else if (mode == ATH5K_ANI_MODE_AUTO) {
		ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_ANI, "ANI auto\n");
		ATH5K_DBG_UNLIMIT(ah, ATH5K_DEBUG_ANI, "ANI auto\n");
		ath5k_ani_set_noise_immunity_level(ah, 0);
		ath5k_ani_set_spur_immunity_level(ah, 0);
		ath5k_ani_set_firstep_level(ah, 0);
@@ -692,7 +692,7 @@ ath5k_ani_init(struct ath5k_hw *ah, enum ath5k_ani_mode mode)
						   ~AR5K_RX_FILTER_PHYERR);
	}

	ah->ah_sc->ani_state.ani_mode = mode;
	ah->ani_state.ani_mode = mode;
}


+212 −28
Original line number Diff line number Diff line
@@ -24,8 +24,10 @@
#define CHAN_DEBUG	0

#include <linux/io.h>
#include <linux/interrupt.h>
#include <linux/types.h>
#include <linux/average.h>
#include <linux/leds.h>
#include <net/mac80211.h>

/* RX/TX descriptor hw structs
@@ -36,7 +38,9 @@
 * TODO: Make a more generic struct (eg. add more stuff to ath5k_capabilities)
 * and clean up common bits, then introduce set/get functions in eeprom.c */
#include "eeprom.h"
#include "debug.h"
#include "../ath.h"
#include "ani.h"

/* PCI IDs */
#define PCI_DEVICE_ID_ATHEROS_AR5210		0x0007 /* AR5210 */
@@ -537,6 +541,27 @@ enum ath5k_tx_queue_id {
#define AR5K_TXQ_FLAG_POST_FR_BKOFF_DIS		0x1000	/* Disable backoff while bursting */
#define AR5K_TXQ_FLAG_COMPRESSION_ENABLE	0x2000	/* Enable hw compression -not implemented-*/

/*
 * Data transmit queue state.  One of these exists for each
 * hardware transmit queue.  Packets sent to us from above
 * are assigned to queues based on their priority.  Not all
 * devices support a complete set of hardware transmit queues.
 * For those devices the array sc_ac2q will map multiple
 * priorities to fewer hardware queues (typically all to one
 * hardware queue).
 */
struct ath5k_txq {
	unsigned int		qnum;	/* hardware q number */
	u32			*link;	/* link ptr in last TX desc */
	struct list_head	q;	/* transmit queue */
	spinlock_t		lock;	/* lock on q and link */
	bool			setup;
	int			txq_len; /* number of queued buffers */
	int			txq_max; /* max allowed num of queued buffers */
	bool			txq_poll_mark;
	unsigned int		txq_stuck;	/* informational counter */
};

/*
 * A struct to hold tx queue's parameters
 */
@@ -1027,9 +1052,66 @@ struct ath5k_avg_val {
	int avg_weight;
};

/***************************************\
  HARDWARE ABSTRACTION LAYER STRUCTURE
\***************************************/
#define ATH5K_LED_MAX_NAME_LEN 31

/*
 * State for LED triggers
 */
struct ath5k_led {
	char name[ATH5K_LED_MAX_NAME_LEN + 1];	/* name of the LED in sysfs */
	struct ath5k_hw *ah;			/* driver state */
	struct led_classdev led_dev;		/* led classdev */
};

/* Rfkill */
struct ath5k_rfkill {
	/* GPIO PIN for rfkill */
	u16 gpio;
	/* polarity of rfkill GPIO PIN */
	bool polarity;
	/* RFKILL toggle tasklet */
	struct tasklet_struct toggleq;
};

/* statistics */
struct ath5k_statistics {
	/* antenna use */
	unsigned int antenna_rx[5];	/* frames count per antenna RX */
	unsigned int antenna_tx[5];	/* frames count per antenna TX */

	/* frame errors */
	unsigned int rx_all_count;	/* all RX frames, including errors */
	unsigned int tx_all_count;	/* all TX frames, including errors */
	unsigned int rx_bytes_count;	/* all RX bytes, including errored pkts
					 * and the MAC headers for each packet
					 */
	unsigned int tx_bytes_count;	/* all TX bytes, including errored pkts
					 * and the MAC headers and padding for
					 * each packet.
					 */
	unsigned int rxerr_crc;
	unsigned int rxerr_phy;
	unsigned int rxerr_phy_code[32];
	unsigned int rxerr_fifo;
	unsigned int rxerr_decrypt;
	unsigned int rxerr_mic;
	unsigned int rxerr_proc;
	unsigned int rxerr_jumbo;
	unsigned int txerr_retry;
	unsigned int txerr_fifo;
	unsigned int txerr_filt;

	/* MIB counters */
	unsigned int ack_fail;
	unsigned int rts_fail;
	unsigned int rts_ok;
	unsigned int fcs_error;
	unsigned int beacons;

	unsigned int mib_intr;
	unsigned int rxorn_intr;
	unsigned int rxeol_intr;
};

/*
 * Misc defines
@@ -1038,12 +1120,114 @@ struct ath5k_avg_val {
#define AR5K_MAX_GPIO		10
#define AR5K_MAX_RF_BANKS	8

/* TODO: Clean up and merge with ath5k_softc */
#if CHAN_DEBUG
#define ATH_CHAN_MAX	(26 + 26 + 26 + 200 + 200)
#else
#define ATH_CHAN_MAX	(14 + 14 + 14 + 252 + 20)
#endif

#define	ATH_RXBUF	40		/* number of RX buffers */
#define	ATH_TXBUF	200		/* number of TX buffers */
#define ATH_BCBUF	4		/* number of beacon buffers */
#define ATH5K_TXQ_LEN_MAX	(ATH_TXBUF / 4)		/* bufs per queue */
#define ATH5K_TXQ_LEN_LOW	(ATH5K_TXQ_LEN_MAX / 2)	/* low mark */

/* Driver state associated with an instance of a device */
struct ath5k_hw {
	struct ath_common       common;

	struct ath5k_softc	*ah_sc;
	void __iomem		*ah_iobase;
	struct pci_dev		*pdev;
	struct device		*dev;		/* for dma mapping */
	int irq;
	u16 devid;
	void __iomem		*iobase;	/* address of the device */
	struct mutex		lock;		/* dev-level lock */
	struct ieee80211_hw	*hw;		/* IEEE 802.11 common */
	struct ieee80211_supported_band sbands[IEEE80211_NUM_BANDS];
	struct ieee80211_channel channels[ATH_CHAN_MAX];
	struct ieee80211_rate	rates[IEEE80211_NUM_BANDS][AR5K_MAX_RATES];
	s8			rate_idx[IEEE80211_NUM_BANDS][AR5K_MAX_RATES];
	enum nl80211_iftype	opmode;

#ifdef CONFIG_ATH5K_DEBUG
	struct ath5k_dbg_info	debug;		/* debug info */
#endif /* CONFIG_ATH5K_DEBUG */

	struct ath5k_buf	*bufptr;	/* allocated buffer ptr */
	struct ath5k_desc	*desc;		/* TX/RX descriptors */
	dma_addr_t		desc_daddr;	/* DMA (physical) address */
	size_t			desc_len;	/* size of TX/RX descriptors */

	DECLARE_BITMAP(status, 6);
#define ATH_STAT_INVALID	0		/* disable hardware accesses */
#define ATH_STAT_MRRETRY	1		/* multi-rate retry support */
#define ATH_STAT_PROMISC	2
#define ATH_STAT_LEDSOFT	3		/* enable LED gpio status */
#define ATH_STAT_STARTED	4		/* opened & irqs enabled */
#define ATH_STAT_2G_DISABLED	5		/* multiband radio without 2G */

	unsigned int		filter_flags;	/* HW flags, AR5K_RX_FILTER_* */
	struct ieee80211_channel *curchan;	/* current h/w channel */

	u16			nvifs;

	enum ath5k_int		imask;		/* interrupt mask copy */

	spinlock_t		irqlock;
	bool			rx_pending;	/* rx tasklet pending */
	bool			tx_pending;	/* tx tasklet pending */

	u8			lladdr[ETH_ALEN];
	u8			bssidmask[ETH_ALEN];

	unsigned int		led_pin,	/* GPIO pin for driving LED */
				led_on;		/* pin setting for LED on */

	struct work_struct	reset_work;	/* deferred chip reset */

	unsigned int		rxbufsize;	/* rx size based on mtu */
	struct list_head	rxbuf;		/* receive buffer */
	spinlock_t		rxbuflock;
	u32			*rxlink;	/* link ptr in last RX desc */
	struct tasklet_struct	rxtq;		/* rx intr tasklet */
	struct ath5k_led	rx_led;		/* rx led */

	struct list_head	txbuf;		/* transmit buffer */
	spinlock_t		txbuflock;
	unsigned int		txbuf_len;	/* buf count in txbuf list */
	struct ath5k_txq	txqs[AR5K_NUM_TX_QUEUES];	/* tx queues */
	struct tasklet_struct	txtq;		/* tx intr tasklet */
	struct ath5k_led	tx_led;		/* tx led */

	struct ath5k_rfkill	rf_kill;

	struct tasklet_struct	calib;		/* calibration tasklet */

	spinlock_t		block;		/* protects beacon */
	struct tasklet_struct	beacontq;	/* beacon intr tasklet */
	struct list_head	bcbuf;		/* beacon buffer */
	struct ieee80211_vif	*bslot[ATH_BCBUF];
	u16			num_ap_vifs;
	u16			num_adhoc_vifs;
	unsigned int		bhalq,		/* SW q for outgoing beacons */
				bmisscount,	/* missed beacon transmits */
				bintval,	/* beacon interval in TU */
				bsent;
	unsigned int		nexttbtt;	/* next beacon time in TU */
	struct ath5k_txq	*cabq;		/* content after beacon */

	int			power_level;	/* Requested tx power in dBm */
	bool			assoc;		/* associate state */
	bool			enable_beacon;	/* true if beacons are on */

	struct ath5k_statistics	stats;

	struct ath5k_ani_state	ani_state;
	struct tasklet_struct	ani_tasklet;	/* ANI calibration */

	struct delayed_work	tx_complete_work;

	struct survey_info	survey;		/* collected survey info */

	enum ath5k_int		ah_imr;

@@ -1172,43 +1356,43 @@ struct ath_bus_ops {
extern const struct ieee80211_ops ath5k_hw_ops;

/* Initialization and detach functions */
int ath5k_init_softc(struct ath5k_softc *sc, const struct ath_bus_ops *bus_ops);
void ath5k_deinit_softc(struct ath5k_softc *sc);
int ath5k_hw_init(struct ath5k_softc *sc);
int ath5k_init_softc(struct ath5k_hw *ah, const struct ath_bus_ops *bus_ops);
void ath5k_deinit_softc(struct ath5k_hw *ah);
int ath5k_hw_init(struct ath5k_hw *ah);
void ath5k_hw_deinit(struct ath5k_hw *ah);

int ath5k_sysfs_register(struct ath5k_softc *sc);
void ath5k_sysfs_unregister(struct ath5k_softc *sc);
int ath5k_sysfs_register(struct ath5k_hw *ah);
void ath5k_sysfs_unregister(struct ath5k_hw *ah);

/* base.c */
struct ath5k_buf;
struct ath5k_txq;

void ath5k_set_beacon_filter(struct ieee80211_hw *hw, bool enable);
bool ath5k_any_vif_assoc(struct ath5k_softc *sc);
bool ath5k_any_vif_assoc(struct ath5k_hw *ah);
void ath5k_tx_queue(struct ieee80211_hw *hw, struct sk_buff *skb,
		    struct ath5k_txq *txq);
int ath5k_init_hw(struct ath5k_softc *sc);
int ath5k_stop_hw(struct ath5k_softc *sc);
void ath5k_mode_setup(struct ath5k_softc *sc, struct ieee80211_vif *vif);
void ath5k_update_bssid_mask_and_opmode(struct ath5k_softc *sc,
int ath5k_init_hw(struct ath5k_hw *ah);
int ath5k_stop_hw(struct ath5k_hw *ah);
void ath5k_mode_setup(struct ath5k_hw *ah, struct ieee80211_vif *vif);
void ath5k_update_bssid_mask_and_opmode(struct ath5k_hw *ah,
					struct ieee80211_vif *vif);
int ath5k_chan_set(struct ath5k_softc *sc, struct ieee80211_channel *chan);
void ath5k_beacon_update_timers(struct ath5k_softc *sc, u64 bc_tsf);
int ath5k_chan_set(struct ath5k_hw *ah, struct ieee80211_channel *chan);
void ath5k_beacon_update_timers(struct ath5k_hw *ah, u64 bc_tsf);
int ath5k_beacon_update(struct ieee80211_hw *hw, struct ieee80211_vif *vif);
void ath5k_beacon_config(struct ath5k_softc *sc);
void ath5k_txbuf_free_skb(struct ath5k_softc *sc, struct ath5k_buf *bf);
void ath5k_rxbuf_free_skb(struct ath5k_softc *sc, struct ath5k_buf *bf);
void ath5k_beacon_config(struct ath5k_hw *ah);
void ath5k_txbuf_free_skb(struct ath5k_hw *ah, struct ath5k_buf *bf);
void ath5k_rxbuf_free_skb(struct ath5k_hw *ah, struct ath5k_buf *bf);

/*Chip id helper functions */
const char *ath5k_chip_name(enum ath5k_srev_type type, u_int16_t val);
int ath5k_hw_read_srev(struct ath5k_hw *ah);

/* LED functions */
int ath5k_init_leds(struct ath5k_softc *sc);
void ath5k_led_enable(struct ath5k_softc *sc);
void ath5k_led_off(struct ath5k_softc *sc);
void ath5k_unregister_leds(struct ath5k_softc *sc);
int ath5k_init_leds(struct ath5k_hw *ah);
void ath5k_led_enable(struct ath5k_hw *ah);
void ath5k_led_off(struct ath5k_hw *ah);
void ath5k_unregister_leds(struct ath5k_hw *ah);


/* Reset Functions */
@@ -1384,7 +1568,7 @@ static inline void __iomem *ath5k_ahb_reg(struct ath5k_hw *ah, u16 reg)
	    (ah->ah_mac_srev >= AR5K_SREV_AR2315_R6)))
		return AR5K_AR2315_PCI_BASE + reg;

	return ah->ah_iobase + reg;
	return ah->iobase + reg;
}

static inline u32 ath5k_hw_reg_read(struct ath5k_hw *ah, u16 reg)
@@ -1401,12 +1585,12 @@ static inline void ath5k_hw_reg_write(struct ath5k_hw *ah, u32 val, u16 reg)

static inline u32 ath5k_hw_reg_read(struct ath5k_hw *ah, u16 reg)
{
	return ioread32(ah->ah_iobase + reg);
	return ioread32(ah->iobase + reg);
}

static inline void ath5k_hw_reg_write(struct ath5k_hw *ah, u32 val, u16 reg)
{
	iowrite32(val, ah->ah_iobase + reg);
	iowrite32(val, ah->iobase + reg);
}

#endif
+15 −16

File changed.

Preview size limit exceeded, changes collapsed.

+548 −584

File changed.

Preview size limit exceeded, changes collapsed.

Loading