📄 rt73usb.c
字号:
buflen = min_t(int, len - i, CSR_CACHE_SIZE_FIRMWARE); timeout = REGISTER_TIMEOUT * (buflen / sizeof(u32)); memcpy(cache, ptr, buflen); rt2x00usb_vendor_request(rt2x00dev, USB_MULTI_WRITE, USB_VENDOR_REQUEST_OUT, FIRMWARE_IMAGE_BASE + i, 0x0000, cache, buflen, timeout); ptr += buflen; } kfree(cache); /* * 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, 0x0000, USB_MODE_FIRMWARE, REGISTER_TIMEOUT_FIRMWARE); if (status < 0) { ERROR(rt2x00dev, "Failed to write Firmware to device.\n"); return status; } rt73usb_disable_led(rt2x00dev); return 0;}static int rt73usb_init_registers(struct rt2x00_dev *rt2x00dev){ u32 reg; rt73usb_register_read(rt2x00dev, TXRX_CSR0, ®); rt2x00_set_field32(®, TXRX_CSR0_AUTO_TX_SEQ, 1); rt2x00_set_field32(®, TXRX_CSR0_DISABLE_RX, 0); rt2x00_set_field32(®, TXRX_CSR0_TX_WITHOUT_WAITING, 0); rt73usb_register_write(rt2x00dev, TXRX_CSR0, reg); rt73usb_register_read(rt2x00dev, TXRX_CSR1, ®); rt2x00_set_field32(®, TXRX_CSR1_BBP_ID0, 47); /* CCK Signal */ rt2x00_set_field32(®, TXRX_CSR1_BBP_ID0_VALID, 1); rt2x00_set_field32(®, TXRX_CSR1_BBP_ID1, 30); /* Rssi */ rt2x00_set_field32(®, TXRX_CSR1_BBP_ID1_VALID, 1); rt2x00_set_field32(®, TXRX_CSR1_BBP_ID2, 42); /* OFDM Rate */ rt2x00_set_field32(®, TXRX_CSR1_BBP_ID2_VALID, 1); rt2x00_set_field32(®, TXRX_CSR1_BBP_ID3, 30); /* Rssi */ rt2x00_set_field32(®, TXRX_CSR1_BBP_ID3_VALID, 1); rt73usb_register_write(rt2x00dev, TXRX_CSR1, reg); /* * CCK TXD BBP registers */ rt73usb_register_read(rt2x00dev, TXRX_CSR2, ®); rt2x00_set_field32(®, TXRX_CSR2_BBP_ID0, 13); rt2x00_set_field32(®, TXRX_CSR2_BBP_ID0_VALID, 1); rt2x00_set_field32(®, TXRX_CSR2_BBP_ID1, 12); rt2x00_set_field32(®, TXRX_CSR2_BBP_ID1_VALID, 1); rt2x00_set_field32(®, TXRX_CSR2_BBP_ID2, 11); rt2x00_set_field32(®, TXRX_CSR2_BBP_ID2_VALID, 1); rt2x00_set_field32(®, TXRX_CSR2_BBP_ID3, 10); rt2x00_set_field32(®, TXRX_CSR2_BBP_ID3_VALID, 1); rt73usb_register_write(rt2x00dev, TXRX_CSR2, reg); /* * OFDM TXD BBP registers */ rt73usb_register_read(rt2x00dev, TXRX_CSR3, ®); rt2x00_set_field32(®, TXRX_CSR3_BBP_ID0, 7); rt2x00_set_field32(®, TXRX_CSR3_BBP_ID0_VALID, 1); rt2x00_set_field32(®, TXRX_CSR3_BBP_ID1, 6); rt2x00_set_field32(®, TXRX_CSR3_BBP_ID1_VALID, 1); rt2x00_set_field32(®, TXRX_CSR3_BBP_ID2, 5); rt2x00_set_field32(®, TXRX_CSR3_BBP_ID2_VALID, 1); rt73usb_register_write(rt2x00dev, TXRX_CSR3, reg); rt73usb_register_read(rt2x00dev, TXRX_CSR7, ®); rt2x00_set_field32(®, TXRX_CSR7_ACK_CTS_6MBS, 59); rt2x00_set_field32(®, TXRX_CSR7_ACK_CTS_9MBS, 53); rt2x00_set_field32(®, TXRX_CSR7_ACK_CTS_12MBS, 49); rt2x00_set_field32(®, TXRX_CSR7_ACK_CTS_18MBS, 46); rt73usb_register_write(rt2x00dev, TXRX_CSR7, reg); rt73usb_register_read(rt2x00dev, TXRX_CSR8, ®); rt2x00_set_field32(®, TXRX_CSR8_ACK_CTS_24MBS, 44); rt2x00_set_field32(®, TXRX_CSR8_ACK_CTS_36MBS, 42); rt2x00_set_field32(®, TXRX_CSR8_ACK_CTS_48MBS, 42); rt2x00_set_field32(®, TXRX_CSR8_ACK_CTS_54MBS, 42); rt73usb_register_write(rt2x00dev, TXRX_CSR8, reg); rt73usb_register_write(rt2x00dev, TXRX_CSR15, 0x0000000f); rt73usb_register_read(rt2x00dev, MAC_CSR6, ®); rt2x00_set_field32(®, MAC_CSR6_MAX_FRAME_UNIT, 0xfff); rt73usb_register_write(rt2x00dev, MAC_CSR6, reg); rt73usb_register_write(rt2x00dev, MAC_CSR10, 0x00000718); if (rt2x00dev->ops->lib->set_device_state(rt2x00dev, STATE_AWAKE)) return -EBUSY; rt73usb_register_write(rt2x00dev, MAC_CSR13, 0x00007f00); /* * Invalidate all Shared Keys (SEC_CSR0), * and clear the Shared key Cipher algorithms (SEC_CSR1 & SEC_CSR5) */ rt73usb_register_write(rt2x00dev, SEC_CSR0, 0x00000000); rt73usb_register_write(rt2x00dev, SEC_CSR1, 0x00000000); rt73usb_register_write(rt2x00dev, SEC_CSR5, 0x00000000); reg = 0x000023b0; if (rt2x00_rf(&rt2x00dev->chip, RF5225) || rt2x00_rf(&rt2x00dev->chip, RF2527)) rt2x00_set_field32(®, PHY_CSR1_RF_RPI, 1); rt73usb_register_write(rt2x00dev, PHY_CSR1, reg); rt73usb_register_write(rt2x00dev, PHY_CSR5, 0x00040a06); rt73usb_register_write(rt2x00dev, PHY_CSR6, 0x00080606); rt73usb_register_write(rt2x00dev, PHY_CSR7, 0x00000408); rt73usb_register_read(rt2x00dev, AC_TXOP_CSR0, ®); rt2x00_set_field32(®, AC_TXOP_CSR0_AC0_TX_OP, 0); rt2x00_set_field32(®, AC_TXOP_CSR0_AC1_TX_OP, 0); rt73usb_register_write(rt2x00dev, AC_TXOP_CSR0, reg); rt73usb_register_read(rt2x00dev, AC_TXOP_CSR1, ®); rt2x00_set_field32(®, AC_TXOP_CSR1_AC2_TX_OP, 192); rt2x00_set_field32(®, AC_TXOP_CSR1_AC3_TX_OP, 48); rt73usb_register_write(rt2x00dev, AC_TXOP_CSR1, reg); rt73usb_register_read(rt2x00dev, MAC_CSR9, ®); rt2x00_set_field32(®, MAC_CSR9_CW_SELECT, 0); rt73usb_register_write(rt2x00dev, MAC_CSR9, reg); /* * We must clear the error counters. * These registers are cleared on read, * so we may pass a useless variable to store the value. */ rt73usb_register_read(rt2x00dev, STA_CSR0, ®); rt73usb_register_read(rt2x00dev, STA_CSR1, ®); rt73usb_register_read(rt2x00dev, STA_CSR2, ®); /* * Reset MAC and BBP registers. */ rt73usb_register_read(rt2x00dev, MAC_CSR1, ®); rt2x00_set_field32(®, MAC_CSR1_SOFT_RESET, 1); rt2x00_set_field32(®, MAC_CSR1_BBP_RESET, 1); rt73usb_register_write(rt2x00dev, MAC_CSR1, reg); rt73usb_register_read(rt2x00dev, MAC_CSR1, ®); rt2x00_set_field32(®, MAC_CSR1_SOFT_RESET, 0); rt2x00_set_field32(®, MAC_CSR1_BBP_RESET, 0); rt73usb_register_write(rt2x00dev, MAC_CSR1, reg); rt73usb_register_read(rt2x00dev, MAC_CSR1, ®); rt2x00_set_field32(®, MAC_CSR1_HOST_READY, 1); rt73usb_register_write(rt2x00dev, MAC_CSR1, reg); return 0;}static int rt73usb_init_bbp(struct rt2x00_dev *rt2x00dev){ unsigned int i; u16 eeprom; u8 reg_id; u8 value; for (i = 0; i < REGISTER_BUSY_COUNT; i++) { rt73usb_bbp_read(rt2x00dev, 0, &value); if ((value != 0xff) && (value != 0x00)) goto continue_csr_init; NOTICE(rt2x00dev, "Waiting for BBP register.\n"); udelay(REGISTER_BUSY_DELAY); } ERROR(rt2x00dev, "BBP register access failed, aborting.\n"); return -EACCES;continue_csr_init: rt73usb_bbp_write(rt2x00dev, 3, 0x80); rt73usb_bbp_write(rt2x00dev, 15, 0x30); rt73usb_bbp_write(rt2x00dev, 21, 0xc8); rt73usb_bbp_write(rt2x00dev, 22, 0x38); rt73usb_bbp_write(rt2x00dev, 23, 0x06); rt73usb_bbp_write(rt2x00dev, 24, 0xfe); rt73usb_bbp_write(rt2x00dev, 25, 0x0a); rt73usb_bbp_write(rt2x00dev, 26, 0x0d); rt73usb_bbp_write(rt2x00dev, 32, 0x0b); rt73usb_bbp_write(rt2x00dev, 34, 0x12); rt73usb_bbp_write(rt2x00dev, 37, 0x07); rt73usb_bbp_write(rt2x00dev, 39, 0xf8); rt73usb_bbp_write(rt2x00dev, 41, 0x60); rt73usb_bbp_write(rt2x00dev, 53, 0x10); rt73usb_bbp_write(rt2x00dev, 54, 0x18); rt73usb_bbp_write(rt2x00dev, 60, 0x10); rt73usb_bbp_write(rt2x00dev, 61, 0x04); rt73usb_bbp_write(rt2x00dev, 62, 0x04); rt73usb_bbp_write(rt2x00dev, 75, 0xfe); rt73usb_bbp_write(rt2x00dev, 86, 0xfe); rt73usb_bbp_write(rt2x00dev, 88, 0xfe); rt73usb_bbp_write(rt2x00dev, 90, 0x0f); rt73usb_bbp_write(rt2x00dev, 99, 0x00); rt73usb_bbp_write(rt2x00dev, 102, 0x16); rt73usb_bbp_write(rt2x00dev, 107, 0x04); DEBUG(rt2x00dev, "Start initialization from EEPROM...\n"); for (i = 0; i < EEPROM_BBP_SIZE; i++) { rt2x00_eeprom_read(rt2x00dev, EEPROM_BBP_START + i, &eeprom); if (eeprom != 0xffff && eeprom != 0x0000) { reg_id = rt2x00_get_field16(eeprom, EEPROM_BBP_REG_ID); value = rt2x00_get_field16(eeprom, EEPROM_BBP_VALUE); DEBUG(rt2x00dev, "BBP: 0x%02x, value: 0x%02x.\n", reg_id, value); rt73usb_bbp_write(rt2x00dev, reg_id, value); } } DEBUG(rt2x00dev, "...End initialization from EEPROM.\n"); return 0;}/* * Device state switch handlers. */static void rt73usb_toggle_rx(struct rt2x00_dev *rt2x00dev, enum dev_state state){ u32 reg; rt73usb_register_read(rt2x00dev, TXRX_CSR0, ®); rt2x00_set_field32(®, TXRX_CSR0_DISABLE_RX, state == STATE_RADIO_RX_OFF); rt73usb_register_write(rt2x00dev, TXRX_CSR0, reg);}static int rt73usb_enable_radio(struct rt2x00_dev *rt2x00dev){ /* * Initialize all registers. */ if (rt73usb_init_registers(rt2x00dev) || rt73usb_init_bbp(rt2x00dev)) { ERROR(rt2x00dev, "Register initialization failed.\n"); return -EIO; } rt2x00usb_enable_radio(rt2x00dev); /* * Enable LED */ rt73usb_enable_led(rt2x00dev); return 0;}static void rt73usb_disable_radio(struct rt2x00_dev *rt2x00dev){ /* * Disable LED */ rt73usb_disable_led(rt2x00dev); rt73usb_register_write(rt2x00dev, MAC_CSR10, 0x00001818); /* * Disable synchronisation. */ rt73usb_register_write(rt2x00dev, TXRX_CSR9, 0); rt2x00usb_disable_radio(rt2x00dev);}static int rt73usb_set_state(struct rt2x00_dev *rt2x00dev, enum dev_state state){ u32 reg; unsigned int i; char put_to_sleep; char current_state; put_to_sleep = (state != STATE_AWAKE); rt73usb_register_read(rt2x00dev, MAC_CSR12, ®); rt2x00_set_field32(®, MAC_CSR12_FORCE_WAKEUP, !put_to_sleep); rt2x00_set_field32(®, MAC_CSR12_PUT_TO_SLEEP, put_to_sleep); rt73usb_register_write(rt2x00dev, MAC_CSR12, reg); /* * Device is not guaranteed to be in the requested state yet. * We must wait until the register indicates that the * device has entered the correct state. */ for (i = 0; i < REGISTER_BUSY_COUNT; i++) { rt73usb_register_read(rt2x00dev, MAC_CSR12, ®); current_state = rt2x00_get_field32(reg, MAC_CSR12_BBP_CURRENT_STATE); if (current_state == !put_to_sleep) return 0; msleep(10); } NOTICE(rt2x00dev, "Device failed to enter state %d, " "current device state %d.\n", !put_to_sleep, current_state); return -EBUSY;}static int rt73usb_set_device_state(struct rt2x00_dev *rt2x00dev, enum dev_state state){ int retval = 0; switch (state) { case STATE_RADIO_ON: retval = rt73usb_enable_radio(rt2x00dev); break; case STATE_RADIO_OFF: rt73usb_disable_radio(rt2x00dev); break; case STATE_RADIO_RX_ON: case STATE_RADIO_RX_OFF: rt73usb_toggle_rx(rt2x00dev, state); break; case STATE_DEEP_SLEEP: case STATE_SLEEP: case STATE_STANDBY: case STATE_AWAKE: retval = rt73usb_set_state(rt2x00dev, state); break; default: retval = -ENOTSUPP; break; } return retval;}/* * TX descriptor initialization */static void rt73usb_write_tx_desc(struct rt2x00_dev *rt2x00dev, struct data_desc *txd, struct txdata_entry_desc *desc, struct ieee80211_hdr *ieee80211hdr, unsigned int length, struct ieee80211_tx_control *control){ u32 word; /* * Start writing the descriptor words. */ rt2x00_desc_read(txd, 1, &word); rt2x00_set_field32(&word, TXD_W1_HOST_Q_ID, desc->queue); rt2x00_set_field32(&word, TXD_W1_AIFSN, desc->aifs); rt2x00_set_field32(&word, TXD_W1_CWMIN, desc->cw_min); rt2x00_set_field32(&word, TXD_W1_CWMAX, desc->cw_max); rt2x00_set_field32(&word, TXD_W1_IV_OFFSET, IEEE80211_HEADER); rt2x00_set_field32(&word, TXD_W1_HW_SEQUENCE, 1); rt2x00_desc_write(txd, 1, word); rt2x00_desc_read(txd, 2, &word); rt2x00_set_field32(&word, TXD_W2_PLCP_SIGNAL, desc->signal); rt2x00_set_field32(&word, TXD_W2_PLCP_SERVICE, desc->service); rt2x00_set_field32(&word, TXD_W2_PLCP_LENGTH_LOW, desc->length_low); rt2x00_set_field32(&word, TXD_W2_PLCP_LENGTH_HIGH, desc->length_high); rt2x00_desc_write(txd, 2, word); rt2x00_desc_read(txd, 5, &word); rt2x00_set_field32(&word, TXD_W5_TX_POWER, TXPOWER_TO_DEV(control->power_level)); rt2x00_set_field32(&word, TXD_W5_WAITING_DMA_DONE_INT, 1); rt2x00_desc_write(txd, 5, word); rt2x00_desc_read(txd, 0, &word); rt2x00_set_field32(&word, TXD_W0_BURST, test_bit(ENTRY_TXD_BURST, &desc->flags)); rt2x00_set_field32(&word, TXD_W0_VALID, 1); rt2x00_set_field32(&word, TXD_W0_MORE_FRAG, test_bit(ENTRY_TXD_MORE_FRAG, &desc->flags)); rt2x00_set_field32(&word, TXD_W0_ACK, !(control->flags & IEEE80211_TXCTL_NO_ACK)); rt2x00_set_field32(&word, TXD_W0_TIMESTAMP, test_bit(ENTRY_TXD_REQ_TIMESTAMP, &desc->flags)); rt2x00_set_field32(&word, TXD_W0_OFDM, test_bit(ENTRY_TXD_OFDM_RATE, &desc->flags)); rt2x00_set_field32(&word, TXD_W0_IFS, desc->ifs); rt2x00_set_field32(&word, TXD_W0_RETRY_MODE, !!(control->flags & IEEE80211_TXCTL_LONG_RETRY_LIMIT)); rt2x00_set_field32(&word, TXD_W0_TKIP_MIC, 0); rt2x00_set_field32(&word, TXD_W0_DATABYTE_COUNT, length); rt2x00_set_field32(&word, TXD_W0_BURST2, test_bit(ENTRY_TXD_BURST, &desc->flags)); rt2x00_set_field32(&word, TXD_W0_CIPHER_ALG, CIPHER_NONE); rt2x00_desc_write(txd, 0, word);}static int rt73usb_get_tx_data_len(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb){ int length; /* * The length _must_ be a multiple of 4, * but it must _not_ be a multiple of the USB packet size. */ length = roundup(skb->len, 4); length += (4 * !(length % rt2x00dev->usb_maxpacket)); return length;}/* * TX data initialization
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -