⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rt2400pci.c

📁 linux内核源码
💻 C
📖 第 1 页 / 共 4 页
字号:
	u32 reg;	u16 word;	u8 *mac;	rt2x00pci_register_read(rt2x00dev, CSR21, &reg);	eeprom.data = rt2x00dev;	eeprom.register_read = rt2400pci_eepromregister_read;	eeprom.register_write = rt2400pci_eepromregister_write;	eeprom.width = rt2x00_get_field32(reg, CSR21_TYPE_93C46) ?	    PCI_EEPROM_WIDTH_93C46 : PCI_EEPROM_WIDTH_93C66;	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));	/*	 * Start validation of the data that has been read.	 */	mac = rt2x00_eeprom_addr(rt2x00dev, EEPROM_MAC_ADDR_0);	if (!is_valid_ether_addr(mac)) {		DECLARE_MAC_BUF(macbuf);		random_ether_addr(mac);		EEPROM(rt2x00dev, "MAC: %s\n", print_mac(macbuf, mac));	}	rt2x00_eeprom_read(rt2x00dev, EEPROM_ANTENNA, &word);	if (word == 0xffff) {		ERROR(rt2x00dev, "Invalid EEPROM data detected.\n");		return -EINVAL;	}	return 0;}static int rt2400pci_init_eeprom(struct rt2x00_dev *rt2x00dev){	u32 reg;	u16 value;	u16 eeprom;	/*	 * Read EEPROM word for configuration.	 */	rt2x00_eeprom_read(rt2x00dev, EEPROM_ANTENNA, &eeprom);	/*	 * Identify RF chipset.	 */	value = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RF_TYPE);	rt2x00pci_register_read(rt2x00dev, CSR0, &reg);	rt2x00_set_chip(rt2x00dev, RT2460, value, reg);	if (!rt2x00_rf(&rt2x00dev->chip, RF2420) &&	    !rt2x00_rf(&rt2x00dev->chip, RF2421)) {		ERROR(rt2x00dev, "Invalid RF chipset detected.\n");		return -ENODEV;	}	/*	 * Identify default antenna configuration.	 */	rt2x00dev->hw->conf.antenna_sel_tx =	    rt2x00_get_field16(eeprom, EEPROM_ANTENNA_TX_DEFAULT);	rt2x00dev->hw->conf.antenna_sel_rx =	    rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RX_DEFAULT);	/*	 * Store led mode, for correct led behaviour.	 */	rt2x00dev->led_mode =	    rt2x00_get_field16(eeprom, EEPROM_ANTENNA_LED_MODE);	/*	 * Detect if this device has an hardware controlled radio.	 */#ifdef CONFIG_RT2400PCI_RFKILL	if (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_HARDWARE_RADIO))		__set_bit(CONFIG_SUPPORT_HW_BUTTON, &rt2x00dev->flags);#endif /* CONFIG_RT2400PCI_RFKILL */	/*	 * Check if the BBP tuning should be enabled.	 */	if (!rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RX_AGCVGC_TUNING))		__set_bit(CONFIG_DISABLE_LINK_TUNING, &rt2x00dev->flags);	return 0;}/* * RF value list for RF2420 & RF2421 * Supports: 2.4 GHz */static const struct rf_channel rf_vals_bg[] = {	{ 1,  0x00022058, 0x000c1fda, 0x00000101, 0 },	{ 2,  0x00022058, 0x000c1fee, 0x00000101, 0 },	{ 3,  0x00022058, 0x000c2002, 0x00000101, 0 },	{ 4,  0x00022058, 0x000c2016, 0x00000101, 0 },	{ 5,  0x00022058, 0x000c202a, 0x00000101, 0 },	{ 6,  0x00022058, 0x000c203e, 0x00000101, 0 },	{ 7,  0x00022058, 0x000c2052, 0x00000101, 0 },	{ 8,  0x00022058, 0x000c2066, 0x00000101, 0 },	{ 9,  0x00022058, 0x000c207a, 0x00000101, 0 },	{ 10, 0x00022058, 0x000c208e, 0x00000101, 0 },	{ 11, 0x00022058, 0x000c20a2, 0x00000101, 0 },	{ 12, 0x00022058, 0x000c20b6, 0x00000101, 0 },	{ 13, 0x00022058, 0x000c20ca, 0x00000101, 0 },	{ 14, 0x00022058, 0x000c20fa, 0x00000101, 0 },};static void rt2400pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev){	struct hw_mode_spec *spec = &rt2x00dev->spec;	u8 *txpower;	unsigned int i;	/*	 * Initialize all hw fields.	 */	rt2x00dev->hw->flags = IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING;	rt2x00dev->hw->extra_tx_headroom = 0;	rt2x00dev->hw->max_signal = MAX_SIGNAL;	rt2x00dev->hw->max_rssi = MAX_RX_SSI;	rt2x00dev->hw->queues = 2;	SET_IEEE80211_DEV(rt2x00dev->hw, &rt2x00dev_pci(rt2x00dev)->dev);	SET_IEEE80211_PERM_ADDR(rt2x00dev->hw,				rt2x00_eeprom_addr(rt2x00dev,						   EEPROM_MAC_ADDR_0));	/*	 * Convert tx_power array in eeprom.	 */	txpower = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_START);	for (i = 0; i < 14; i++)		txpower[i] = TXPOWER_FROM_DEV(txpower[i]);	/*	 * Initialize hw_mode information.	 */	spec->num_modes = 1;	spec->num_rates = 4;	spec->tx_power_a = NULL;	spec->tx_power_bg = txpower;	spec->tx_power_default = DEFAULT_TXPOWER;	spec->num_channels = ARRAY_SIZE(rf_vals_bg);	spec->channels = rf_vals_bg;}static int rt2400pci_probe_hw(struct rt2x00_dev *rt2x00dev){	int retval;	/*	 * Allocate eeprom data.	 */	retval = rt2400pci_validate_eeprom(rt2x00dev);	if (retval)		return retval;	retval = rt2400pci_init_eeprom(rt2x00dev);	if (retval)		return retval;	/*	 * Initialize hw specifications.	 */	rt2400pci_probe_hw_mode(rt2x00dev);	/*	 * This device requires the beacon ring	 */	__set_bit(DRIVER_REQUIRE_BEACON_RING, &rt2x00dev->flags);	/*	 * Set the rssi offset.	 */	rt2x00dev->rssi_offset = DEFAULT_RSSI_OFFSET;	return 0;}/* * IEEE80211 stack callback functions. */static void rt2400pci_configure_filter(struct ieee80211_hw *hw,				       unsigned int changed_flags,				       unsigned int *total_flags,				       int mc_count,				       struct dev_addr_list *mc_list){	struct rt2x00_dev *rt2x00dev = hw->priv;	struct interface *intf = &rt2x00dev->interface;	u32 reg;	/*	 * Mask off any flags we are going to ignore from	 * the total_flags field.	 */	*total_flags &=	    FIF_ALLMULTI |	    FIF_FCSFAIL |	    FIF_PLCPFAIL |	    FIF_CONTROL |	    FIF_OTHER_BSS |	    FIF_PROMISC_IN_BSS;	/*	 * Apply some rules to the filters:	 * - Some filters imply different filters to be set.	 * - Some things we can't filter out at all.	 * - Some filters are set based on interface type.	 */	*total_flags |= FIF_ALLMULTI;	if (*total_flags & FIF_OTHER_BSS ||	    *total_flags & FIF_PROMISC_IN_BSS)		*total_flags |= FIF_PROMISC_IN_BSS | FIF_OTHER_BSS;	if (is_interface_type(intf, IEEE80211_IF_TYPE_AP))		*total_flags |= FIF_PROMISC_IN_BSS;	/*	 * Check if there is any work left for us.	 */	if (intf->filter == *total_flags)		return;	intf->filter = *total_flags;	/*	 * Start configuration steps.	 * Note that the version error will always be dropped	 * since there is no filter for it at this time.	 */	rt2x00pci_register_read(rt2x00dev, RXCSR0, &reg);	rt2x00_set_field32(&reg, RXCSR0_DROP_CRC,			   !(*total_flags & FIF_FCSFAIL));	rt2x00_set_field32(&reg, RXCSR0_DROP_PHYSICAL,			   !(*total_flags & FIF_PLCPFAIL));	rt2x00_set_field32(&reg, RXCSR0_DROP_CONTROL,			   !(*total_flags & FIF_CONTROL));	rt2x00_set_field32(&reg, RXCSR0_DROP_NOT_TO_ME,			   !(*total_flags & FIF_PROMISC_IN_BSS));	rt2x00_set_field32(&reg, RXCSR0_DROP_TODS,			   !(*total_flags & FIF_PROMISC_IN_BSS));	rt2x00_set_field32(&reg, RXCSR0_DROP_VERSION_ERROR, 1);	rt2x00pci_register_write(rt2x00dev, RXCSR0, reg);}static int rt2400pci_set_retry_limit(struct ieee80211_hw *hw,				     u32 short_retry, u32 long_retry){	struct rt2x00_dev *rt2x00dev = hw->priv;	u32 reg;	rt2x00pci_register_read(rt2x00dev, CSR11, &reg);	rt2x00_set_field32(&reg, CSR11_LONG_RETRY, long_retry);	rt2x00_set_field32(&reg, CSR11_SHORT_RETRY, short_retry);	rt2x00pci_register_write(rt2x00dev, CSR11, reg);	return 0;}static int rt2400pci_conf_tx(struct ieee80211_hw *hw,			     int queue,			     const struct ieee80211_tx_queue_params *params){	struct rt2x00_dev *rt2x00dev = hw->priv;	/*	 * We don't support variating cw_min and cw_max variables	 * per queue. So by default we only configure the TX queue,	 * and ignore all other configurations.	 */	if (queue != IEEE80211_TX_QUEUE_DATA0)		return -EINVAL;	if (rt2x00mac_conf_tx(hw, queue, params))		return -EINVAL;	/*	 * Write configuration to register.	 */	rt2400pci_config_cw(rt2x00dev, &rt2x00dev->tx->tx_params);	return 0;}static u64 rt2400pci_get_tsf(struct ieee80211_hw *hw){	struct rt2x00_dev *rt2x00dev = hw->priv;	u64 tsf;	u32 reg;	rt2x00pci_register_read(rt2x00dev, CSR17, &reg);	tsf = (u64) rt2x00_get_field32(reg, CSR17_HIGH_TSFTIMER) << 32;	rt2x00pci_register_read(rt2x00dev, CSR16, &reg);	tsf |= rt2x00_get_field32(reg, CSR16_LOW_TSFTIMER);	return tsf;}static void rt2400pci_reset_tsf(struct ieee80211_hw *hw){	struct rt2x00_dev *rt2x00dev = hw->priv;	rt2x00pci_register_write(rt2x00dev, CSR16, 0);	rt2x00pci_register_write(rt2x00dev, CSR17, 0);}static int rt2400pci_tx_last_beacon(struct ieee80211_hw *hw){	struct rt2x00_dev *rt2x00dev = hw->priv;	u32 reg;	rt2x00pci_register_read(rt2x00dev, CSR15, &reg);	return rt2x00_get_field32(reg, CSR15_BEACON_SENT);}static const struct ieee80211_ops rt2400pci_mac80211_ops = {	.tx			= rt2x00mac_tx,	.start			= rt2x00mac_start,	.stop			= rt2x00mac_stop,	.add_interface		= rt2x00mac_add_interface,	.remove_interface	= rt2x00mac_remove_interface,	.config			= rt2x00mac_config,	.config_interface	= rt2x00mac_config_interface,	.configure_filter	= rt2400pci_configure_filter,	.get_stats		= rt2x00mac_get_stats,	.set_retry_limit	= rt2400pci_set_retry_limit,	.erp_ie_changed		= rt2x00mac_erp_ie_changed,	.conf_tx		= rt2400pci_conf_tx,	.get_tx_stats		= rt2x00mac_get_tx_stats,	.get_tsf		= rt2400pci_get_tsf,	.reset_tsf		= rt2400pci_reset_tsf,	.beacon_update		= rt2x00pci_beacon_update,	.tx_last_beacon		= rt2400pci_tx_last_beacon,};static const struct rt2x00lib_ops rt2400pci_rt2x00_ops = {	.irq_handler		= rt2400pci_interrupt,	.probe_hw		= rt2400pci_probe_hw,	.initialize		= rt2x00pci_initialize,	.uninitialize		= rt2x00pci_uninitialize,	.set_device_state	= rt2400pci_set_device_state,	.rfkill_poll		= rt2400pci_rfkill_poll,	.link_stats		= rt2400pci_link_stats,	.reset_tuner		= rt2400pci_reset_tuner,	.link_tuner		= rt2400pci_link_tuner,	.write_tx_desc		= rt2400pci_write_tx_desc,	.write_tx_data		= rt2x00pci_write_tx_data,	.kick_tx_queue		= rt2400pci_kick_tx_queue,	.fill_rxdone		= rt2400pci_fill_rxdone,	.config_mac_addr	= rt2400pci_config_mac_addr,	.config_bssid		= rt2400pci_config_bssid,	.config_type		= rt2400pci_config_type,	.config_preamble	= rt2400pci_config_preamble,	.config			= rt2400pci_config,};static const struct rt2x00_ops rt2400pci_ops = {	.name		= DRV_NAME,	.rxd_size	= RXD_DESC_SIZE,	.txd_size	= TXD_DESC_SIZE,	.eeprom_size	= EEPROM_SIZE,	.rf_size	= RF_SIZE,	.lib		= &rt2400pci_rt2x00_ops,	.hw		= &rt2400pci_mac80211_ops,#ifdef CONFIG_RT2X00_LIB_DEBUGFS	.debugfs	= &rt2400pci_rt2x00debug,#endif /* CONFIG_RT2X00_LIB_DEBUGFS */};/* * RT2400pci module information. */static struct pci_device_id rt2400pci_device_table[] = {	{ PCI_DEVICE(0x1814, 0x0101), PCI_DEVICE_DATA(&rt2400pci_ops) },	{ 0, }};MODULE_AUTHOR(DRV_PROJECT);MODULE_VERSION(DRV_VERSION);MODULE_DESCRIPTION("Ralink RT2400 PCI & PCMCIA Wireless LAN driver.");MODULE_SUPPORTED_DEVICE("Ralink RT2460 PCI & PCMCIA chipset based cards");MODULE_DEVICE_TABLE(pci, rt2400pci_device_table);MODULE_LICENSE("GPL");static struct pci_driver rt2400pci_driver = {	.name		= DRV_NAME,	.id_table	= rt2400pci_device_table,	.probe		= rt2x00pci_probe,	.remove		= __devexit_p(rt2x00pci_remove),	.suspend	= rt2x00pci_suspend,	.resume		= rt2x00pci_resume,};static int __init rt2400pci_init(void){	return pci_register_driver(&rt2400pci_driver);}static void __exit rt2400pci_exit(void){	pci_unregister_driver(&rt2400pci_driver);}module_init(rt2400pci_init);module_exit(rt2400pci_exit);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -