static void rt2800pci_read_eeprom_pci(struct rt2x00_dev *rt2x00dev)
{
	struct eeprom_93cx6 eeprom;
	u32 reg;

	rt2800_register_read(rt2x00dev, E2PROM_CSR, &reg);

	eeprom.data = rt2x00dev;
	eeprom.register_read = rt2800pci_eepromregister_read;
	eeprom.register_write = rt2800pci_eepromregister_write;
	switch (rt2x00_get_field32(reg, E2PROM_CSR_TYPE))
	{
	case 0:
		eeprom.width = PCI_EEPROM_WIDTH_93C46;
		break;
	case 1:
		eeprom.width = PCI_EEPROM_WIDTH_93C66;
		break;
	default:
		eeprom.width = PCI_EEPROM_WIDTH_93C86;
		break;
	}
	eeprom.reg_data_in = 0;
	eeprom.reg_data_out = 0;
	eeprom.reg_data_clock = 0;
	eeprom.reg_chip_select = 0;

	eeprom_93cx6_multiread(&eeprom, EEPROM_BASE, rt2x00dev->eeprom,
			       EEPROM_SIZE / sizeof(u16));
}
Exemplo n.º 2
0
static void rt2800pci_mcu_status(struct rt2x00_dev *rt2x00dev, const u8 token)
{
	unsigned int i;
	u32 reg;

	/*
	 * SOC devices don't support MCU requests.
	 */
	if (rt2x00_is_soc(rt2x00dev))
		return;

	for (i = 0; i < 200; i++) {
		rt2800_register_read(rt2x00dev, H2M_MAILBOX_CID, &reg);

		if ((rt2x00_get_field32(reg, H2M_MAILBOX_CID_CMD0) == token) ||
		    (rt2x00_get_field32(reg, H2M_MAILBOX_CID_CMD1) == token) ||
		    (rt2x00_get_field32(reg, H2M_MAILBOX_CID_CMD2) == token) ||
		    (rt2x00_get_field32(reg, H2M_MAILBOX_CID_CMD3) == token))
			break;

		udelay(REGISTER_BUSY_DELAY);
	}

	if (i == 200)
		ERROR(rt2x00dev, "MCU request failed, no response from hardware\n");

	rt2800_register_write(rt2x00dev, H2M_MAILBOX_STATUS, ~0);
	rt2800_register_write(rt2x00dev, H2M_MAILBOX_CID, ~0);
}
Exemplo n.º 3
0
/*
 * Device state switch handlers.
 */
static void rt2800pci_toggle_rx(struct rt2x00_dev *rt2x00dev,
				enum dev_state state)
{
	u32 reg;

	rt2800_register_read(rt2x00dev, MAC_SYS_CTRL, &reg);
	rt2x00_set_field32(&reg, MAC_SYS_CTRL_ENABLE_RX,
			   (state == STATE_RADIO_RX_ON) ||
			   (state == STATE_RADIO_RX_ON_LINK));
	rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, reg);
}
Exemplo n.º 4
0
static void rt2800usb_stop_queue(struct data_queue *queue)
{
	struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;
	u32 reg;

	switch (queue->qid) {
	case QID_RX:
		rt2800_register_read(rt2x00dev, MAC_SYS_CTRL, &reg);
		rt2x00_set_field32(&reg, MAC_SYS_CTRL_ENABLE_RX, 0);
		rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, reg);
		break;
	case QID_BEACON:
		rt2800_register_read(rt2x00dev, BCN_TIME_CFG, &reg);
		rt2x00_set_field32(&reg, BCN_TIME_CFG_TSF_TICKING, 0);
		rt2x00_set_field32(&reg, BCN_TIME_CFG_TBTT_ENABLE, 0);
		rt2x00_set_field32(&reg, BCN_TIME_CFG_BEACON_GEN, 0);
		rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg);
		break;
	default:
		break;
	}
}
Exemplo n.º 5
0
/*
 * Watchdog handlers
 */
static void rt2800usb_watchdog(struct rt2x00_dev *rt2x00dev)
{
	unsigned int i;
	u32 reg;

	rt2800_register_read(rt2x00dev, TXRXQ_PCNT, &reg);
	if (rt2x00_get_field32(reg, TXRXQ_PCNT_TX0Q)) {
		WARNING(rt2x00dev, "TX HW queue 0 timed out,"
			" invoke forced kick\n");

		rt2800_register_write(rt2x00dev, PBF_CFG, 0xf40012);

		for (i = 0; i < 10; i++) {
			udelay(10);
			if (!rt2x00_get_field32(reg, TXRXQ_PCNT_TX0Q))
				break;
		}

		rt2800_register_write(rt2x00dev, PBF_CFG, 0xf40006);
	}

	rt2800_register_read(rt2x00dev, TXRXQ_PCNT, &reg);
	if (rt2x00_get_field32(reg, TXRXQ_PCNT_TX1Q)) {
		WARNING(rt2x00dev, "TX HW queue 1 timed out,"
			" invoke forced kick\n");

		rt2800_register_write(rt2x00dev, PBF_CFG, 0xf4000a);

		for (i = 0; i < 10; i++) {
			udelay(10);
			if (!rt2x00_get_field32(reg, TXRXQ_PCNT_TX1Q))
				break;
		}

		rt2800_register_write(rt2x00dev, PBF_CFG, 0xf40006);
	}

	rt2x00usb_watchdog(rt2x00dev);
}
static int rt2800pci_init_queues(struct rt2x00_dev *rt2x00dev)
{
	struct queue_entry_priv_pci *entry_priv;
	u32 reg;

	/*
	 * Initialize registers.
	 */
	entry_priv = rt2x00dev->tx[0].entries[0].priv_data;
	rt2800_register_write(rt2x00dev, TX_BASE_PTR0, entry_priv->desc_dma);
	rt2800_register_write(rt2x00dev, TX_MAX_CNT0, rt2x00dev->tx[0].limit);
	rt2800_register_write(rt2x00dev, TX_CTX_IDX0, 0);
	rt2800_register_write(rt2x00dev, TX_DTX_IDX0, 0);

	entry_priv = rt2x00dev->tx[1].entries[0].priv_data;
	rt2800_register_write(rt2x00dev, TX_BASE_PTR1, entry_priv->desc_dma);
	rt2800_register_write(rt2x00dev, TX_MAX_CNT1, rt2x00dev->tx[1].limit);
	rt2800_register_write(rt2x00dev, TX_CTX_IDX1, 0);
	rt2800_register_write(rt2x00dev, TX_DTX_IDX1, 0);

	entry_priv = rt2x00dev->tx[2].entries[0].priv_data;
	rt2800_register_write(rt2x00dev, TX_BASE_PTR2, entry_priv->desc_dma);
	rt2800_register_write(rt2x00dev, TX_MAX_CNT2, rt2x00dev->tx[2].limit);
	rt2800_register_write(rt2x00dev, TX_CTX_IDX2, 0);
	rt2800_register_write(rt2x00dev, TX_DTX_IDX2, 0);

	entry_priv = rt2x00dev->tx[3].entries[0].priv_data;
	rt2800_register_write(rt2x00dev, TX_BASE_PTR3, entry_priv->desc_dma);
	rt2800_register_write(rt2x00dev, TX_MAX_CNT3, rt2x00dev->tx[3].limit);
	rt2800_register_write(rt2x00dev, TX_CTX_IDX3, 0);
	rt2800_register_write(rt2x00dev, TX_DTX_IDX3, 0);

	entry_priv = rt2x00dev->rx->entries[0].priv_data;
	rt2800_register_write(rt2x00dev, RX_BASE_PTR, entry_priv->desc_dma);
	rt2800_register_write(rt2x00dev, RX_MAX_CNT, rt2x00dev->rx[0].limit);
	rt2800_register_write(rt2x00dev, RX_CRX_IDX, rt2x00dev->rx[0].limit - 1);
	rt2800_register_write(rt2x00dev, RX_DRX_IDX, 0);

	/*
	 * Enable global DMA configuration
	 */
	rt2800_register_read(rt2x00dev, WPDMA_GLO_CFG, &reg);
	rt2x00_set_field32(&reg, WPDMA_GLO_CFG_ENABLE_TX_DMA, 0);
	rt2x00_set_field32(&reg, WPDMA_GLO_CFG_ENABLE_RX_DMA, 0);
	rt2x00_set_field32(&reg, WPDMA_GLO_CFG_TX_WRITEBACK_DONE, 1);
	rt2800_register_write(rt2x00dev, WPDMA_GLO_CFG, reg);

	rt2800_register_write(rt2x00dev, DELAY_INT_CFG, 0);

	return 0;
}
Exemplo n.º 7
0
static void rt2800pci_eepromregister_read(struct eeprom_93cx6 *eeprom)
{
	struct rt2x00_dev *rt2x00dev = eeprom->data;
	u32 reg;

	rt2800_register_read(rt2x00dev, E2PROM_CSR, &reg);

	eeprom->reg_data_in = !!rt2x00_get_field32(reg, E2PROM_CSR_DATA_IN);
	eeprom->reg_data_out = !!rt2x00_get_field32(reg, E2PROM_CSR_DATA_OUT);
	eeprom->reg_data_clock =
	    !!rt2x00_get_field32(reg, E2PROM_CSR_DATA_CLOCK);
	eeprom->reg_chip_select =
	    !!rt2x00_get_field32(reg, E2PROM_CSR_CHIP_SELECT);
}
Exemplo n.º 8
0
static int rt2800usb_init_registers(struct rt2x00_dev *rt2x00dev)
{
	u32 reg;
	int i;

	/*
	 * Wait until BBP and RF are ready.
	 */
	for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
		rt2800_register_read(rt2x00dev, MAC_CSR0, &reg);
		if (reg && reg != ~0)
			break;
		msleep(1);
	}

	if (i == REGISTER_BUSY_COUNT) {
		ERROR(rt2x00dev, "Unstable hardware.\n");
		return -EBUSY;
	}

	rt2800_register_read(rt2x00dev, PBF_SYS_CTRL, &reg);
	rt2800_register_write(rt2x00dev, PBF_SYS_CTRL, reg & ~0x00002000);

	rt2800_register_read(rt2x00dev, MAC_SYS_CTRL, &reg);
	rt2x00_set_field32(&reg, MAC_SYS_CTRL_RESET_CSR, 1);
	rt2x00_set_field32(&reg, MAC_SYS_CTRL_RESET_BBP, 1);
	rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, reg);

	rt2800_register_write(rt2x00dev, USB_DMA_CFG, 0x00000000);

	rt2x00usb_vendor_request_sw(rt2x00dev, USB_DEVICE_MODE, 0,
				    USB_MODE_RESET, REGISTER_TIMEOUT);

	rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, 0x00000000);

	return 0;
}
Exemplo n.º 9
0
/*
 * Device state switch handlers.
 */
static void rt2800pci_toggle_irq(struct rt2x00_dev *rt2x00dev,
				 enum dev_state state)
{
	int mask = (state == STATE_RADIO_IRQ_ON) ||
		   (state == STATE_RADIO_IRQ_ON_ISR);
	u32 reg;

	/*
	 * When interrupts are being enabled, the interrupt registers
	 * should clear the register to assure a clean state.
	 */
	if (state == STATE_RADIO_IRQ_ON) {
		rt2800_register_read(rt2x00dev, INT_SOURCE_CSR, &reg);
		rt2800_register_write(rt2x00dev, INT_SOURCE_CSR, reg);
	}

	rt2800_register_read(rt2x00dev, INT_MASK_CSR, &reg);
	rt2x00_set_field32(&reg, INT_MASK_CSR_RXDELAYINT, 0);
	rt2x00_set_field32(&reg, INT_MASK_CSR_TXDELAYINT, 0);
	rt2x00_set_field32(&reg, INT_MASK_CSR_RX_DONE, mask);
	rt2x00_set_field32(&reg, INT_MASK_CSR_AC0_DMA_DONE, 0);
	rt2x00_set_field32(&reg, INT_MASK_CSR_AC1_DMA_DONE, 0);
	rt2x00_set_field32(&reg, INT_MASK_CSR_AC2_DMA_DONE, 0);
	rt2x00_set_field32(&reg, INT_MASK_CSR_AC3_DMA_DONE, 0);
	rt2x00_set_field32(&reg, INT_MASK_CSR_HCCA_DMA_DONE, 0);
	rt2x00_set_field32(&reg, INT_MASK_CSR_MGMT_DMA_DONE, 0);
	rt2x00_set_field32(&reg, INT_MASK_CSR_MCU_COMMAND, 0);
	rt2x00_set_field32(&reg, INT_MASK_CSR_RXTX_COHERENT, 0);
	rt2x00_set_field32(&reg, INT_MASK_CSR_TBTT, mask);
	rt2x00_set_field32(&reg, INT_MASK_CSR_PRE_TBTT, mask);
	rt2x00_set_field32(&reg, INT_MASK_CSR_TX_FIFO_STATUS, mask);
	rt2x00_set_field32(&reg, INT_MASK_CSR_AUTO_WAKEUP, mask);
	rt2x00_set_field32(&reg, INT_MASK_CSR_GPTIMER, 0);
	rt2x00_set_field32(&reg, INT_MASK_CSR_RX_COHERENT, 0);
	rt2x00_set_field32(&reg, INT_MASK_CSR_TX_COHERENT, 0);
	rt2800_register_write(rt2x00dev, INT_MASK_CSR, reg);
}
Exemplo n.º 10
0
static int rt2800pci_wait_wpdma_ready(struct rt2x00_dev *rt2x00dev)
{
	unsigned int i;
	u32 reg;

	for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
		rt2800_register_read(rt2x00dev, WPDMA_GLO_CFG, &reg);
		if (!rt2x00_get_field32(reg, WPDMA_GLO_CFG_TX_DMA_BUSY) &&
		    !rt2x00_get_field32(reg, WPDMA_GLO_CFG_RX_DMA_BUSY))
			return 0;

		msleep(1);
	}

	ERROR(rt2x00dev, "WPDMA TX/RX busy, aborting.\n");
	return -EACCES;
}
Exemplo n.º 11
0
static void rt2800pci_kill_tx_queue(struct rt2x00_dev *rt2x00dev,
				    const enum data_queue_qid qid)
{
	u32 reg;

	if (qid == QID_BEACON) {
		rt2800_register_write(rt2x00dev, BCN_TIME_CFG, 0);
		return;
	}

	rt2800_register_read(rt2x00dev, WPDMA_RST_IDX, &reg);
	rt2x00_set_field32(&reg, WPDMA_RST_IDX_DTX_IDX0, (qid == QID_AC_BE));
	rt2x00_set_field32(&reg, WPDMA_RST_IDX_DTX_IDX1, (qid == QID_AC_BK));
	rt2x00_set_field32(&reg, WPDMA_RST_IDX_DTX_IDX2, (qid == QID_AC_VI));
	rt2x00_set_field32(&reg, WPDMA_RST_IDX_DTX_IDX3, (qid == QID_AC_VO));
	rt2800_register_write(rt2x00dev, WPDMA_RST_IDX, reg);
}
Exemplo n.º 12
0
static void rt2800usb_disable_radio(struct rt2x00_dev *rt2x00dev)
{
	u32 reg;

	rt2800_register_read(rt2x00dev, WPDMA_GLO_CFG, &reg);
	rt2x00_set_field32(&reg, WPDMA_GLO_CFG_ENABLE_TX_DMA, 0);
	rt2x00_set_field32(&reg, WPDMA_GLO_CFG_ENABLE_RX_DMA, 0);
	rt2800_register_write(rt2x00dev, WPDMA_GLO_CFG, reg);

	rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, 0);
	rt2800_register_write(rt2x00dev, PWR_PIN_CFG, 0);
	rt2800_register_write(rt2x00dev, TX_PIN_CFG, 0);

	/* Wait for DMA, ignore error */
	rt2800_wait_wpdma_ready(rt2x00dev);

	rt2x00usb_disable_radio(rt2x00dev);
}
Exemplo n.º 13
0
static void rt2800usb_kick_tx_queue(struct rt2x00_dev *rt2x00dev,
				    const enum data_queue_qid queue)
{
	u32 reg;

	if (queue != QID_BEACON) {
		rt2x00usb_kick_tx_queue(rt2x00dev, queue);
		return;
	}

	rt2800_register_read(rt2x00dev, BCN_TIME_CFG, &reg);
	if (!rt2x00_get_field32(reg, BCN_TIME_CFG_BEACON_GEN)) {
		rt2x00_set_field32(&reg, BCN_TIME_CFG_TSF_TICKING, 1);
		rt2x00_set_field32(&reg, BCN_TIME_CFG_TBTT_ENABLE, 1);
		rt2x00_set_field32(&reg, BCN_TIME_CFG_BEACON_GEN, 1);
		rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg);
	}
}
Exemplo n.º 14
0
/*
 * TX data initialization
 */
static void rt2800usb_write_beacon(struct queue_entry *entry,
				   struct txentry_desc *txdesc)
{
	struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
	unsigned int beacon_base;
	u32 reg;

	/*
	 * Disable beaconing while we are reloading the beacon data,
	 * otherwise we might be sending out invalid data.
	 */
	rt2800_register_read(rt2x00dev, BCN_TIME_CFG, &reg);
	rt2x00_set_field32(&reg, BCN_TIME_CFG_BEACON_GEN, 0);
	rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg);

	/*
	 * Add the TXWI for the beacon to the skb.
	 */
	rt2800_write_txwi(entry->skb, txdesc);
	skb_push(entry->skb, TXWI_DESC_SIZE);

	/*
	 * Write entire beacon with descriptor to register.
	 */
	beacon_base = HW_BEACON_OFFSET(entry->entry_idx);
	rt2x00usb_vendor_request_large_buff(rt2x00dev, USB_MULTI_WRITE,
					    USB_VENDOR_REQUEST_OUT, beacon_base,
					    entry->skb->data, entry->skb->len,
					    REGISTER_TIMEOUT32(entry->skb->len));

	/*
	 * Enable beaconing again.
	 */
	rt2x00_set_field32(&reg, BCN_TIME_CFG_TSF_TICKING, 1);
	rt2x00_set_field32(&reg, BCN_TIME_CFG_TBTT_ENABLE, 1);
	rt2x00_set_field32(&reg, BCN_TIME_CFG_BEACON_GEN, 1);
	rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg);

	/*
	 * Clean up the beacon skb.
	 */
	dev_kfree_skb(entry->skb);
	entry->skb = NULL;
}
Exemplo n.º 15
0
static void rt2800pci_disable_radio(struct rt2x00_dev *rt2x00dev)
{
	u32 reg;

	rt2800_disable_radio(rt2x00dev);

	rt2800_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00001280);

	rt2800_register_read(rt2x00dev, WPDMA_RST_IDX, &reg);
	rt2x00_set_field32(&reg, WPDMA_RST_IDX_DTX_IDX0, 1);
	rt2x00_set_field32(&reg, WPDMA_RST_IDX_DTX_IDX1, 1);
	rt2x00_set_field32(&reg, WPDMA_RST_IDX_DTX_IDX2, 1);
	rt2x00_set_field32(&reg, WPDMA_RST_IDX_DTX_IDX3, 1);
	rt2x00_set_field32(&reg, WPDMA_RST_IDX_DTX_IDX4, 1);
	rt2x00_set_field32(&reg, WPDMA_RST_IDX_DTX_IDX5, 1);
	rt2x00_set_field32(&reg, WPDMA_RST_IDX_DRX_IDX0, 1);
	rt2800_register_write(rt2x00dev, WPDMA_RST_IDX, reg);

	rt2800_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00000e1f);
	rt2800_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00000e00);
}
Exemplo n.º 16
0
static void rt2800pci_txstatus_interrupt(struct rt2x00_dev *rt2x00dev)
{
	u32 status;
	int i;

	/*
	 * The TX_FIFO_STATUS interrupt needs special care. We should
	 * read TX_STA_FIFO but we should do it immediately as otherwise
	 * the register can overflow and we would lose status reports.
	 *
	 * Hence, read the TX_STA_FIFO register and copy all tx status
	 * reports into a kernel FIFO which is handled in the txstatus
	 * tasklet. We use a tasklet to process the tx status reports
	 * because we can schedule the tasklet multiple times (when the
	 * interrupt fires again during tx status processing).
	 *
	 * Furthermore we don't disable the TX_FIFO_STATUS
	 * interrupt here but leave it enabled so that the TX_STA_FIFO
	 * can also be read while the interrupt thread gets executed.
	 *
	 * Since we have only one producer and one consumer we don't
	 * need to lock the kfifo.
	 */
	for (i = 0; i < rt2x00dev->ops->tx->entry_num; i++) {
		rt2800_register_read(rt2x00dev, TX_STA_FIFO, &status);

		if (!rt2x00_get_field32(status, TX_STA_FIFO_VALID))
			break;

		if (!kfifo_put(&rt2x00dev->txstatus_fifo, &status)) {
			WARNING(rt2x00dev, "TX status FIFO overrun,"
				"drop tx status report.\n");
			break;
		}
	}

	/* Schedule the tasklet for processing the tx status. */
	tasklet_schedule(&rt2x00dev->txstatus_tasklet);
}
Exemplo n.º 17
0
static int rt2800usb_enable_radio(struct rt2x00_dev *rt2x00dev)
{
	u32 reg;

	if (unlikely(rt2800_wait_wpdma_ready(rt2x00dev)))
		return -EIO;

	rt2800_register_read(rt2x00dev, USB_DMA_CFG, &reg);
	rt2x00_set_field32(&reg, USB_DMA_CFG_PHY_CLEAR, 0);
	rt2x00_set_field32(&reg, USB_DMA_CFG_RX_BULK_AGG_EN, 0);
	rt2x00_set_field32(&reg, USB_DMA_CFG_RX_BULK_AGG_TIMEOUT, 128);
	/*
	 * Total room for RX frames in kilobytes, PBF might still exceed
	 * this limit so reduce the number to prevent errors.
	 */
	rt2x00_set_field32(&reg, USB_DMA_CFG_RX_BULK_AGG_LIMIT,
			   ((RX_ENTRIES * DATA_FRAME_SIZE) / 1024) - 3);
	rt2x00_set_field32(&reg, USB_DMA_CFG_RX_BULK_EN, 1);
	rt2x00_set_field32(&reg, USB_DMA_CFG_TX_BULK_EN, 1);
	rt2800_register_write(rt2x00dev, USB_DMA_CFG, reg);

	return rt2800_enable_radio(rt2x00dev);
}
Exemplo n.º 18
0
/*
 * TX data initialization
 */
static void rt2800usb_write_beacon(struct queue_entry *entry)
{
	struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
	struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
	unsigned int beacon_base;
	u32 reg;

	/*
	 * Add the descriptor in front of the skb.
	 */
	skb_push(entry->skb, entry->queue->desc_size);
	memcpy(entry->skb->data, skbdesc->desc, skbdesc->desc_len);
	skbdesc->desc = entry->skb->data;

	/*
	 * Disable beaconing while we are reloading the beacon data,
	 * otherwise we might be sending out invalid data.
	 */
	rt2800_register_read(rt2x00dev, BCN_TIME_CFG, &reg);
	rt2x00_set_field32(&reg, BCN_TIME_CFG_BEACON_GEN, 0);
	rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg);

	/*
	 * Write entire beacon with descriptor to register.
	 */
	beacon_base = HW_BEACON_OFFSET(entry->entry_idx);
	rt2x00usb_vendor_request_large_buff(rt2x00dev, USB_MULTI_WRITE,
					    USB_VENDOR_REQUEST_OUT, beacon_base,
					    entry->skb->data, entry->skb->len,
					    REGISTER_TIMEOUT32(entry->skb->len));

	/*
	 * Clean up the beacon skb.
	 */
	dev_kfree_skb(entry->skb);
	entry->skb = NULL;
}
Exemplo n.º 19
0
/*
 * Interrupt functions.
 */
static void rt2800pci_txdone(struct rt2x00_dev *rt2x00dev)
{
	struct data_queue *queue;
	struct queue_entry *entry;
	struct queue_entry *entry_done;
	struct queue_entry_priv_pci *entry_priv;
	struct txdone_entry_desc txdesc;
	u32 word;
	u32 reg;
	u32 old_reg;
	unsigned int type;
	unsigned int index;
	u16 mcs, real_mcs;

	/*
	 * During each loop we will compare the freshly read
	 * TX_STA_FIFO register value with the value read from
	 * the previous loop. If the 2 values are equal then
	 * we should stop processing because the chance it
	 * quite big that the device has been unplugged and
	 * we risk going into an endless loop.
	 */
	old_reg = 0;

	while (1) {
		rt2800_register_read(rt2x00dev, TX_STA_FIFO, &reg);
		if (!rt2x00_get_field32(reg, TX_STA_FIFO_VALID))
			break;

		if (old_reg == reg)
			break;
		old_reg = reg;

		/*
		 * Skip this entry when it contains an invalid
		 * queue identication number.
		 */
		type = rt2x00_get_field32(reg, TX_STA_FIFO_PID_TYPE) - 1;
		if (type >= QID_RX)
			continue;

		queue = rt2x00queue_get_queue(rt2x00dev, type);
		if (unlikely(!queue))
			continue;

		/*
		 * Skip this entry when it contains an invalid
		 * index number.
		 */
		index = rt2x00_get_field32(reg, TX_STA_FIFO_WCID) - 1;
		if (unlikely(index >= queue->limit))
			continue;

		entry = &queue->entries[index];
		entry_priv = entry->priv_data;
		rt2x00_desc_read((__le32 *)entry->skb->data, 0, &word);

		entry_done = rt2x00queue_get_entry(queue, Q_INDEX_DONE);
		while (entry != entry_done) {
			/*
			 * Catch up.
			 * Just report any entries we missed as failed.
			 */
			WARNING(rt2x00dev,
				"TX status report missed for entry %d\n",
				entry_done->entry_idx);

			txdesc.flags = 0;
			__set_bit(TXDONE_UNKNOWN, &txdesc.flags);
			txdesc.retry = 0;

			rt2x00lib_txdone(entry_done, &txdesc);
			entry_done = rt2x00queue_get_entry(queue, Q_INDEX_DONE);
		}

		/*
		 * Obtain the status about this packet.
		 */
		txdesc.flags = 0;
		if (rt2x00_get_field32(reg, TX_STA_FIFO_TX_SUCCESS))
			__set_bit(TXDONE_SUCCESS, &txdesc.flags);
		else
			__set_bit(TXDONE_FAILURE, &txdesc.flags);

		/*
		 * Ralink has a retry mechanism using a global fallback
		 * table. We setup this fallback table to try immediate
		 * lower rate for all rates. In the TX_STA_FIFO,
		 * the MCS field contains the MCS used for the successfull
		 * transmission. If the first transmission succeed,
		 * we have mcs == tx_mcs. On the second transmission,
		 * we have mcs = tx_mcs - 1. So the number of
		 * retry is (tx_mcs - mcs).
		 */
		mcs = rt2x00_get_field32(word, TXWI_W0_MCS);
		real_mcs = rt2x00_get_field32(reg, TX_STA_FIFO_MCS);
		__set_bit(TXDONE_FALLBACK, &txdesc.flags);
		txdesc.retry = mcs - min(mcs, real_mcs);

		rt2x00lib_txdone(entry, &txdesc);
	}
}
Exemplo n.º 20
0
/*
 * Interrupt functions.
 */
static void rt2800pci_wakeup(struct rt2x00_dev *rt2x00dev)
{
	struct ieee80211_conf conf = { .flags = 0 };
	struct rt2x00lib_conf libconf = { .conf = &conf };

	rt2800_config(rt2x00dev, &libconf, IEEE80211_CONF_CHANGE_PS);
}

static void rt2800pci_txdone(struct rt2x00_dev *rt2x00dev)
{
	struct data_queue *queue;
	struct queue_entry *entry;
	u32 status;
	u8 qid;

	while (kfifo_get(&rt2x00dev->txstatus_fifo, &status)) {
		qid = rt2x00_get_field32(status, TX_STA_FIFO_PID_QUEUE);
		if (qid >= QID_RX) {
			/*
			 * Unknown queue, this shouldn't happen. Just drop
			 * this tx status.
			 */
			WARNING(rt2x00dev, "Got TX status report with "
					   "unexpected pid %u, dropping\n", qid);
			break;
		}

		queue = rt2x00queue_get_queue(rt2x00dev, qid);
		if (unlikely(queue == NULL)) {
			/*
			 * The queue is NULL, this shouldn't happen. Stop
			 * processing here and drop the tx status
			 */
			WARNING(rt2x00dev, "Got TX status for an unavailable "
					   "queue %u, dropping\n", qid);
			break;
		}

		if (rt2x00queue_empty(queue)) {
			/*
			 * The queue is empty. Stop processing here
			 * and drop the tx status.
			 */
			WARNING(rt2x00dev, "Got TX status for an empty "
					   "queue %u, dropping\n", qid);
			break;
		}

		entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE);
		rt2800_txdone_entry(entry, status);
	}
}

static void rt2800pci_enable_interrupt(struct rt2x00_dev *rt2x00dev,
				       struct rt2x00_field32 irq_field)
{
	unsigned long flags;
	u32 reg;

	/*
	 * Enable a single interrupt. The interrupt mask register
	 * access needs locking.
	 */
	spin_lock_irqsave(&rt2x00dev->irqmask_lock, flags);
	rt2800_register_read(rt2x00dev, INT_MASK_CSR, &reg);
	rt2x00_set_field32(&reg, irq_field, 1);
	rt2800_register_write(rt2x00dev, INT_MASK_CSR, reg);
	spin_unlock_irqrestore(&rt2x00dev->irqmask_lock, flags);
}
Exemplo n.º 21
0
static int rt2800usb_load_firmware(struct rt2x00_dev *rt2x00dev,
				   const u8 *data, const size_t len)
{
	unsigned int i;
	int status;
	u32 reg;
	u32 offset;
	u32 length;

	/*
	 * Check which section of the firmware we need.
	 */
	if (rt2x00_rt(rt2x00dev, RT2860) ||
	    rt2x00_rt(rt2x00dev, RT2872) ||
	    rt2x00_rt(rt2x00dev, RT3070)) {
		offset = 0;
		length = 4096;
	} else {
		offset = 4096;
		length = 4096;
	}

	/*
	 * Wait for stable hardware.
	 */
	for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
		rt2800_register_read(rt2x00dev, MAC_CSR0, &reg);
		if (reg && reg != ~0)
			break;
		msleep(1);
	}

	if (i == REGISTER_BUSY_COUNT) {
		ERROR(rt2x00dev, "Unstable hardware.\n");
		return -EBUSY;
	}

	/*
	 * Write firmware to device.
	 */
	rt2x00usb_vendor_request_large_buff(rt2x00dev, USB_MULTI_WRITE,
					    USB_VENDOR_REQUEST_OUT,
					    FIRMWARE_IMAGE_BASE,
					    data + offset, length,
					    REGISTER_TIMEOUT32(length));

	rt2800_register_write(rt2x00dev, H2M_MAILBOX_CID, ~0);
	rt2800_register_write(rt2x00dev, H2M_MAILBOX_STATUS, ~0);

	/*
	 * Send firmware request to device to load firmware,
	 * we need to specify a long timeout time.
	 */
	status = rt2x00usb_vendor_request_sw(rt2x00dev, USB_DEVICE_MODE,
					     0, USB_MODE_FIRMWARE,
					     REGISTER_TIMEOUT_FIRMWARE);
	if (status < 0) {
		ERROR(rt2x00dev, "Failed to write Firmware to device.\n");
		return status;
	}

	msleep(10);
	rt2800_register_write(rt2x00dev, H2M_MAILBOX_CSR, 0);

	/*
	 * Send signal to firmware during boot time.
	 */
	rt2800_mcu_request(rt2x00dev, MCU_BOOT_SIGNAL, 0xff, 0, 0);

	if (rt2x00_rt(rt2x00dev, RT3070) ||
	    rt2x00_rt(rt2x00dev, RT3071) ||
	    rt2x00_rt(rt2x00dev, RT3572)) {
		udelay(200);
		rt2800_mcu_request(rt2x00dev, MCU_CURRENT, 0, 0, 0);
		udelay(10);
	}

	/*
	 * Wait for device to stabilize.
	 */
	for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
		rt2800_register_read(rt2x00dev, PBF_SYS_CTRL, &reg);
		if (rt2x00_get_field32(reg, PBF_SYS_CTRL_READY))
			break;
		msleep(1);
	}

	if (i == REGISTER_BUSY_COUNT) {
		ERROR(rt2x00dev, "PBF system register not ready.\n");
		return -EBUSY;
	}

	/*
	 * Initialize firmware.
	 */
	rt2800_register_write(rt2x00dev, H2M_BBP_AGENT, 0);
	rt2800_register_write(rt2x00dev, H2M_MAILBOX_CSR, 0);
	msleep(1);

	return 0;
}
Exemplo n.º 22
0
static int rt2800pci_load_firmware(struct rt2x00_dev *rt2x00dev,
				   const u8 *data, const size_t len)
{
	unsigned int i;
	u32 reg;

	/*
	 * Wait for stable hardware.
	 */
	for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
		rt2800_register_read(rt2x00dev, MAC_CSR0, &reg);
		if (reg && reg != ~0)
			break;
		msleep(1);
	}

	if (i == REGISTER_BUSY_COUNT) {
		ERROR(rt2x00dev, "Unstable hardware.\n");
		return -EBUSY;
	}

	rt2800_register_write(rt2x00dev, PWR_PIN_CFG, 0x00000002);
	rt2800_register_write(rt2x00dev, AUTOWAKEUP_CFG, 0x00000000);

	/*
	 * Disable DMA, will be reenabled later when enabling
	 * the radio.
	 */
	rt2800_register_read(rt2x00dev, WPDMA_GLO_CFG, &reg);
	rt2x00_set_field32(&reg, WPDMA_GLO_CFG_ENABLE_TX_DMA, 0);
	rt2x00_set_field32(&reg, WPDMA_GLO_CFG_TX_DMA_BUSY, 0);
	rt2x00_set_field32(&reg, WPDMA_GLO_CFG_ENABLE_RX_DMA, 0);
	rt2x00_set_field32(&reg, WPDMA_GLO_CFG_RX_DMA_BUSY, 0);
	rt2x00_set_field32(&reg, WPDMA_GLO_CFG_TX_WRITEBACK_DONE, 1);
	rt2800_register_write(rt2x00dev, WPDMA_GLO_CFG, reg);

	/*
	 * enable Host program ram write selection
	 */
	reg = 0;
	rt2x00_set_field32(&reg, PBF_SYS_CTRL_HOST_RAM_WRITE, 1);
	rt2800_register_write(rt2x00dev, PBF_SYS_CTRL, reg);

	/*
	 * Write firmware to device.
	 */
	rt2800_register_multiwrite(rt2x00dev, FIRMWARE_IMAGE_BASE,
				      data, len);

	rt2800_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00000);
	rt2800_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00001);

	/*
	 * Wait for device to stabilize.
	 */
	for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
		rt2800_register_read(rt2x00dev, PBF_SYS_CTRL, &reg);
		if (rt2x00_get_field32(reg, PBF_SYS_CTRL_READY))
			break;
		msleep(1);
	}

	if (i == REGISTER_BUSY_COUNT) {
		ERROR(rt2x00dev, "PBF system register not ready.\n");
		return -EBUSY;
	}

	/*
	 * Disable interrupts
	 */
	rt2x00dev->ops->lib->set_device_state(rt2x00dev, STATE_RADIO_IRQ_OFF);

	/*
	 * Initialize BBP R/W access agent
	 */
	rt2800_register_write(rt2x00dev, H2M_BBP_AGENT, 0);
	rt2800_register_write(rt2x00dev, H2M_MAILBOX_CSR, 0);

	return 0;
}
Exemplo n.º 23
0
static int rt2800usb_enable_radio(struct rt2x00_dev *rt2x00dev)
{
	u32 reg;
	u16 word;

	/*
	 * Initialize all registers.
	 */
	if (unlikely(rt2800_wait_wpdma_ready(rt2x00dev) ||
		     rt2800_init_registers(rt2x00dev) ||
		     rt2800_init_bbp(rt2x00dev) ||
		     rt2800_init_rfcsr(rt2x00dev)))
		return -EIO;

	rt2800_register_read(rt2x00dev, MAC_SYS_CTRL, &reg);
	rt2x00_set_field32(&reg, MAC_SYS_CTRL_ENABLE_TX, 1);
	rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, reg);

	udelay(50);

	rt2800_register_read(rt2x00dev, WPDMA_GLO_CFG, &reg);
	rt2x00_set_field32(&reg, WPDMA_GLO_CFG_TX_WRITEBACK_DONE, 1);
	rt2x00_set_field32(&reg, WPDMA_GLO_CFG_ENABLE_RX_DMA, 1);
	rt2x00_set_field32(&reg, WPDMA_GLO_CFG_ENABLE_TX_DMA, 1);
	rt2800_register_write(rt2x00dev, WPDMA_GLO_CFG, reg);


	rt2800_register_read(rt2x00dev, USB_DMA_CFG, &reg);
	rt2x00_set_field32(&reg, USB_DMA_CFG_PHY_CLEAR, 0);
	rt2x00_set_field32(&reg, USB_DMA_CFG_RX_BULK_AGG_EN, 0);
	rt2x00_set_field32(&reg, USB_DMA_CFG_RX_BULK_AGG_TIMEOUT, 128);
	/*
	 * Total room for RX frames in kilobytes, PBF might still exceed
	 * this limit so reduce the number to prevent errors.
	 */
	rt2x00_set_field32(&reg, USB_DMA_CFG_RX_BULK_AGG_LIMIT,
			   ((RX_ENTRIES * DATA_FRAME_SIZE) / 1024) - 3);
	rt2x00_set_field32(&reg, USB_DMA_CFG_RX_BULK_EN, 1);
	rt2x00_set_field32(&reg, USB_DMA_CFG_TX_BULK_EN, 1);
	rt2800_register_write(rt2x00dev, USB_DMA_CFG, reg);

	rt2800_register_read(rt2x00dev, MAC_SYS_CTRL, &reg);
	rt2x00_set_field32(&reg, MAC_SYS_CTRL_ENABLE_TX, 1);
	rt2x00_set_field32(&reg, MAC_SYS_CTRL_ENABLE_RX, 1);
	rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, reg);

	/*
	 * Initialize LED control
	 */
	rt2x00_eeprom_read(rt2x00dev, EEPROM_LED1, &word);
	rt2800_mcu_request(rt2x00dev, MCU_LED_1, 0xff,
			      word & 0xff, (word >> 8) & 0xff);

	rt2x00_eeprom_read(rt2x00dev, EEPROM_LED2, &word);
	rt2800_mcu_request(rt2x00dev, MCU_LED_2, 0xff,
			      word & 0xff, (word >> 8) & 0xff);

	rt2x00_eeprom_read(rt2x00dev, EEPROM_LED3, &word);
	rt2800_mcu_request(rt2x00dev, MCU_LED_3, 0xff,
			      word & 0xff, (word >> 8) & 0xff);

	return 0;
}