162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci Copyright (C) 2009 - 2010 Ivo van Doorn <IvDoorn@gmail.com> 462306a36Sopenharmony_ci Copyright (C) 2009 Alban Browaeys <prahal@yahoo.com> 562306a36Sopenharmony_ci Copyright (C) 2009 Felix Fietkau <nbd@openwrt.org> 662306a36Sopenharmony_ci Copyright (C) 2009 Luis Correia <luis.f.correia@gmail.com> 762306a36Sopenharmony_ci Copyright (C) 2009 Mattias Nissler <mattias.nissler@gmx.de> 862306a36Sopenharmony_ci Copyright (C) 2009 Mark Asselstine <asselsm@gmail.com> 962306a36Sopenharmony_ci Copyright (C) 2009 Xose Vazquez Perez <xose.vazquez@gmail.com> 1062306a36Sopenharmony_ci Copyright (C) 2009 Bart Zolnierkiewicz <bzolnier@gmail.com> 1162306a36Sopenharmony_ci <http://rt2x00.serialmonkey.com> 1262306a36Sopenharmony_ci 1362306a36Sopenharmony_ci */ 1462306a36Sopenharmony_ci 1562306a36Sopenharmony_ci/* 1662306a36Sopenharmony_ci Module: rt2800pci 1762306a36Sopenharmony_ci Abstract: rt2800pci device specific routines. 1862306a36Sopenharmony_ci Supported chipsets: RT2800E & RT2800ED. 1962306a36Sopenharmony_ci */ 2062306a36Sopenharmony_ci 2162306a36Sopenharmony_ci#include <linux/delay.h> 2262306a36Sopenharmony_ci#include <linux/etherdevice.h> 2362306a36Sopenharmony_ci#include <linux/init.h> 2462306a36Sopenharmony_ci#include <linux/kernel.h> 2562306a36Sopenharmony_ci#include <linux/module.h> 2662306a36Sopenharmony_ci#include <linux/pci.h> 2762306a36Sopenharmony_ci#include <linux/eeprom_93cx6.h> 2862306a36Sopenharmony_ci 2962306a36Sopenharmony_ci#include "rt2x00.h" 3062306a36Sopenharmony_ci#include "rt2x00mmio.h" 3162306a36Sopenharmony_ci#include "rt2x00pci.h" 3262306a36Sopenharmony_ci#include "rt2800lib.h" 3362306a36Sopenharmony_ci#include "rt2800mmio.h" 3462306a36Sopenharmony_ci#include "rt2800.h" 3562306a36Sopenharmony_ci#include "rt2800pci.h" 3662306a36Sopenharmony_ci 3762306a36Sopenharmony_ci/* 3862306a36Sopenharmony_ci * Allow hardware encryption to be disabled. 3962306a36Sopenharmony_ci */ 4062306a36Sopenharmony_cistatic bool modparam_nohwcrypt = false; 4162306a36Sopenharmony_cimodule_param_named(nohwcrypt, modparam_nohwcrypt, bool, 0444); 4262306a36Sopenharmony_ciMODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption."); 4362306a36Sopenharmony_ci 4462306a36Sopenharmony_cistatic bool rt2800pci_hwcrypt_disabled(struct rt2x00_dev *rt2x00dev) 4562306a36Sopenharmony_ci{ 4662306a36Sopenharmony_ci return modparam_nohwcrypt; 4762306a36Sopenharmony_ci} 4862306a36Sopenharmony_ci 4962306a36Sopenharmony_cistatic void rt2800pci_mcu_status(struct rt2x00_dev *rt2x00dev, const u8 token) 5062306a36Sopenharmony_ci{ 5162306a36Sopenharmony_ci unsigned int i; 5262306a36Sopenharmony_ci u32 reg; 5362306a36Sopenharmony_ci 5462306a36Sopenharmony_ci /* 5562306a36Sopenharmony_ci * SOC devices don't support MCU requests. 5662306a36Sopenharmony_ci */ 5762306a36Sopenharmony_ci if (rt2x00_is_soc(rt2x00dev)) 5862306a36Sopenharmony_ci return; 5962306a36Sopenharmony_ci 6062306a36Sopenharmony_ci for (i = 0; i < 200; i++) { 6162306a36Sopenharmony_ci reg = rt2x00mmio_register_read(rt2x00dev, H2M_MAILBOX_CID); 6262306a36Sopenharmony_ci 6362306a36Sopenharmony_ci if ((rt2x00_get_field32(reg, H2M_MAILBOX_CID_CMD0) == token) || 6462306a36Sopenharmony_ci (rt2x00_get_field32(reg, H2M_MAILBOX_CID_CMD1) == token) || 6562306a36Sopenharmony_ci (rt2x00_get_field32(reg, H2M_MAILBOX_CID_CMD2) == token) || 6662306a36Sopenharmony_ci (rt2x00_get_field32(reg, H2M_MAILBOX_CID_CMD3) == token)) 6762306a36Sopenharmony_ci break; 6862306a36Sopenharmony_ci 6962306a36Sopenharmony_ci udelay(REGISTER_BUSY_DELAY); 7062306a36Sopenharmony_ci } 7162306a36Sopenharmony_ci 7262306a36Sopenharmony_ci if (i == 200) 7362306a36Sopenharmony_ci rt2x00_err(rt2x00dev, "MCU request failed, no response from hardware\n"); 7462306a36Sopenharmony_ci 7562306a36Sopenharmony_ci rt2x00mmio_register_write(rt2x00dev, H2M_MAILBOX_STATUS, ~0); 7662306a36Sopenharmony_ci rt2x00mmio_register_write(rt2x00dev, H2M_MAILBOX_CID, ~0); 7762306a36Sopenharmony_ci} 7862306a36Sopenharmony_ci 7962306a36Sopenharmony_cistatic void rt2800pci_eepromregister_read(struct eeprom_93cx6 *eeprom) 8062306a36Sopenharmony_ci{ 8162306a36Sopenharmony_ci struct rt2x00_dev *rt2x00dev = eeprom->data; 8262306a36Sopenharmony_ci u32 reg; 8362306a36Sopenharmony_ci 8462306a36Sopenharmony_ci reg = rt2x00mmio_register_read(rt2x00dev, E2PROM_CSR); 8562306a36Sopenharmony_ci 8662306a36Sopenharmony_ci eeprom->reg_data_in = !!rt2x00_get_field32(reg, E2PROM_CSR_DATA_IN); 8762306a36Sopenharmony_ci eeprom->reg_data_out = !!rt2x00_get_field32(reg, E2PROM_CSR_DATA_OUT); 8862306a36Sopenharmony_ci eeprom->reg_data_clock = 8962306a36Sopenharmony_ci !!rt2x00_get_field32(reg, E2PROM_CSR_DATA_CLOCK); 9062306a36Sopenharmony_ci eeprom->reg_chip_select = 9162306a36Sopenharmony_ci !!rt2x00_get_field32(reg, E2PROM_CSR_CHIP_SELECT); 9262306a36Sopenharmony_ci} 9362306a36Sopenharmony_ci 9462306a36Sopenharmony_cistatic void rt2800pci_eepromregister_write(struct eeprom_93cx6 *eeprom) 9562306a36Sopenharmony_ci{ 9662306a36Sopenharmony_ci struct rt2x00_dev *rt2x00dev = eeprom->data; 9762306a36Sopenharmony_ci u32 reg = 0; 9862306a36Sopenharmony_ci 9962306a36Sopenharmony_ci rt2x00_set_field32(®, E2PROM_CSR_DATA_IN, !!eeprom->reg_data_in); 10062306a36Sopenharmony_ci rt2x00_set_field32(®, E2PROM_CSR_DATA_OUT, !!eeprom->reg_data_out); 10162306a36Sopenharmony_ci rt2x00_set_field32(®, E2PROM_CSR_DATA_CLOCK, 10262306a36Sopenharmony_ci !!eeprom->reg_data_clock); 10362306a36Sopenharmony_ci rt2x00_set_field32(®, E2PROM_CSR_CHIP_SELECT, 10462306a36Sopenharmony_ci !!eeprom->reg_chip_select); 10562306a36Sopenharmony_ci 10662306a36Sopenharmony_ci rt2x00mmio_register_write(rt2x00dev, E2PROM_CSR, reg); 10762306a36Sopenharmony_ci} 10862306a36Sopenharmony_ci 10962306a36Sopenharmony_cistatic int rt2800pci_read_eeprom_pci(struct rt2x00_dev *rt2x00dev) 11062306a36Sopenharmony_ci{ 11162306a36Sopenharmony_ci struct eeprom_93cx6 eeprom; 11262306a36Sopenharmony_ci u32 reg; 11362306a36Sopenharmony_ci 11462306a36Sopenharmony_ci reg = rt2x00mmio_register_read(rt2x00dev, E2PROM_CSR); 11562306a36Sopenharmony_ci 11662306a36Sopenharmony_ci eeprom.data = rt2x00dev; 11762306a36Sopenharmony_ci eeprom.register_read = rt2800pci_eepromregister_read; 11862306a36Sopenharmony_ci eeprom.register_write = rt2800pci_eepromregister_write; 11962306a36Sopenharmony_ci switch (rt2x00_get_field32(reg, E2PROM_CSR_TYPE)) 12062306a36Sopenharmony_ci { 12162306a36Sopenharmony_ci case 0: 12262306a36Sopenharmony_ci eeprom.width = PCI_EEPROM_WIDTH_93C46; 12362306a36Sopenharmony_ci break; 12462306a36Sopenharmony_ci case 1: 12562306a36Sopenharmony_ci eeprom.width = PCI_EEPROM_WIDTH_93C66; 12662306a36Sopenharmony_ci break; 12762306a36Sopenharmony_ci default: 12862306a36Sopenharmony_ci eeprom.width = PCI_EEPROM_WIDTH_93C86; 12962306a36Sopenharmony_ci break; 13062306a36Sopenharmony_ci } 13162306a36Sopenharmony_ci eeprom.reg_data_in = 0; 13262306a36Sopenharmony_ci eeprom.reg_data_out = 0; 13362306a36Sopenharmony_ci eeprom.reg_data_clock = 0; 13462306a36Sopenharmony_ci eeprom.reg_chip_select = 0; 13562306a36Sopenharmony_ci 13662306a36Sopenharmony_ci eeprom_93cx6_multiread(&eeprom, EEPROM_BASE, rt2x00dev->eeprom, 13762306a36Sopenharmony_ci EEPROM_SIZE / sizeof(u16)); 13862306a36Sopenharmony_ci 13962306a36Sopenharmony_ci return 0; 14062306a36Sopenharmony_ci} 14162306a36Sopenharmony_ci 14262306a36Sopenharmony_cistatic int rt2800pci_efuse_detect(struct rt2x00_dev *rt2x00dev) 14362306a36Sopenharmony_ci{ 14462306a36Sopenharmony_ci return rt2800_efuse_detect(rt2x00dev); 14562306a36Sopenharmony_ci} 14662306a36Sopenharmony_ci 14762306a36Sopenharmony_cistatic inline int rt2800pci_read_eeprom_efuse(struct rt2x00_dev *rt2x00dev) 14862306a36Sopenharmony_ci{ 14962306a36Sopenharmony_ci return rt2800_read_eeprom_efuse(rt2x00dev); 15062306a36Sopenharmony_ci} 15162306a36Sopenharmony_ci 15262306a36Sopenharmony_ci/* 15362306a36Sopenharmony_ci * Firmware functions 15462306a36Sopenharmony_ci */ 15562306a36Sopenharmony_cistatic char *rt2800pci_get_firmware_name(struct rt2x00_dev *rt2x00dev) 15662306a36Sopenharmony_ci{ 15762306a36Sopenharmony_ci /* 15862306a36Sopenharmony_ci * Chip rt3290 use specific 4KB firmware named rt3290.bin. 15962306a36Sopenharmony_ci */ 16062306a36Sopenharmony_ci if (rt2x00_rt(rt2x00dev, RT3290)) 16162306a36Sopenharmony_ci return FIRMWARE_RT3290; 16262306a36Sopenharmony_ci else 16362306a36Sopenharmony_ci return FIRMWARE_RT2860; 16462306a36Sopenharmony_ci} 16562306a36Sopenharmony_ci 16662306a36Sopenharmony_cistatic int rt2800pci_write_firmware(struct rt2x00_dev *rt2x00dev, 16762306a36Sopenharmony_ci const u8 *data, const size_t len) 16862306a36Sopenharmony_ci{ 16962306a36Sopenharmony_ci u32 reg; 17062306a36Sopenharmony_ci 17162306a36Sopenharmony_ci /* 17262306a36Sopenharmony_ci * enable Host program ram write selection 17362306a36Sopenharmony_ci */ 17462306a36Sopenharmony_ci reg = 0; 17562306a36Sopenharmony_ci rt2x00_set_field32(®, PBF_SYS_CTRL_HOST_RAM_WRITE, 1); 17662306a36Sopenharmony_ci rt2x00mmio_register_write(rt2x00dev, PBF_SYS_CTRL, reg); 17762306a36Sopenharmony_ci 17862306a36Sopenharmony_ci /* 17962306a36Sopenharmony_ci * Write firmware to device. 18062306a36Sopenharmony_ci */ 18162306a36Sopenharmony_ci rt2x00mmio_register_multiwrite(rt2x00dev, FIRMWARE_IMAGE_BASE, 18262306a36Sopenharmony_ci data, len); 18362306a36Sopenharmony_ci 18462306a36Sopenharmony_ci rt2x00mmio_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00000); 18562306a36Sopenharmony_ci rt2x00mmio_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00001); 18662306a36Sopenharmony_ci 18762306a36Sopenharmony_ci rt2x00mmio_register_write(rt2x00dev, H2M_BBP_AGENT, 0); 18862306a36Sopenharmony_ci rt2x00mmio_register_write(rt2x00dev, H2M_MAILBOX_CSR, 0); 18962306a36Sopenharmony_ci 19062306a36Sopenharmony_ci return 0; 19162306a36Sopenharmony_ci} 19262306a36Sopenharmony_ci 19362306a36Sopenharmony_ci/* 19462306a36Sopenharmony_ci * Device state switch handlers. 19562306a36Sopenharmony_ci */ 19662306a36Sopenharmony_cistatic int rt2800pci_enable_radio(struct rt2x00_dev *rt2x00dev) 19762306a36Sopenharmony_ci{ 19862306a36Sopenharmony_ci int retval; 19962306a36Sopenharmony_ci 20062306a36Sopenharmony_ci retval = rt2800mmio_enable_radio(rt2x00dev); 20162306a36Sopenharmony_ci if (retval) 20262306a36Sopenharmony_ci return retval; 20362306a36Sopenharmony_ci 20462306a36Sopenharmony_ci /* After resume MCU_BOOT_SIGNAL will trash these. */ 20562306a36Sopenharmony_ci rt2x00mmio_register_write(rt2x00dev, H2M_MAILBOX_STATUS, ~0); 20662306a36Sopenharmony_ci rt2x00mmio_register_write(rt2x00dev, H2M_MAILBOX_CID, ~0); 20762306a36Sopenharmony_ci 20862306a36Sopenharmony_ci rt2800_mcu_request(rt2x00dev, MCU_SLEEP, TOKEN_RADIO_OFF, 0xff, 0x02); 20962306a36Sopenharmony_ci rt2800pci_mcu_status(rt2x00dev, TOKEN_RADIO_OFF); 21062306a36Sopenharmony_ci 21162306a36Sopenharmony_ci rt2800_mcu_request(rt2x00dev, MCU_WAKEUP, TOKEN_WAKEUP, 0, 0); 21262306a36Sopenharmony_ci rt2800pci_mcu_status(rt2x00dev, TOKEN_WAKEUP); 21362306a36Sopenharmony_ci 21462306a36Sopenharmony_ci return retval; 21562306a36Sopenharmony_ci} 21662306a36Sopenharmony_ci 21762306a36Sopenharmony_cistatic int rt2800pci_set_state(struct rt2x00_dev *rt2x00dev, 21862306a36Sopenharmony_ci enum dev_state state) 21962306a36Sopenharmony_ci{ 22062306a36Sopenharmony_ci if (state == STATE_AWAKE) { 22162306a36Sopenharmony_ci rt2800_mcu_request(rt2x00dev, MCU_WAKEUP, TOKEN_WAKEUP, 22262306a36Sopenharmony_ci 0, 0x02); 22362306a36Sopenharmony_ci rt2800pci_mcu_status(rt2x00dev, TOKEN_WAKEUP); 22462306a36Sopenharmony_ci } else if (state == STATE_SLEEP) { 22562306a36Sopenharmony_ci rt2x00mmio_register_write(rt2x00dev, H2M_MAILBOX_STATUS, 22662306a36Sopenharmony_ci 0xffffffff); 22762306a36Sopenharmony_ci rt2x00mmio_register_write(rt2x00dev, H2M_MAILBOX_CID, 22862306a36Sopenharmony_ci 0xffffffff); 22962306a36Sopenharmony_ci rt2800_mcu_request(rt2x00dev, MCU_SLEEP, TOKEN_SLEEP, 23062306a36Sopenharmony_ci 0xff, 0x01); 23162306a36Sopenharmony_ci } 23262306a36Sopenharmony_ci 23362306a36Sopenharmony_ci return 0; 23462306a36Sopenharmony_ci} 23562306a36Sopenharmony_ci 23662306a36Sopenharmony_cistatic int rt2800pci_set_device_state(struct rt2x00_dev *rt2x00dev, 23762306a36Sopenharmony_ci enum dev_state state) 23862306a36Sopenharmony_ci{ 23962306a36Sopenharmony_ci int retval = 0; 24062306a36Sopenharmony_ci 24162306a36Sopenharmony_ci switch (state) { 24262306a36Sopenharmony_ci case STATE_RADIO_ON: 24362306a36Sopenharmony_ci retval = rt2800pci_enable_radio(rt2x00dev); 24462306a36Sopenharmony_ci break; 24562306a36Sopenharmony_ci case STATE_RADIO_OFF: 24662306a36Sopenharmony_ci /* 24762306a36Sopenharmony_ci * After the radio has been disabled, the device should 24862306a36Sopenharmony_ci * be put to sleep for powersaving. 24962306a36Sopenharmony_ci */ 25062306a36Sopenharmony_ci rt2800pci_set_state(rt2x00dev, STATE_SLEEP); 25162306a36Sopenharmony_ci break; 25262306a36Sopenharmony_ci case STATE_RADIO_IRQ_ON: 25362306a36Sopenharmony_ci case STATE_RADIO_IRQ_OFF: 25462306a36Sopenharmony_ci rt2800mmio_toggle_irq(rt2x00dev, state); 25562306a36Sopenharmony_ci break; 25662306a36Sopenharmony_ci case STATE_DEEP_SLEEP: 25762306a36Sopenharmony_ci case STATE_SLEEP: 25862306a36Sopenharmony_ci case STATE_STANDBY: 25962306a36Sopenharmony_ci case STATE_AWAKE: 26062306a36Sopenharmony_ci retval = rt2800pci_set_state(rt2x00dev, state); 26162306a36Sopenharmony_ci break; 26262306a36Sopenharmony_ci default: 26362306a36Sopenharmony_ci retval = -ENOTSUPP; 26462306a36Sopenharmony_ci break; 26562306a36Sopenharmony_ci } 26662306a36Sopenharmony_ci 26762306a36Sopenharmony_ci if (unlikely(retval)) 26862306a36Sopenharmony_ci rt2x00_err(rt2x00dev, "Device failed to enter state %d (%d)\n", 26962306a36Sopenharmony_ci state, retval); 27062306a36Sopenharmony_ci 27162306a36Sopenharmony_ci return retval; 27262306a36Sopenharmony_ci} 27362306a36Sopenharmony_ci 27462306a36Sopenharmony_ci/* 27562306a36Sopenharmony_ci * Device probe functions. 27662306a36Sopenharmony_ci */ 27762306a36Sopenharmony_cistatic int rt2800pci_read_eeprom(struct rt2x00_dev *rt2x00dev) 27862306a36Sopenharmony_ci{ 27962306a36Sopenharmony_ci int retval; 28062306a36Sopenharmony_ci 28162306a36Sopenharmony_ci if (rt2800pci_efuse_detect(rt2x00dev)) 28262306a36Sopenharmony_ci retval = rt2800pci_read_eeprom_efuse(rt2x00dev); 28362306a36Sopenharmony_ci else 28462306a36Sopenharmony_ci retval = rt2800pci_read_eeprom_pci(rt2x00dev); 28562306a36Sopenharmony_ci 28662306a36Sopenharmony_ci return retval; 28762306a36Sopenharmony_ci} 28862306a36Sopenharmony_ci 28962306a36Sopenharmony_cistatic const struct ieee80211_ops rt2800pci_mac80211_ops = { 29062306a36Sopenharmony_ci .tx = rt2x00mac_tx, 29162306a36Sopenharmony_ci .wake_tx_queue = ieee80211_handle_wake_tx_queue, 29262306a36Sopenharmony_ci .start = rt2x00mac_start, 29362306a36Sopenharmony_ci .stop = rt2x00mac_stop, 29462306a36Sopenharmony_ci .add_interface = rt2x00mac_add_interface, 29562306a36Sopenharmony_ci .remove_interface = rt2x00mac_remove_interface, 29662306a36Sopenharmony_ci .config = rt2x00mac_config, 29762306a36Sopenharmony_ci .configure_filter = rt2x00mac_configure_filter, 29862306a36Sopenharmony_ci .set_key = rt2x00mac_set_key, 29962306a36Sopenharmony_ci .sw_scan_start = rt2x00mac_sw_scan_start, 30062306a36Sopenharmony_ci .sw_scan_complete = rt2x00mac_sw_scan_complete, 30162306a36Sopenharmony_ci .get_stats = rt2x00mac_get_stats, 30262306a36Sopenharmony_ci .get_key_seq = rt2800_get_key_seq, 30362306a36Sopenharmony_ci .set_rts_threshold = rt2800_set_rts_threshold, 30462306a36Sopenharmony_ci .sta_add = rt2800_sta_add, 30562306a36Sopenharmony_ci .sta_remove = rt2800_sta_remove, 30662306a36Sopenharmony_ci .bss_info_changed = rt2x00mac_bss_info_changed, 30762306a36Sopenharmony_ci .conf_tx = rt2800_conf_tx, 30862306a36Sopenharmony_ci .get_tsf = rt2800_get_tsf, 30962306a36Sopenharmony_ci .rfkill_poll = rt2x00mac_rfkill_poll, 31062306a36Sopenharmony_ci .ampdu_action = rt2800_ampdu_action, 31162306a36Sopenharmony_ci .flush = rt2x00mac_flush, 31262306a36Sopenharmony_ci .get_survey = rt2800_get_survey, 31362306a36Sopenharmony_ci .get_ringparam = rt2x00mac_get_ringparam, 31462306a36Sopenharmony_ci .tx_frames_pending = rt2x00mac_tx_frames_pending, 31562306a36Sopenharmony_ci .reconfig_complete = rt2x00mac_reconfig_complete, 31662306a36Sopenharmony_ci}; 31762306a36Sopenharmony_ci 31862306a36Sopenharmony_cistatic const struct rt2800_ops rt2800pci_rt2800_ops = { 31962306a36Sopenharmony_ci .register_read = rt2x00mmio_register_read, 32062306a36Sopenharmony_ci .register_read_lock = rt2x00mmio_register_read, /* same for PCI */ 32162306a36Sopenharmony_ci .register_write = rt2x00mmio_register_write, 32262306a36Sopenharmony_ci .register_write_lock = rt2x00mmio_register_write, /* same for PCI */ 32362306a36Sopenharmony_ci .register_multiread = rt2x00mmio_register_multiread, 32462306a36Sopenharmony_ci .register_multiwrite = rt2x00mmio_register_multiwrite, 32562306a36Sopenharmony_ci .regbusy_read = rt2x00mmio_regbusy_read, 32662306a36Sopenharmony_ci .read_eeprom = rt2800pci_read_eeprom, 32762306a36Sopenharmony_ci .hwcrypt_disabled = rt2800pci_hwcrypt_disabled, 32862306a36Sopenharmony_ci .drv_write_firmware = rt2800pci_write_firmware, 32962306a36Sopenharmony_ci .drv_init_registers = rt2800mmio_init_registers, 33062306a36Sopenharmony_ci .drv_get_txwi = rt2800mmio_get_txwi, 33162306a36Sopenharmony_ci .drv_get_dma_done = rt2800mmio_get_dma_done, 33262306a36Sopenharmony_ci}; 33362306a36Sopenharmony_ci 33462306a36Sopenharmony_cistatic const struct rt2x00lib_ops rt2800pci_rt2x00_ops = { 33562306a36Sopenharmony_ci .irq_handler = rt2800mmio_interrupt, 33662306a36Sopenharmony_ci .txstatus_tasklet = rt2800mmio_txstatus_tasklet, 33762306a36Sopenharmony_ci .pretbtt_tasklet = rt2800mmio_pretbtt_tasklet, 33862306a36Sopenharmony_ci .tbtt_tasklet = rt2800mmio_tbtt_tasklet, 33962306a36Sopenharmony_ci .rxdone_tasklet = rt2800mmio_rxdone_tasklet, 34062306a36Sopenharmony_ci .autowake_tasklet = rt2800mmio_autowake_tasklet, 34162306a36Sopenharmony_ci .probe_hw = rt2800mmio_probe_hw, 34262306a36Sopenharmony_ci .get_firmware_name = rt2800pci_get_firmware_name, 34362306a36Sopenharmony_ci .check_firmware = rt2800_check_firmware, 34462306a36Sopenharmony_ci .load_firmware = rt2800_load_firmware, 34562306a36Sopenharmony_ci .initialize = rt2x00mmio_initialize, 34662306a36Sopenharmony_ci .uninitialize = rt2x00mmio_uninitialize, 34762306a36Sopenharmony_ci .get_entry_state = rt2800mmio_get_entry_state, 34862306a36Sopenharmony_ci .clear_entry = rt2800mmio_clear_entry, 34962306a36Sopenharmony_ci .set_device_state = rt2800pci_set_device_state, 35062306a36Sopenharmony_ci .rfkill_poll = rt2800_rfkill_poll, 35162306a36Sopenharmony_ci .link_stats = rt2800_link_stats, 35262306a36Sopenharmony_ci .reset_tuner = rt2800_reset_tuner, 35362306a36Sopenharmony_ci .link_tuner = rt2800_link_tuner, 35462306a36Sopenharmony_ci .gain_calibration = rt2800_gain_calibration, 35562306a36Sopenharmony_ci .vco_calibration = rt2800_vco_calibration, 35662306a36Sopenharmony_ci .watchdog = rt2800_watchdog, 35762306a36Sopenharmony_ci .start_queue = rt2800mmio_start_queue, 35862306a36Sopenharmony_ci .kick_queue = rt2800mmio_kick_queue, 35962306a36Sopenharmony_ci .stop_queue = rt2800mmio_stop_queue, 36062306a36Sopenharmony_ci .flush_queue = rt2800mmio_flush_queue, 36162306a36Sopenharmony_ci .write_tx_desc = rt2800mmio_write_tx_desc, 36262306a36Sopenharmony_ci .write_tx_data = rt2800_write_tx_data, 36362306a36Sopenharmony_ci .write_beacon = rt2800_write_beacon, 36462306a36Sopenharmony_ci .clear_beacon = rt2800_clear_beacon, 36562306a36Sopenharmony_ci .fill_rxdone = rt2800mmio_fill_rxdone, 36662306a36Sopenharmony_ci .config_shared_key = rt2800_config_shared_key, 36762306a36Sopenharmony_ci .config_pairwise_key = rt2800_config_pairwise_key, 36862306a36Sopenharmony_ci .config_filter = rt2800_config_filter, 36962306a36Sopenharmony_ci .config_intf = rt2800_config_intf, 37062306a36Sopenharmony_ci .config_erp = rt2800_config_erp, 37162306a36Sopenharmony_ci .config_ant = rt2800_config_ant, 37262306a36Sopenharmony_ci .config = rt2800_config, 37362306a36Sopenharmony_ci .pre_reset_hw = rt2800_pre_reset_hw, 37462306a36Sopenharmony_ci}; 37562306a36Sopenharmony_ci 37662306a36Sopenharmony_cistatic const struct rt2x00_ops rt2800pci_ops = { 37762306a36Sopenharmony_ci .name = KBUILD_MODNAME, 37862306a36Sopenharmony_ci .drv_data_size = sizeof(struct rt2800_drv_data), 37962306a36Sopenharmony_ci .max_ap_intf = 8, 38062306a36Sopenharmony_ci .eeprom_size = EEPROM_SIZE, 38162306a36Sopenharmony_ci .rf_size = RF_SIZE, 38262306a36Sopenharmony_ci .tx_queues = NUM_TX_QUEUES, 38362306a36Sopenharmony_ci .queue_init = rt2800mmio_queue_init, 38462306a36Sopenharmony_ci .lib = &rt2800pci_rt2x00_ops, 38562306a36Sopenharmony_ci .drv = &rt2800pci_rt2800_ops, 38662306a36Sopenharmony_ci .hw = &rt2800pci_mac80211_ops, 38762306a36Sopenharmony_ci#ifdef CONFIG_RT2X00_LIB_DEBUGFS 38862306a36Sopenharmony_ci .debugfs = &rt2800_rt2x00debug, 38962306a36Sopenharmony_ci#endif /* CONFIG_RT2X00_LIB_DEBUGFS */ 39062306a36Sopenharmony_ci}; 39162306a36Sopenharmony_ci 39262306a36Sopenharmony_ci/* 39362306a36Sopenharmony_ci * RT2800pci module information. 39462306a36Sopenharmony_ci */ 39562306a36Sopenharmony_cistatic const struct pci_device_id rt2800pci_device_table[] = { 39662306a36Sopenharmony_ci { PCI_DEVICE(0x1814, 0x0601) }, 39762306a36Sopenharmony_ci { PCI_DEVICE(0x1814, 0x0681) }, 39862306a36Sopenharmony_ci { PCI_DEVICE(0x1814, 0x0701) }, 39962306a36Sopenharmony_ci { PCI_DEVICE(0x1814, 0x0781) }, 40062306a36Sopenharmony_ci { PCI_DEVICE(0x1814, 0x3090) }, 40162306a36Sopenharmony_ci { PCI_DEVICE(0x1814, 0x3091) }, 40262306a36Sopenharmony_ci { PCI_DEVICE(0x1814, 0x3092) }, 40362306a36Sopenharmony_ci { PCI_DEVICE(0x1432, 0x7708) }, 40462306a36Sopenharmony_ci { PCI_DEVICE(0x1432, 0x7727) }, 40562306a36Sopenharmony_ci { PCI_DEVICE(0x1432, 0x7728) }, 40662306a36Sopenharmony_ci { PCI_DEVICE(0x1432, 0x7738) }, 40762306a36Sopenharmony_ci { PCI_DEVICE(0x1432, 0x7748) }, 40862306a36Sopenharmony_ci { PCI_DEVICE(0x1432, 0x7758) }, 40962306a36Sopenharmony_ci { PCI_DEVICE(0x1432, 0x7768) }, 41062306a36Sopenharmony_ci { PCI_DEVICE(0x1462, 0x891a) }, 41162306a36Sopenharmony_ci { PCI_DEVICE(0x1a3b, 0x1059) }, 41262306a36Sopenharmony_ci#ifdef CONFIG_RT2800PCI_RT3290 41362306a36Sopenharmony_ci { PCI_DEVICE(0x1814, 0x3290) }, 41462306a36Sopenharmony_ci#endif 41562306a36Sopenharmony_ci#ifdef CONFIG_RT2800PCI_RT33XX 41662306a36Sopenharmony_ci { PCI_DEVICE(0x1814, 0x3390) }, 41762306a36Sopenharmony_ci#endif 41862306a36Sopenharmony_ci#ifdef CONFIG_RT2800PCI_RT35XX 41962306a36Sopenharmony_ci { PCI_DEVICE(0x1432, 0x7711) }, 42062306a36Sopenharmony_ci { PCI_DEVICE(0x1432, 0x7722) }, 42162306a36Sopenharmony_ci { PCI_DEVICE(0x1814, 0x3060) }, 42262306a36Sopenharmony_ci { PCI_DEVICE(0x1814, 0x3062) }, 42362306a36Sopenharmony_ci { PCI_DEVICE(0x1814, 0x3562) }, 42462306a36Sopenharmony_ci { PCI_DEVICE(0x1814, 0x3592) }, 42562306a36Sopenharmony_ci { PCI_DEVICE(0x1814, 0x3593) }, 42662306a36Sopenharmony_ci { PCI_DEVICE(0x1814, 0x359f) }, 42762306a36Sopenharmony_ci#endif 42862306a36Sopenharmony_ci#ifdef CONFIG_RT2800PCI_RT53XX 42962306a36Sopenharmony_ci { PCI_DEVICE(0x1814, 0x5360) }, 43062306a36Sopenharmony_ci { PCI_DEVICE(0x1814, 0x5362) }, 43162306a36Sopenharmony_ci { PCI_DEVICE(0x1814, 0x5390) }, 43262306a36Sopenharmony_ci { PCI_DEVICE(0x1814, 0x5392) }, 43362306a36Sopenharmony_ci { PCI_DEVICE(0x1814, 0x539a) }, 43462306a36Sopenharmony_ci { PCI_DEVICE(0x1814, 0x539b) }, 43562306a36Sopenharmony_ci { PCI_DEVICE(0x1814, 0x539f) }, 43662306a36Sopenharmony_ci#endif 43762306a36Sopenharmony_ci { 0, } 43862306a36Sopenharmony_ci}; 43962306a36Sopenharmony_ci 44062306a36Sopenharmony_ciMODULE_AUTHOR(DRV_PROJECT); 44162306a36Sopenharmony_ciMODULE_VERSION(DRV_VERSION); 44262306a36Sopenharmony_ciMODULE_DESCRIPTION("Ralink RT2800 PCI & PCMCIA Wireless LAN driver."); 44362306a36Sopenharmony_ciMODULE_FIRMWARE(FIRMWARE_RT2860); 44462306a36Sopenharmony_ciMODULE_DEVICE_TABLE(pci, rt2800pci_device_table); 44562306a36Sopenharmony_ciMODULE_LICENSE("GPL"); 44662306a36Sopenharmony_ci 44762306a36Sopenharmony_cistatic int rt2800pci_probe(struct pci_dev *pci_dev, 44862306a36Sopenharmony_ci const struct pci_device_id *id) 44962306a36Sopenharmony_ci{ 45062306a36Sopenharmony_ci return rt2x00pci_probe(pci_dev, &rt2800pci_ops); 45162306a36Sopenharmony_ci} 45262306a36Sopenharmony_ci 45362306a36Sopenharmony_cistatic struct pci_driver rt2800pci_driver = { 45462306a36Sopenharmony_ci .name = KBUILD_MODNAME, 45562306a36Sopenharmony_ci .id_table = rt2800pci_device_table, 45662306a36Sopenharmony_ci .probe = rt2800pci_probe, 45762306a36Sopenharmony_ci .remove = rt2x00pci_remove, 45862306a36Sopenharmony_ci .driver.pm = &rt2x00pci_pm_ops, 45962306a36Sopenharmony_ci}; 46062306a36Sopenharmony_ci 46162306a36Sopenharmony_cimodule_pci_driver(rt2800pci_driver); 462