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

Commit f10023a4 authored by David S. Miller's avatar David S. Miller
Browse files
parents 4ada8107 640c65ea
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -587,8 +587,8 @@ struct ath9k_country_entry {
	u8 iso[3];
};

#define REG_WRITE(_ah, _reg, _val) iowrite32(_val, _ah->ah_sh + _reg)
#define REG_READ(_ah, _reg) ioread32(_ah->ah_sh + _reg)
#define REG_WRITE(_ah, _reg, _val) ath9k_iowrite32((_ah), (_reg), (_val))
#define REG_READ(_ah, _reg) ath9k_ioread32((_ah), (_reg))

#define SM(_v, _f)  (((_v) << _f##_S) & _f)
#define MS(_v, _f)  (((_v) & _f) >> _f##_S)
+33 −0
Original line number Diff line number Diff line
@@ -701,6 +701,7 @@ struct ath_softc {
	struct ath_hal *sc_ah;
	void __iomem *mem;
	spinlock_t sc_resetlock;
	spinlock_t sc_serial_rw;
	struct mutex mutex;

	u8 sc_curbssid[ETH_ALEN];
@@ -751,4 +752,36 @@ int ath_get_hal_qnum(u16 queue, struct ath_softc *sc);
int ath_get_mac80211_qnum(u32 queue, struct ath_softc *sc);
int ath_cabq_update(struct ath_softc *);

/*
 * Read and write, they both share the same lock. We do this to serialize
 * reads and writes on Atheros 802.11n PCI devices only. This is required
 * as the FIFO on these devices can only accept sanely 2 requests. After
 * that the device goes bananas. Serializing the reads/writes prevents this
 * from happening.
 */

static inline void ath9k_iowrite32(struct ath_hal *ah, u32 reg_offset, u32 val)
{
	if (ah->ah_config.serialize_regmode == SER_REG_MODE_ON) {
		unsigned long flags;
		spin_lock_irqsave(&ah->ah_sc->sc_serial_rw, flags);
		iowrite32(val, ah->ah_sc->mem + reg_offset);
		spin_unlock_irqrestore(&ah->ah_sc->sc_serial_rw, flags);
	} else
		iowrite32(val, ah->ah_sc->mem + reg_offset);
}

static inline unsigned int ath9k_ioread32(struct ath_hal *ah, u32 reg_offset)
{
	u32 val;
	if (ah->ah_config.serialize_regmode == SER_REG_MODE_ON) {
		unsigned long flags;
		spin_lock_irqsave(&ah->ah_sc->sc_serial_rw, flags);
		val = ioread32(ah->ah_sc->mem + reg_offset);
		spin_unlock_irqrestore(&ah->ah_sc->sc_serial_rw, flags);
	} else
		val = ioread32(ah->ah_sc->mem + reg_offset);
	return val;
}

#endif /* CORE_H */
+21 −1
Original line number Diff line number Diff line
@@ -437,6 +437,25 @@ static void ath9k_hw_set_defaults(struct ath_hal *ah)
	}

	ah->ah_config.intr_mitigation = 1;

	/*
	 * We need this for PCI devices only (Cardbus, PCI, miniPCI)
	 * _and_ if on non-uniprocessor systems (Multiprocessor/HT).
	 * This means we use it for all AR5416 devices, and the few
	 * minor PCI AR9280 devices out there.
	 *
	 * Serialization is required because these devices do not handle
	 * well the case of two concurrent reads/writes due to the latency
	 * involved. During one read/write another read/write can be issued
	 * on another CPU while the previous read/write may still be working
	 * on our hardware, if we hit this case the hardware poops in a loop.
	 * We prevent this by serializing reads and writes.
	 *
	 * This issue is not present on PCI-Express devices or pre-AR5416
	 * devices (legacy, 802.11abg).
	 */
	if (num_possible_cpus() > 1)
		ah->ah_config.serialize_regmode = SER_REG_MODE_AUTO;
}

static struct ath_hal_5416 *ath9k_hw_newstate(u16 devid,
@@ -668,7 +687,8 @@ static struct ath_hal *ath9k_hw_do_attach(u16 devid, struct ath_softc *sc,
	}

	if (ah->ah_config.serialize_regmode == SER_REG_MODE_AUTO) {
		if (ah->ah_macVersion == AR_SREV_VERSION_5416_PCI) {
		if (ah->ah_macVersion == AR_SREV_VERSION_5416_PCI ||
		    (AR_SREV_9280(ah) && !ah->ah_isPciExpress)) {
			ah->ah_config.serialize_regmode =
				SER_REG_MODE_ON;
		} else {
+1 −0
Original line number Diff line number Diff line
@@ -1336,6 +1336,7 @@ static int ath_init(u16 devid, struct ath_softc *sc)
		printk(KERN_ERR "Unable to create debugfs files\n");

	spin_lock_init(&sc->sc_resetlock);
	spin_lock_init(&sc->sc_serial_rw);
	mutex_init(&sc->mutex);
	tasklet_init(&sc->intr_tq, ath9k_tasklet, (unsigned long)sc);
	tasklet_init(&sc->bcon_tasklet, ath9k_beacon_tasklet,
+6 −2
Original line number Diff line number Diff line
@@ -575,13 +575,17 @@ static int zd_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)

	r = fill_ctrlset(mac, skb);
	if (r)
		return r;
		goto fail;

	info->rate_driver_data[0] = hw;

	r = zd_usb_tx(&mac->chip.usb, skb);
	if (r)
		return r;
		goto fail;
	return 0;

fail:
	dev_kfree_skb(skb);
	return 0;
}

Loading