/* * Device state switch handlers. */ static int rt2800usb_init_registers(struct rt2x00_dev *rt2x00dev) { u32 reg; /* * Wait until BBP and RF are ready. */ if (rt2800_wait_csr_ready(rt2x00dev)) return -EBUSY; rt2x00usb_register_read(rt2x00dev, PBF_SYS_CTRL, ®); rt2x00usb_register_write(rt2x00dev, PBF_SYS_CTRL, reg & ~0x00002000); rt2x00usb_register_write(rt2x00dev, PWR_PIN_CFG, 0x00000003); rt2x00usb_register_read(rt2x00dev, MAC_SYS_CTRL, ®); rt2x00_set_field32(®, MAC_SYS_CTRL_RESET_CSR, 1); rt2x00_set_field32(®, MAC_SYS_CTRL_RESET_BBP, 1); rt2x00usb_register_write(rt2x00dev, MAC_SYS_CTRL, reg); rt2x00usb_register_write(rt2x00dev, USB_DMA_CFG, 0x00000000); rt2x00usb_vendor_request_sw(rt2x00dev, USB_DEVICE_MODE, 0, USB_MODE_RESET, REGISTER_TIMEOUT); rt2x00usb_register_write(rt2x00dev, MAC_SYS_CTRL, 0x00000000); return 0; }
static void rt2800usb_stop_queue(struct data_queue *queue) { struct rt2x00_dev *rt2x00dev = queue->rt2x00dev; u32 reg; switch (queue->qid) { case QID_RX: rt2x00usb_register_read(rt2x00dev, MAC_SYS_CTRL, ®); rt2x00_set_field32(®, MAC_SYS_CTRL_ENABLE_RX, 0); rt2x00usb_register_write(rt2x00dev, MAC_SYS_CTRL, reg); break; case QID_BEACON: rt2x00usb_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); rt2x00usb_register_write(rt2x00dev, BCN_TIME_CFG, reg); break; default: break; } }
/* * Watchdog handlers */ static void rt2800usb_watchdog(struct rt2x00_dev *rt2x00dev) { unsigned int i; u32 reg; rt2x00usb_register_read(rt2x00dev, TXRXQ_PCNT, ®); if (rt2x00_get_field32(reg, TXRXQ_PCNT_TX0Q)) { WARNING(rt2x00dev, "TX HW queue 0 timed out," " invoke forced kick\n"); rt2x00usb_register_write(rt2x00dev, PBF_CFG, 0xf40012); for (i = 0; i < 10; i++) { udelay(10); if (!rt2x00_get_field32(reg, TXRXQ_PCNT_TX0Q)) break; } rt2x00usb_register_write(rt2x00dev, PBF_CFG, 0xf40006); } rt2x00usb_register_read(rt2x00dev, TXRXQ_PCNT, ®); if (rt2x00_get_field32(reg, TXRXQ_PCNT_TX1Q)) { WARNING(rt2x00dev, "TX HW queue 1 timed out," " invoke forced kick\n"); rt2x00usb_register_write(rt2x00dev, PBF_CFG, 0xf4000a); for (i = 0; i < 10; i++) { udelay(10); if (!rt2x00_get_field32(reg, TXRXQ_PCNT_TX1Q)) break; } rt2x00usb_register_write(rt2x00dev, PBF_CFG, 0xf40006); } rt2x00usb_watchdog(rt2x00dev); }
static int rt2800usb_enable_radio(struct rt2x00_dev *rt2x00dev) { u32 reg; if (unlikely(rt2800_wait_wpdma_ready(rt2x00dev))) return -EIO; rt2x00usb_register_read(rt2x00dev, USB_DMA_CFG, ®); rt2x00_set_field32(®, USB_DMA_CFG_PHY_CLEAR, 0); rt2x00_set_field32(®, USB_DMA_CFG_RX_BULK_AGG_EN, 0); rt2x00_set_field32(®, 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(®, USB_DMA_CFG_RX_BULK_AGG_LIMIT, ((rt2x00dev->ops->rx->entry_num * DATA_FRAME_SIZE) / 1024) - 3); rt2x00_set_field32(®, USB_DMA_CFG_RX_BULK_EN, 1); rt2x00_set_field32(®, USB_DMA_CFG_TX_BULK_EN, 1); rt2x00usb_register_write(rt2x00dev, USB_DMA_CFG, reg); return rt2800_enable_radio(rt2x00dev); }
static int rt2800usb_probe_hw(struct rt2x00_dev *rt2x00dev) { int retval; u32 reg; /* * Allocate eeprom data. */ retval = rt2800usb_validate_eeprom(rt2x00dev); if (retval) return retval; retval = rt2800_init_eeprom(rt2x00dev); if (retval) return retval; /* * Enable rfkill polling by setting GPIO direction of the * rfkill switch GPIO pin correctly. */ rt2x00usb_register_read(rt2x00dev, GPIO_CTRL_CFG, ®); rt2x00_set_field32(®, GPIO_CTRL_CFG_GPIOD_BIT2, 1); rt2x00usb_register_write(rt2x00dev, GPIO_CTRL_CFG, reg); /* * Initialize hw specifications. */ retval = rt2800_probe_hw_mode(rt2x00dev); if (retval) return retval; /* * This device has multiple filters for control frames * and has a separate filter for PS Poll frames. */ __set_bit(CAPABILITY_CONTROL_FILTERS, &rt2x00dev->cap_flags); __set_bit(CAPABILITY_CONTROL_FILTER_PSPOLL, &rt2x00dev->cap_flags); /* * This device requires firmware. */ __set_bit(REQUIRE_FIRMWARE, &rt2x00dev->cap_flags); __set_bit(REQUIRE_L2PAD, &rt2x00dev->cap_flags); if (!modparam_nohwcrypt) __set_bit(CAPABILITY_HW_CRYPTO, &rt2x00dev->cap_flags); __set_bit(CAPABILITY_LINK_TUNING, &rt2x00dev->cap_flags); __set_bit(REQUIRE_HT_TX_DESC, &rt2x00dev->cap_flags); __set_bit(REQUIRE_TXSTATUS_FIFO, &rt2x00dev->cap_flags); __set_bit(REQUIRE_PS_AUTOWAKE, &rt2x00dev->cap_flags); setup_timer(&rt2x00dev->txstatus_timer, rt2800usb_tx_sta_fifo_timeout, (unsigned long) rt2x00dev); /* * Set the rssi offset. */ rt2x00dev->rssi_offset = DEFAULT_RSSI_OFFSET; /* * Overwrite TX done handler */ PREPARE_WORK(&rt2x00dev->txdone_work, rt2800usb_work_txdone); return 0; }