|
@@ -552,6 +552,143 @@ void rt2800mmio_toggle_irq(struct rt2x00_dev *rt2x00dev,
|
|
|
}
|
|
|
EXPORT_SYMBOL_GPL(rt2800mmio_toggle_irq);
|
|
|
|
|
|
+/*
|
|
|
+ * Queue handlers.
|
|
|
+ */
|
|
|
+void rt2800mmio_start_queue(struct data_queue *queue)
|
|
|
+{
|
|
|
+ struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;
|
|
|
+ u32 reg;
|
|
|
+
|
|
|
+ switch (queue->qid) {
|
|
|
+ case QID_RX:
|
|
|
+ rt2x00mmio_register_read(rt2x00dev, MAC_SYS_CTRL, ®);
|
|
|
+ rt2x00_set_field32(®, MAC_SYS_CTRL_ENABLE_RX, 1);
|
|
|
+ rt2x00mmio_register_write(rt2x00dev, MAC_SYS_CTRL, reg);
|
|
|
+ break;
|
|
|
+ case QID_BEACON:
|
|
|
+ rt2x00mmio_register_read(rt2x00dev, BCN_TIME_CFG, ®);
|
|
|
+ rt2x00_set_field32(®, BCN_TIME_CFG_TSF_TICKING, 1);
|
|
|
+ rt2x00_set_field32(®, BCN_TIME_CFG_TBTT_ENABLE, 1);
|
|
|
+ rt2x00_set_field32(®, BCN_TIME_CFG_BEACON_GEN, 1);
|
|
|
+ rt2x00mmio_register_write(rt2x00dev, BCN_TIME_CFG, reg);
|
|
|
+
|
|
|
+ rt2x00mmio_register_read(rt2x00dev, INT_TIMER_EN, ®);
|
|
|
+ rt2x00_set_field32(®, INT_TIMER_EN_PRE_TBTT_TIMER, 1);
|
|
|
+ rt2x00mmio_register_write(rt2x00dev, INT_TIMER_EN, reg);
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ break;
|
|
|
+ }
|
|
|
+}
|
|
|
+EXPORT_SYMBOL_GPL(rt2800mmio_start_queue);
|
|
|
+
|
|
|
+void rt2800mmio_kick_queue(struct data_queue *queue)
|
|
|
+{
|
|
|
+ struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;
|
|
|
+ struct queue_entry *entry;
|
|
|
+
|
|
|
+ switch (queue->qid) {
|
|
|
+ case QID_AC_VO:
|
|
|
+ case QID_AC_VI:
|
|
|
+ case QID_AC_BE:
|
|
|
+ case QID_AC_BK:
|
|
|
+ entry = rt2x00queue_get_entry(queue, Q_INDEX);
|
|
|
+ rt2x00mmio_register_write(rt2x00dev, TX_CTX_IDX(queue->qid),
|
|
|
+ entry->entry_idx);
|
|
|
+ break;
|
|
|
+ case QID_MGMT:
|
|
|
+ entry = rt2x00queue_get_entry(queue, Q_INDEX);
|
|
|
+ rt2x00mmio_register_write(rt2x00dev, TX_CTX_IDX(5),
|
|
|
+ entry->entry_idx);
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ break;
|
|
|
+ }
|
|
|
+}
|
|
|
+EXPORT_SYMBOL_GPL(rt2800mmio_kick_queue);
|
|
|
+
|
|
|
+void rt2800mmio_stop_queue(struct data_queue *queue)
|
|
|
+{
|
|
|
+ struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;
|
|
|
+ u32 reg;
|
|
|
+
|
|
|
+ switch (queue->qid) {
|
|
|
+ case QID_RX:
|
|
|
+ rt2x00mmio_register_read(rt2x00dev, MAC_SYS_CTRL, ®);
|
|
|
+ rt2x00_set_field32(®, MAC_SYS_CTRL_ENABLE_RX, 0);
|
|
|
+ rt2x00mmio_register_write(rt2x00dev, MAC_SYS_CTRL, reg);
|
|
|
+ break;
|
|
|
+ case QID_BEACON:
|
|
|
+ rt2x00mmio_register_read(rt2x00dev, BCN_TIME_CFG, ®);
|
|
|
+ rt2x00_set_field32(®, BCN_TIME_CFG_TSF_TICKING, 0);
|
|
|
+ rt2x00_set_field32(®, BCN_TIME_CFG_TBTT_ENABLE, 0);
|
|
|
+ rt2x00_set_field32(®, BCN_TIME_CFG_BEACON_GEN, 0);
|
|
|
+ rt2x00mmio_register_write(rt2x00dev, BCN_TIME_CFG, reg);
|
|
|
+
|
|
|
+ rt2x00mmio_register_read(rt2x00dev, INT_TIMER_EN, ®);
|
|
|
+ rt2x00_set_field32(®, INT_TIMER_EN_PRE_TBTT_TIMER, 0);
|
|
|
+ rt2x00mmio_register_write(rt2x00dev, INT_TIMER_EN, reg);
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Wait for current invocation to finish. The tasklet
|
|
|
+ * won't be scheduled anymore afterwards since we disabled
|
|
|
+ * the TBTT and PRE TBTT timer.
|
|
|
+ */
|
|
|
+ tasklet_kill(&rt2x00dev->tbtt_tasklet);
|
|
|
+ tasklet_kill(&rt2x00dev->pretbtt_tasklet);
|
|
|
+
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ break;
|
|
|
+ }
|
|
|
+}
|
|
|
+EXPORT_SYMBOL_GPL(rt2800mmio_stop_queue);
|
|
|
+
|
|
|
+void rt2800mmio_queue_init(struct data_queue *queue)
|
|
|
+{
|
|
|
+ struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;
|
|
|
+ unsigned short txwi_size, rxwi_size;
|
|
|
+
|
|
|
+ rt2800_get_txwi_rxwi_size(rt2x00dev, &txwi_size, &rxwi_size);
|
|
|
+
|
|
|
+ switch (queue->qid) {
|
|
|
+ case QID_RX:
|
|
|
+ queue->limit = 128;
|
|
|
+ queue->data_size = AGGREGATION_SIZE;
|
|
|
+ queue->desc_size = RXD_DESC_SIZE;
|
|
|
+ queue->winfo_size = rxwi_size;
|
|
|
+ queue->priv_size = sizeof(struct queue_entry_priv_mmio);
|
|
|
+ break;
|
|
|
+
|
|
|
+ case QID_AC_VO:
|
|
|
+ case QID_AC_VI:
|
|
|
+ case QID_AC_BE:
|
|
|
+ case QID_AC_BK:
|
|
|
+ queue->limit = 64;
|
|
|
+ queue->data_size = AGGREGATION_SIZE;
|
|
|
+ queue->desc_size = TXD_DESC_SIZE;
|
|
|
+ queue->winfo_size = txwi_size;
|
|
|
+ queue->priv_size = sizeof(struct queue_entry_priv_mmio);
|
|
|
+ break;
|
|
|
+
|
|
|
+ case QID_BEACON:
|
|
|
+ queue->limit = 8;
|
|
|
+ queue->data_size = 0; /* No DMA required for beacons */
|
|
|
+ queue->desc_size = TXD_DESC_SIZE;
|
|
|
+ queue->winfo_size = txwi_size;
|
|
|
+ queue->priv_size = sizeof(struct queue_entry_priv_mmio);
|
|
|
+ break;
|
|
|
+
|
|
|
+ case QID_ATIM:
|
|
|
+ /* fallthrough */
|
|
|
+ default:
|
|
|
+ BUG();
|
|
|
+ break;
|
|
|
+ }
|
|
|
+}
|
|
|
+EXPORT_SYMBOL_GPL(rt2800mmio_queue_init);
|
|
|
+
|
|
|
MODULE_AUTHOR(DRV_PROJECT);
|
|
|
MODULE_VERSION(DRV_VERSION);
|
|
|
MODULE_DESCRIPTION("rt2800 MMIO library");
|