static int rt2800pci_set_state(struct rt2x00_dev *rt2x00dev, enum dev_state state) { if (state == STATE_AWAKE) { rt2800_mcu_request(rt2x00dev, MCU_WAKEUP, TOKEN_WAKEUP, 0, 0x02); rt2800pci_mcu_status(rt2x00dev, TOKEN_WAKEUP); } else if (state == STATE_SLEEP) { rt2800_shared_mem_lock(rt2x00dev); rt2x00mmio_register_write(rt2x00dev, H2M_MAILBOX_STATUS, 0xffffffff); rt2x00mmio_register_write(rt2x00dev, H2M_MAILBOX_CID, 0xffffffff); rt2800_shared_mem_unlock(rt2x00dev); rt2800_mcu_request(rt2x00dev, MCU_SLEEP, TOKEN_SLEEP, 0xff, 0x01); } return 0; }
/* * Device state switch handlers. */ static int rt2800pci_enable_radio(struct rt2x00_dev *rt2x00dev) { int retval; retval = rt2800mmio_enable_radio(rt2x00dev); if (retval) return retval; /* After resume MCU_BOOT_SIGNAL will trash these. */ rt2800_shared_mem_lock(rt2x00dev); rt2x00mmio_register_write(rt2x00dev, H2M_MAILBOX_STATUS, ~0); rt2x00mmio_register_write(rt2x00dev, H2M_MAILBOX_CID, ~0); rt2800_shared_mem_unlock(rt2x00dev); rt2800_mcu_request(rt2x00dev, MCU_SLEEP, TOKEN_RADIO_OFF, 0xff, 0x02); rt2800pci_mcu_status(rt2x00dev, TOKEN_RADIO_OFF); rt2800_mcu_request(rt2x00dev, MCU_WAKEUP, TOKEN_WAKEUP, 0, 0); rt2800pci_mcu_status(rt2x00dev, TOKEN_WAKEUP); return retval; }
/* * Device state switch handlers. */ static void rt2800pci_toggle_irq(struct rt2x00_dev *rt2x00dev, enum dev_state state) { u32 reg; unsigned long flags; /* * When interrupts are being enabled, the interrupt registers * should clear the register to assure a clean state. */ if (state == STATE_RADIO_IRQ_ON) { rt2x00mmio_register_read(rt2x00dev, INT_SOURCE_CSR, ®); rt2x00mmio_register_write(rt2x00dev, INT_SOURCE_CSR, reg); } spin_lock_irqsave(&rt2x00dev->irqmask_lock, flags); reg = 0; if (state == STATE_RADIO_IRQ_ON) { rt2x00_set_field32(®, INT_MASK_CSR_RX_DONE, 1); rt2x00_set_field32(®, INT_MASK_CSR_TBTT, 1); rt2x00_set_field32(®, INT_MASK_CSR_PRE_TBTT, 1); rt2x00_set_field32(®, INT_MASK_CSR_TX_FIFO_STATUS, 1); rt2x00_set_field32(®, INT_MASK_CSR_AUTO_WAKEUP, 1); } rt2x00mmio_register_write(rt2x00dev, INT_MASK_CSR, reg); spin_unlock_irqrestore(&rt2x00dev->irqmask_lock, flags); if (state == STATE_RADIO_IRQ_OFF) { /* * Wait for possibly running tasklets to finish. */ tasklet_kill(&rt2x00dev->txstatus_tasklet); tasklet_kill(&rt2x00dev->rxdone_tasklet); tasklet_kill(&rt2x00dev->autowake_tasklet); tasklet_kill(&rt2x00dev->tbtt_tasklet); tasklet_kill(&rt2x00dev->pretbtt_tasklet); } }
static void rt2800pci_eepromregister_write(struct eeprom_93cx6 *eeprom) { struct rt2x00_dev *rt2x00dev = eeprom->data; u32 reg = 0; rt2x00_set_field32(®, E2PROM_CSR_DATA_IN, !!eeprom->reg_data_in); rt2x00_set_field32(®, E2PROM_CSR_DATA_OUT, !!eeprom->reg_data_out); rt2x00_set_field32(®, E2PROM_CSR_DATA_CLOCK, !!eeprom->reg_data_clock); rt2x00_set_field32(®, E2PROM_CSR_CHIP_SELECT, !!eeprom->reg_chip_select); rt2x00mmio_register_write(rt2x00dev, E2PROM_CSR, reg); }
static void rt2800pci_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; } }
static inline void rt2800pci_enable_interrupt(struct rt2x00_dev *rt2x00dev, struct rt2x00_field32 irq_field) { u32 reg; /* * Enable a single interrupt. The interrupt mask register * access needs locking. */ spin_lock_irq(&rt2x00dev->irqmask_lock); rt2x00mmio_register_read(rt2x00dev, INT_MASK_CSR, ®); rt2x00_set_field32(®, irq_field, 1); rt2x00mmio_register_write(rt2x00dev, INT_MASK_CSR, reg); spin_unlock_irq(&rt2x00dev->irqmask_lock); }
int rt2800mmio_init_registers(struct rt2x00_dev *rt2x00dev) { u32 reg; /* * Reset DMA indexes */ reg = rt2x00mmio_register_read(rt2x00dev, WPDMA_RST_IDX); rt2x00_set_field32(®, WPDMA_RST_IDX_DTX_IDX0, 1); rt2x00_set_field32(®, WPDMA_RST_IDX_DTX_IDX1, 1); rt2x00_set_field32(®, WPDMA_RST_IDX_DTX_IDX2, 1); rt2x00_set_field32(®, WPDMA_RST_IDX_DTX_IDX3, 1); rt2x00_set_field32(®, WPDMA_RST_IDX_DTX_IDX4, 1); rt2x00_set_field32(®, WPDMA_RST_IDX_DTX_IDX5, 1); rt2x00_set_field32(®, WPDMA_RST_IDX_DRX_IDX0, 1); rt2x00mmio_register_write(rt2x00dev, WPDMA_RST_IDX, reg); rt2x00mmio_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00000e1f); rt2x00mmio_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00000e00); if (rt2x00_is_pcie(rt2x00dev) && (rt2x00_rt(rt2x00dev, RT3090) || rt2x00_rt(rt2x00dev, RT3390) || rt2x00_rt(rt2x00dev, RT3572) || rt2x00_rt(rt2x00dev, RT3593) || rt2x00_rt(rt2x00dev, RT5390) || rt2x00_rt(rt2x00dev, RT5392) || rt2x00_rt(rt2x00dev, RT5592))) { reg = rt2x00mmio_register_read(rt2x00dev, AUX_CTRL); rt2x00_set_field32(®, AUX_CTRL_FORCE_PCIE_CLK, 1); rt2x00_set_field32(®, AUX_CTRL_WAKE_PCIE_EN, 1); rt2x00mmio_register_write(rt2x00dev, AUX_CTRL, reg); } rt2x00mmio_register_write(rt2x00dev, PWR_PIN_CFG, 0x00000003); reg = 0; rt2x00_set_field32(®, MAC_SYS_CTRL_RESET_CSR, 1); rt2x00_set_field32(®, MAC_SYS_CTRL_RESET_BBP, 1); rt2x00mmio_register_write(rt2x00dev, MAC_SYS_CTRL, reg); rt2x00mmio_register_write(rt2x00dev, MAC_SYS_CTRL, 0x00000000); return 0; }
static void rt2800soc_disable_radio(struct rt2x00_dev *rt2x00dev) { rt2800_disable_radio(rt2x00dev); rt2x00mmio_register_write(rt2x00dev, PWR_PIN_CFG, 0); rt2x00mmio_register_write(rt2x00dev, TX_PIN_CFG, 0); }
static int rt2800pci_init_queues(struct rt2x00_dev *rt2x00dev) { struct queue_entry_priv_mmio *entry_priv; /* * Initialize registers. */ entry_priv = rt2x00dev->tx[0].entries[0].priv_data; rt2x00mmio_register_write(rt2x00dev, TX_BASE_PTR0, entry_priv->desc_dma); rt2x00mmio_register_write(rt2x00dev, TX_MAX_CNT0, rt2x00dev->tx[0].limit); rt2x00mmio_register_write(rt2x00dev, TX_CTX_IDX0, 0); rt2x00mmio_register_write(rt2x00dev, TX_DTX_IDX0, 0); entry_priv = rt2x00dev->tx[1].entries[0].priv_data; rt2x00mmio_register_write(rt2x00dev, TX_BASE_PTR1, entry_priv->desc_dma); rt2x00mmio_register_write(rt2x00dev, TX_MAX_CNT1, rt2x00dev->tx[1].limit); rt2x00mmio_register_write(rt2x00dev, TX_CTX_IDX1, 0); rt2x00mmio_register_write(rt2x00dev, TX_DTX_IDX1, 0); entry_priv = rt2x00dev->tx[2].entries[0].priv_data; rt2x00mmio_register_write(rt2x00dev, TX_BASE_PTR2, entry_priv->desc_dma); rt2x00mmio_register_write(rt2x00dev, TX_MAX_CNT2, rt2x00dev->tx[2].limit); rt2x00mmio_register_write(rt2x00dev, TX_CTX_IDX2, 0); rt2x00mmio_register_write(rt2x00dev, TX_DTX_IDX2, 0); entry_priv = rt2x00dev->tx[3].entries[0].priv_data; rt2x00mmio_register_write(rt2x00dev, TX_BASE_PTR3, entry_priv->desc_dma); rt2x00mmio_register_write(rt2x00dev, TX_MAX_CNT3, rt2x00dev->tx[3].limit); rt2x00mmio_register_write(rt2x00dev, TX_CTX_IDX3, 0); rt2x00mmio_register_write(rt2x00dev, TX_DTX_IDX3, 0); rt2x00mmio_register_write(rt2x00dev, TX_BASE_PTR4, 0); rt2x00mmio_register_write(rt2x00dev, TX_MAX_CNT4, 0); rt2x00mmio_register_write(rt2x00dev, TX_CTX_IDX4, 0); rt2x00mmio_register_write(rt2x00dev, TX_DTX_IDX4, 0); rt2x00mmio_register_write(rt2x00dev, TX_BASE_PTR5, 0); rt2x00mmio_register_write(rt2x00dev, TX_MAX_CNT5, 0); rt2x00mmio_register_write(rt2x00dev, TX_CTX_IDX5, 0); rt2x00mmio_register_write(rt2x00dev, TX_DTX_IDX5, 0); entry_priv = rt2x00dev->rx->entries[0].priv_data; rt2x00mmio_register_write(rt2x00dev, RX_BASE_PTR, entry_priv->desc_dma); rt2x00mmio_register_write(rt2x00dev, RX_MAX_CNT, rt2x00dev->rx[0].limit); rt2x00mmio_register_write(rt2x00dev, RX_CRX_IDX, rt2x00dev->rx[0].limit - 1); rt2x00mmio_register_write(rt2x00dev, RX_DRX_IDX, 0); rt2800_disable_wpdma(rt2x00dev); rt2x00mmio_register_write(rt2x00dev, DELAY_INT_CFG, 0); return 0; }