brintos

brintos / linux-shallow public Read only

0
0
Text · 24.8 KiB · 5323acf Raw
860 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*	Copyright (C) 2009 - 2010 Ivo van Doorn <IvDoorn@gmail.com>3 *	Copyright (C) 2009 Alban Browaeys <prahal@yahoo.com>4 *	Copyright (C) 2009 Felix Fietkau <nbd@openwrt.org>5 *	Copyright (C) 2009 Luis Correia <luis.f.correia@gmail.com>6 *	Copyright (C) 2009 Mattias Nissler <mattias.nissler@gmx.de>7 *	Copyright (C) 2009 Mark Asselstine <asselsm@gmail.com>8 *	Copyright (C) 2009 Xose Vazquez Perez <xose.vazquez@gmail.com>9 *	Copyright (C) 2009 Bart Zolnierkiewicz <bzolnier@gmail.com>10 *	<http://rt2x00.serialmonkey.com>11 */12 13/*	Module: rt2800mmio14 *	Abstract: rt2800 MMIO device routines.15 */16 17#include <linux/kernel.h>18#include <linux/module.h>19#include <linux/export.h>20 21#include "rt2x00.h"22#include "rt2x00mmio.h"23#include "rt2800.h"24#include "rt2800lib.h"25#include "rt2800mmio.h"26 27unsigned int rt2800mmio_get_dma_done(struct data_queue *queue)28{29	struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;30	struct queue_entry *entry;31	int idx, qid;32 33	switch (queue->qid) {34	case QID_AC_VO:35	case QID_AC_VI:36	case QID_AC_BE:37	case QID_AC_BK:38		qid = queue->qid;39		idx = rt2x00mmio_register_read(rt2x00dev, TX_DTX_IDX(qid));40		break;41	case QID_MGMT:42		idx = rt2x00mmio_register_read(rt2x00dev, TX_DTX_IDX(5));43		break;44	case QID_RX:45		entry = rt2x00queue_get_entry(queue, Q_INDEX_DMA_DONE);46		idx = entry->entry_idx;47		break;48	default:49		WARN_ON_ONCE(1);50		idx = 0;51		break;52	}53 54	return idx;55}56EXPORT_SYMBOL_GPL(rt2800mmio_get_dma_done);57 58/*59 * TX descriptor initialization60 */61__le32 *rt2800mmio_get_txwi(struct queue_entry *entry)62{63	return (__le32 *) entry->skb->data;64}65EXPORT_SYMBOL_GPL(rt2800mmio_get_txwi);66 67void rt2800mmio_write_tx_desc(struct queue_entry *entry,68			      struct txentry_desc *txdesc)69{70	struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);71	struct queue_entry_priv_mmio *entry_priv = entry->priv_data;72	__le32 *txd = entry_priv->desc;73	u32 word;74	const unsigned int txwi_size = entry->queue->winfo_size;75 76	/*77	 * The buffers pointed by SD_PTR0/SD_LEN0 and SD_PTR1/SD_LEN178	 * must contains a TXWI structure + 802.11 header + padding + 802.1179	 * data. We choose to have SD_PTR0/SD_LEN0 only contains TXWI and80	 * SD_PTR1/SD_LEN1 contains 802.11 header + padding + 802.1181	 * data. It means that LAST_SEC0 is always 0.82	 */83 84	/*85	 * Initialize TX descriptor86	 */87	word = 0;88	rt2x00_set_field32(&word, TXD_W0_SD_PTR0, skbdesc->skb_dma);89	rt2x00_desc_write(txd, 0, word);90 91	word = 0;92	rt2x00_set_field32(&word, TXD_W1_SD_LEN1, entry->skb->len);93	rt2x00_set_field32(&word, TXD_W1_LAST_SEC1,94			   !test_bit(ENTRY_TXD_MORE_FRAG, &txdesc->flags));95	rt2x00_set_field32(&word, TXD_W1_BURST,96			   test_bit(ENTRY_TXD_BURST, &txdesc->flags));97	rt2x00_set_field32(&word, TXD_W1_SD_LEN0, txwi_size);98	rt2x00_set_field32(&word, TXD_W1_LAST_SEC0, 0);99	rt2x00_set_field32(&word, TXD_W1_DMA_DONE, 0);100	rt2x00_desc_write(txd, 1, word);101 102	word = 0;103	rt2x00_set_field32(&word, TXD_W2_SD_PTR1,104			   skbdesc->skb_dma + txwi_size);105	rt2x00_desc_write(txd, 2, word);106 107	word = 0;108	rt2x00_set_field32(&word, TXD_W3_WIV,109			   !test_bit(ENTRY_TXD_ENCRYPT_IV, &txdesc->flags));110	rt2x00_set_field32(&word, TXD_W3_QSEL, 2);111	rt2x00_desc_write(txd, 3, word);112 113	/*114	 * Register descriptor details in skb frame descriptor.115	 */116	skbdesc->desc = txd;117	skbdesc->desc_len = TXD_DESC_SIZE;118}119EXPORT_SYMBOL_GPL(rt2800mmio_write_tx_desc);120 121/*122 * RX control handlers123 */124void rt2800mmio_fill_rxdone(struct queue_entry *entry,125			    struct rxdone_entry_desc *rxdesc)126{127	struct queue_entry_priv_mmio *entry_priv = entry->priv_data;128	__le32 *rxd = entry_priv->desc;129	u32 word;130 131	word = rt2x00_desc_read(rxd, 3);132 133	if (rt2x00_get_field32(word, RXD_W3_CRC_ERROR))134		rxdesc->flags |= RX_FLAG_FAILED_FCS_CRC;135 136	/*137	 * Unfortunately we don't know the cipher type used during138	 * decryption. This prevents us from correct providing139	 * correct statistics through debugfs.140	 */141	rxdesc->cipher_status = rt2x00_get_field32(word, RXD_W3_CIPHER_ERROR);142 143	if (rt2x00_get_field32(word, RXD_W3_DECRYPTED)) {144		/*145		 * Hardware has stripped IV/EIV data from 802.11 frame during146		 * decryption. Unfortunately the descriptor doesn't contain147		 * any fields with the EIV/IV data either, so they can't148		 * be restored by rt2x00lib.149		 */150		rxdesc->flags |= RX_FLAG_IV_STRIPPED;151 152		/*153		 * The hardware has already checked the Michael Mic and has154		 * stripped it from the frame. Signal this to mac80211.155		 */156		rxdesc->flags |= RX_FLAG_MMIC_STRIPPED;157 158		if (rxdesc->cipher_status == RX_CRYPTO_SUCCESS) {159			rxdesc->flags |= RX_FLAG_DECRYPTED;160		} else if (rxdesc->cipher_status == RX_CRYPTO_FAIL_MIC) {161			/*162			 * In order to check the Michael Mic, the packet must have163			 * been decrypted.  Mac80211 doesnt check the MMIC failure 164			 * flag to initiate MMIC countermeasures if the decoded flag165			 * has not been set.166			 */167			rxdesc->flags |= RX_FLAG_DECRYPTED;168 169			rxdesc->flags |= RX_FLAG_MMIC_ERROR;170		}171	}172 173	if (rt2x00_get_field32(word, RXD_W3_MY_BSS))174		rxdesc->dev_flags |= RXDONE_MY_BSS;175 176	if (rt2x00_get_field32(word, RXD_W3_L2PAD))177		rxdesc->dev_flags |= RXDONE_L2PAD;178 179	/*180	 * Process the RXWI structure that is at the start of the buffer.181	 */182	rt2800_process_rxwi(entry, rxdesc);183}184EXPORT_SYMBOL_GPL(rt2800mmio_fill_rxdone);185 186/*187 * Interrupt functions.188 */189static void rt2800mmio_wakeup(struct rt2x00_dev *rt2x00dev)190{191	struct ieee80211_conf conf = { .flags = 0 };192	struct rt2x00lib_conf libconf = { .conf = &conf };193 194	rt2800_config(rt2x00dev, &libconf, IEEE80211_CONF_CHANGE_PS);195}196 197static inline void rt2800mmio_enable_interrupt(struct rt2x00_dev *rt2x00dev,198					       struct rt2x00_field32 irq_field)199{200	u32 reg;201 202	/*203	 * Enable a single interrupt. The interrupt mask register204	 * access needs locking.205	 */206	spin_lock_irq(&rt2x00dev->irqmask_lock);207	reg = rt2x00mmio_register_read(rt2x00dev, INT_MASK_CSR);208	rt2x00_set_field32(&reg, irq_field, 1);209	rt2x00mmio_register_write(rt2x00dev, INT_MASK_CSR, reg);210	spin_unlock_irq(&rt2x00dev->irqmask_lock);211}212 213void rt2800mmio_pretbtt_tasklet(struct tasklet_struct *t)214{215	struct rt2x00_dev *rt2x00dev = from_tasklet(rt2x00dev, t,216						    pretbtt_tasklet);217	rt2x00lib_pretbtt(rt2x00dev);218	if (test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))219		rt2800mmio_enable_interrupt(rt2x00dev, INT_MASK_CSR_PRE_TBTT);220}221EXPORT_SYMBOL_GPL(rt2800mmio_pretbtt_tasklet);222 223void rt2800mmio_tbtt_tasklet(struct tasklet_struct *t)224{225	struct rt2x00_dev *rt2x00dev = from_tasklet(rt2x00dev, t, tbtt_tasklet);226	struct rt2800_drv_data *drv_data = rt2x00dev->drv_data;227	u32 reg;228 229	rt2x00lib_beacondone(rt2x00dev);230 231	if (rt2x00dev->intf_ap_count) {232		/*233		 * The rt2800pci hardware tbtt timer is off by 1us per tbtt234		 * causing beacon skew and as a result causing problems with235		 * some powersaving clients over time. Shorten the beacon236		 * interval every 64 beacons by 64us to mitigate this effect.237		 */238		if (drv_data->tbtt_tick == (BCN_TBTT_OFFSET - 2)) {239			reg = rt2x00mmio_register_read(rt2x00dev, BCN_TIME_CFG);240			rt2x00_set_field32(&reg, BCN_TIME_CFG_BEACON_INTERVAL,241					   (rt2x00dev->beacon_int * 16) - 1);242			rt2x00mmio_register_write(rt2x00dev, BCN_TIME_CFG, reg);243		} else if (drv_data->tbtt_tick == (BCN_TBTT_OFFSET - 1)) {244			reg = rt2x00mmio_register_read(rt2x00dev, BCN_TIME_CFG);245			rt2x00_set_field32(&reg, BCN_TIME_CFG_BEACON_INTERVAL,246					   (rt2x00dev->beacon_int * 16));247			rt2x00mmio_register_write(rt2x00dev, BCN_TIME_CFG, reg);248		}249		drv_data->tbtt_tick++;250		drv_data->tbtt_tick %= BCN_TBTT_OFFSET;251	}252 253	if (test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))254		rt2800mmio_enable_interrupt(rt2x00dev, INT_MASK_CSR_TBTT);255}256EXPORT_SYMBOL_GPL(rt2800mmio_tbtt_tasklet);257 258void rt2800mmio_rxdone_tasklet(struct tasklet_struct *t)259{260	struct rt2x00_dev *rt2x00dev = from_tasklet(rt2x00dev, t,261						    rxdone_tasklet);262	if (rt2x00mmio_rxdone(rt2x00dev))263		tasklet_schedule(&rt2x00dev->rxdone_tasklet);264	else if (test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))265		rt2800mmio_enable_interrupt(rt2x00dev, INT_MASK_CSR_RX_DONE);266}267EXPORT_SYMBOL_GPL(rt2800mmio_rxdone_tasklet);268 269void rt2800mmio_autowake_tasklet(struct tasklet_struct *t)270{271	struct rt2x00_dev *rt2x00dev = from_tasklet(rt2x00dev, t,272						    autowake_tasklet);273	rt2800mmio_wakeup(rt2x00dev);274	if (test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))275		rt2800mmio_enable_interrupt(rt2x00dev,276					    INT_MASK_CSR_AUTO_WAKEUP);277}278EXPORT_SYMBOL_GPL(rt2800mmio_autowake_tasklet);279 280static void rt2800mmio_fetch_txstatus(struct rt2x00_dev *rt2x00dev)281{282	u32 status;283	unsigned long flags;284 285	/*286	 * The TX_FIFO_STATUS interrupt needs special care. We should287	 * read TX_STA_FIFO but we should do it immediately as otherwise288	 * the register can overflow and we would lose status reports.289	 *290	 * Hence, read the TX_STA_FIFO register and copy all tx status291	 * reports into a kernel FIFO which is handled in the txstatus292	 * tasklet. We use a tasklet to process the tx status reports293	 * because we can schedule the tasklet multiple times (when the294	 * interrupt fires again during tx status processing).295	 *296	 * We also read statuses from tx status timeout timer, use297	 * lock to prevent concurent writes to fifo.298	 */299 300	spin_lock_irqsave(&rt2x00dev->irqmask_lock, flags);301 302	while (!kfifo_is_full(&rt2x00dev->txstatus_fifo)) {303		status = rt2x00mmio_register_read(rt2x00dev, TX_STA_FIFO);304		if (!rt2x00_get_field32(status, TX_STA_FIFO_VALID))305			break;306 307		kfifo_put(&rt2x00dev->txstatus_fifo, status);308	}309 310	spin_unlock_irqrestore(&rt2x00dev->irqmask_lock, flags);311}312 313void rt2800mmio_txstatus_tasklet(struct tasklet_struct *t)314{315	struct rt2x00_dev *rt2x00dev = from_tasklet(rt2x00dev, t,316						    txstatus_tasklet);317 318	rt2800_txdone(rt2x00dev, 16);319 320	if (!kfifo_is_empty(&rt2x00dev->txstatus_fifo))321		tasklet_schedule(&rt2x00dev->txstatus_tasklet);322 323}324EXPORT_SYMBOL_GPL(rt2800mmio_txstatus_tasklet);325 326irqreturn_t rt2800mmio_interrupt(int irq, void *dev_instance)327{328	struct rt2x00_dev *rt2x00dev = dev_instance;329	u32 reg, mask;330 331	/* Read status and ACK all interrupts */332	reg = rt2x00mmio_register_read(rt2x00dev, INT_SOURCE_CSR);333	rt2x00mmio_register_write(rt2x00dev, INT_SOURCE_CSR, reg);334 335	if (!reg)336		return IRQ_NONE;337 338	if (!test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))339		return IRQ_HANDLED;340 341	/*342	 * Since INT_MASK_CSR and INT_SOURCE_CSR use the same bits343	 * for interrupts and interrupt masks we can just use the value of344	 * INT_SOURCE_CSR to create the interrupt mask.345	 */346	mask = ~reg;347 348	if (rt2x00_get_field32(reg, INT_SOURCE_CSR_TX_FIFO_STATUS)) {349		rt2x00_set_field32(&mask, INT_MASK_CSR_TX_FIFO_STATUS, 1);350		rt2800mmio_fetch_txstatus(rt2x00dev);351		if (!kfifo_is_empty(&rt2x00dev->txstatus_fifo))352			tasklet_schedule(&rt2x00dev->txstatus_tasklet);353	}354 355	if (rt2x00_get_field32(reg, INT_SOURCE_CSR_PRE_TBTT))356		tasklet_hi_schedule(&rt2x00dev->pretbtt_tasklet);357 358	if (rt2x00_get_field32(reg, INT_SOURCE_CSR_TBTT))359		tasklet_hi_schedule(&rt2x00dev->tbtt_tasklet);360 361	if (rt2x00_get_field32(reg, INT_SOURCE_CSR_RX_DONE))362		tasklet_schedule(&rt2x00dev->rxdone_tasklet);363 364	if (rt2x00_get_field32(reg, INT_SOURCE_CSR_AUTO_WAKEUP))365		tasklet_schedule(&rt2x00dev->autowake_tasklet);366 367	/*368	 * Disable all interrupts for which a tasklet was scheduled right now,369	 * the tasklet will reenable the appropriate interrupts.370	 */371	spin_lock(&rt2x00dev->irqmask_lock);372	reg = rt2x00mmio_register_read(rt2x00dev, INT_MASK_CSR);373	reg &= mask;374	rt2x00mmio_register_write(rt2x00dev, INT_MASK_CSR, reg);375	spin_unlock(&rt2x00dev->irqmask_lock);376 377	return IRQ_HANDLED;378}379EXPORT_SYMBOL_GPL(rt2800mmio_interrupt);380 381void rt2800mmio_toggle_irq(struct rt2x00_dev *rt2x00dev,382			   enum dev_state state)383{384	u32 reg;385	unsigned long flags;386 387	/*388	 * When interrupts are being enabled, the interrupt registers389	 * should clear the register to assure a clean state.390	 */391	if (state == STATE_RADIO_IRQ_ON) {392		reg = rt2x00mmio_register_read(rt2x00dev, INT_SOURCE_CSR);393		rt2x00mmio_register_write(rt2x00dev, INT_SOURCE_CSR, reg);394	}395 396	spin_lock_irqsave(&rt2x00dev->irqmask_lock, flags);397	reg = 0;398	if (state == STATE_RADIO_IRQ_ON) {399		rt2x00_set_field32(&reg, INT_MASK_CSR_RX_DONE, 1);400		rt2x00_set_field32(&reg, INT_MASK_CSR_TBTT, 1);401		rt2x00_set_field32(&reg, INT_MASK_CSR_PRE_TBTT, 1);402		rt2x00_set_field32(&reg, INT_MASK_CSR_TX_FIFO_STATUS, 1);403		rt2x00_set_field32(&reg, INT_MASK_CSR_AUTO_WAKEUP, 1);404	}405	rt2x00mmio_register_write(rt2x00dev, INT_MASK_CSR, reg);406	spin_unlock_irqrestore(&rt2x00dev->irqmask_lock, flags);407 408	if (state == STATE_RADIO_IRQ_OFF) {409		/*410		 * Wait for possibly running tasklets to finish.411		 */412		tasklet_kill(&rt2x00dev->txstatus_tasklet);413		tasklet_kill(&rt2x00dev->rxdone_tasklet);414		tasklet_kill(&rt2x00dev->autowake_tasklet);415		tasklet_kill(&rt2x00dev->tbtt_tasklet);416		tasklet_kill(&rt2x00dev->pretbtt_tasklet);417	}418}419EXPORT_SYMBOL_GPL(rt2800mmio_toggle_irq);420 421/*422 * Queue handlers.423 */424void rt2800mmio_start_queue(struct data_queue *queue)425{426	struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;427	u32 reg;428 429	switch (queue->qid) {430	case QID_RX:431		reg = rt2x00mmio_register_read(rt2x00dev, MAC_SYS_CTRL);432		rt2x00_set_field32(&reg, MAC_SYS_CTRL_ENABLE_RX, 1);433		rt2x00mmio_register_write(rt2x00dev, MAC_SYS_CTRL, reg);434		break;435	case QID_BEACON:436		reg = rt2x00mmio_register_read(rt2x00dev, BCN_TIME_CFG);437		rt2x00_set_field32(&reg, BCN_TIME_CFG_TSF_TICKING, 1);438		rt2x00_set_field32(&reg, BCN_TIME_CFG_TBTT_ENABLE, 1);439		rt2x00_set_field32(&reg, BCN_TIME_CFG_BEACON_GEN, 1);440		rt2x00mmio_register_write(rt2x00dev, BCN_TIME_CFG, reg);441 442		reg = rt2x00mmio_register_read(rt2x00dev, INT_TIMER_EN);443		rt2x00_set_field32(&reg, INT_TIMER_EN_PRE_TBTT_TIMER, 1);444		rt2x00mmio_register_write(rt2x00dev, INT_TIMER_EN, reg);445		break;446	default:447		break;448	}449}450EXPORT_SYMBOL_GPL(rt2800mmio_start_queue);451 452/* 200 ms */453#define TXSTATUS_TIMEOUT 200000000454 455void rt2800mmio_kick_queue(struct data_queue *queue)456{457	struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;458	struct queue_entry *entry;459 460	switch (queue->qid) {461	case QID_AC_VO:462	case QID_AC_VI:463	case QID_AC_BE:464	case QID_AC_BK:465		WARN_ON_ONCE(rt2x00queue_empty(queue));466		entry = rt2x00queue_get_entry(queue, Q_INDEX);467		rt2x00mmio_register_write(rt2x00dev, TX_CTX_IDX(queue->qid),468					  entry->entry_idx);469		hrtimer_start(&rt2x00dev->txstatus_timer,470			      TXSTATUS_TIMEOUT, HRTIMER_MODE_REL);471		break;472	case QID_MGMT:473		entry = rt2x00queue_get_entry(queue, Q_INDEX);474		rt2x00mmio_register_write(rt2x00dev, TX_CTX_IDX(5),475					  entry->entry_idx);476		break;477	default:478		break;479	}480}481EXPORT_SYMBOL_GPL(rt2800mmio_kick_queue);482 483void rt2800mmio_flush_queue(struct data_queue *queue, bool drop)484{485	struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;486	bool tx_queue = false;487	unsigned int i;488 489	switch (queue->qid) {490	case QID_AC_VO:491	case QID_AC_VI:492	case QID_AC_BE:493	case QID_AC_BK:494		tx_queue = true;495		break;496	case QID_RX:497		break;498	default:499		return;500	}501 502	for (i = 0; i < 5; i++) {503		/*504		 * Check if the driver is already done, otherwise we505		 * have to sleep a little while to give the driver/hw506		 * the oppurtunity to complete interrupt process itself.507		 */508		if (rt2x00queue_empty(queue))509			break;510 511		/*512		 * For TX queues schedule completion tasklet to catch513		 * tx status timeouts, othewise just wait.514		 */515		if (tx_queue)516			queue_work(rt2x00dev->workqueue, &rt2x00dev->txdone_work);517 518		/*519		 * Wait for a little while to give the driver520		 * the oppurtunity to recover itself.521		 */522		msleep(50);523	}524}525EXPORT_SYMBOL_GPL(rt2800mmio_flush_queue);526 527void rt2800mmio_stop_queue(struct data_queue *queue)528{529	struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;530	u32 reg;531 532	switch (queue->qid) {533	case QID_RX:534		reg = rt2x00mmio_register_read(rt2x00dev, MAC_SYS_CTRL);535		rt2x00_set_field32(&reg, MAC_SYS_CTRL_ENABLE_RX, 0);536		rt2x00mmio_register_write(rt2x00dev, MAC_SYS_CTRL, reg);537		break;538	case QID_BEACON:539		reg = rt2x00mmio_register_read(rt2x00dev, BCN_TIME_CFG);540		rt2x00_set_field32(&reg, BCN_TIME_CFG_TSF_TICKING, 0);541		rt2x00_set_field32(&reg, BCN_TIME_CFG_TBTT_ENABLE, 0);542		rt2x00_set_field32(&reg, BCN_TIME_CFG_BEACON_GEN, 0);543		rt2x00mmio_register_write(rt2x00dev, BCN_TIME_CFG, reg);544 545		reg = rt2x00mmio_register_read(rt2x00dev, INT_TIMER_EN);546		rt2x00_set_field32(&reg, INT_TIMER_EN_PRE_TBTT_TIMER, 0);547		rt2x00mmio_register_write(rt2x00dev, INT_TIMER_EN, reg);548 549		/*550		 * Wait for current invocation to finish. The tasklet551		 * won't be scheduled anymore afterwards since we disabled552		 * the TBTT and PRE TBTT timer.553		 */554		tasklet_kill(&rt2x00dev->tbtt_tasklet);555		tasklet_kill(&rt2x00dev->pretbtt_tasklet);556 557		break;558	default:559		break;560	}561}562EXPORT_SYMBOL_GPL(rt2800mmio_stop_queue);563 564void rt2800mmio_queue_init(struct data_queue *queue)565{566	struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;567	unsigned short txwi_size, rxwi_size;568 569	rt2800_get_txwi_rxwi_size(rt2x00dev, &txwi_size, &rxwi_size);570 571	switch (queue->qid) {572	case QID_RX:573		queue->limit = 128;574		queue->data_size = AGGREGATION_SIZE;575		queue->desc_size = RXD_DESC_SIZE;576		queue->winfo_size = rxwi_size;577		queue->priv_size = sizeof(struct queue_entry_priv_mmio);578		break;579 580	case QID_AC_VO:581	case QID_AC_VI:582	case QID_AC_BE:583	case QID_AC_BK:584		queue->limit = 64;585		queue->data_size = AGGREGATION_SIZE;586		queue->desc_size = TXD_DESC_SIZE;587		queue->winfo_size = txwi_size;588		queue->priv_size = sizeof(struct queue_entry_priv_mmio);589		break;590 591	case QID_BEACON:592		queue->limit = 8;593		queue->data_size = 0; /* No DMA required for beacons */594		queue->desc_size = TXD_DESC_SIZE;595		queue->winfo_size = txwi_size;596		queue->priv_size = sizeof(struct queue_entry_priv_mmio);597		break;598 599	case QID_ATIM:600	default:601		BUG();602		break;603	}604}605EXPORT_SYMBOL_GPL(rt2800mmio_queue_init);606 607/*608 * Initialization functions.609 */610bool rt2800mmio_get_entry_state(struct queue_entry *entry)611{612	struct queue_entry_priv_mmio *entry_priv = entry->priv_data;613	u32 word;614 615	if (entry->queue->qid == QID_RX) {616		word = rt2x00_desc_read(entry_priv->desc, 1);617 618		return (!rt2x00_get_field32(word, RXD_W1_DMA_DONE));619	} else {620		word = rt2x00_desc_read(entry_priv->desc, 1);621 622		return (!rt2x00_get_field32(word, TXD_W1_DMA_DONE));623	}624}625EXPORT_SYMBOL_GPL(rt2800mmio_get_entry_state);626 627void rt2800mmio_clear_entry(struct queue_entry *entry)628{629	struct queue_entry_priv_mmio *entry_priv = entry->priv_data;630	struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);631	struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;632	u32 word;633 634	if (entry->queue->qid == QID_RX) {635		word = rt2x00_desc_read(entry_priv->desc, 0);636		rt2x00_set_field32(&word, RXD_W0_SDP0, skbdesc->skb_dma);637		rt2x00_desc_write(entry_priv->desc, 0, word);638 639		word = rt2x00_desc_read(entry_priv->desc, 1);640		rt2x00_set_field32(&word, RXD_W1_DMA_DONE, 0);641		rt2x00_desc_write(entry_priv->desc, 1, word);642 643		/*644		 * Set RX IDX in register to inform hardware that we have645		 * handled this entry and it is available for reuse again.646		 */647		rt2x00mmio_register_write(rt2x00dev, RX_CRX_IDX,648					  entry->entry_idx);649	} else {650		word = rt2x00_desc_read(entry_priv->desc, 1);651		rt2x00_set_field32(&word, TXD_W1_DMA_DONE, 1);652		rt2x00_desc_write(entry_priv->desc, 1, word);653 654		/* If last entry stop txstatus timer */655		if (entry->queue->length == 1)656			hrtimer_cancel(&rt2x00dev->txstatus_timer);657	}658}659EXPORT_SYMBOL_GPL(rt2800mmio_clear_entry);660 661int rt2800mmio_init_queues(struct rt2x00_dev *rt2x00dev)662{663	struct queue_entry_priv_mmio *entry_priv;664 665	/*666	 * Initialize registers.667	 */668	entry_priv = rt2x00dev->tx[0].entries[0].priv_data;669	rt2x00mmio_register_write(rt2x00dev, TX_BASE_PTR0,670				  entry_priv->desc_dma);671	rt2x00mmio_register_write(rt2x00dev, TX_MAX_CNT0,672				  rt2x00dev->tx[0].limit);673	rt2x00mmio_register_write(rt2x00dev, TX_CTX_IDX0, 0);674	rt2x00mmio_register_write(rt2x00dev, TX_DTX_IDX0, 0);675 676	entry_priv = rt2x00dev->tx[1].entries[0].priv_data;677	rt2x00mmio_register_write(rt2x00dev, TX_BASE_PTR1,678				  entry_priv->desc_dma);679	rt2x00mmio_register_write(rt2x00dev, TX_MAX_CNT1,680				  rt2x00dev->tx[1].limit);681	rt2x00mmio_register_write(rt2x00dev, TX_CTX_IDX1, 0);682	rt2x00mmio_register_write(rt2x00dev, TX_DTX_IDX1, 0);683 684	entry_priv = rt2x00dev->tx[2].entries[0].priv_data;685	rt2x00mmio_register_write(rt2x00dev, TX_BASE_PTR2,686				  entry_priv->desc_dma);687	rt2x00mmio_register_write(rt2x00dev, TX_MAX_CNT2,688				  rt2x00dev->tx[2].limit);689	rt2x00mmio_register_write(rt2x00dev, TX_CTX_IDX2, 0);690	rt2x00mmio_register_write(rt2x00dev, TX_DTX_IDX2, 0);691 692	entry_priv = rt2x00dev->tx[3].entries[0].priv_data;693	rt2x00mmio_register_write(rt2x00dev, TX_BASE_PTR3,694				  entry_priv->desc_dma);695	rt2x00mmio_register_write(rt2x00dev, TX_MAX_CNT3,696				  rt2x00dev->tx[3].limit);697	rt2x00mmio_register_write(rt2x00dev, TX_CTX_IDX3, 0);698	rt2x00mmio_register_write(rt2x00dev, TX_DTX_IDX3, 0);699 700	rt2x00mmio_register_write(rt2x00dev, TX_BASE_PTR4, 0);701	rt2x00mmio_register_write(rt2x00dev, TX_MAX_CNT4, 0);702	rt2x00mmio_register_write(rt2x00dev, TX_CTX_IDX4, 0);703	rt2x00mmio_register_write(rt2x00dev, TX_DTX_IDX4, 0);704 705	rt2x00mmio_register_write(rt2x00dev, TX_BASE_PTR5, 0);706	rt2x00mmio_register_write(rt2x00dev, TX_MAX_CNT5, 0);707	rt2x00mmio_register_write(rt2x00dev, TX_CTX_IDX5, 0);708	rt2x00mmio_register_write(rt2x00dev, TX_DTX_IDX5, 0);709 710	entry_priv = rt2x00dev->rx->entries[0].priv_data;711	rt2x00mmio_register_write(rt2x00dev, RX_BASE_PTR,712				  entry_priv->desc_dma);713	rt2x00mmio_register_write(rt2x00dev, RX_MAX_CNT,714				  rt2x00dev->rx[0].limit);715	rt2x00mmio_register_write(rt2x00dev, RX_CRX_IDX,716				  rt2x00dev->rx[0].limit - 1);717	rt2x00mmio_register_write(rt2x00dev, RX_DRX_IDX, 0);718 719	rt2800_disable_wpdma(rt2x00dev);720 721	rt2x00mmio_register_write(rt2x00dev, DELAY_INT_CFG, 0);722 723	return 0;724}725EXPORT_SYMBOL_GPL(rt2800mmio_init_queues);726 727int rt2800mmio_init_registers(struct rt2x00_dev *rt2x00dev)728{729	u32 reg;730 731	/*732	 * Reset DMA indexes733	 */734	reg = rt2x00mmio_register_read(rt2x00dev, WPDMA_RST_IDX);735	rt2x00_set_field32(&reg, WPDMA_RST_IDX_DTX_IDX0, 1);736	rt2x00_set_field32(&reg, WPDMA_RST_IDX_DTX_IDX1, 1);737	rt2x00_set_field32(&reg, WPDMA_RST_IDX_DTX_IDX2, 1);738	rt2x00_set_field32(&reg, WPDMA_RST_IDX_DTX_IDX3, 1);739	rt2x00_set_field32(&reg, WPDMA_RST_IDX_DTX_IDX4, 1);740	rt2x00_set_field32(&reg, WPDMA_RST_IDX_DTX_IDX5, 1);741	rt2x00_set_field32(&reg, WPDMA_RST_IDX_DRX_IDX0, 1);742	rt2x00mmio_register_write(rt2x00dev, WPDMA_RST_IDX, reg);743 744	rt2x00mmio_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00000e1f);745	rt2x00mmio_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00000e00);746 747	if (rt2x00_is_pcie(rt2x00dev) &&748	    (rt2x00_rt(rt2x00dev, RT3090) ||749	     rt2x00_rt(rt2x00dev, RT3390) ||750	     rt2x00_rt(rt2x00dev, RT3572) ||751	     rt2x00_rt(rt2x00dev, RT3593) ||752	     rt2x00_rt(rt2x00dev, RT5390) ||753	     rt2x00_rt(rt2x00dev, RT5392) ||754	     rt2x00_rt(rt2x00dev, RT5592))) {755		reg = rt2x00mmio_register_read(rt2x00dev, AUX_CTRL);756		rt2x00_set_field32(&reg, AUX_CTRL_FORCE_PCIE_CLK, 1);757		rt2x00_set_field32(&reg, AUX_CTRL_WAKE_PCIE_EN, 1);758		rt2x00mmio_register_write(rt2x00dev, AUX_CTRL, reg);759	}760 761	rt2x00mmio_register_write(rt2x00dev, PWR_PIN_CFG, 0x00000003);762 763	if (rt2x00_rt(rt2x00dev, RT6352))764		return 0;765 766	reg = 0;767	rt2x00_set_field32(&reg, MAC_SYS_CTRL_RESET_CSR, 1);768	rt2x00_set_field32(&reg, MAC_SYS_CTRL_RESET_BBP, 1);769	rt2x00mmio_register_write(rt2x00dev, MAC_SYS_CTRL, reg);770 771	rt2x00mmio_register_write(rt2x00dev, MAC_SYS_CTRL, 0x00000000);772 773	return 0;774}775EXPORT_SYMBOL_GPL(rt2800mmio_init_registers);776 777/*778 * Device state switch handlers.779 */780int rt2800mmio_enable_radio(struct rt2x00_dev *rt2x00dev)781{782	/* Wait for DMA, ignore error until we initialize queues. */783	rt2800_wait_wpdma_ready(rt2x00dev);784 785	if (unlikely(rt2800mmio_init_queues(rt2x00dev)))786		return -EIO;787 788	return rt2800_enable_radio(rt2x00dev);789}790EXPORT_SYMBOL_GPL(rt2800mmio_enable_radio);791 792static void rt2800mmio_work_txdone(struct work_struct *work)793{794	struct rt2x00_dev *rt2x00dev =795	    container_of(work, struct rt2x00_dev, txdone_work);796 797	if (!test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))798		return;799 800	while (!kfifo_is_empty(&rt2x00dev->txstatus_fifo) ||801	       rt2800_txstatus_timeout(rt2x00dev)) {802 803		tasklet_disable(&rt2x00dev->txstatus_tasklet);804		rt2800_txdone(rt2x00dev, UINT_MAX);805		rt2800_txdone_nostatus(rt2x00dev);806		tasklet_enable(&rt2x00dev->txstatus_tasklet);807	}808 809	if (rt2800_txstatus_pending(rt2x00dev))810		hrtimer_start(&rt2x00dev->txstatus_timer,811			      TXSTATUS_TIMEOUT, HRTIMER_MODE_REL);812}813 814static enum hrtimer_restart rt2800mmio_tx_sta_fifo_timeout(struct hrtimer *timer)815{816	struct rt2x00_dev *rt2x00dev =817	    container_of(timer, struct rt2x00_dev, txstatus_timer);818 819	if (!test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))820		goto out;821 822	if (!rt2800_txstatus_pending(rt2x00dev))823		goto out;824 825	rt2800mmio_fetch_txstatus(rt2x00dev);826	if (!kfifo_is_empty(&rt2x00dev->txstatus_fifo))827		tasklet_schedule(&rt2x00dev->txstatus_tasklet);828	else829		queue_work(rt2x00dev->workqueue, &rt2x00dev->txdone_work);830out:831	return HRTIMER_NORESTART;832}833 834int rt2800mmio_probe_hw(struct rt2x00_dev *rt2x00dev)835{836	int retval;837 838	retval = rt2800_probe_hw(rt2x00dev);839	if (retval)840		return retval;841 842	/*843	 * Set txstatus timer function.844	 */845	rt2x00dev->txstatus_timer.function = rt2800mmio_tx_sta_fifo_timeout;846 847	/*848	 * Overwrite TX done handler849	 */850	INIT_WORK(&rt2x00dev->txdone_work, rt2800mmio_work_txdone);851 852	return 0;853}854EXPORT_SYMBOL_GPL(rt2800mmio_probe_hw);855 856MODULE_AUTHOR(DRV_PROJECT);857MODULE_VERSION(DRV_VERSION);858MODULE_DESCRIPTION("rt2800 MMIO library");859MODULE_LICENSE("GPL");860