mirror of
git://projects.qi-hardware.com/openwrt-xburst.git
synced 2024-12-24 21:54:36 +02:00
Fix rt2x00 compilation and upgrade to the current mainline version (2.6.24)
git-svn-id: svn://svn.openwrt.org/openwrt/trunk@10573 3c298f89-4303-0410-b956-a3cf2f4a3e73
This commit is contained in:
parent
eccad93958
commit
bffb95528c
@ -10,7 +10,7 @@ include $(TOPDIR)/rules.mk
|
||||
include $(INCLUDE_DIR)/kernel.mk
|
||||
|
||||
PKG_NAME:=rt2x00
|
||||
PKG_VERSION:=cvs-20070712
|
||||
PKG_VERSION:=$(KERNEL_VERSION)
|
||||
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
|
||||
@ -109,6 +109,7 @@ PKG_EXTRA_KCONFIG:= \
|
||||
CONFIG_MAC80211=y \
|
||||
CONFIG_RT2X00=y \
|
||||
CONFIG_RT2X00_DEBUG=y \
|
||||
CONFIG_RT2X00_LIB_FIRMWARE=y \
|
||||
|
||||
ifneq ($(CONFIG_PACKAGE_kmod-rt2x00-pci),)
|
||||
PKG_EXTRA_KCONFIG+= CONFIG_RT2X00PCI=y
|
||||
|
@ -62,7 +62,7 @@ ifeq ($(CONFIG_RT2400PCI),y)
|
||||
obj-m += rt2400pci.o
|
||||
ifeq ($(CONFIG_RT2400PCI_RFKILL),y)
|
||||
rt2x00lib-objs += rt2x00rfkill.o
|
||||
CFLAGS += -DCONFIG_RT2X00_LIB_RFKILL
|
||||
EXTRA_CFLAGS += -DCONFIG_RT2X00_LIB_RFKILL
|
||||
endif
|
||||
endif
|
||||
|
||||
@ -70,7 +70,7 @@ ifeq ($(CONFIG_RT2500PCI),y)
|
||||
obj-m += rt2500pci.o
|
||||
ifeq ($(CONFIG_RT2500PCI_RFKILL),y)
|
||||
rt2x00lib-objs += rt2x00rfkill.o
|
||||
CFLAGS += -DCONFIG_RT2X00_LIB_RFKILL
|
||||
EXTRA_CFLAGS += -DCONFIG_RT2X00_LIB_RFKILL
|
||||
endif
|
||||
endif
|
||||
|
||||
@ -79,17 +79,17 @@ ifeq ($(CONFIG_RT2500USB),y)
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_RT61PCI),y)
|
||||
CFLAGS += -DCONFIG_RT2X00_LIB_FIRMWARE
|
||||
EXTRA_CFLAGS += -DCONFIG_RT2X00_LIB_FIRMWARE
|
||||
rt2x00lib-objs += rt2x00firmware.o
|
||||
obj-m += rt61pci.o
|
||||
ifeq ($(CONFIG_RT61PCI_RFKILL),y)
|
||||
rt2x00lib-objs += rt2x00rfkill.o
|
||||
CFLAGS += -DCONFIG_RT2X00_LIB_RFKILL
|
||||
EXTRA_CFLAGS += -DCONFIG_RT2X00_LIB_RFKILL
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_RT73USB),y)
|
||||
CFLAGS += -DCONFIG_RT2X00_LIB_FIRMWARE
|
||||
EXTRA_CFLAGS += -DCONFIG_RT2X00_LIB_FIRMWARE
|
||||
rt2x00lib-objs += rt2x00firmware.o
|
||||
obj-m += rt73usb.o
|
||||
endif
|
||||
@ -97,7 +97,7 @@ endif
|
||||
endif
|
||||
|
||||
MAKEFLAGS += --no-print-directory
|
||||
CFLAGS := -include $(SUBDIRS)/rt2x00_compat.h $(CFLAGS)
|
||||
EXTRA_CFLAGS := -include $(SUBDIRS)/rt2x00_compat.h $(CFLAGS)
|
||||
|
||||
all: default
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -35,9 +35,10 @@
|
||||
|
||||
/*
|
||||
* Signal information.
|
||||
* Defaul offset is required for RSSI <-> dBm conversion.
|
||||
*/
|
||||
#define MAX_SIGNAL 100
|
||||
#define MAX_RX_SSI -1
|
||||
#define MAX_RX_NOISE -110
|
||||
#define DEFAULT_RSSI_OFFSET 100
|
||||
|
||||
/*
|
||||
@ -48,6 +49,7 @@
|
||||
#define EEPROM_BASE 0x0000
|
||||
#define EEPROM_SIZE 0x0100
|
||||
#define BBP_SIZE 0x0020
|
||||
#define RF_SIZE 0x0010
|
||||
|
||||
/*
|
||||
* Control/Status Registers(CSR).
|
||||
@ -544,7 +546,6 @@
|
||||
*/
|
||||
#define MACCSR0 0x00e0
|
||||
|
||||
|
||||
/*
|
||||
* MACCSR1: MAC configuration register 1.
|
||||
* KICK_RX: Kick one-shot rx in one-shot rx mode.
|
||||
@ -716,10 +717,33 @@
|
||||
#define ARCSR5_SERVICE FIELD32(0x0000ff00)
|
||||
#define ARCSR5_LENGTH FIELD32(0xffff0000)
|
||||
|
||||
/*
|
||||
* BBP registers.
|
||||
* The wordsize of the BBP is 8 bits.
|
||||
*/
|
||||
|
||||
/*
|
||||
* R1: TX antenna control
|
||||
*/
|
||||
#define BBP_R1_TX_ANTENNA FIELD8(0x03)
|
||||
|
||||
/*
|
||||
* R4: RX antenna control
|
||||
*/
|
||||
#define BBP_R4_RX_ANTENNA FIELD8(0x06)
|
||||
|
||||
/*
|
||||
* RF registers
|
||||
*/
|
||||
|
||||
/*
|
||||
* RF 1
|
||||
*/
|
||||
#define RF1_TUNER FIELD32(0x00020000)
|
||||
|
||||
/*
|
||||
* RF 3
|
||||
*/
|
||||
#define RF3_TUNER FIELD32(0x00000100)
|
||||
#define RF3_TXPOWER FIELD32(0x00003e00)
|
||||
|
||||
@ -776,21 +800,6 @@
|
||||
#define EEPROM_TXPOWER_1 FIELD16(0x00ff)
|
||||
#define EEPROM_TXPOWER_2 FIELD16(0xff00)
|
||||
|
||||
/*
|
||||
* BBP content.
|
||||
* The wordsize of the BBP is 8 bits.
|
||||
*/
|
||||
|
||||
/*
|
||||
* BBP_R1: TX antenna control
|
||||
*/
|
||||
#define BBP_R1_TX_ANTENNA FIELD8(0x03)
|
||||
|
||||
/*
|
||||
* BBP_R4: RX antenna control
|
||||
*/
|
||||
#define BBP_R4_RX_ANTENNA FIELD8(0x06)
|
||||
|
||||
/*
|
||||
* DMA descriptor defines.
|
||||
*/
|
||||
@ -867,7 +876,7 @@
|
||||
#define RXD_W0_MULTICAST FIELD32(0x00000004)
|
||||
#define RXD_W0_BROADCAST FIELD32(0x00000008)
|
||||
#define RXD_W0_MY_BSS FIELD32(0x00000010)
|
||||
#define RXD_W0_CRC FIELD32(0x00000020)
|
||||
#define RXD_W0_CRC_ERROR FIELD32(0x00000020)
|
||||
#define RXD_W0_PHYSICAL_ERROR FIELD32(0x00000080)
|
||||
#define RXD_W0_DATABYTE_COUNT FIELD32(0xffff0000)
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -46,9 +46,10 @@
|
||||
|
||||
/*
|
||||
* Signal information.
|
||||
* Defaul offset is required for RSSI <-> dBm conversion.
|
||||
*/
|
||||
#define MAX_SIGNAL 100
|
||||
#define MAX_RX_SSI -1
|
||||
#define MAX_RX_NOISE -110
|
||||
#define DEFAULT_RSSI_OFFSET 121
|
||||
|
||||
/*
|
||||
@ -59,6 +60,7 @@
|
||||
#define EEPROM_BASE 0x0000
|
||||
#define EEPROM_SIZE 0x0200
|
||||
#define BBP_SIZE 0x0040
|
||||
#define RF_SIZE 0x0014
|
||||
|
||||
/*
|
||||
* Control/Status Registers(CSR).
|
||||
@ -438,16 +440,16 @@
|
||||
|
||||
/*
|
||||
* TXCSR8: CCK Tx BBP register.
|
||||
* CCK_SIGNAL: BBP rate field address for CCK.
|
||||
* CCK_SERVICE: BBP service field address for CCK.
|
||||
* CCK_LENGTH_LOW: BBP length low byte address for CCK.
|
||||
* CCK_LENGTH_HIGH: BBP length high byte address for CCK.
|
||||
*/
|
||||
#define TXCSR8 0x0098
|
||||
#define TXCSR8_CCK_SIGNAL FIELD32(0x000000ff)
|
||||
#define TXCSR8_CCK_SERVICE FIELD32(0x0000ff00)
|
||||
#define TXCSR8_CCK_LENGTH_LOW FIELD32(0x00ff0000)
|
||||
#define TXCSR8_CCK_LENGTH_HIGH FIELD32(0xff000000)
|
||||
#define TXCSR8_BBP_ID0 FIELD32(0x0000007f)
|
||||
#define TXCSR8_BBP_ID0_VALID FIELD32(0x00000080)
|
||||
#define TXCSR8_BBP_ID1 FIELD32(0x00007f00)
|
||||
#define TXCSR8_BBP_ID1_VALID FIELD32(0x00008000)
|
||||
#define TXCSR8_BBP_ID2 FIELD32(0x007f0000)
|
||||
#define TXCSR8_BBP_ID2_VALID FIELD32(0x00800000)
|
||||
#define TXCSR8_BBP_ID3 FIELD32(0x7f000000)
|
||||
#define TXCSR8_BBP_ID3_VALID FIELD32(0x80000000)
|
||||
|
||||
/*
|
||||
* TXCSR9: OFDM TX BBP registers
|
||||
@ -862,14 +864,32 @@
|
||||
#define ARCSR5_LENGTH FIELD32(0xffff0000)
|
||||
|
||||
/*
|
||||
* ACK/CTS payload consumed time registers.
|
||||
* ARTCSR0: CCK ACK/CTS payload consumed time for 1/2/5.5/11 mbps.
|
||||
* ARTCSR1: OFDM ACK/CTS payload consumed time for 6/9/12/18 mbps.
|
||||
* ARTCSR2: OFDM ACK/CTS payload consumed time for 24/36/48/54 mbps.
|
||||
*/
|
||||
#define ARTCSR0 0x014c
|
||||
#define ARTCSR0_ACK_CTS_11MBS FIELD32(0x000000ff)
|
||||
#define ARTCSR0_ACK_CTS_5_5MBS FIELD32(0x0000ff00)
|
||||
#define ARTCSR0_ACK_CTS_2MBS FIELD32(0x00ff0000)
|
||||
#define ARTCSR0_ACK_CTS_1MBS FIELD32(0xff000000)
|
||||
|
||||
|
||||
/*
|
||||
* ARTCSR1: OFDM ACK/CTS payload consumed time for 6/9/12/18 mbps.
|
||||
*/
|
||||
#define ARTCSR1 0x0150
|
||||
#define ARTCSR1_ACK_CTS_6MBS FIELD32(0x000000ff)
|
||||
#define ARTCSR1_ACK_CTS_9MBS FIELD32(0x0000ff00)
|
||||
#define ARTCSR1_ACK_CTS_12MBS FIELD32(0x00ff0000)
|
||||
#define ARTCSR1_ACK_CTS_18MBS FIELD32(0xff000000)
|
||||
|
||||
/*
|
||||
* ARTCSR2: OFDM ACK/CTS payload consumed time for 24/36/48/54 mbps.
|
||||
*/
|
||||
#define ARTCSR2 0x0154
|
||||
#define ARTCSR2_ACK_CTS_24MBS FIELD32(0x000000ff)
|
||||
#define ARTCSR2_ACK_CTS_36MBS FIELD32(0x0000ff00)
|
||||
#define ARTCSR2_ACK_CTS_48MBS FIELD32(0x00ff0000)
|
||||
#define ARTCSR2_ACK_CTS_54MBS FIELD32(0xff000000)
|
||||
|
||||
/*
|
||||
* SECCSR1_RT2509: WEP control register.
|
||||
@ -945,10 +965,40 @@
|
||||
#define UART2CSR3 0x0198
|
||||
#define UART2CSR4 0x019c
|
||||
|
||||
/*
|
||||
* BBP registers.
|
||||
* The wordsize of the BBP is 8 bits.
|
||||
*/
|
||||
|
||||
/*
|
||||
* R2: TX antenna control
|
||||
*/
|
||||
#define BBP_R2_TX_ANTENNA FIELD8(0x03)
|
||||
#define BBP_R2_TX_IQ_FLIP FIELD8(0x04)
|
||||
|
||||
/*
|
||||
* R14: RX antenna control
|
||||
*/
|
||||
#define BBP_R14_RX_ANTENNA FIELD8(0x03)
|
||||
#define BBP_R14_RX_IQ_FLIP FIELD8(0x04)
|
||||
|
||||
/*
|
||||
* BBP_R70
|
||||
*/
|
||||
#define BBP_R70_JAPAN_FILTER FIELD8(0x08)
|
||||
|
||||
/*
|
||||
* RF registers
|
||||
*/
|
||||
|
||||
/*
|
||||
* RF 1
|
||||
*/
|
||||
#define RF1_TUNER FIELD32(0x00020000)
|
||||
|
||||
/*
|
||||
* RF 3
|
||||
*/
|
||||
#define RF3_TUNER FIELD32(0x00000100)
|
||||
#define RF3_TXPOWER FIELD32(0x00003e00)
|
||||
|
||||
@ -1029,28 +1079,6 @@
|
||||
#define EEPROM_CALIBRATE_OFFSET 0x3e
|
||||
#define EEPROM_CALIBRATE_OFFSET_RSSI FIELD16(0x00ff)
|
||||
|
||||
/*
|
||||
* BBP content.
|
||||
* The wordsize of the BBP is 8 bits.
|
||||
*/
|
||||
|
||||
/*
|
||||
* BBP_R2: TX antenna control
|
||||
*/
|
||||
#define BBP_R2_TX_ANTENNA FIELD8(0x03)
|
||||
#define BBP_R2_TX_IQ_FLIP FIELD8(0x04)
|
||||
|
||||
/*
|
||||
* BBP_R14: RX antenna control
|
||||
*/
|
||||
#define BBP_R14_RX_ANTENNA FIELD8(0x03)
|
||||
#define BBP_R14_RX_IQ_FLIP FIELD8(0x04)
|
||||
|
||||
/*
|
||||
* BBP_R70
|
||||
*/
|
||||
#define BBP_R70_JAPAN_FILTER FIELD8(0x08)
|
||||
|
||||
/*
|
||||
* DMA descriptor defines.
|
||||
*/
|
||||
@ -1135,7 +1163,7 @@
|
||||
#define RXD_W0_MULTICAST FIELD32(0x00000004)
|
||||
#define RXD_W0_BROADCAST FIELD32(0x00000008)
|
||||
#define RXD_W0_MY_BSS FIELD32(0x00000010)
|
||||
#define RXD_W0_CRC FIELD32(0x00000020)
|
||||
#define RXD_W0_CRC_ERROR FIELD32(0x00000020)
|
||||
#define RXD_W0_OFDM FIELD32(0x00000040)
|
||||
#define RXD_W0_PHYSICAL_ERROR FIELD32(0x00000080)
|
||||
#define RXD_W0_CIPHER_OWNER FIELD32(0x00000100)
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -46,9 +46,10 @@
|
||||
|
||||
/*
|
||||
* Signal information.
|
||||
* Defaul offset is required for RSSI <-> dBm conversion.
|
||||
*/
|
||||
#define MAX_SIGNAL 100
|
||||
#define MAX_RX_SSI -1
|
||||
#define MAX_RX_NOISE -110
|
||||
#define DEFAULT_RSSI_OFFSET 120
|
||||
|
||||
/*
|
||||
@ -59,6 +60,7 @@
|
||||
#define EEPROM_BASE 0x0000
|
||||
#define EEPROM_SIZE 0x006a
|
||||
#define BBP_SIZE 0x0060
|
||||
#define RF_SIZE 0x0014
|
||||
|
||||
/*
|
||||
* Control/Status Registers(CSR).
|
||||
@ -72,8 +74,14 @@
|
||||
|
||||
/*
|
||||
* MAC_CSR1: System control.
|
||||
* SOFT_RESET: Software reset, 1: reset, 0: normal.
|
||||
* BBP_RESET: Hardware reset, 1: reset, 0, release.
|
||||
* HOST_READY: Host ready after initialization.
|
||||
*/
|
||||
#define MAC_CSR1 0x0402
|
||||
#define MAC_CSR1_SOFT_RESET FIELD16(0x00000001)
|
||||
#define MAC_CSR1_BBP_RESET FIELD16(0x00000002)
|
||||
#define MAC_CSR1_HOST_READY FIELD16(0x00000004)
|
||||
|
||||
/*
|
||||
* MAC_CSR2: STA MAC register 0.
|
||||
@ -246,8 +254,8 @@
|
||||
#define TXRX_CSR2_DROP_NOT_TO_ME FIELD16(0x0010)
|
||||
#define TXRX_CSR2_DROP_TODS FIELD16(0x0020)
|
||||
#define TXRX_CSR2_DROP_VERSION_ERROR FIELD16(0x0040)
|
||||
#define TXRX_CSR2_DROP_MCAST FIELD16(0x0200)
|
||||
#define TXRX_CSR2_DROP_BCAST FIELD16(0x0400)
|
||||
#define TXRX_CSR2_DROP_MULTICAST FIELD16(0x0200)
|
||||
#define TXRX_CSR2_DROP_BROADCAST FIELD16(0x0400)
|
||||
|
||||
/*
|
||||
* RX BBP ID registers
|
||||
@ -258,16 +266,40 @@
|
||||
#define TXRX_CSR4 0x0448
|
||||
|
||||
/*
|
||||
* TX BBP ID registers
|
||||
* TXRX_CSR5: CCK TX BBP ID0.
|
||||
* TXRX_CSR5: CCK TX BBP ID1.
|
||||
* TXRX_CSR5: OFDM TX BBP ID0.
|
||||
* TXRX_CSR5: OFDM TX BBP ID1.
|
||||
*/
|
||||
#define TXRX_CSR5 0x044a
|
||||
#define TXRX_CSR5_BBP_ID0 FIELD16(0x007f)
|
||||
#define TXRX_CSR5_BBP_ID0_VALID FIELD16(0x0080)
|
||||
#define TXRX_CSR5_BBP_ID1 FIELD16(0x7f00)
|
||||
#define TXRX_CSR5_BBP_ID1_VALID FIELD16(0x8000)
|
||||
|
||||
/*
|
||||
* TXRX_CSR6: CCK TX BBP ID1.
|
||||
*/
|
||||
#define TXRX_CSR6 0x044c
|
||||
#define TXRX_CSR6_BBP_ID0 FIELD16(0x007f)
|
||||
#define TXRX_CSR6_BBP_ID0_VALID FIELD16(0x0080)
|
||||
#define TXRX_CSR6_BBP_ID1 FIELD16(0x7f00)
|
||||
#define TXRX_CSR6_BBP_ID1_VALID FIELD16(0x8000)
|
||||
|
||||
/*
|
||||
* TXRX_CSR7: OFDM TX BBP ID0.
|
||||
*/
|
||||
#define TXRX_CSR7 0x044e
|
||||
#define TXRX_CSR7_BBP_ID0 FIELD16(0x007f)
|
||||
#define TXRX_CSR7_BBP_ID0_VALID FIELD16(0x0080)
|
||||
#define TXRX_CSR7_BBP_ID1 FIELD16(0x7f00)
|
||||
#define TXRX_CSR7_BBP_ID1_VALID FIELD16(0x8000)
|
||||
|
||||
/*
|
||||
* TXRX_CSR5: OFDM TX BBP ID1.
|
||||
*/
|
||||
#define TXRX_CSR8 0x0450
|
||||
#define TXRX_CSR8_BBP_ID0 FIELD16(0x007f)
|
||||
#define TXRX_CSR8_BBP_ID0_VALID FIELD16(0x0080)
|
||||
#define TXRX_CSR8_BBP_ID1 FIELD16(0x7f00)
|
||||
#define TXRX_CSR8_BBP_ID1_VALID FIELD16(0x8000)
|
||||
|
||||
/*
|
||||
* TXRX_CSR9: TX ACK time-out.
|
||||
@ -408,6 +440,7 @@
|
||||
* PHY_CSR4: Interface configuration.
|
||||
*/
|
||||
#define PHY_CSR4 0x04c8
|
||||
#define PHY_CSR4_LOW_RF_LE FIELD16(0x0001)
|
||||
|
||||
/*
|
||||
* BBP pre-TX registers.
|
||||
@ -473,28 +506,70 @@
|
||||
#define STA_CSR0_FCS_ERROR FIELD16(0xffff)
|
||||
|
||||
/*
|
||||
* Statistic Register.
|
||||
* STA_CSR1: PLCP error.
|
||||
* STA_CSR2: LONG error.
|
||||
* STA_CSR3: CCA false alarm.
|
||||
* STA_CSR4: RX FIFO overflow.
|
||||
* STA_CSR5: Beacon sent counter.
|
||||
* STA_CSR1: PLCP error count.
|
||||
*/
|
||||
#define STA_CSR1 0x04e2
|
||||
|
||||
/*
|
||||
* STA_CSR2: LONG error count.
|
||||
*/
|
||||
#define STA_CSR2 0x04e4
|
||||
|
||||
/*
|
||||
* STA_CSR3: CCA false alarm.
|
||||
* FALSE_CCA_ERROR: False CCA error count, cleared when read.
|
||||
*/
|
||||
#define STA_CSR3 0x04e6
|
||||
#define STA_CSR3_FALSE_CCA_ERROR FIELD16(0xffff)
|
||||
|
||||
/*
|
||||
* STA_CSR4: RX FIFO overflow.
|
||||
*/
|
||||
#define STA_CSR4 0x04e8
|
||||
|
||||
/*
|
||||
* STA_CSR5: Beacon sent counter.
|
||||
*/
|
||||
#define STA_CSR5 0x04ea
|
||||
|
||||
/*
|
||||
* Statistics registers
|
||||
*/
|
||||
#define STA_CSR6 0x04ec
|
||||
#define STA_CSR7 0x04ee
|
||||
#define STA_CSR8 0x04f0
|
||||
#define STA_CSR9 0x04f2
|
||||
#define STA_CSR10 0x04f4
|
||||
|
||||
/*
|
||||
* BBP registers.
|
||||
* The wordsize of the BBP is 8 bits.
|
||||
*/
|
||||
|
||||
/*
|
||||
* R2: TX antenna control
|
||||
*/
|
||||
#define BBP_R2_TX_ANTENNA FIELD8(0x03)
|
||||
#define BBP_R2_TX_IQ_FLIP FIELD8(0x04)
|
||||
|
||||
/*
|
||||
* R14: RX antenna control
|
||||
*/
|
||||
#define BBP_R14_RX_ANTENNA FIELD8(0x03)
|
||||
#define BBP_R14_RX_IQ_FLIP FIELD8(0x04)
|
||||
|
||||
/*
|
||||
* RF registers.
|
||||
*/
|
||||
|
||||
/*
|
||||
* RF 1
|
||||
*/
|
||||
#define RF1_TUNER FIELD32(0x00020000)
|
||||
|
||||
/*
|
||||
* RF 3
|
||||
*/
|
||||
#define RF3_TUNER FIELD32(0x00000100)
|
||||
#define RF3_TXPOWER FIELD32(0x00003e00)
|
||||
|
||||
@ -614,23 +689,6 @@
|
||||
#define EEPROM_CALIBRATE_OFFSET 0x0036
|
||||
#define EEPROM_CALIBRATE_OFFSET_RSSI FIELD16(0x00ff)
|
||||
|
||||
/*
|
||||
* BBP content.
|
||||
* The wordsize of the BBP is 8 bits.
|
||||
*/
|
||||
|
||||
/*
|
||||
* BBP_R2: TX antenna control
|
||||
*/
|
||||
#define BBP_R2_TX_ANTENNA FIELD8(0x03)
|
||||
#define BBP_R2_TX_IQ_FLIP FIELD8(0x04)
|
||||
|
||||
/*
|
||||
* BBP_R14: RX antenna control
|
||||
*/
|
||||
#define BBP_R14_RX_ANTENNA FIELD8(0x03)
|
||||
#define BBP_R14_RX_IQ_FLIP FIELD8(0x04)
|
||||
|
||||
/*
|
||||
* DMA descriptor defines.
|
||||
*/
|
||||
@ -693,11 +751,11 @@
|
||||
#define RXD_W0_MULTICAST FIELD32(0x00000004)
|
||||
#define RXD_W0_BROADCAST FIELD32(0x00000008)
|
||||
#define RXD_W0_MY_BSS FIELD32(0x00000010)
|
||||
#define RXD_W0_CRC FIELD32(0x00000020)
|
||||
#define RXD_W0_CRC_ERROR FIELD32(0x00000020)
|
||||
#define RXD_W0_OFDM FIELD32(0x00000040)
|
||||
#define RXD_W0_PHYSICAL_ERROR FIELD32(0x00000080)
|
||||
#define RXD_W0_CIPHER FIELD32(0x00000100)
|
||||
#define RXD_W0_CI_ERROR FIELD32(0x00000200)
|
||||
#define RXD_W0_CIPHER_ERROR FIELD32(0x00000200)
|
||||
#define RXD_W0_DATABYTE_COUNT FIELD32(0x0fff0000)
|
||||
|
||||
/*
|
||||
|
File diff suppressed because it is too large
Load Diff
205
package/rt2x00/src/rt2x00config.c
Normal file
205
package/rt2x00/src/rt2x00config.c
Normal file
@ -0,0 +1,205 @@
|
||||
/*
|
||||
Copyright (C) 2004 - 2007 rt2x00 SourceForge Project
|
||||
<http://rt2x00.serialmonkey.com>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the
|
||||
Free Software Foundation, Inc.,
|
||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
Module: rt2x00lib
|
||||
Abstract: rt2x00 generic configuration routines.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Set enviroment defines for rt2x00.h
|
||||
*/
|
||||
#define DRV_NAME "rt2x00lib"
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
#include "rt2x00.h"
|
||||
#include "rt2x00lib.h"
|
||||
|
||||
|
||||
/*
|
||||
* The MAC and BSSID addressess are simple array of bytes,
|
||||
* these arrays are little endian, so when sending the addressess
|
||||
* to the drivers, copy the it into a endian-signed variable.
|
||||
*
|
||||
* Note that all devices (except rt2500usb) have 32 bits
|
||||
* register word sizes. This means that whatever variable we
|
||||
* pass _must_ be a multiple of 32 bits. Otherwise the device
|
||||
* might not accept what we are sending to it.
|
||||
* This will also make it easier for the driver to write
|
||||
* the data to the device.
|
||||
*
|
||||
* Also note that when NULL is passed as address the
|
||||
* we will send 00:00:00:00:00 to the device to clear the address.
|
||||
* This will prevent the device being confused when it wants
|
||||
* to ACK frames or consideres itself associated.
|
||||
*/
|
||||
void rt2x00lib_config_mac_addr(struct rt2x00_dev *rt2x00dev, u8 *mac)
|
||||
{
|
||||
__le32 reg[2];
|
||||
|
||||
memset(®, 0, sizeof(reg));
|
||||
if (mac)
|
||||
memcpy(®, mac, ETH_ALEN);
|
||||
|
||||
rt2x00dev->ops->lib->config_mac_addr(rt2x00dev, ®[0]);
|
||||
}
|
||||
|
||||
void rt2x00lib_config_bssid(struct rt2x00_dev *rt2x00dev, u8 *bssid)
|
||||
{
|
||||
__le32 reg[2];
|
||||
|
||||
memset(®, 0, sizeof(reg));
|
||||
if (bssid)
|
||||
memcpy(®, bssid, ETH_ALEN);
|
||||
|
||||
rt2x00dev->ops->lib->config_bssid(rt2x00dev, ®[0]);
|
||||
}
|
||||
|
||||
void rt2x00lib_config_type(struct rt2x00_dev *rt2x00dev, const int type)
|
||||
{
|
||||
int tsf_sync;
|
||||
|
||||
switch (type) {
|
||||
case IEEE80211_IF_TYPE_IBSS:
|
||||
case IEEE80211_IF_TYPE_AP:
|
||||
tsf_sync = TSF_SYNC_BEACON;
|
||||
break;
|
||||
case IEEE80211_IF_TYPE_STA:
|
||||
tsf_sync = TSF_SYNC_INFRA;
|
||||
break;
|
||||
default:
|
||||
tsf_sync = TSF_SYNC_NONE;
|
||||
break;
|
||||
}
|
||||
|
||||
rt2x00dev->ops->lib->config_type(rt2x00dev, type, tsf_sync);
|
||||
}
|
||||
|
||||
void rt2x00lib_config(struct rt2x00_dev *rt2x00dev,
|
||||
struct ieee80211_conf *conf, const int force_config)
|
||||
{
|
||||
struct rt2x00lib_conf libconf;
|
||||
struct ieee80211_hw_mode *mode;
|
||||
struct ieee80211_rate *rate;
|
||||
int flags = 0;
|
||||
int short_slot_time;
|
||||
|
||||
/*
|
||||
* In some situations we want to force all configurations
|
||||
* to be reloaded (When resuming for instance).
|
||||
*/
|
||||
if (force_config) {
|
||||
flags = CONFIG_UPDATE_ALL;
|
||||
goto config;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check which configuration options have been
|
||||
* updated and should be send to the device.
|
||||
*/
|
||||
if (rt2x00dev->rx_status.phymode != conf->phymode)
|
||||
flags |= CONFIG_UPDATE_PHYMODE;
|
||||
if (rt2x00dev->rx_status.channel != conf->channel)
|
||||
flags |= CONFIG_UPDATE_CHANNEL;
|
||||
if (rt2x00dev->tx_power != conf->power_level)
|
||||
flags |= CONFIG_UPDATE_TXPOWER;
|
||||
if (rt2x00dev->rx_status.antenna == conf->antenna_sel_rx)
|
||||
flags |= CONFIG_UPDATE_ANTENNA;
|
||||
|
||||
/*
|
||||
* The following configuration options are never
|
||||
* stored anywhere and will always be updated.
|
||||
*/
|
||||
flags |= CONFIG_UPDATE_SLOT_TIME;
|
||||
flags |= CONFIG_UPDATE_BEACON_INT;
|
||||
|
||||
/*
|
||||
* We have determined what options should be updated,
|
||||
* now precalculate device configuration values depending
|
||||
* on what configuration options need to be updated.
|
||||
*/
|
||||
config:
|
||||
memset(&libconf, 0, sizeof(libconf));
|
||||
|
||||
if (flags & CONFIG_UPDATE_PHYMODE) {
|
||||
switch (conf->phymode) {
|
||||
case MODE_IEEE80211A:
|
||||
libconf.phymode = HWMODE_A;
|
||||
break;
|
||||
case MODE_IEEE80211B:
|
||||
libconf.phymode = HWMODE_B;
|
||||
break;
|
||||
case MODE_IEEE80211G:
|
||||
libconf.phymode = HWMODE_G;
|
||||
break;
|
||||
default:
|
||||
ERROR(rt2x00dev,
|
||||
"Attempt to configure unsupported mode (%d)"
|
||||
"Defaulting to 802.11b", conf->phymode);
|
||||
libconf.phymode = HWMODE_B;
|
||||
}
|
||||
|
||||
mode = &rt2x00dev->hwmodes[libconf.phymode];
|
||||
rate = &mode->rates[mode->num_rates - 1];
|
||||
|
||||
libconf.basic_rates =
|
||||
DEVICE_GET_RATE_FIELD(rate->val, RATEMASK) & DEV_BASIC_RATEMASK;
|
||||
}
|
||||
|
||||
if (flags & CONFIG_UPDATE_CHANNEL) {
|
||||
memcpy(&libconf.rf,
|
||||
&rt2x00dev->spec.channels[conf->channel_val],
|
||||
sizeof(libconf.rf));
|
||||
}
|
||||
|
||||
if (flags & CONFIG_UPDATE_SLOT_TIME) {
|
||||
short_slot_time = conf->flags & IEEE80211_CONF_SHORT_SLOT_TIME;
|
||||
|
||||
libconf.slot_time =
|
||||
short_slot_time ? SHORT_SLOT_TIME : SLOT_TIME;
|
||||
libconf.sifs = SIFS;
|
||||
libconf.pifs = short_slot_time ? SHORT_PIFS : PIFS;
|
||||
libconf.difs = short_slot_time ? SHORT_DIFS : DIFS;
|
||||
libconf.eifs = EIFS;
|
||||
}
|
||||
|
||||
libconf.conf = conf;
|
||||
|
||||
/*
|
||||
* Start configuration.
|
||||
*/
|
||||
rt2x00dev->ops->lib->config(rt2x00dev, flags, &libconf);
|
||||
|
||||
/*
|
||||
* Some configuration changes affect the link quality
|
||||
* which means we need to reset the link tuner.
|
||||
*/
|
||||
if (flags & (CONFIG_UPDATE_CHANNEL | CONFIG_UPDATE_ANTENNA))
|
||||
rt2x00lib_reset_link_tuner(rt2x00dev);
|
||||
|
||||
rt2x00dev->curr_hwmode = libconf.phymode;
|
||||
rt2x00dev->rx_status.phymode = conf->phymode;
|
||||
rt2x00dev->rx_status.freq = conf->freq;
|
||||
rt2x00dev->rx_status.channel = conf->channel;
|
||||
rt2x00dev->tx_power = conf->power_level;
|
||||
rt2x00dev->rx_status.antenna = conf->antenna_sel_rx;
|
||||
}
|
@ -21,22 +21,22 @@
|
||||
/*
|
||||
Module: rt2x00lib
|
||||
Abstract: rt2x00 debugfs specific routines.
|
||||
Supported chipsets: RT2460, RT2560, RT2570,
|
||||
rt2561, rt2561s, rt2661, rt2571W & rt2671.
|
||||
*/
|
||||
|
||||
#include <linux/debugfs.h>
|
||||
/*
|
||||
* Set enviroment defines for rt2x00.h
|
||||
*/
|
||||
#define DRV_NAME "rt2x00lib"
|
||||
|
||||
#include <asm/uaccess.h>
|
||||
#include <linux/debugfs.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/uaccess.h>
|
||||
|
||||
#include "rt2x00.h"
|
||||
#include "rt2x00debug.h"
|
||||
#include "rt2x00lib.h"
|
||||
|
||||
#define PRINT_REG8_STR ( "0x%.2x\n" )
|
||||
#define PRINT_REG16_STR ( "0x%.4x\n" )
|
||||
#define PRINT_REG32_STR ( "0x%.8x\n" )
|
||||
#define PRINT_REG_LEN_MAX ( 16 )
|
||||
#define PRINT_LINE_LEN_MAX ( 32 )
|
||||
#define PRINT_LINE_LEN_MAX 32
|
||||
|
||||
struct rt2x00debug_intf {
|
||||
/*
|
||||
@ -57,19 +57,24 @@ struct rt2x00debug_intf {
|
||||
* - driver folder
|
||||
* - driver file
|
||||
* - chipset file
|
||||
* - device flags file
|
||||
* - register offset/value files
|
||||
* - eeprom offset/value files
|
||||
* - bbp offset/value files
|
||||
* - rf offset/value files
|
||||
*/
|
||||
struct dentry *driver_folder;
|
||||
struct dentry *driver_entry;
|
||||
struct dentry *chipset_entry;
|
||||
struct dentry *dev_flags;
|
||||
struct dentry *csr_off_entry;
|
||||
struct dentry *csr_val_entry;
|
||||
struct dentry *eeprom_off_entry;
|
||||
struct dentry *eeprom_val_entry;
|
||||
struct dentry *bbp_off_entry;
|
||||
struct dentry *bbp_val_entry;
|
||||
struct dentry *rf_off_entry;
|
||||
struct dentry *rf_val_entry;
|
||||
|
||||
/*
|
||||
* Driver and chipset files will use a data buffer
|
||||
@ -85,6 +90,7 @@ struct rt2x00debug_intf {
|
||||
unsigned int offset_csr;
|
||||
unsigned int offset_eeprom;
|
||||
unsigned int offset_bbp;
|
||||
unsigned int offset_rf;
|
||||
};
|
||||
|
||||
static int rt2x00debug_file_open(struct inode *inode, struct file *file)
|
||||
@ -108,127 +114,120 @@ static int rt2x00debug_file_release(struct inode *inode, struct file *file)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static ssize_t rt2x00debug_file_read(void *device, char __user *buf,
|
||||
loff_t *offset, unsigned int word, const struct rt2x00debug_reg *reg)
|
||||
{
|
||||
unsigned long value;
|
||||
unsigned int size;
|
||||
char *line;
|
||||
|
||||
if (*offset)
|
||||
return 0;
|
||||
|
||||
line = kzalloc(PRINT_REG_LEN_MAX, GFP_KERNEL);
|
||||
if (!line)
|
||||
return -ENOMEM;
|
||||
|
||||
reg->read(device, word, &value);
|
||||
|
||||
if (reg->word_size == sizeof(u8))
|
||||
size = sprintf(line, PRINT_REG8_STR, (u8)value);
|
||||
else if (reg->word_size == sizeof(u16))
|
||||
size = sprintf(line, PRINT_REG16_STR, (u16)value);
|
||||
else
|
||||
size = sprintf(line, PRINT_REG32_STR, (u32)value);
|
||||
|
||||
if (copy_to_user(buf, line, size))
|
||||
goto exit;
|
||||
|
||||
kfree(line);
|
||||
|
||||
*offset += size;
|
||||
return size;
|
||||
|
||||
exit:
|
||||
kfree(line);
|
||||
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
static ssize_t rt2x00debug_file_write(void *device, const char __user *buf,
|
||||
loff_t *offset, unsigned int word, unsigned int length,
|
||||
const struct rt2x00debug_reg *reg)
|
||||
{
|
||||
unsigned long value;
|
||||
int size;
|
||||
char *line;
|
||||
|
||||
line = kzalloc(length, GFP_KERNEL);
|
||||
if (!line)
|
||||
return -ENOMEM;
|
||||
|
||||
if (copy_from_user(line, buf, length))
|
||||
goto exit;
|
||||
|
||||
size = strlen(line);
|
||||
value = simple_strtoul(line, NULL, 0);
|
||||
|
||||
reg->write(device, word, &value);
|
||||
|
||||
kfree(line);
|
||||
|
||||
*offset += size;
|
||||
return size;
|
||||
|
||||
exit:
|
||||
kfree(line);
|
||||
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
#define RT2X00DEBUGFS_OPS_READ(__name) \
|
||||
static ssize_t rt2x00debug_read_##__name(struct file *file, \
|
||||
char __user *buf, size_t length, loff_t *offset) \
|
||||
{ \
|
||||
#define RT2X00DEBUGFS_OPS_READ(__name, __format, __type) \
|
||||
static ssize_t rt2x00debug_read_##__name(struct file *file, \
|
||||
char __user *buf, \
|
||||
size_t length, \
|
||||
loff_t *offset) \
|
||||
{ \
|
||||
struct rt2x00debug_intf *intf = file->private_data; \
|
||||
const struct rt2x00debug *debug = intf->debug; \
|
||||
const struct rt2x00debug_reg *reg = &debug->reg_##__name;\
|
||||
char line[16]; \
|
||||
size_t size; \
|
||||
__type value; \
|
||||
\
|
||||
if (intf->offset_##__name > reg->word_count) \
|
||||
if (*offset) \
|
||||
return 0; \
|
||||
\
|
||||
if (intf->offset_##__name >= debug->__name.word_count) \
|
||||
return -EINVAL; \
|
||||
\
|
||||
return rt2x00debug_file_read(intf->rt2x00dev, buf, \
|
||||
offset, intf->offset_##__name, reg); \
|
||||
}
|
||||
debug->__name.read(intf->rt2x00dev, \
|
||||
intf->offset_##__name, &value); \
|
||||
\
|
||||
size = sprintf(line, __format, value); \
|
||||
\
|
||||
if (copy_to_user(buf, line, size)) \
|
||||
return -EFAULT; \
|
||||
\
|
||||
*offset += size; \
|
||||
return size; \
|
||||
}
|
||||
|
||||
RT2X00DEBUGFS_OPS_READ(csr);
|
||||
RT2X00DEBUGFS_OPS_READ(eeprom);
|
||||
RT2X00DEBUGFS_OPS_READ(bbp);
|
||||
|
||||
#define RT2X00DEBUGFS_OPS_WRITE(__name) \
|
||||
static ssize_t rt2x00debug_write_##__name(struct file *file, \
|
||||
const char __user *buf, size_t length, loff_t *offset) \
|
||||
{ \
|
||||
#define RT2X00DEBUGFS_OPS_WRITE(__name, __type) \
|
||||
static ssize_t rt2x00debug_write_##__name(struct file *file, \
|
||||
const char __user *buf,\
|
||||
size_t length, \
|
||||
loff_t *offset) \
|
||||
{ \
|
||||
struct rt2x00debug_intf *intf = file->private_data; \
|
||||
const struct rt2x00debug *debug = intf->debug; \
|
||||
const struct rt2x00debug_reg *reg = &debug->reg_##__name;\
|
||||
char line[16]; \
|
||||
size_t size; \
|
||||
__type value; \
|
||||
\
|
||||
if (intf->offset_##__name > reg->word_count) \
|
||||
if (*offset) \
|
||||
return 0; \
|
||||
\
|
||||
if (!capable(CAP_NET_ADMIN)) \
|
||||
return -EPERM; \
|
||||
\
|
||||
if (intf->offset_##__name >= debug->__name.word_count) \
|
||||
return -EINVAL; \
|
||||
\
|
||||
return rt2x00debug_file_write(intf->rt2x00dev, buf, \
|
||||
offset, intf->offset_##__name, length, reg); \
|
||||
}
|
||||
if (copy_from_user(line, buf, length)) \
|
||||
return -EFAULT; \
|
||||
\
|
||||
size = strlen(line); \
|
||||
value = simple_strtoul(line, NULL, 0); \
|
||||
\
|
||||
debug->__name.write(intf->rt2x00dev, \
|
||||
intf->offset_##__name, value); \
|
||||
\
|
||||
*offset += size; \
|
||||
return size; \
|
||||
}
|
||||
|
||||
RT2X00DEBUGFS_OPS_WRITE(csr);
|
||||
RT2X00DEBUGFS_OPS_WRITE(eeprom);
|
||||
RT2X00DEBUGFS_OPS_WRITE(bbp);
|
||||
|
||||
#define RT2X00DEBUGFS_OPS(__name) \
|
||||
static const struct file_operations rt2x00debug_fop_##__name = {\
|
||||
#define RT2X00DEBUGFS_OPS(__name, __format, __type) \
|
||||
RT2X00DEBUGFS_OPS_READ(__name, __format, __type); \
|
||||
RT2X00DEBUGFS_OPS_WRITE(__name, __type); \
|
||||
\
|
||||
static const struct file_operations rt2x00debug_fop_##__name = {\
|
||||
.owner = THIS_MODULE, \
|
||||
.read = rt2x00debug_read_##__name, \
|
||||
.write = rt2x00debug_write_##__name, \
|
||||
.open = rt2x00debug_file_open, \
|
||||
.release = rt2x00debug_file_release, \
|
||||
};
|
||||
};
|
||||
|
||||
RT2X00DEBUGFS_OPS(csr);
|
||||
RT2X00DEBUGFS_OPS(eeprom);
|
||||
RT2X00DEBUGFS_OPS(bbp);
|
||||
RT2X00DEBUGFS_OPS(csr, "0x%.8x\n", u32);
|
||||
RT2X00DEBUGFS_OPS(eeprom, "0x%.4x\n", u16);
|
||||
RT2X00DEBUGFS_OPS(bbp, "0x%.2x\n", u8);
|
||||
RT2X00DEBUGFS_OPS(rf, "0x%.8x\n", u32);
|
||||
|
||||
static ssize_t rt2x00debug_read_dev_flags(struct file *file,
|
||||
char __user *buf,
|
||||
size_t length,
|
||||
loff_t *offset)
|
||||
{
|
||||
struct rt2x00debug_intf *intf = file->private_data;
|
||||
char line[16];
|
||||
size_t size;
|
||||
|
||||
if (*offset)
|
||||
return 0;
|
||||
|
||||
size = sprintf(line, "0x%.8x\n", (unsigned int)intf->rt2x00dev->flags);
|
||||
|
||||
if (copy_to_user(buf, line, size))
|
||||
return -EFAULT;
|
||||
|
||||
*offset += size;
|
||||
return size;
|
||||
}
|
||||
|
||||
static const struct file_operations rt2x00debug_fop_dev_flags = {
|
||||
.owner = THIS_MODULE,
|
||||
.read = rt2x00debug_read_dev_flags,
|
||||
.open = rt2x00debug_file_open,
|
||||
.release = rt2x00debug_file_release,
|
||||
};
|
||||
|
||||
static struct dentry *rt2x00debug_create_file_driver(const char *name,
|
||||
struct rt2x00debug_intf *intf, struct debugfs_blob_wrapper *blob)
|
||||
struct rt2x00debug_intf
|
||||
*intf,
|
||||
struct debugfs_blob_wrapper
|
||||
*blob)
|
||||
{
|
||||
char *data;
|
||||
|
||||
@ -246,20 +245,24 @@ static struct dentry *rt2x00debug_create_file_driver(const char *name,
|
||||
}
|
||||
|
||||
static struct dentry *rt2x00debug_create_file_chipset(const char *name,
|
||||
struct rt2x00debug_intf *intf, struct debugfs_blob_wrapper *blob)
|
||||
struct rt2x00debug_intf
|
||||
*intf,
|
||||
struct
|
||||
debugfs_blob_wrapper
|
||||
*blob)
|
||||
{
|
||||
const struct rt2x00debug *debug = intf->debug;
|
||||
char *data;
|
||||
|
||||
data = kzalloc(3 * PRINT_LINE_LEN_MAX, GFP_KERNEL);
|
||||
data = kzalloc(4 * PRINT_LINE_LEN_MAX, GFP_KERNEL);
|
||||
if (!data)
|
||||
return NULL;
|
||||
|
||||
blob->data = data;
|
||||
data += sprintf(data, "csr length: %d\n", debug->reg_csr.word_count);
|
||||
data += sprintf(data, "eeprom length: %d\n",
|
||||
debug->reg_eeprom.word_count);
|
||||
data += sprintf(data, "bbp length: %d\n", debug->reg_bbp.word_count);
|
||||
data += sprintf(data, "csr length: %d\n", debug->csr.word_count);
|
||||
data += sprintf(data, "eeprom length: %d\n", debug->eeprom.word_count);
|
||||
data += sprintf(data, "bbp length: %d\n", debug->bbp.word_count);
|
||||
data += sprintf(data, "rf length: %d\n", debug->rf.word_count);
|
||||
blob->size = strlen(blob->data);
|
||||
|
||||
return debugfs_create_blob(name, S_IRUGO, intf->driver_folder, blob);
|
||||
@ -280,53 +283,54 @@ void rt2x00debug_register(struct rt2x00_dev *rt2x00dev)
|
||||
intf->rt2x00dev = rt2x00dev;
|
||||
rt2x00dev->debugfs_intf = intf;
|
||||
|
||||
intf->driver_folder = debugfs_create_dir(intf->rt2x00dev->ops->name,
|
||||
intf->driver_folder =
|
||||
debugfs_create_dir(intf->rt2x00dev->ops->name,
|
||||
rt2x00dev->hw->wiphy->debugfsdir);
|
||||
if (IS_ERR(intf->driver_folder))
|
||||
goto exit;
|
||||
|
||||
intf->driver_entry = rt2x00debug_create_file_driver("driver",
|
||||
intf, &intf->driver_blob);
|
||||
intf->driver_entry =
|
||||
rt2x00debug_create_file_driver("driver", intf, &intf->driver_blob);
|
||||
if (IS_ERR(intf->driver_entry))
|
||||
goto exit;
|
||||
|
||||
intf->chipset_entry = rt2x00debug_create_file_chipset("chipset",
|
||||
intf->chipset_entry =
|
||||
rt2x00debug_create_file_chipset("chipset",
|
||||
intf, &intf->chipset_blob);
|
||||
if (IS_ERR(intf->chipset_entry))
|
||||
goto exit;
|
||||
|
||||
intf->csr_off_entry = debugfs_create_u32("csr_offset",
|
||||
S_IRUGO | S_IWUSR, intf->driver_folder, &intf->offset_csr);
|
||||
if (IS_ERR(intf->csr_off_entry))
|
||||
intf->dev_flags = debugfs_create_file("dev_flags", S_IRUGO,
|
||||
intf->driver_folder, intf,
|
||||
&rt2x00debug_fop_dev_flags);
|
||||
if (IS_ERR(intf->dev_flags))
|
||||
goto exit;
|
||||
|
||||
intf->csr_val_entry = debugfs_create_file("csr_value",
|
||||
S_IRUGO | S_IWUSR, intf->driver_folder, intf,
|
||||
&rt2x00debug_fop_csr);
|
||||
if (IS_ERR(intf->csr_val_entry))
|
||||
goto exit;
|
||||
#define RT2X00DEBUGFS_CREATE_ENTRY(__intf, __name) \
|
||||
({ \
|
||||
(__intf)->__name##_off_entry = \
|
||||
debugfs_create_u32(__stringify(__name) "_offset", \
|
||||
S_IRUGO | S_IWUSR, \
|
||||
(__intf)->driver_folder, \
|
||||
&(__intf)->offset_##__name); \
|
||||
if (IS_ERR((__intf)->__name##_off_entry)) \
|
||||
goto exit; \
|
||||
\
|
||||
(__intf)->__name##_val_entry = \
|
||||
debugfs_create_file(__stringify(__name) "_value", \
|
||||
S_IRUGO | S_IWUSR, \
|
||||
(__intf)->driver_folder, \
|
||||
(__intf), &rt2x00debug_fop_##__name);\
|
||||
if (IS_ERR((__intf)->__name##_val_entry)) \
|
||||
goto exit; \
|
||||
})
|
||||
|
||||
intf->eeprom_off_entry = debugfs_create_u32("eeprom_offset",
|
||||
S_IRUGO | S_IWUSR, intf->driver_folder, &intf->offset_eeprom);
|
||||
if (IS_ERR(intf->eeprom_off_entry))
|
||||
goto exit;
|
||||
RT2X00DEBUGFS_CREATE_ENTRY(intf, csr);
|
||||
RT2X00DEBUGFS_CREATE_ENTRY(intf, eeprom);
|
||||
RT2X00DEBUGFS_CREATE_ENTRY(intf, bbp);
|
||||
RT2X00DEBUGFS_CREATE_ENTRY(intf, rf);
|
||||
|
||||
intf->eeprom_val_entry = debugfs_create_file("eeprom_value",
|
||||
S_IRUGO | S_IWUSR, intf->driver_folder, intf,
|
||||
&rt2x00debug_fop_eeprom);
|
||||
if (IS_ERR(intf->eeprom_val_entry))
|
||||
goto exit;
|
||||
|
||||
intf->bbp_off_entry = debugfs_create_u32("bbp_offset",
|
||||
S_IRUGO | S_IWUSR, intf->driver_folder, &intf->offset_bbp);
|
||||
if (IS_ERR(intf->bbp_off_entry))
|
||||
goto exit;
|
||||
|
||||
intf->bbp_val_entry = debugfs_create_file("bbp_value",
|
||||
S_IRUGO | S_IWUSR, intf->driver_folder, intf,
|
||||
&rt2x00debug_fop_bbp);
|
||||
if (IS_ERR(intf->bbp_val_entry))
|
||||
goto exit;
|
||||
#undef RT2X00DEBUGFS_CREATE_ENTRY
|
||||
|
||||
return;
|
||||
|
||||
@ -344,12 +348,15 @@ void rt2x00debug_deregister(struct rt2x00_dev *rt2x00dev)
|
||||
if (unlikely(!intf))
|
||||
return;
|
||||
|
||||
debugfs_remove(intf->rf_val_entry);
|
||||
debugfs_remove(intf->rf_off_entry);
|
||||
debugfs_remove(intf->bbp_val_entry);
|
||||
debugfs_remove(intf->bbp_off_entry);
|
||||
debugfs_remove(intf->eeprom_val_entry);
|
||||
debugfs_remove(intf->eeprom_off_entry);
|
||||
debugfs_remove(intf->csr_val_entry);
|
||||
debugfs_remove(intf->csr_off_entry);
|
||||
debugfs_remove(intf->dev_flags);
|
||||
debugfs_remove(intf->chipset_entry);
|
||||
debugfs_remove(intf->driver_entry);
|
||||
debugfs_remove(intf->driver_folder);
|
||||
|
@ -21,23 +21,23 @@
|
||||
/*
|
||||
Module: rt2x00debug
|
||||
Abstract: Data structures for the rt2x00debug.
|
||||
Supported chipsets: RT2460, RT2560, RT2570,
|
||||
rt2561, rt2561s, rt2661, rt2571W & rt2671.
|
||||
*/
|
||||
|
||||
#ifndef RT2X00DEBUG_H
|
||||
#define RT2X00DEBUG_H
|
||||
|
||||
typedef void (debug_access_t)(struct rt2x00_dev *rt2x00dev,
|
||||
const unsigned long word, void *data);
|
||||
struct rt2x00_dev;
|
||||
|
||||
struct rt2x00debug_reg {
|
||||
debug_access_t *read;
|
||||
debug_access_t *write;
|
||||
|
||||
unsigned int word_size;
|
||||
unsigned int word_count;
|
||||
};
|
||||
#define RT2X00DEBUGFS_REGISTER_ENTRY(__name, __type) \
|
||||
struct reg##__name { \
|
||||
void (*read)(const struct rt2x00_dev *rt2x00dev, \
|
||||
const unsigned int word, __type *data); \
|
||||
void (*write)(const struct rt2x00_dev *rt2x00dev, \
|
||||
const unsigned int word, __type data); \
|
||||
\
|
||||
unsigned int word_size; \
|
||||
unsigned int word_count; \
|
||||
} __name
|
||||
|
||||
struct rt2x00debug {
|
||||
/*
|
||||
@ -46,19 +46,12 @@ struct rt2x00debug {
|
||||
struct module *owner;
|
||||
|
||||
/*
|
||||
* Register access information.
|
||||
* Register access entries.
|
||||
*/
|
||||
struct rt2x00debug_reg reg_csr;
|
||||
struct rt2x00debug_reg reg_eeprom;
|
||||
struct rt2x00debug_reg reg_bbp;
|
||||
RT2X00DEBUGFS_REGISTER_ENTRY(csr, u32);
|
||||
RT2X00DEBUGFS_REGISTER_ENTRY(eeprom, u16);
|
||||
RT2X00DEBUGFS_REGISTER_ENTRY(bbp, u8);
|
||||
RT2X00DEBUGFS_REGISTER_ENTRY(rf, u32);
|
||||
};
|
||||
|
||||
#ifdef CONFIG_RT2X00_LIB_DEBUGFS
|
||||
void rt2x00debug_register(struct rt2x00_dev *rt2x00dev);
|
||||
void rt2x00debug_deregister(struct rt2x00_dev *rt2x00dev);
|
||||
#else /* CONFIG_RT2X00_LIB_DEBUGFS */
|
||||
static inline void rt2x00debug_register(struct rt2x00_dev *rt2x00dev){}
|
||||
static inline void rt2x00debug_deregister(struct rt2x00_dev *rt2x00dev){}
|
||||
#endif /* CONFIG_RT2X00_LIB_DEBUGFS */
|
||||
|
||||
#endif /* RT2X00DEBUG_H */
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -20,8 +20,7 @@
|
||||
|
||||
/*
|
||||
Module: rt2x00lib
|
||||
Abstract: rt2x00 firmware loading specific routines.
|
||||
Supported chipsets: rt2561, rt2561s, rt2661, rt2571W & rt2671.
|
||||
Abstract: rt2x00 firmware loading routines.
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -29,24 +28,44 @@
|
||||
*/
|
||||
#define DRV_NAME "rt2x00lib"
|
||||
|
||||
#include <linux/delay.h>
|
||||
#include <linux/crc-itu-t.h>
|
||||
#include <linux/firmware.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
#include "rt2x00.h"
|
||||
#include "rt2x00lib.h"
|
||||
#include "rt2x00firmware.h"
|
||||
|
||||
static void rt2x00lib_load_firmware_continued(const struct firmware *fw,
|
||||
void *context)
|
||||
static int rt2x00lib_request_firmware(struct rt2x00_dev *rt2x00dev)
|
||||
{
|
||||
struct rt2x00_dev *rt2x00dev = context;
|
||||
struct device *device = wiphy_dev(rt2x00dev->hw->wiphy);
|
||||
const struct firmware *fw;
|
||||
char *fw_name;
|
||||
int retval;
|
||||
u16 crc;
|
||||
u16 tmp;
|
||||
|
||||
/*
|
||||
* Read correct firmware from harddisk.
|
||||
*/
|
||||
fw_name = rt2x00dev->ops->lib->get_firmware_name(rt2x00dev);
|
||||
if (!fw_name) {
|
||||
ERROR(rt2x00dev,
|
||||
"Invalid firmware filename.\n"
|
||||
"Please file bug report to %s.\n", DRV_PROJECT);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
INFO(rt2x00dev, "Loading firmware file '%s'.\n", fw_name);
|
||||
|
||||
retval = request_firmware(&fw, fw_name, device);
|
||||
if (retval) {
|
||||
ERROR(rt2x00dev, "Failed to request Firmware.\n");
|
||||
return retval;
|
||||
}
|
||||
|
||||
if (!fw || !fw->size || !fw->data) {
|
||||
ERROR(rt2x00dev, "Failed to read Firmware.\n");
|
||||
goto exit_failed;
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -57,75 +76,49 @@ static void rt2x00lib_load_firmware_continued(const struct firmware *fw,
|
||||
*/
|
||||
tmp = 0;
|
||||
crc = crc_itu_t(0, fw->data, fw->size - 2);
|
||||
crc = crc_itu_t(crc, (u8*)&tmp, 2);
|
||||
crc = crc_itu_t(crc, (u8 *)&tmp, 2);
|
||||
|
||||
if (crc != (fw->data[fw->size - 2] << 8 | fw->data[fw->size - 1])) {
|
||||
ERROR(rt2x00dev, "Firmware CRC error.\n");
|
||||
goto exit_failed;
|
||||
retval = -ENOENT;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
INFO(rt2x00dev, "Firmware detected - version: %d.%d.\n",
|
||||
fw->data[fw->size - 4], fw->data[fw->size - 3]);
|
||||
|
||||
rt2x00dev->fw = fw;
|
||||
|
||||
return 0;
|
||||
|
||||
exit:
|
||||
release_firmware(fw);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
int rt2x00lib_load_firmware(struct rt2x00_dev *rt2x00dev)
|
||||
{
|
||||
int retval;
|
||||
|
||||
if (!rt2x00dev->fw) {
|
||||
retval = rt2x00lib_request_firmware(rt2x00dev);
|
||||
if (retval)
|
||||
return retval;
|
||||
}
|
||||
|
||||
/*
|
||||
* Send firmware to the device.
|
||||
*/
|
||||
if (rt2x00dev->ops->lib->load_firmware(rt2x00dev, fw->data, fw->size))
|
||||
goto exit_failed;
|
||||
|
||||
INFO(rt2x00dev, "Firmware detected - version: %d.%d.\n",
|
||||
fw->data[fw->size - 4], fw->data[fw->size - 3]);
|
||||
|
||||
__set_bit(FIRMWARE_LOADED, &rt2x00dev->flags);
|
||||
|
||||
return;
|
||||
|
||||
exit_failed:
|
||||
rt2x00debug_deregister(rt2x00dev);
|
||||
|
||||
__set_bit(FIRMWARE_FAILED, &rt2x00dev->flags);
|
||||
retval = rt2x00dev->ops->lib->load_firmware(rt2x00dev,
|
||||
rt2x00dev->fw->data,
|
||||
rt2x00dev->fw->size);
|
||||
return retval;
|
||||
}
|
||||
|
||||
int rt2x00lib_load_firmware(struct rt2x00_dev *rt2x00dev)
|
||||
void rt2x00lib_free_firmware(struct rt2x00_dev *rt2x00dev)
|
||||
{
|
||||
char *fw_name;
|
||||
int status = -EINVAL;
|
||||
|
||||
/*
|
||||
* Read correct firmware from harddisk.
|
||||
*/
|
||||
fw_name = rt2x00dev->ops->lib->get_fw_name(rt2x00dev);
|
||||
if (!fw_name) {
|
||||
ERROR(rt2x00dev,
|
||||
"Invalid firmware filename.\n"
|
||||
"Please file bug report to %s.\n", DRV_PROJECT);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
INFO(rt2x00dev, "Loading firmware file '%s'.\n", fw_name);
|
||||
|
||||
status = request_firmware_nowait(THIS_MODULE, FW_ACTION_HOTPLUG,
|
||||
fw_name, wiphy_dev(rt2x00dev->hw->wiphy), rt2x00dev,
|
||||
&rt2x00lib_load_firmware_continued);
|
||||
|
||||
if (status)
|
||||
ERROR(rt2x00dev, "Failed to request Firmware.\n");
|
||||
|
||||
return status;
|
||||
release_firmware(rt2x00dev->fw);
|
||||
rt2x00dev->fw = NULL;
|
||||
}
|
||||
|
||||
int rt2x00lib_load_firmware_wait(struct rt2x00_dev *rt2x00dev)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
if (!test_bit(FIRMWARE_REQUIRED, &rt2x00dev->flags))
|
||||
return 0;
|
||||
|
||||
for (i = 0; i < 150; i++) {
|
||||
if (test_bit(FIRMWARE_FAILED, &rt2x00dev->flags))
|
||||
return -EIO;
|
||||
if (test_bit(FIRMWARE_LOADED, &rt2x00dev->flags))
|
||||
return 0;
|
||||
msleep(20);
|
||||
}
|
||||
|
||||
ERROR(rt2x00dev, "Firmware loading timed out.\n");
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
@ -20,62 +20,100 @@
|
||||
|
||||
/*
|
||||
Module: rt2x00lib
|
||||
Abstract: Data structures for the rt2x00lib module.
|
||||
Supported chipsets: RT2460, RT2560, RT2570,
|
||||
rt2561, rt2561s, rt2661, rt2571W & rt2671.
|
||||
Abstract: Data structures and definitions for the rt2x00lib module.
|
||||
*/
|
||||
|
||||
#ifndef RT2X00LIB_H
|
||||
#define RT2X00LIB_H
|
||||
|
||||
/*
|
||||
* Driver allocation handlers.
|
||||
* Interval defines
|
||||
* Both the link tuner as the rfkill will be called once per second.
|
||||
*/
|
||||
int rt2x00lib_probe_dev(struct rt2x00_dev *rt2x00dev);
|
||||
void rt2x00lib_remove_dev(struct rt2x00_dev *rt2x00dev);
|
||||
#define LINK_TUNE_INTERVAL ( round_jiffies_relative(HZ) )
|
||||
#define RFKILL_POLL_INTERVAL ( 1000 )
|
||||
|
||||
/*
|
||||
* Driver status handlers.
|
||||
* Radio control handlers.
|
||||
*/
|
||||
int rt2x00lib_suspend(struct rt2x00_dev *rt2x00dev, pm_message_t state);
|
||||
int rt2x00lib_resume(struct rt2x00_dev *rt2x00dev);
|
||||
int rt2x00lib_enable_radio(struct rt2x00_dev *rt2x00dev);
|
||||
void rt2x00lib_disable_radio(struct rt2x00_dev *rt2x00dev);
|
||||
void rt2x00lib_toggle_rx(struct rt2x00_dev *rt2x00dev, enum dev_state state);
|
||||
void rt2x00lib_reset_link_tuner(struct rt2x00_dev *rt2x00dev);
|
||||
|
||||
/*
|
||||
* Interrupt context handlers.
|
||||
* Initialization handlers.
|
||||
*/
|
||||
void rt2x00lib_txdone(struct data_entry *entry,
|
||||
const int status, const int retry);
|
||||
void rt2x00lib_rxdone(struct data_entry *entry, char *data,
|
||||
const int size, const int signal, const int rssi, const int ofdm);
|
||||
int rt2x00lib_initialize(struct rt2x00_dev *rt2x00dev);
|
||||
void rt2x00lib_uninitialize(struct rt2x00_dev *rt2x00dev);
|
||||
|
||||
/*
|
||||
* TX descriptor initializer
|
||||
* Configuration handlers.
|
||||
*/
|
||||
void rt2x00lib_write_tx_desc(struct rt2x00_dev *rt2x00dev,
|
||||
struct data_entry *entry, struct data_desc *txd,
|
||||
struct ieee80211_hdr *ieee80211hdr, unsigned int length,
|
||||
struct ieee80211_tx_control *control);
|
||||
void rt2x00lib_config_mac_addr(struct rt2x00_dev *rt2x00dev, u8 *mac);
|
||||
void rt2x00lib_config_bssid(struct rt2x00_dev *rt2x00dev, u8 *bssid);
|
||||
void rt2x00lib_config_type(struct rt2x00_dev *rt2x00dev, const int type);
|
||||
void rt2x00lib_config(struct rt2x00_dev *rt2x00dev,
|
||||
struct ieee80211_conf *conf, const int force_config);
|
||||
|
||||
/*
|
||||
* mac80211 handlers.
|
||||
* Firmware handlers.
|
||||
*/
|
||||
int rt2x00lib_tx(struct ieee80211_hw *hw, struct sk_buff *skb,
|
||||
struct ieee80211_tx_control *control);
|
||||
int rt2x00lib_reset(struct ieee80211_hw *hw);
|
||||
int rt2x00lib_add_interface(struct ieee80211_hw *hw,
|
||||
struct ieee80211_if_init_conf *conf);
|
||||
void rt2x00lib_remove_interface(struct ieee80211_hw *hw,
|
||||
struct ieee80211_if_init_conf *conf);
|
||||
int rt2x00lib_config(struct ieee80211_hw *hw, struct ieee80211_conf *conf);
|
||||
int rt2x00lib_config_interface(struct ieee80211_hw *hw, int if_id,
|
||||
struct ieee80211_if_conf *conf);
|
||||
void rt2x00lib_set_multicast_list(struct ieee80211_hw *hw,
|
||||
unsigned short flags, int mc_count);
|
||||
int rt2x00lib_get_tx_stats(struct ieee80211_hw *hw,
|
||||
struct ieee80211_tx_queue_stats *stats);
|
||||
int rt2x00lib_conf_tx(struct ieee80211_hw *hw, int queue,
|
||||
const struct ieee80211_tx_queue_params *params);
|
||||
#ifdef CONFIG_RT2X00_LIB_FIRMWARE
|
||||
int rt2x00lib_load_firmware(struct rt2x00_dev *rt2x00dev);
|
||||
void rt2x00lib_free_firmware(struct rt2x00_dev *rt2x00dev);
|
||||
#else
|
||||
static inline int rt2x00lib_load_firmware(struct rt2x00_dev *rt2x00dev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
static inline void rt2x00lib_free_firmware(struct rt2x00_dev *rt2x00dev)
|
||||
{
|
||||
}
|
||||
#endif /* CONFIG_RT2X00_LIB_FIRMWARE */
|
||||
|
||||
#include "rt2x00debug.h"
|
||||
/*
|
||||
* Debugfs handlers.
|
||||
*/
|
||||
#ifdef CONFIG_RT2X00_LIB_DEBUGFS
|
||||
void rt2x00debug_register(struct rt2x00_dev *rt2x00dev);
|
||||
void rt2x00debug_deregister(struct rt2x00_dev *rt2x00dev);
|
||||
#else
|
||||
static inline void rt2x00debug_register(struct rt2x00_dev *rt2x00dev)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void rt2x00debug_deregister(struct rt2x00_dev *rt2x00dev)
|
||||
{
|
||||
}
|
||||
#endif /* CONFIG_RT2X00_LIB_DEBUGFS */
|
||||
|
||||
/*
|
||||
* RFkill handlers.
|
||||
*/
|
||||
#ifdef CONFIG_RT2X00_LIB_RFKILL
|
||||
int rt2x00rfkill_register(struct rt2x00_dev *rt2x00dev);
|
||||
void rt2x00rfkill_unregister(struct rt2x00_dev *rt2x00dev);
|
||||
int rt2x00rfkill_allocate(struct rt2x00_dev *rt2x00dev);
|
||||
void rt2x00rfkill_free(struct rt2x00_dev *rt2x00dev);
|
||||
#else
|
||||
static inline int rt2x00rfkill_register(struct rt2x00_dev *rt2x00dev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void rt2x00rfkill_unregister(struct rt2x00_dev *rt2x00dev)
|
||||
{
|
||||
}
|
||||
|
||||
static inline int rt2x00rfkill_allocate(struct rt2x00_dev *rt2x00dev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void rt2x00rfkill_free(struct rt2x00_dev *rt2x00dev)
|
||||
{
|
||||
}
|
||||
#endif /* CONFIG_RT2X00_LIB_RFKILL */
|
||||
|
||||
#endif /* RT2X00LIB_H */
|
||||
|
@ -19,10 +19,8 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
Module: rt2x00lib
|
||||
Module: rt2x00mac
|
||||
Abstract: rt2x00 generic mac80211 routines.
|
||||
Supported chipsets: RT2460, RT2560, RT2570,
|
||||
rt2561, rt2561s, rt2661, rt2571W & rt2671.
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -30,14 +28,15 @@
|
||||
*/
|
||||
#define DRV_NAME "rt2x00lib"
|
||||
|
||||
#include <linux/netdevice.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
#include "rt2x00.h"
|
||||
#include "rt2x00lib.h"
|
||||
#include "rt2x00dev.h"
|
||||
|
||||
static int rt2x00_tx_rts_cts(struct rt2x00_dev *rt2x00dev,
|
||||
struct data_ring *ring, struct sk_buff *frag_skb,
|
||||
static int rt2x00mac_tx_rts_cts(struct rt2x00_dev *rt2x00dev,
|
||||
struct data_ring *ring,
|
||||
struct sk_buff *frag_skb,
|
||||
struct ieee80211_tx_control *control)
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
@ -58,13 +57,13 @@ static int rt2x00_tx_rts_cts(struct rt2x00_dev *rt2x00dev,
|
||||
skb_put(skb, size);
|
||||
|
||||
if (control->flags & IEEE80211_TXCTL_USE_CTS_PROTECT)
|
||||
ieee80211_ctstoself_get(rt2x00dev->hw,
|
||||
ieee80211_ctstoself_get(rt2x00dev->hw, rt2x00dev->interface.id,
|
||||
frag_skb->data, frag_skb->len, control,
|
||||
(struct ieee80211_cts*)(skb->data));
|
||||
(struct ieee80211_cts *)(skb->data));
|
||||
else
|
||||
ieee80211_rts_get(rt2x00dev->hw,
|
||||
ieee80211_rts_get(rt2x00dev->hw, rt2x00dev->interface.id,
|
||||
frag_skb->data, frag_skb->len, control,
|
||||
(struct ieee80211_rts*)(skb->data));
|
||||
(struct ieee80211_rts *)(skb->data));
|
||||
|
||||
if (rt2x00dev->ops->lib->write_tx_data(rt2x00dev, ring, skb, control)) {
|
||||
WARNING(rt2x00dev, "Failed to send RTS/CTS frame.\n");
|
||||
@ -74,18 +73,29 @@ static int rt2x00_tx_rts_cts(struct rt2x00_dev *rt2x00dev,
|
||||
return NETDEV_TX_OK;
|
||||
}
|
||||
|
||||
int rt2x00lib_tx(struct ieee80211_hw *hw, struct sk_buff *skb,
|
||||
int rt2x00mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb,
|
||||
struct ieee80211_tx_control *control)
|
||||
{
|
||||
struct rt2x00_dev *rt2x00dev = hw->priv;
|
||||
struct ieee80211_hdr *ieee80211hdr = (struct ieee80211_hdr*)skb->data;
|
||||
struct ieee80211_hdr *ieee80211hdr = (struct ieee80211_hdr *)skb->data;
|
||||
struct data_ring *ring;
|
||||
u16 frame_control;
|
||||
|
||||
/*
|
||||
* Mac80211 might be calling this function while we are trying
|
||||
* to remove the device or perhaps suspending it.
|
||||
* Note that we can only stop the TX queues inside the TX path
|
||||
* due to possible race conditions in mac80211.
|
||||
*/
|
||||
if (!test_bit(DEVICE_PRESENT, &rt2x00dev->flags)) {
|
||||
ieee80211_stop_queues(hw);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Determine which ring to put packet on.
|
||||
*/
|
||||
ring = rt2x00_get_ring(rt2x00dev, control->queue);
|
||||
ring = rt2x00lib_get_ring(rt2x00dev, control->queue);
|
||||
if (unlikely(!ring)) {
|
||||
ERROR(rt2x00dev,
|
||||
"Attempt to send packet over invalid queue %d.\n"
|
||||
@ -102,12 +112,13 @@ int rt2x00lib_tx(struct ieee80211_hw *hw, struct sk_buff *skb,
|
||||
* frame as well as the data frame.
|
||||
*/
|
||||
frame_control = le16_to_cpu(ieee80211hdr->frame_control);
|
||||
if (control->flags & IEEE80211_TXCTL_USE_RTS_CTS &&
|
||||
!is_cts_frame(frame_control) && !is_rts_frame(frame_control)) {
|
||||
if (!is_rts_frame(frame_control) && !is_cts_frame(frame_control) &&
|
||||
(control->flags & (IEEE80211_TXCTL_USE_RTS_CTS |
|
||||
IEEE80211_TXCTL_USE_CTS_PROTECT))) {
|
||||
if (rt2x00_ring_free(ring) <= 1)
|
||||
return NETDEV_TX_BUSY;
|
||||
|
||||
if (rt2x00_tx_rts_cts(rt2x00dev, ring, skb, control))
|
||||
if (rt2x00mac_tx_rts_cts(rt2x00dev, ring, skb, control))
|
||||
return NETDEV_TX_BUSY;
|
||||
}
|
||||
|
||||
@ -119,64 +130,26 @@ int rt2x00lib_tx(struct ieee80211_hw *hw, struct sk_buff *skb,
|
||||
|
||||
return NETDEV_TX_OK;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rt2x00lib_tx);
|
||||
EXPORT_SYMBOL_GPL(rt2x00mac_tx);
|
||||
|
||||
int rt2x00lib_reset(struct ieee80211_hw *hw)
|
||||
int rt2x00mac_start(struct ieee80211_hw *hw)
|
||||
{
|
||||
struct rt2x00_dev *rt2x00dev = hw->priv;
|
||||
|
||||
rt2x00lib_disable_radio(rt2x00dev);
|
||||
return rt2x00lib_enable_radio(rt2x00dev);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rt2x00lib_reset);
|
||||
|
||||
int rt2x00lib_add_interface(struct ieee80211_hw *hw,
|
||||
struct ieee80211_if_init_conf *conf)
|
||||
{
|
||||
struct rt2x00_dev *rt2x00dev = hw->priv;
|
||||
struct interface *intf = &rt2x00dev->interface;
|
||||
int status;
|
||||
|
||||
/*
|
||||
* We only support 1 non-monitor interface.
|
||||
*/
|
||||
if (conf->type != IEEE80211_IF_TYPE_MNTR &&
|
||||
is_interface_present(intf))
|
||||
return -ENOBUFS;
|
||||
if (!test_bit(DEVICE_PRESENT, &rt2x00dev->flags) ||
|
||||
test_bit(DEVICE_STARTED, &rt2x00dev->flags))
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* We support muliple monitor mode interfaces.
|
||||
* All we need to do is increase the monitor_count.
|
||||
* If this is the first interface which is added,
|
||||
* we should load the firmware now.
|
||||
*/
|
||||
if (conf->type == IEEE80211_IF_TYPE_MNTR) {
|
||||
intf->monitor_count++;
|
||||
} else {
|
||||
intf->id = conf->if_id;
|
||||
intf->type = conf->type;
|
||||
if (conf->type == IEEE80211_IF_TYPE_AP)
|
||||
memcpy(&intf->bssid, conf->mac_addr, ETH_ALEN);
|
||||
intf->promisc = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize interface, and enable the radio when this
|
||||
* is the first interface that is brought up.
|
||||
*/
|
||||
if (!test_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags)) {
|
||||
/*
|
||||
* We must wait on the firmware before
|
||||
* we can safely continue.
|
||||
*/
|
||||
status = rt2x00lib_load_firmware_wait(rt2x00dev);
|
||||
if (test_bit(DRIVER_REQUIRE_FIRMWARE, &rt2x00dev->flags)) {
|
||||
status = rt2x00lib_load_firmware(rt2x00dev);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
/*
|
||||
* Before initialization, the mac address should
|
||||
* be configured.
|
||||
*/
|
||||
rt2x00dev->ops->lib->config_mac_addr(rt2x00dev,
|
||||
conf->mac_addr);
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize the device.
|
||||
@ -189,60 +162,116 @@ int rt2x00lib_add_interface(struct ieee80211_hw *hw,
|
||||
* Enable radio.
|
||||
*/
|
||||
status = rt2x00lib_enable_radio(rt2x00dev);
|
||||
if (status)
|
||||
if (status) {
|
||||
rt2x00lib_uninitialize(rt2x00dev);
|
||||
return status;
|
||||
}
|
||||
|
||||
__set_bit(DEVICE_STARTED, &rt2x00dev->flags);
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rt2x00lib_add_interface);
|
||||
EXPORT_SYMBOL_GPL(rt2x00mac_start);
|
||||
|
||||
void rt2x00lib_remove_interface(struct ieee80211_hw *hw,
|
||||
void rt2x00mac_stop(struct ieee80211_hw *hw)
|
||||
{
|
||||
struct rt2x00_dev *rt2x00dev = hw->priv;
|
||||
|
||||
if (!test_bit(DEVICE_PRESENT, &rt2x00dev->flags))
|
||||
return;
|
||||
|
||||
/*
|
||||
* Perhaps we can add something smarter here,
|
||||
* but for now just disabling the radio should do.
|
||||
*/
|
||||
rt2x00lib_disable_radio(rt2x00dev);
|
||||
|
||||
__clear_bit(DEVICE_STARTED, &rt2x00dev->flags);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rt2x00mac_stop);
|
||||
|
||||
int rt2x00mac_add_interface(struct ieee80211_hw *hw,
|
||||
struct ieee80211_if_init_conf *conf)
|
||||
{
|
||||
struct rt2x00_dev *rt2x00dev = hw->priv;
|
||||
struct interface *intf = &rt2x00dev->interface;
|
||||
|
||||
/* FIXME: Beaconing is broken in rt2x00. */
|
||||
if (conf->type == IEEE80211_IF_TYPE_IBSS ||
|
||||
conf->type == IEEE80211_IF_TYPE_AP) {
|
||||
ERROR(rt2x00dev,
|
||||
"rt2x00 does not support Adhoc or Master mode");
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
/*
|
||||
* Don't allow interfaces to be added while
|
||||
* either the device has disappeared or when
|
||||
* another interface is already present.
|
||||
*/
|
||||
if (!test_bit(DEVICE_PRESENT, &rt2x00dev->flags) ||
|
||||
is_interface_present(intf))
|
||||
return -ENOBUFS;
|
||||
|
||||
intf->id = conf->if_id;
|
||||
intf->type = conf->type;
|
||||
if (conf->type == IEEE80211_IF_TYPE_AP)
|
||||
memcpy(&intf->bssid, conf->mac_addr, ETH_ALEN);
|
||||
memcpy(&intf->mac, conf->mac_addr, ETH_ALEN);
|
||||
|
||||
/*
|
||||
* The MAC adddress must be configured after the device
|
||||
* has been initialized. Otherwise the device can reset
|
||||
* the MAC registers.
|
||||
*/
|
||||
rt2x00lib_config_mac_addr(rt2x00dev, intf->mac);
|
||||
rt2x00lib_config_type(rt2x00dev, conf->type);
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rt2x00mac_add_interface);
|
||||
|
||||
void rt2x00mac_remove_interface(struct ieee80211_hw *hw,
|
||||
struct ieee80211_if_init_conf *conf)
|
||||
{
|
||||
struct rt2x00_dev *rt2x00dev = hw->priv;
|
||||
struct interface *intf = &rt2x00dev->interface;
|
||||
|
||||
/*
|
||||
* We only support 1 non-monitor interface.
|
||||
* Don't allow interfaces to be remove while
|
||||
* either the device has disappeared or when
|
||||
* no interface is present.
|
||||
*/
|
||||
if (conf->type != IEEE80211_IF_TYPE_MNTR &&
|
||||
if (!test_bit(DEVICE_PRESENT, &rt2x00dev->flags) ||
|
||||
!is_interface_present(intf))
|
||||
return;
|
||||
|
||||
/*
|
||||
* When removing an monitor interface, decrease monitor_count.
|
||||
* For non-monitor interfaces, all interface data needs to be reset.
|
||||
*/
|
||||
if (conf->type == IEEE80211_IF_TYPE_MNTR) {
|
||||
intf->monitor_count--;
|
||||
} else if (intf->type == conf->type) {
|
||||
intf->id = 0;
|
||||
intf->type = -EINVAL;
|
||||
intf->type = INVALID_INTERFACE;
|
||||
memset(&intf->bssid, 0x00, ETH_ALEN);
|
||||
intf->promisc = 0;
|
||||
}
|
||||
memset(&intf->mac, 0x00, ETH_ALEN);
|
||||
|
||||
/*
|
||||
* If this was the last interface,
|
||||
* this is the time to disable the radio.
|
||||
* If this is not the last interface, then we should
|
||||
* check if we should switch completely to monitor
|
||||
* mode or completely switch to the non-monitor mode.
|
||||
* Make sure the bssid and mac address registers
|
||||
* are cleared to prevent false ACKing of frames.
|
||||
*/
|
||||
if (!is_monitor_present(intf) && !is_interface_present(intf))
|
||||
rt2x00lib_disable_radio(rt2x00dev);
|
||||
else if (is_monitor_present(intf) ^ is_interface_present(intf))
|
||||
rt2x00lib_config_type(rt2x00dev,
|
||||
is_interface_present(intf) ?
|
||||
intf->type : IEEE80211_IF_TYPE_MNTR);
|
||||
rt2x00lib_config_mac_addr(rt2x00dev, intf->mac);
|
||||
rt2x00lib_config_bssid(rt2x00dev, intf->bssid);
|
||||
rt2x00lib_config_type(rt2x00dev, intf->type);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rt2x00lib_remove_interface);
|
||||
EXPORT_SYMBOL_GPL(rt2x00mac_remove_interface);
|
||||
|
||||
int rt2x00lib_config(struct ieee80211_hw *hw, struct ieee80211_conf *conf)
|
||||
int rt2x00mac_config(struct ieee80211_hw *hw, struct ieee80211_conf *conf)
|
||||
{
|
||||
struct rt2x00_dev *rt2x00dev = hw->priv;
|
||||
|
||||
/*
|
||||
* Mac80211 might be calling this function while we are trying
|
||||
* to remove the device or perhaps suspending it.
|
||||
*/
|
||||
if (!test_bit(DEVICE_PRESENT, &rt2x00dev->flags))
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* Check if we need to disable the radio,
|
||||
* if this is not the case, at least the RX must be disabled.
|
||||
@ -251,32 +280,24 @@ int rt2x00lib_config(struct ieee80211_hw *hw, struct ieee80211_conf *conf)
|
||||
if (!conf->radio_enabled)
|
||||
rt2x00lib_disable_radio(rt2x00dev);
|
||||
else
|
||||
rt2x00lib_toggle_rx(rt2x00dev, 0);
|
||||
rt2x00lib_toggle_rx(rt2x00dev, STATE_RADIO_RX_OFF);
|
||||
}
|
||||
|
||||
rt2x00lib_config_phymode(rt2x00dev, conf->phymode);
|
||||
rt2x00lib_config_channel(rt2x00dev, conf->channel_val,
|
||||
conf->channel, conf->freq, conf->power_level);
|
||||
rt2x00lib_config_txpower(rt2x00dev, conf->power_level);
|
||||
rt2x00lib_config_antenna(rt2x00dev,
|
||||
conf->antenna_sel_tx, conf->antenna_sel_rx);
|
||||
rt2x00dev->ops->lib->config_duration(rt2x00dev,
|
||||
(conf->flags & IEEE80211_CONF_SHORT_SLOT_TIME),
|
||||
conf->beacon_int);
|
||||
rt2x00lib_config(rt2x00dev, conf, 0);
|
||||
|
||||
/*
|
||||
* Reenable RX only if the radio should be on.
|
||||
*/
|
||||
if (test_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags))
|
||||
rt2x00lib_toggle_rx(rt2x00dev, 1);
|
||||
rt2x00lib_toggle_rx(rt2x00dev, STATE_RADIO_RX_ON);
|
||||
else if (conf->radio_enabled)
|
||||
return rt2x00lib_enable_radio(rt2x00dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rt2x00lib_config);
|
||||
EXPORT_SYMBOL_GPL(rt2x00mac_config);
|
||||
|
||||
int rt2x00lib_config_interface(struct ieee80211_hw *hw, int if_id,
|
||||
int rt2x00mac_config_interface(struct ieee80211_hw *hw, int if_id,
|
||||
struct ieee80211_if_conf *conf)
|
||||
{
|
||||
struct rt2x00_dev *rt2x00dev = hw->priv;
|
||||
@ -284,13 +305,17 @@ int rt2x00lib_config_interface(struct ieee80211_hw *hw, int if_id,
|
||||
int status;
|
||||
|
||||
/*
|
||||
* Monitor mode does not need configuring.
|
||||
* Mac80211 might be calling this function while we are trying
|
||||
* to remove the device or perhaps suspending it.
|
||||
*/
|
||||
if (!test_bit(DEVICE_PRESENT, &rt2x00dev->flags))
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* If the given type does not match the configured type,
|
||||
* there has been a problem.
|
||||
*/
|
||||
if (conf->type == IEEE80211_IF_TYPE_MNTR)
|
||||
return 0;
|
||||
else if (conf->type != intf->type)
|
||||
if (conf->type != intf->type)
|
||||
return -EINVAL;
|
||||
|
||||
/*
|
||||
@ -300,14 +325,7 @@ int rt2x00lib_config_interface(struct ieee80211_hw *hw, int if_id,
|
||||
*/
|
||||
if (conf->type != IEEE80211_IF_TYPE_AP)
|
||||
memcpy(&intf->bssid, conf->bssid, ETH_ALEN);
|
||||
|
||||
/*
|
||||
* Enable configuration.
|
||||
* For Monitor mode, promisc mode will be forced on.
|
||||
*/
|
||||
rt2x00lib_config_type(rt2x00dev, conf->type);
|
||||
rt2x00lib_config_promisc(rt2x00dev, rt2x00dev->interface.promisc);
|
||||
rt2x00dev->ops->lib->config_bssid(rt2x00dev, intf->bssid);
|
||||
rt2x00lib_config_bssid(rt2x00dev, intf->bssid);
|
||||
|
||||
/*
|
||||
* We only need to initialize the beacon when master mode is enabled.
|
||||
@ -316,45 +334,32 @@ int rt2x00lib_config_interface(struct ieee80211_hw *hw, int if_id,
|
||||
return 0;
|
||||
|
||||
status = rt2x00dev->ops->hw->beacon_update(rt2x00dev->hw,
|
||||
conf->beacon, conf->beacon_control);
|
||||
conf->beacon,
|
||||
conf->beacon_control);
|
||||
if (status)
|
||||
dev_kfree_skb(conf->beacon);
|
||||
|
||||
return status;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rt2x00lib_config_interface);
|
||||
EXPORT_SYMBOL_GPL(rt2x00mac_config_interface);
|
||||
|
||||
void rt2x00lib_set_multicast_list(struct ieee80211_hw *hw,
|
||||
unsigned short flags, int mc_count)
|
||||
int rt2x00mac_get_stats(struct ieee80211_hw *hw,
|
||||
struct ieee80211_low_level_stats *stats)
|
||||
{
|
||||
struct rt2x00_dev *rt2x00dev = hw->priv;
|
||||
|
||||
/*
|
||||
* Promisc mode is forced on for Monitor interfaces.
|
||||
* The dot11ACKFailureCount, dot11RTSFailureCount and
|
||||
* dot11RTSSuccessCount are updated in interrupt time.
|
||||
* dot11FCSErrorCount is updated in the link tuner.
|
||||
*/
|
||||
if (is_monitor_present(&rt2x00dev->interface))
|
||||
return;
|
||||
memcpy(stats, &rt2x00dev->low_level_stats, sizeof(*stats));
|
||||
|
||||
/*
|
||||
* Check if the new state is different then the old state.
|
||||
*/
|
||||
if (test_bit(INTERFACE_ENABLED_PROMISC, &rt2x00dev->flags) ==
|
||||
!!(flags & IFF_PROMISC))
|
||||
return;
|
||||
|
||||
rt2x00dev->interface.promisc = !!(flags & IFF_PROMISC);
|
||||
|
||||
/*
|
||||
* Schedule the link tuner if this does not run
|
||||
* automatically. The link tuner will be automatically
|
||||
* switched off when it is not required.
|
||||
*/
|
||||
if (!work_pending(&rt2x00dev->link.work.work))
|
||||
queue_work(rt2x00dev->hw->workqueue, &rt2x00dev->link.work.work);
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rt2x00lib_set_multicast_list);
|
||||
EXPORT_SYMBOL_GPL(rt2x00mac_get_stats);
|
||||
|
||||
int rt2x00lib_get_tx_stats(struct ieee80211_hw *hw,
|
||||
int rt2x00mac_get_tx_stats(struct ieee80211_hw *hw,
|
||||
struct ieee80211_tx_queue_stats *stats)
|
||||
{
|
||||
struct rt2x00_dev *rt2x00dev = hw->priv;
|
||||
@ -366,15 +371,49 @@ int rt2x00lib_get_tx_stats(struct ieee80211_hw *hw,
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rt2x00lib_get_tx_stats);
|
||||
EXPORT_SYMBOL_GPL(rt2x00mac_get_tx_stats);
|
||||
|
||||
int rt2x00lib_conf_tx(struct ieee80211_hw *hw, int queue,
|
||||
void rt2x00mac_erp_ie_changed(struct ieee80211_hw *hw, u8 changes,
|
||||
int cts_protection, int preamble)
|
||||
{
|
||||
struct rt2x00_dev *rt2x00dev = hw->priv;
|
||||
int short_preamble;
|
||||
int ack_timeout;
|
||||
int ack_consume_time;
|
||||
int difs;
|
||||
|
||||
/*
|
||||
* We only support changing preamble mode.
|
||||
*/
|
||||
if (!(changes & IEEE80211_ERP_CHANGE_PREAMBLE))
|
||||
return;
|
||||
|
||||
short_preamble = !preamble;
|
||||
preamble = !!(preamble) ? PREAMBLE : SHORT_PREAMBLE;
|
||||
|
||||
difs = (hw->conf.flags & IEEE80211_CONF_SHORT_SLOT_TIME) ?
|
||||
SHORT_DIFS : DIFS;
|
||||
ack_timeout = difs + PLCP + preamble + get_duration(ACK_SIZE, 10);
|
||||
|
||||
ack_consume_time = SIFS + PLCP + preamble + get_duration(ACK_SIZE, 10);
|
||||
|
||||
if (short_preamble)
|
||||
__set_bit(CONFIG_SHORT_PREAMBLE, &rt2x00dev->flags);
|
||||
else
|
||||
__clear_bit(CONFIG_SHORT_PREAMBLE, &rt2x00dev->flags);
|
||||
|
||||
rt2x00dev->ops->lib->config_preamble(rt2x00dev, short_preamble,
|
||||
ack_timeout, ack_consume_time);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rt2x00mac_erp_ie_changed);
|
||||
|
||||
int rt2x00mac_conf_tx(struct ieee80211_hw *hw, int queue,
|
||||
const struct ieee80211_tx_queue_params *params)
|
||||
{
|
||||
struct rt2x00_dev *rt2x00dev = hw->priv;
|
||||
struct data_ring *ring;
|
||||
|
||||
ring = rt2x00_get_ring(rt2x00dev, queue);
|
||||
ring = rt2x00lib_get_ring(rt2x00dev, queue);
|
||||
if (unlikely(!ring))
|
||||
return -EINVAL;
|
||||
|
||||
@ -404,4 +443,4 @@ int rt2x00lib_conf_tx(struct ieee80211_hw *hw, int queue,
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rt2x00lib_conf_tx);
|
||||
EXPORT_SYMBOL_GPL(rt2x00mac_conf_tx);
|
||||
|
@ -21,7 +21,6 @@
|
||||
/*
|
||||
Module: rt2x00pci
|
||||
Abstract: rt2x00 generic pci device routines.
|
||||
Supported chipsets: rt2460, rt2560, rt2561, rt2561s & rt2661.
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -29,14 +28,12 @@
|
||||
*/
|
||||
#define DRV_NAME "rt2x00pci"
|
||||
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/version.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/pci.h>
|
||||
|
||||
#include "rt2x00.h"
|
||||
#include "rt2x00lib.h"
|
||||
#include "rt2x00pci.h"
|
||||
|
||||
/*
|
||||
@ -47,11 +44,11 @@ int rt2x00pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb,
|
||||
{
|
||||
struct rt2x00_dev *rt2x00dev = hw->priv;
|
||||
struct data_ring *ring =
|
||||
rt2x00_get_ring(rt2x00dev, IEEE80211_TX_QUEUE_BEACON);
|
||||
rt2x00lib_get_ring(rt2x00dev, IEEE80211_TX_QUEUE_BEACON);
|
||||
struct data_entry *entry = rt2x00_get_data_entry(ring);
|
||||
|
||||
/*
|
||||
* Just in case the ieee80211 doesn't set this,
|
||||
* Just in case mac80211 doesn't set this correctly,
|
||||
* but we need this queue set for the descriptor
|
||||
* initialization.
|
||||
*/
|
||||
@ -61,8 +58,9 @@ int rt2x00pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb,
|
||||
* Update the beacon entry.
|
||||
*/
|
||||
memcpy(entry->data_addr, skb->data, skb->len);
|
||||
rt2x00lib_write_tx_desc(rt2x00dev, entry, entry->priv,
|
||||
(struct ieee80211_hdr*)skb->data, skb->len, control);
|
||||
rt2x00lib_write_tx_desc(rt2x00dev, entry->priv,
|
||||
(struct ieee80211_hdr *)skb->data,
|
||||
skb->len, control);
|
||||
|
||||
/*
|
||||
* Enable beacon generation.
|
||||
@ -73,24 +71,6 @@ int rt2x00pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb,
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rt2x00pci_beacon_update);
|
||||
|
||||
void rt2x00pci_beacondone(struct rt2x00_dev *rt2x00dev, const int queue)
|
||||
{
|
||||
struct data_ring *ring = rt2x00_get_ring(rt2x00dev, queue);
|
||||
struct data_entry *entry = rt2x00_get_data_entry(ring);
|
||||
struct sk_buff *skb;
|
||||
|
||||
skb = ieee80211_beacon_get(rt2x00dev->hw,
|
||||
rt2x00dev->interface.id, &entry->tx_status.control);
|
||||
if (!skb)
|
||||
return;
|
||||
|
||||
rt2x00dev->ops->hw->beacon_update(rt2x00dev->hw, skb,
|
||||
&entry->tx_status.control);
|
||||
|
||||
dev_kfree_skb(skb);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rt2x00pci_beacondone);
|
||||
|
||||
/*
|
||||
* TX data handlers.
|
||||
*/
|
||||
@ -98,7 +78,7 @@ int rt2x00pci_write_tx_data(struct rt2x00_dev *rt2x00dev,
|
||||
struct data_ring *ring, struct sk_buff *skb,
|
||||
struct ieee80211_tx_control *control)
|
||||
{
|
||||
struct ieee80211_hdr *ieee80211hdr = (struct ieee80211_hdr*)skb->data;
|
||||
struct ieee80211_hdr *ieee80211hdr = (struct ieee80211_hdr *)skb->data;
|
||||
struct data_entry *entry = rt2x00_get_data_entry(ring);
|
||||
struct data_desc *txd = entry->priv;
|
||||
u32 word;
|
||||
@ -123,7 +103,7 @@ int rt2x00pci_write_tx_data(struct rt2x00_dev *rt2x00dev,
|
||||
entry->skb = skb;
|
||||
memcpy(&entry->tx_status.control, control, sizeof(*control));
|
||||
memcpy(entry->data_addr, skb->data, skb->len);
|
||||
rt2x00lib_write_tx_desc(rt2x00dev, entry, txd, ieee80211hdr,
|
||||
rt2x00lib_write_tx_desc(rt2x00dev, txd, ieee80211hdr,
|
||||
skb->len, control);
|
||||
|
||||
rt2x00_ring_index_inc(ring);
|
||||
@ -143,35 +123,53 @@ void rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev)
|
||||
struct data_ring *ring = rt2x00dev->rx;
|
||||
struct data_entry *entry;
|
||||
struct data_desc *rxd;
|
||||
u32 desc;
|
||||
int signal;
|
||||
int rssi;
|
||||
int ofdm;
|
||||
int size;
|
||||
struct sk_buff *skb;
|
||||
struct ieee80211_hdr *hdr;
|
||||
struct rxdata_entry_desc desc;
|
||||
int header_size;
|
||||
int align;
|
||||
u32 word;
|
||||
|
||||
while (1) {
|
||||
entry = rt2x00_get_data_entry(ring);
|
||||
rxd = entry->priv;
|
||||
rt2x00_desc_read(rxd, 0, &desc);
|
||||
rt2x00_desc_read(rxd, 0, &word);
|
||||
|
||||
if (rt2x00_get_field32(desc, RXD_ENTRY_OWNER_NIC))
|
||||
if (rt2x00_get_field32(word, RXD_ENTRY_OWNER_NIC))
|
||||
break;
|
||||
|
||||
size = rt2x00dev->ops->lib->fill_rxdone(
|
||||
entry, &signal, &rssi, &ofdm);
|
||||
if (size < 0)
|
||||
goto skip_entry;
|
||||
memset(&desc, 0x00, sizeof(desc));
|
||||
rt2x00dev->ops->lib->fill_rxdone(entry, &desc);
|
||||
|
||||
hdr = (struct ieee80211_hdr *)entry->data_addr;
|
||||
header_size =
|
||||
ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_control));
|
||||
|
||||
/*
|
||||
* Send the packet to upper layer.
|
||||
* The data behind the ieee80211 header must be
|
||||
* aligned on a 4 byte boundary.
|
||||
*/
|
||||
rt2x00lib_rxdone(entry, entry->data_addr, size,
|
||||
signal, rssi, ofdm);
|
||||
align = header_size % 4;
|
||||
|
||||
/*
|
||||
* Allocate the sk_buffer, initialize it and copy
|
||||
* all data into it.
|
||||
*/
|
||||
skb = dev_alloc_skb(desc.size + align);
|
||||
if (!skb)
|
||||
return;
|
||||
|
||||
skb_reserve(skb, align);
|
||||
memcpy(skb_put(skb, desc.size), entry->data_addr, desc.size);
|
||||
|
||||
/*
|
||||
* Send the frame to rt2x00lib for further processing.
|
||||
*/
|
||||
rt2x00lib_rxdone(entry, skb, &desc);
|
||||
|
||||
skip_entry:
|
||||
if (test_bit(DEVICE_ENABLED_RADIO, &ring->rt2x00dev->flags)) {
|
||||
rt2x00_set_field32(&desc, RXD_ENTRY_OWNER_NIC, 1);
|
||||
rt2x00_desc_write(rxd, 0, desc);
|
||||
rt2x00_set_field32(&word, RXD_ENTRY_OWNER_NIC, 1);
|
||||
rt2x00_desc_write(rxd, 0, word);
|
||||
}
|
||||
|
||||
rt2x00_ring_index_inc(ring);
|
||||
@ -189,19 +187,19 @@ EXPORT_SYMBOL_GPL(rt2x00pci_rxdone);
|
||||
|
||||
#define data_addr_offset(__ring, __i) \
|
||||
({ \
|
||||
(__ring)->data_addr \
|
||||
+ ((__ring)->stats.limit * (__ring)->desc_size) \
|
||||
+ ((__i) * (__ring)->data_size); \
|
||||
(__ring)->data_addr + \
|
||||
((__ring)->stats.limit * (__ring)->desc_size) + \
|
||||
((__i) * (__ring)->data_size); \
|
||||
})
|
||||
|
||||
#define data_dma_offset(__ring, __i) \
|
||||
({ \
|
||||
(__ring)->data_dma \
|
||||
+ ((__ring)->stats.limit * (__ring)->desc_size) \
|
||||
+ ((__i) * (__ring)->data_size); \
|
||||
(__ring)->data_dma + \
|
||||
((__ring)->stats.limit * (__ring)->desc_size) + \
|
||||
((__i) * (__ring)->data_size); \
|
||||
})
|
||||
|
||||
static int rt2x00pci_alloc_ring(struct rt2x00_dev *rt2x00dev,
|
||||
static int rt2x00pci_alloc_dma(struct rt2x00_dev *rt2x00dev,
|
||||
struct data_ring *ring)
|
||||
{
|
||||
unsigned int i;
|
||||
@ -210,7 +208,8 @@ static int rt2x00pci_alloc_ring(struct rt2x00_dev *rt2x00dev,
|
||||
* Allocate DMA memory for descriptor and buffer.
|
||||
*/
|
||||
ring->data_addr = pci_alloc_consistent(rt2x00dev_pci(rt2x00dev),
|
||||
rt2x00_get_ring_size(ring), &ring->data_dma);
|
||||
rt2x00_get_ring_size(ring),
|
||||
&ring->data_dma);
|
||||
if (!ring->data_addr)
|
||||
return -ENOMEM;
|
||||
|
||||
@ -227,6 +226,16 @@ static int rt2x00pci_alloc_ring(struct rt2x00_dev *rt2x00dev,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void rt2x00pci_free_dma(struct rt2x00_dev *rt2x00dev,
|
||||
struct data_ring *ring)
|
||||
{
|
||||
if (ring->data_addr)
|
||||
pci_free_consistent(rt2x00dev_pci(rt2x00dev),
|
||||
rt2x00_get_ring_size(ring),
|
||||
ring->data_addr, ring->data_dma);
|
||||
ring->data_addr = NULL;
|
||||
}
|
||||
|
||||
int rt2x00pci_initialize(struct rt2x00_dev *rt2x00dev)
|
||||
{
|
||||
struct pci_dev *pci_dev = rt2x00dev_pci(rt2x00dev);
|
||||
@ -237,7 +246,7 @@ int rt2x00pci_initialize(struct rt2x00_dev *rt2x00dev)
|
||||
* Allocate DMA
|
||||
*/
|
||||
ring_for_each(rt2x00dev, ring) {
|
||||
status = rt2x00pci_alloc_ring(rt2x00dev, ring);
|
||||
status = rt2x00pci_alloc_dma(rt2x00dev, ring);
|
||||
if (status)
|
||||
goto exit;
|
||||
}
|
||||
@ -246,7 +255,7 @@ int rt2x00pci_initialize(struct rt2x00_dev *rt2x00dev)
|
||||
* Register interrupt handler.
|
||||
*/
|
||||
status = request_irq(pci_dev->irq, rt2x00dev->ops->lib->irq_handler,
|
||||
IRQF_SHARED, pci_dev->driver->name, rt2x00dev);
|
||||
IRQF_SHARED, pci_name(pci_dev), rt2x00dev);
|
||||
if (status) {
|
||||
ERROR(rt2x00dev, "IRQ %d allocation failed (error %d).\n",
|
||||
pci_dev->irq, status);
|
||||
@ -274,43 +283,58 @@ void rt2x00pci_uninitialize(struct rt2x00_dev *rt2x00dev)
|
||||
/*
|
||||
* Free DMA
|
||||
*/
|
||||
ring_for_each(rt2x00dev, ring) {
|
||||
if (ring->data_addr)
|
||||
pci_free_consistent(rt2x00dev_pci(rt2x00dev),
|
||||
rt2x00_get_ring_size(ring),
|
||||
ring->data_addr, ring->data_dma);
|
||||
ring->data_addr = NULL;
|
||||
}
|
||||
ring_for_each(rt2x00dev, ring)
|
||||
rt2x00pci_free_dma(rt2x00dev, ring);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rt2x00pci_uninitialize);
|
||||
|
||||
/*
|
||||
* PCI driver handlers.
|
||||
*/
|
||||
static int rt2x00pci_alloc_csr(struct rt2x00_dev *rt2x00dev)
|
||||
static void rt2x00pci_free_reg(struct rt2x00_dev *rt2x00dev)
|
||||
{
|
||||
rt2x00dev->csr_addr = ioremap(
|
||||
pci_resource_start(rt2x00dev_pci(rt2x00dev), 0),
|
||||
pci_resource_len(rt2x00dev_pci(rt2x00dev), 0));
|
||||
if (!rt2x00dev->csr_addr) {
|
||||
ERROR(rt2x00dev, "Ioremap failed.\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
kfree(rt2x00dev->rf);
|
||||
rt2x00dev->rf = NULL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
kfree(rt2x00dev->eeprom);
|
||||
rt2x00dev->eeprom = NULL;
|
||||
|
||||
static void rt2x00pci_free_csr(struct rt2x00_dev *rt2x00dev)
|
||||
{
|
||||
if (rt2x00dev->csr_addr) {
|
||||
iounmap(rt2x00dev->csr_addr);
|
||||
rt2x00dev->csr_addr = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static int rt2x00pci_alloc_reg(struct rt2x00_dev *rt2x00dev)
|
||||
{
|
||||
struct pci_dev *pci_dev = rt2x00dev_pci(rt2x00dev);
|
||||
|
||||
rt2x00dev->csr_addr = ioremap(pci_resource_start(pci_dev, 0),
|
||||
pci_resource_len(pci_dev, 0));
|
||||
if (!rt2x00dev->csr_addr)
|
||||
goto exit;
|
||||
|
||||
rt2x00dev->eeprom = kzalloc(rt2x00dev->ops->eeprom_size, GFP_KERNEL);
|
||||
if (!rt2x00dev->eeprom)
|
||||
goto exit;
|
||||
|
||||
rt2x00dev->rf = kzalloc(rt2x00dev->ops->rf_size, GFP_KERNEL);
|
||||
if (!rt2x00dev->rf)
|
||||
goto exit;
|
||||
|
||||
return 0;
|
||||
|
||||
exit:
|
||||
ERROR_PROBE("Failed to allocate registers.\n");
|
||||
|
||||
rt2x00pci_free_reg(rt2x00dev);
|
||||
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
int rt2x00pci_probe(struct pci_dev *pci_dev, const struct pci_device_id *id)
|
||||
{
|
||||
struct rt2x00_ops *ops = (struct rt2x00_ops*)id->driver_data;
|
||||
struct rt2x00_ops *ops = (struct rt2x00_ops *)id->driver_data;
|
||||
struct ieee80211_hw *hw;
|
||||
struct rt2x00_dev *rt2x00dev;
|
||||
int retval;
|
||||
@ -353,18 +377,18 @@ int rt2x00pci_probe(struct pci_dev *pci_dev, const struct pci_device_id *id)
|
||||
rt2x00dev->ops = ops;
|
||||
rt2x00dev->hw = hw;
|
||||
|
||||
retval = rt2x00pci_alloc_csr(rt2x00dev);
|
||||
retval = rt2x00pci_alloc_reg(rt2x00dev);
|
||||
if (retval)
|
||||
goto exit_free_device;
|
||||
|
||||
retval = rt2x00lib_probe_dev(rt2x00dev);
|
||||
if (retval)
|
||||
goto exit_free_csr;
|
||||
goto exit_free_reg;
|
||||
|
||||
return 0;
|
||||
|
||||
exit_free_csr:
|
||||
rt2x00pci_free_csr(rt2x00dev);
|
||||
exit_free_reg:
|
||||
rt2x00pci_free_reg(rt2x00dev);
|
||||
|
||||
exit_free_device:
|
||||
ieee80211_free_hw(hw);
|
||||
@ -391,6 +415,7 @@ void rt2x00pci_remove(struct pci_dev *pci_dev)
|
||||
* Free all allocated data.
|
||||
*/
|
||||
rt2x00lib_remove_dev(rt2x00dev);
|
||||
rt2x00pci_free_reg(rt2x00dev);
|
||||
ieee80211_free_hw(hw);
|
||||
|
||||
/*
|
||||
@ -413,7 +438,7 @@ int rt2x00pci_suspend(struct pci_dev *pci_dev, pm_message_t state)
|
||||
if (retval)
|
||||
return retval;
|
||||
|
||||
rt2x00pci_free_csr(rt2x00dev);
|
||||
rt2x00pci_free_reg(rt2x00dev);
|
||||
|
||||
pci_save_state(pci_dev);
|
||||
pci_disable_device(pci_dev);
|
||||
@ -434,11 +459,20 @@ int rt2x00pci_resume(struct pci_dev *pci_dev)
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
retval = rt2x00pci_alloc_csr(rt2x00dev);
|
||||
retval = rt2x00pci_alloc_reg(rt2x00dev);
|
||||
if (retval)
|
||||
return retval;
|
||||
|
||||
return rt2x00lib_resume(rt2x00dev);
|
||||
retval = rt2x00lib_resume(rt2x00dev);
|
||||
if (retval)
|
||||
goto exit_free_reg;
|
||||
|
||||
return 0;
|
||||
|
||||
exit_free_reg:
|
||||
rt2x00pci_free_reg(rt2x00dev);
|
||||
|
||||
return retval;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rt2x00pci_resume);
|
||||
#endif /* CONFIG_PM */
|
||||
|
@ -21,12 +21,13 @@
|
||||
/*
|
||||
Module: rt2x00pci
|
||||
Abstract: Data structures for the rt2x00pci module.
|
||||
Supported chipsets: rt2460, rt2560, rt2561, rt2561s & rt2661.
|
||||
*/
|
||||
|
||||
#ifndef RT2X00PCI_H
|
||||
#define RT2X00PCI_H
|
||||
|
||||
#include <linux/io.h>
|
||||
|
||||
/*
|
||||
* This variable should be used with the
|
||||
* pci_driver structure initialization.
|
||||
@ -35,9 +36,9 @@
|
||||
|
||||
/*
|
||||
* Register defines.
|
||||
* When register access attempts should be repeated
|
||||
* only REGISTER_BUSY_COUNT attempts with a delay
|
||||
* of REGISTER_BUSY_DELAY us should be taken.
|
||||
* Some registers require multiple attempts before success,
|
||||
* in those cases REGISTER_BUSY_COUNT attempts should be
|
||||
* taken with a REGISTER_BUSY_DELAY interval.
|
||||
*/
|
||||
#define REGISTER_BUSY_COUNT 5
|
||||
#define REGISTER_BUSY_DELAY 100
|
||||
@ -46,6 +47,8 @@
|
||||
* Descriptor availability flags.
|
||||
* All PCI device descriptors have these 2 flags
|
||||
* with the exact same definition.
|
||||
* By storing them here we can use them inside rt2x00pci
|
||||
* for some simple entry availability checking.
|
||||
*/
|
||||
#define TXD_ENTRY_OWNER_NIC FIELD32(0x00000001)
|
||||
#define TXD_ENTRY_VALID FIELD32(0x00000002)
|
||||
@ -55,27 +58,31 @@
|
||||
* Register access.
|
||||
*/
|
||||
static inline void rt2x00pci_register_read(const struct rt2x00_dev *rt2x00dev,
|
||||
const unsigned long offset, u32 *value)
|
||||
const unsigned long offset,
|
||||
u32 *value)
|
||||
{
|
||||
*value = readl(rt2x00dev->csr_addr + offset);
|
||||
}
|
||||
|
||||
static inline void rt2x00pci_register_multiread(
|
||||
const struct rt2x00_dev *rt2x00dev,
|
||||
const unsigned long offset, void *value, const u16 length)
|
||||
static inline void
|
||||
rt2x00pci_register_multiread(const struct rt2x00_dev *rt2x00dev,
|
||||
const unsigned long offset,
|
||||
void *value, const u16 length)
|
||||
{
|
||||
memcpy_fromio(value, rt2x00dev->csr_addr + offset, length);
|
||||
}
|
||||
|
||||
static inline void rt2x00pci_register_write(const struct rt2x00_dev *rt2x00dev,
|
||||
const unsigned long offset, u32 value)
|
||||
const unsigned long offset,
|
||||
u32 value)
|
||||
{
|
||||
writel(value, rt2x00dev->csr_addr + offset);
|
||||
}
|
||||
|
||||
static inline void rt2x00pci_register_multiwrite(
|
||||
const struct rt2x00_dev *rt2x00dev,
|
||||
const unsigned long offset, void *value, const u16 length)
|
||||
static inline void
|
||||
rt2x00pci_register_multiwrite(const struct rt2x00_dev *rt2x00dev,
|
||||
const unsigned long offset,
|
||||
void *value, const u16 length)
|
||||
{
|
||||
memcpy_toio(rt2x00dev->csr_addr + offset, value, length);
|
||||
}
|
||||
@ -85,7 +92,6 @@ static inline void rt2x00pci_register_multiwrite(
|
||||
*/
|
||||
int rt2x00pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb,
|
||||
struct ieee80211_tx_control *control);
|
||||
void rt2x00pci_beacondone(struct rt2x00_dev *rt2x00dev, const int queue);
|
||||
|
||||
/*
|
||||
* TX data handlers.
|
||||
@ -113,6 +119,9 @@ void rt2x00pci_remove(struct pci_dev *pci_dev);
|
||||
#ifdef CONFIG_PM
|
||||
int rt2x00pci_suspend(struct pci_dev *pci_dev, pm_message_t state);
|
||||
int rt2x00pci_resume(struct pci_dev *pci_dev);
|
||||
#else
|
||||
#define rt2x00pci_suspend NULL
|
||||
#define rt2x00pci_resume NULL
|
||||
#endif /* CONFIG_PM */
|
||||
|
||||
#endif /* RT2X00PCI_H */
|
||||
|
292
package/rt2x00/src/rt2x00reg.h
Normal file
292
package/rt2x00/src/rt2x00reg.h
Normal file
@ -0,0 +1,292 @@
|
||||
/*
|
||||
Copyright (C) 2004 - 2007 rt2x00 SourceForge Project
|
||||
<http://rt2x00.serialmonkey.com>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the
|
||||
Free Software Foundation, Inc.,
|
||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
Module: rt2x00
|
||||
Abstract: rt2x00 generic register information.
|
||||
*/
|
||||
|
||||
#ifndef RT2X00REG_H
|
||||
#define RT2X00REG_H
|
||||
|
||||
/*
|
||||
* TX result flags.
|
||||
*/
|
||||
enum TX_STATUS {
|
||||
TX_SUCCESS = 0,
|
||||
TX_SUCCESS_RETRY = 1,
|
||||
TX_FAIL_RETRY = 2,
|
||||
TX_FAIL_INVALID = 3,
|
||||
TX_FAIL_OTHER = 4,
|
||||
};
|
||||
|
||||
/*
|
||||
* Antenna values
|
||||
*/
|
||||
enum antenna {
|
||||
ANTENNA_SW_DIVERSITY = 0,
|
||||
ANTENNA_A = 1,
|
||||
ANTENNA_B = 2,
|
||||
ANTENNA_HW_DIVERSITY = 3,
|
||||
};
|
||||
|
||||
/*
|
||||
* Led mode values.
|
||||
*/
|
||||
enum led_mode {
|
||||
LED_MODE_DEFAULT = 0,
|
||||
LED_MODE_TXRX_ACTIVITY = 1,
|
||||
LED_MODE_SIGNAL_STRENGTH = 2,
|
||||
LED_MODE_ASUS = 3,
|
||||
LED_MODE_ALPHA = 4,
|
||||
};
|
||||
|
||||
/*
|
||||
* TSF sync values
|
||||
*/
|
||||
enum tsf_sync {
|
||||
TSF_SYNC_NONE = 0,
|
||||
TSF_SYNC_INFRA = 1,
|
||||
TSF_SYNC_BEACON = 2,
|
||||
};
|
||||
|
||||
/*
|
||||
* Device states
|
||||
*/
|
||||
enum dev_state {
|
||||
STATE_DEEP_SLEEP = 0,
|
||||
STATE_SLEEP = 1,
|
||||
STATE_STANDBY = 2,
|
||||
STATE_AWAKE = 3,
|
||||
|
||||
/*
|
||||
* Additional device states, these values are
|
||||
* not strict since they are not directly passed
|
||||
* into the device.
|
||||
*/
|
||||
STATE_RADIO_ON,
|
||||
STATE_RADIO_OFF,
|
||||
STATE_RADIO_RX_ON,
|
||||
STATE_RADIO_RX_OFF,
|
||||
STATE_RADIO_IRQ_ON,
|
||||
STATE_RADIO_IRQ_OFF,
|
||||
};
|
||||
|
||||
/*
|
||||
* IFS backoff values
|
||||
*/
|
||||
enum ifs {
|
||||
IFS_BACKOFF = 0,
|
||||
IFS_SIFS = 1,
|
||||
IFS_NEW_BACKOFF = 2,
|
||||
IFS_NONE = 3,
|
||||
};
|
||||
|
||||
/*
|
||||
* Cipher types for hardware encryption
|
||||
*/
|
||||
enum cipher {
|
||||
CIPHER_NONE = 0,
|
||||
CIPHER_WEP64 = 1,
|
||||
CIPHER_WEP128 = 2,
|
||||
CIPHER_TKIP = 3,
|
||||
CIPHER_AES = 4,
|
||||
/*
|
||||
* The following fields were added by rt61pci and rt73usb.
|
||||
*/
|
||||
CIPHER_CKIP64 = 5,
|
||||
CIPHER_CKIP128 = 6,
|
||||
CIPHER_TKIP_NO_MIC = 7,
|
||||
};
|
||||
|
||||
/*
|
||||
* Register handlers.
|
||||
* We store the position of a register field inside a field structure,
|
||||
* This will simplify the process of setting and reading a certain field
|
||||
* inside the register while making sure the process remains byte order safe.
|
||||
*/
|
||||
struct rt2x00_field8 {
|
||||
u8 bit_offset;
|
||||
u8 bit_mask;
|
||||
};
|
||||
|
||||
struct rt2x00_field16 {
|
||||
u16 bit_offset;
|
||||
u16 bit_mask;
|
||||
};
|
||||
|
||||
struct rt2x00_field32 {
|
||||
u32 bit_offset;
|
||||
u32 bit_mask;
|
||||
};
|
||||
|
||||
/*
|
||||
* Power of two check, this will check
|
||||
* if the mask that has been given contains
|
||||
* and contiguous set of bits.
|
||||
*/
|
||||
#define is_power_of_two(x) ( !((x) & ((x)-1)) )
|
||||
#define low_bit_mask(x) ( ((x)-1) & ~(x) )
|
||||
#define is_valid_mask(x) is_power_of_two(1 + (x) + low_bit_mask(x))
|
||||
|
||||
#define FIELD8(__mask) \
|
||||
({ \
|
||||
BUILD_BUG_ON(!(__mask) || \
|
||||
!is_valid_mask(__mask) || \
|
||||
(__mask) != (u8)(__mask)); \
|
||||
(struct rt2x00_field8) { \
|
||||
__ffs(__mask), (__mask) \
|
||||
}; \
|
||||
})
|
||||
|
||||
#define FIELD16(__mask) \
|
||||
({ \
|
||||
BUILD_BUG_ON(!(__mask) || \
|
||||
!is_valid_mask(__mask) || \
|
||||
(__mask) != (u16)(__mask));\
|
||||
(struct rt2x00_field16) { \
|
||||
__ffs(__mask), (__mask) \
|
||||
}; \
|
||||
})
|
||||
|
||||
#define FIELD32(__mask) \
|
||||
({ \
|
||||
BUILD_BUG_ON(!(__mask) || \
|
||||
!is_valid_mask(__mask) || \
|
||||
(__mask) != (u32)(__mask));\
|
||||
(struct rt2x00_field32) { \
|
||||
__ffs(__mask), (__mask) \
|
||||
}; \
|
||||
})
|
||||
|
||||
static inline void rt2x00_set_field32(u32 *reg,
|
||||
const struct rt2x00_field32 field,
|
||||
const u32 value)
|
||||
{
|
||||
*reg &= ~(field.bit_mask);
|
||||
*reg |= (value << field.bit_offset) & field.bit_mask;
|
||||
}
|
||||
|
||||
static inline u32 rt2x00_get_field32(const u32 reg,
|
||||
const struct rt2x00_field32 field)
|
||||
{
|
||||
return (reg & field.bit_mask) >> field.bit_offset;
|
||||
}
|
||||
|
||||
static inline void rt2x00_set_field16(u16 *reg,
|
||||
const struct rt2x00_field16 field,
|
||||
const u16 value)
|
||||
{
|
||||
*reg &= ~(field.bit_mask);
|
||||
*reg |= (value << field.bit_offset) & field.bit_mask;
|
||||
}
|
||||
|
||||
static inline u16 rt2x00_get_field16(const u16 reg,
|
||||
const struct rt2x00_field16 field)
|
||||
{
|
||||
return (reg & field.bit_mask) >> field.bit_offset;
|
||||
}
|
||||
|
||||
static inline void rt2x00_set_field8(u8 *reg,
|
||||
const struct rt2x00_field8 field,
|
||||
const u8 value)
|
||||
{
|
||||
*reg &= ~(field.bit_mask);
|
||||
*reg |= (value << field.bit_offset) & field.bit_mask;
|
||||
}
|
||||
|
||||
static inline u8 rt2x00_get_field8(const u8 reg,
|
||||
const struct rt2x00_field8 field)
|
||||
{
|
||||
return (reg & field.bit_mask) >> field.bit_offset;
|
||||
}
|
||||
|
||||
/*
|
||||
* Device specific rate value.
|
||||
* We will have to create the device specific rate value
|
||||
* passed to the ieee80211 kernel. We need to make it a consist of
|
||||
* multiple fields because we want to store more then 1 device specific
|
||||
* values inside the value.
|
||||
* 1 - rate, stored as 100 kbit/s.
|
||||
* 2 - preamble, short_preamble enabled flag.
|
||||
* 3 - MASK_RATE, which rates are enabled in this mode, this mask
|
||||
* corresponds with the TX register format for the current device.
|
||||
* 4 - plcp, 802.11b rates are device specific,
|
||||
* 802.11g rates are set according to the ieee802.11a-1999 p.14.
|
||||
* The bit to enable preamble is set in a seperate define.
|
||||
*/
|
||||
#define DEV_RATE FIELD32(0x000007ff)
|
||||
#define DEV_PREAMBLE FIELD32(0x00000800)
|
||||
#define DEV_RATEMASK FIELD32(0x00fff000)
|
||||
#define DEV_PLCP FIELD32(0xff000000)
|
||||
|
||||
/*
|
||||
* Bitfields
|
||||
*/
|
||||
#define DEV_RATEBIT_1MB ( 1 << 0 )
|
||||
#define DEV_RATEBIT_2MB ( 1 << 1 )
|
||||
#define DEV_RATEBIT_5_5MB ( 1 << 2 )
|
||||
#define DEV_RATEBIT_11MB ( 1 << 3 )
|
||||
#define DEV_RATEBIT_6MB ( 1 << 4 )
|
||||
#define DEV_RATEBIT_9MB ( 1 << 5 )
|
||||
#define DEV_RATEBIT_12MB ( 1 << 6 )
|
||||
#define DEV_RATEBIT_18MB ( 1 << 7 )
|
||||
#define DEV_RATEBIT_24MB ( 1 << 8 )
|
||||
#define DEV_RATEBIT_36MB ( 1 << 9 )
|
||||
#define DEV_RATEBIT_48MB ( 1 << 10 )
|
||||
#define DEV_RATEBIT_54MB ( 1 << 11 )
|
||||
|
||||
/*
|
||||
* Bitmasks for DEV_RATEMASK
|
||||
*/
|
||||
#define DEV_RATEMASK_1MB ( (DEV_RATEBIT_1MB << 1) -1 )
|
||||
#define DEV_RATEMASK_2MB ( (DEV_RATEBIT_2MB << 1) -1 )
|
||||
#define DEV_RATEMASK_5_5MB ( (DEV_RATEBIT_5_5MB << 1) -1 )
|
||||
#define DEV_RATEMASK_11MB ( (DEV_RATEBIT_11MB << 1) -1 )
|
||||
#define DEV_RATEMASK_6MB ( (DEV_RATEBIT_6MB << 1) -1 )
|
||||
#define DEV_RATEMASK_9MB ( (DEV_RATEBIT_9MB << 1) -1 )
|
||||
#define DEV_RATEMASK_12MB ( (DEV_RATEBIT_12MB << 1) -1 )
|
||||
#define DEV_RATEMASK_18MB ( (DEV_RATEBIT_18MB << 1) -1 )
|
||||
#define DEV_RATEMASK_24MB ( (DEV_RATEBIT_24MB << 1) -1 )
|
||||
#define DEV_RATEMASK_36MB ( (DEV_RATEBIT_36MB << 1) -1 )
|
||||
#define DEV_RATEMASK_48MB ( (DEV_RATEBIT_48MB << 1) -1 )
|
||||
#define DEV_RATEMASK_54MB ( (DEV_RATEBIT_54MB << 1) -1 )
|
||||
|
||||
/*
|
||||
* Bitmask groups of bitrates
|
||||
*/
|
||||
#define DEV_BASIC_RATEMASK \
|
||||
( DEV_RATEMASK_11MB | \
|
||||
DEV_RATEBIT_6MB | DEV_RATEBIT_12MB | DEV_RATEBIT_24MB )
|
||||
|
||||
#define DEV_CCK_RATEMASK ( DEV_RATEMASK_11MB )
|
||||
#define DEV_OFDM_RATEMASK ( DEV_RATEMASK_54MB & ~DEV_CCK_RATEMASK )
|
||||
|
||||
/*
|
||||
* Macro's to set and get specific fields from the device specific val and val2
|
||||
* fields inside the ieee80211_rate entry.
|
||||
*/
|
||||
#define DEVICE_SET_RATE_FIELD(__value, __mask) \
|
||||
(int)( ((__value) << DEV_##__mask.bit_offset) & DEV_##__mask.bit_mask )
|
||||
|
||||
#define DEVICE_GET_RATE_FIELD(__value, __mask) \
|
||||
(int)( ((__value) & DEV_##__mask.bit_mask) >> DEV_##__mask.bit_offset )
|
||||
|
||||
#endif /* RT2X00REG_H */
|
@ -19,9 +19,8 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
Module: rt2x00lib
|
||||
Abstract: rt2x00 rfkill specific routines.
|
||||
Supported chipsets: RT2460, RT2560, rt2561, rt2561s, rt2661.
|
||||
Module: rt2x00rfkill
|
||||
Abstract: rt2x00 rfkill routines.
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -29,101 +28,119 @@
|
||||
*/
|
||||
#define DRV_NAME "rt2x00lib"
|
||||
|
||||
#include <linux/input-polldev.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/rfkill.h>
|
||||
|
||||
#include "rt2x00.h"
|
||||
#include "rt2x00lib.h"
|
||||
|
||||
static int rt2x00lib_toggle_radio(void *data, enum rfkill_state state)
|
||||
static int rt2x00rfkill_toggle_radio(void *data, enum rfkill_state state)
|
||||
{
|
||||
struct rt2x00_dev* rt2x00dev = data;
|
||||
struct rt2x00_dev *rt2x00dev = data;
|
||||
int retval = 0;
|
||||
|
||||
if (unlikely(!rt2x00dev))
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* Only continue if we have an active interface,
|
||||
* either monitor or non-monitor should be present.
|
||||
* Only continue if there are enabled interfaces.
|
||||
*/
|
||||
if (!is_interface_present(&rt2x00dev->interface) &&
|
||||
!is_monitor_present(&rt2x00dev->interface))
|
||||
if (!test_bit(DEVICE_STARTED, &rt2x00dev->flags))
|
||||
return 0;
|
||||
|
||||
if (state == RFKILL_STATE_ON) {
|
||||
INFO(rt2x00dev, "Hardware button pressed, enabling radio.\n");
|
||||
__set_bit(DEVICE_ENABLED_RADIO_HW, &rt2x00dev->flags);
|
||||
__clear_bit(DEVICE_DISABLED_RADIO_HW, &rt2x00dev->flags);
|
||||
retval = rt2x00lib_enable_radio(rt2x00dev);
|
||||
} else if (state == RFKILL_STATE_OFF) {
|
||||
INFO(rt2x00dev, "Hardware button pressed, disabling radio.\n");
|
||||
__clear_bit(DEVICE_ENABLED_RADIO_HW, &rt2x00dev->flags);
|
||||
__set_bit(DEVICE_DISABLED_RADIO_HW, &rt2x00dev->flags);
|
||||
rt2x00lib_disable_radio(rt2x00dev);
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
static void rt2x00lib_rfkill_poll(struct work_struct *work)
|
||||
static void rt2x00rfkill_poll(struct input_polled_dev *poll_dev)
|
||||
{
|
||||
struct rt2x00_dev *rt2x00dev =
|
||||
container_of(work, struct rt2x00_dev, rfkill_work.work);
|
||||
struct rt2x00_dev *rt2x00dev = poll_dev->private;
|
||||
int state = rt2x00dev->ops->lib->rfkill_poll(rt2x00dev);
|
||||
|
||||
rfkill_switch_all(rt2x00dev->rfkill->type,
|
||||
rt2x00dev->ops->lib->rfkill_poll(rt2x00dev));
|
||||
|
||||
queue_delayed_work(rt2x00dev->hw->workqueue, &rt2x00dev->rfkill_work,
|
||||
RFKILL_POLL_INTERVAL);
|
||||
if (rt2x00dev->rfkill->state != state)
|
||||
input_report_key(poll_dev->input, KEY_WLAN, 1);
|
||||
}
|
||||
|
||||
int rt2x00lib_register_rfkill(struct rt2x00_dev *rt2x00dev)
|
||||
int rt2x00rfkill_register(struct rt2x00_dev *rt2x00dev)
|
||||
{
|
||||
int status = rfkill_register(rt2x00dev->rfkill);
|
||||
if (status) {
|
||||
int retval;
|
||||
|
||||
if (!test_bit(CONFIG_SUPPORT_HW_BUTTON, &rt2x00dev->flags))
|
||||
return 0;
|
||||
|
||||
retval = rfkill_register(rt2x00dev->rfkill);
|
||||
if (retval) {
|
||||
ERROR(rt2x00dev, "Failed to register rfkill handler.\n");
|
||||
return status;
|
||||
return retval;
|
||||
}
|
||||
|
||||
rt2x00lib_rfkill_poll(&rt2x00dev->rfkill_work.work);
|
||||
retval = input_register_polled_device(rt2x00dev->poll_dev);
|
||||
if (retval) {
|
||||
ERROR(rt2x00dev, "Failed to register polled device.\n");
|
||||
rfkill_unregister(rt2x00dev->rfkill);
|
||||
return retval;
|
||||
}
|
||||
|
||||
return !schedule_delayed_work(&rt2x00dev->rfkill_work,
|
||||
RFKILL_POLL_INTERVAL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void rt2x00lib_unregister_rfkill(struct rt2x00_dev *rt2x00dev)
|
||||
void rt2x00rfkill_unregister(struct rt2x00_dev *rt2x00dev)
|
||||
{
|
||||
if (delayed_work_pending(&rt2x00dev->rfkill_work))
|
||||
cancel_rearming_delayed_workqueue(
|
||||
rt2x00dev->hw->workqueue, &rt2x00dev->rfkill_work);
|
||||
if (!test_bit(CONFIG_SUPPORT_HW_BUTTON, &rt2x00dev->flags))
|
||||
return;
|
||||
|
||||
input_unregister_polled_device(rt2x00dev->poll_dev);
|
||||
rfkill_unregister(rt2x00dev->rfkill);
|
||||
}
|
||||
|
||||
int rt2x00lib_allocate_rfkill(struct rt2x00_dev *rt2x00dev)
|
||||
int rt2x00rfkill_allocate(struct rt2x00_dev *rt2x00dev)
|
||||
{
|
||||
struct rfkill *rfkill;
|
||||
struct device *device = wiphy_dev(rt2x00dev->hw->wiphy);
|
||||
|
||||
if (!test_bit(DEVICE_SUPPORT_HW_BUTTON, &rt2x00dev->flags))
|
||||
if (!test_bit(CONFIG_SUPPORT_HW_BUTTON, &rt2x00dev->flags))
|
||||
return 0;
|
||||
|
||||
rfkill = rfkill_allocate(rt2x00dev->device, RFKILL_TYPE_WLAN);
|
||||
if (!rfkill) {
|
||||
rt2x00dev->rfkill = rfkill_allocate(device, RFKILL_TYPE_WLAN);
|
||||
if (!rt2x00dev->rfkill) {
|
||||
ERROR(rt2x00dev, "Failed to allocate rfkill handler.\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
rfkill->name = rt2x00dev->ops->name;
|
||||
rfkill->data = rt2x00dev;
|
||||
rfkill->toggle_radio = rt2x00lib_toggle_radio;
|
||||
rt2x00dev->rfkill = rfkill;
|
||||
rt2x00dev->rfkill->name = rt2x00dev->ops->name;
|
||||
rt2x00dev->rfkill->data = rt2x00dev;
|
||||
rt2x00dev->rfkill->state = rt2x00dev->ops->lib->rfkill_poll(rt2x00dev);
|
||||
rt2x00dev->rfkill->toggle_radio = rt2x00rfkill_toggle_radio;
|
||||
|
||||
INIT_DELAYED_WORK(&rt2x00dev->rfkill_work, rt2x00lib_rfkill_poll);
|
||||
rt2x00dev->poll_dev = input_allocate_polled_device();
|
||||
if (!rt2x00dev->poll_dev) {
|
||||
ERROR(rt2x00dev, "Failed to allocate polled device.\n");
|
||||
rfkill_free(rt2x00dev->rfkill);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
rt2x00dev->poll_dev->private = rt2x00dev;
|
||||
rt2x00dev->poll_dev->poll = rt2x00rfkill_poll;
|
||||
rt2x00dev->poll_dev->poll_interval = RFKILL_POLL_INTERVAL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void rt2x00lib_free_rfkill(struct rt2x00_dev *rt2x00dev)
|
||||
void rt2x00rfkill_free(struct rt2x00_dev *rt2x00dev)
|
||||
{
|
||||
if (!test_bit(DEVICE_SUPPORT_HW_BUTTON, &rt2x00dev->flags))
|
||||
if (!test_bit(CONFIG_SUPPORT_HW_BUTTON, &rt2x00dev->flags))
|
||||
return;
|
||||
|
||||
input_free_polled_device(rt2x00dev->poll_dev);
|
||||
rfkill_free(rt2x00dev->rfkill);
|
||||
}
|
||||
|
268
package/rt2x00/src/rt2x00ring.h
Normal file
268
package/rt2x00/src/rt2x00ring.h
Normal file
@ -0,0 +1,268 @@
|
||||
/*
|
||||
Copyright (C) 2004 - 2007 rt2x00 SourceForge Project
|
||||
<http://rt2x00.serialmonkey.com>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the
|
||||
Free Software Foundation, Inc.,
|
||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
Module: rt2x00
|
||||
Abstract: rt2x00 ring datastructures and routines
|
||||
*/
|
||||
|
||||
#ifndef RT2X00RING_H
|
||||
#define RT2X00RING_H
|
||||
|
||||
/*
|
||||
* data_desc
|
||||
* Each data entry also contains a descriptor which is used by the
|
||||
* device to determine what should be done with the packet and
|
||||
* what the current status is.
|
||||
* This structure is greatly simplified, but the descriptors
|
||||
* are basically a list of little endian 32 bit values.
|
||||
* Make the array by default 1 word big, this will allow us
|
||||
* to use sizeof() correctly.
|
||||
*/
|
||||
struct data_desc {
|
||||
__le32 word[1];
|
||||
};
|
||||
|
||||
/*
|
||||
* rxdata_entry_desc
|
||||
* Summary of information that has been read from the
|
||||
* RX frame descriptor.
|
||||
*/
|
||||
struct rxdata_entry_desc {
|
||||
int signal;
|
||||
int rssi;
|
||||
int ofdm;
|
||||
int size;
|
||||
int flags;
|
||||
};
|
||||
|
||||
/*
|
||||
* txdata_entry_desc
|
||||
* Summary of information that should be written into the
|
||||
* descriptor for sending a TX frame.
|
||||
*/
|
||||
struct txdata_entry_desc {
|
||||
unsigned long flags;
|
||||
#define ENTRY_TXDONE 1
|
||||
#define ENTRY_TXD_RTS_FRAME 2
|
||||
#define ENTRY_TXD_OFDM_RATE 3
|
||||
#define ENTRY_TXD_MORE_FRAG 4
|
||||
#define ENTRY_TXD_REQ_TIMESTAMP 5
|
||||
#define ENTRY_TXD_BURST 6
|
||||
|
||||
/*
|
||||
* Queue ID. ID's 0-4 are data TX rings
|
||||
*/
|
||||
int queue;
|
||||
#define QUEUE_MGMT 13
|
||||
#define QUEUE_RX 14
|
||||
#define QUEUE_OTHER 15
|
||||
|
||||
/*
|
||||
* PLCP values.
|
||||
*/
|
||||
u16 length_high;
|
||||
u16 length_low;
|
||||
u16 signal;
|
||||
u16 service;
|
||||
|
||||
/*
|
||||
* Timing information
|
||||
*/
|
||||
int aifs;
|
||||
int ifs;
|
||||
int cw_min;
|
||||
int cw_max;
|
||||
};
|
||||
|
||||
/*
|
||||
* data_entry
|
||||
* The data ring is a list of data entries.
|
||||
* Each entry holds a reference to the descriptor
|
||||
* and the data buffer. For TX rings the reference to the
|
||||
* sk_buff of the packet being transmitted is also stored here.
|
||||
*/
|
||||
struct data_entry {
|
||||
/*
|
||||
* Status flags
|
||||
*/
|
||||
unsigned long flags;
|
||||
#define ENTRY_OWNER_NIC 1
|
||||
|
||||
/*
|
||||
* Ring we belong to.
|
||||
*/
|
||||
struct data_ring *ring;
|
||||
|
||||
/*
|
||||
* sk_buff for the packet which is being transmitted
|
||||
* in this entry (Only used with TX related rings).
|
||||
*/
|
||||
struct sk_buff *skb;
|
||||
|
||||
/*
|
||||
* Store a ieee80211_tx_status structure in each
|
||||
* ring entry, this will optimize the txdone
|
||||
* handler.
|
||||
*/
|
||||
struct ieee80211_tx_status tx_status;
|
||||
|
||||
/*
|
||||
* private pointer specific to driver.
|
||||
*/
|
||||
void *priv;
|
||||
|
||||
/*
|
||||
* Data address for this entry.
|
||||
*/
|
||||
void *data_addr;
|
||||
dma_addr_t data_dma;
|
||||
};
|
||||
|
||||
/*
|
||||
* data_ring
|
||||
* Data rings are used by the device to send and receive packets.
|
||||
* The data_addr is the base address of the data memory.
|
||||
* To determine at which point in the ring we are,
|
||||
* have to use the rt2x00_ring_index_*() functions.
|
||||
*/
|
||||
struct data_ring {
|
||||
/*
|
||||
* Pointer to main rt2x00dev structure where this
|
||||
* ring belongs to.
|
||||
*/
|
||||
struct rt2x00_dev *rt2x00dev;
|
||||
|
||||
/*
|
||||
* Base address for the device specific data entries.
|
||||
*/
|
||||
struct data_entry *entry;
|
||||
|
||||
/*
|
||||
* TX queue statistic info.
|
||||
*/
|
||||
struct ieee80211_tx_queue_stats_data stats;
|
||||
|
||||
/*
|
||||
* TX Queue parameters.
|
||||
*/
|
||||
struct ieee80211_tx_queue_params tx_params;
|
||||
|
||||
/*
|
||||
* Base address for data ring.
|
||||
*/
|
||||
dma_addr_t data_dma;
|
||||
void *data_addr;
|
||||
|
||||
/*
|
||||
* Index variables.
|
||||
*/
|
||||
u16 index;
|
||||
u16 index_done;
|
||||
|
||||
/*
|
||||
* Size of packet and descriptor in bytes.
|
||||
*/
|
||||
u16 data_size;
|
||||
u16 desc_size;
|
||||
};
|
||||
|
||||
/*
|
||||
* Handlers to determine the address of the current device specific
|
||||
* data entry, where either index or index_done points to.
|
||||
*/
|
||||
static inline struct data_entry *rt2x00_get_data_entry(struct data_ring *ring)
|
||||
{
|
||||
return &ring->entry[ring->index];
|
||||
}
|
||||
|
||||
static inline struct data_entry *rt2x00_get_data_entry_done(struct data_ring
|
||||
*ring)
|
||||
{
|
||||
return &ring->entry[ring->index_done];
|
||||
}
|
||||
|
||||
/*
|
||||
* Total ring memory
|
||||
*/
|
||||
static inline int rt2x00_get_ring_size(struct data_ring *ring)
|
||||
{
|
||||
return ring->stats.limit * (ring->desc_size + ring->data_size);
|
||||
}
|
||||
|
||||
/*
|
||||
* Ring index manipulation functions.
|
||||
*/
|
||||
static inline void rt2x00_ring_index_inc(struct data_ring *ring)
|
||||
{
|
||||
ring->index++;
|
||||
if (ring->index >= ring->stats.limit)
|
||||
ring->index = 0;
|
||||
ring->stats.len++;
|
||||
}
|
||||
|
||||
static inline void rt2x00_ring_index_done_inc(struct data_ring *ring)
|
||||
{
|
||||
ring->index_done++;
|
||||
if (ring->index_done >= ring->stats.limit)
|
||||
ring->index_done = 0;
|
||||
ring->stats.len--;
|
||||
ring->stats.count++;
|
||||
}
|
||||
|
||||
static inline void rt2x00_ring_index_clear(struct data_ring *ring)
|
||||
{
|
||||
ring->index = 0;
|
||||
ring->index_done = 0;
|
||||
ring->stats.len = 0;
|
||||
ring->stats.count = 0;
|
||||
}
|
||||
|
||||
static inline int rt2x00_ring_empty(struct data_ring *ring)
|
||||
{
|
||||
return ring->stats.len == 0;
|
||||
}
|
||||
|
||||
static inline int rt2x00_ring_full(struct data_ring *ring)
|
||||
{
|
||||
return ring->stats.len == ring->stats.limit;
|
||||
}
|
||||
|
||||
static inline int rt2x00_ring_free(struct data_ring *ring)
|
||||
{
|
||||
return ring->stats.limit - ring->stats.len;
|
||||
}
|
||||
|
||||
/*
|
||||
* TX/RX Descriptor access functions.
|
||||
*/
|
||||
static inline void rt2x00_desc_read(struct data_desc *desc,
|
||||
const u8 word, u32 *value)
|
||||
{
|
||||
*value = le32_to_cpu(desc->word[word]);
|
||||
}
|
||||
|
||||
static inline void rt2x00_desc_write(struct data_desc *desc,
|
||||
const u8 word, const u32 value)
|
||||
{
|
||||
desc->word[word] = cpu_to_le32(value);
|
||||
}
|
||||
|
||||
#endif /* RT2X00RING_H */
|
@ -21,7 +21,6 @@
|
||||
/*
|
||||
Module: rt2x00usb
|
||||
Abstract: rt2x00 generic usb device routines.
|
||||
Supported chipsets: rt2570, rt2571W & rt2671.
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -31,169 +30,87 @@
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/version.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/usb.h>
|
||||
|
||||
#include "rt2x00.h"
|
||||
#include "rt2x00lib.h"
|
||||
#include "rt2x00usb.h"
|
||||
|
||||
/*
|
||||
* Interfacing with the HW.
|
||||
*/
|
||||
int rt2x00usb_vendor_request(const struct rt2x00_dev *rt2x00dev,
|
||||
const u8 request, const u8 type, const u16 offset,
|
||||
u32 value, void *buffer, const u16 buffer_length, const u16 timeout)
|
||||
const u8 request, const u8 requesttype,
|
||||
const u16 offset, const u16 value,
|
||||
void *buffer, const u16 buffer_length,
|
||||
const int timeout)
|
||||
{
|
||||
struct usb_device *usb_dev = interface_to_usbdev(
|
||||
rt2x00dev_usb(rt2x00dev));
|
||||
struct usb_device *usb_dev =
|
||||
interface_to_usbdev(rt2x00dev_usb(rt2x00dev));
|
||||
int status;
|
||||
unsigned int i;
|
||||
unsigned int pipe =
|
||||
(requesttype == USB_VENDOR_REQUEST_IN) ?
|
||||
usb_rcvctrlpipe(usb_dev, 0) : usb_sndctrlpipe(usb_dev, 0);
|
||||
|
||||
for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
|
||||
status = usb_control_msg(
|
||||
usb_dev,
|
||||
(type == USB_VENDOR_REQUEST_IN) ?
|
||||
usb_rcvctrlpipe(usb_dev, 0) :
|
||||
usb_sndctrlpipe(usb_dev, 0),
|
||||
request, type, value, offset, buffer, buffer_length,
|
||||
status = usb_control_msg(usb_dev, pipe, request, requesttype,
|
||||
value, offset, buffer, buffer_length,
|
||||
timeout);
|
||||
if (status >= 0)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* Check for errors
|
||||
* -ENODEV: Device has disappeared, no point continuing.
|
||||
* All other errors: Try again.
|
||||
*/
|
||||
else if (status == -ENODEV)
|
||||
break;
|
||||
}
|
||||
|
||||
ERROR(rt2x00dev, "Vendor Request 0x%02x failed for offset 0x%04x"
|
||||
" with error %d.\n", request, offset, status);
|
||||
ERROR(rt2x00dev,
|
||||
"Vendor Request 0x%02x failed for offset 0x%04x with error %d.\n",
|
||||
request, offset, status);
|
||||
|
||||
return status;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rt2x00usb_vendor_request);
|
||||
|
||||
/*
|
||||
* Beacon handlers.
|
||||
*/
|
||||
int rt2x00usb_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb,
|
||||
struct ieee80211_tx_control *control)
|
||||
int rt2x00usb_vendor_request_buff(const struct rt2x00_dev *rt2x00dev,
|
||||
const u8 request, const u8 requesttype,
|
||||
const u16 offset, void *buffer,
|
||||
const u16 buffer_length, const int timeout)
|
||||
{
|
||||
struct rt2x00_dev *rt2x00dev = hw->priv;
|
||||
struct usb_device *usb_dev =
|
||||
interface_to_usbdev(rt2x00dev_usb(rt2x00dev));
|
||||
struct data_ring *ring =
|
||||
rt2x00_get_ring(rt2x00dev, IEEE80211_TX_QUEUE_BEACON);
|
||||
struct data_entry *beacon;
|
||||
struct data_entry *guardian;
|
||||
int length;
|
||||
int status;
|
||||
|
||||
/*
|
||||
* Just in case the ieee80211 doesn't set this,
|
||||
* but we need this queue set for the descriptor
|
||||
* initialization.
|
||||
* Check for Cache availability.
|
||||
*/
|
||||
control->queue = IEEE80211_TX_QUEUE_BEACON;
|
||||
|
||||
/*
|
||||
* Obtain 2 entries, one for the guardian byte,
|
||||
* the second for the actual beacon.
|
||||
*/
|
||||
guardian = rt2x00_get_data_entry(ring);
|
||||
rt2x00_ring_index_inc(ring);
|
||||
beacon = rt2x00_get_data_entry(ring);
|
||||
|
||||
/*
|
||||
* First we create the beacon.
|
||||
*/
|
||||
skb_push(skb, ring->desc_size);
|
||||
rt2x00lib_write_tx_desc(rt2x00dev, beacon,
|
||||
(struct data_desc*)skb->data,
|
||||
(struct ieee80211_hdr*)(skb->data + ring->desc_size),
|
||||
skb->len - ring->desc_size,
|
||||
control);
|
||||
|
||||
/*
|
||||
* Length passed to usb_fill_urb cannot be an odd number,
|
||||
* so add 1 byte to make it even.
|
||||
*/
|
||||
length = skb->len;
|
||||
if (length % 2)
|
||||
length++;
|
||||
|
||||
usb_fill_bulk_urb(
|
||||
beacon->priv,
|
||||
usb_dev,
|
||||
usb_sndbulkpipe(usb_dev, 1),
|
||||
skb->data,
|
||||
length,
|
||||
rt2x00usb_beacondone,
|
||||
beacon);
|
||||
|
||||
beacon->skb = skb;
|
||||
|
||||
/*
|
||||
* Second we need to create the guardian byte.
|
||||
* We only need a single byte, so lets recycle
|
||||
* the 'flags' field we are not using for beacons.
|
||||
*/
|
||||
guardian->flags = 0;
|
||||
usb_fill_bulk_urb(
|
||||
guardian->priv,
|
||||
usb_dev,
|
||||
usb_sndbulkpipe(usb_dev, 1),
|
||||
&guardian->flags,
|
||||
1,
|
||||
rt2x00usb_beacondone,
|
||||
guardian);
|
||||
|
||||
/*
|
||||
* Send out the guardian byte.
|
||||
*/
|
||||
usb_submit_urb(guardian->priv, GFP_ATOMIC);
|
||||
|
||||
/*
|
||||
* Enable beacon generation.
|
||||
*/
|
||||
rt2x00dev->ops->lib->kick_tx_queue(rt2x00dev, control->queue);
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rt2x00usb_beacon_update);
|
||||
|
||||
void rt2x00usb_beacondone(struct urb *urb)
|
||||
{
|
||||
struct data_entry *entry = (struct data_entry*)urb->context;
|
||||
struct data_ring *ring = entry->ring;
|
||||
|
||||
if (!test_bit(DEVICE_ENABLED_RADIO, &ring->rt2x00dev->flags))
|
||||
return;
|
||||
|
||||
/*
|
||||
* Check if this was the guardian beacon,
|
||||
* if that was the case we need to send the real beacon now.
|
||||
* Otherwise we should free the sk_buffer, the device
|
||||
* should be doing the rest of the work now.
|
||||
*/
|
||||
if (ring->index == 1) {
|
||||
rt2x00_ring_index_done_inc(ring);
|
||||
entry = rt2x00_get_data_entry(ring);
|
||||
usb_submit_urb(entry->priv, GFP_ATOMIC);
|
||||
rt2x00_ring_index_inc(ring);
|
||||
} else if (ring->index_done == 1) {
|
||||
entry = rt2x00_get_data_entry_done(ring);
|
||||
if (entry->skb) {
|
||||
dev_kfree_skb(entry->skb);
|
||||
entry->skb = NULL;
|
||||
}
|
||||
rt2x00_ring_index_done_inc(ring);
|
||||
if (unlikely(!rt2x00dev->csr_cache || buffer_length > CSR_CACHE_SIZE)) {
|
||||
ERROR(rt2x00dev, "CSR cache not available.\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
if (requesttype == USB_VENDOR_REQUEST_OUT)
|
||||
memcpy(rt2x00dev->csr_cache, buffer, buffer_length);
|
||||
|
||||
status = rt2x00usb_vendor_request(rt2x00dev, request, requesttype,
|
||||
offset, 0, rt2x00dev->csr_cache,
|
||||
buffer_length, timeout);
|
||||
|
||||
if (!status && requesttype == USB_VENDOR_REQUEST_IN)
|
||||
memcpy(buffer, rt2x00dev->csr_cache, buffer_length);
|
||||
|
||||
return status;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rt2x00usb_beacondone);
|
||||
EXPORT_SYMBOL_GPL(rt2x00usb_vendor_request_buff);
|
||||
|
||||
/*
|
||||
* TX data handlers.
|
||||
*/
|
||||
static void rt2x00usb_interrupt_txdone(struct urb *urb)
|
||||
{
|
||||
struct data_entry *entry = (struct data_entry*)urb->context;
|
||||
struct data_entry *entry = (struct data_entry *)urb->context;
|
||||
struct data_ring *ring = entry->ring;
|
||||
struct rt2x00_dev *rt2x00dev = ring->rt2x00dev;
|
||||
struct data_desc *txd = (struct data_desc *)entry->skb->data;
|
||||
@ -240,10 +157,9 @@ int rt2x00usb_write_tx_data(struct rt2x00_dev *rt2x00dev,
|
||||
{
|
||||
struct usb_device *usb_dev =
|
||||
interface_to_usbdev(rt2x00dev_usb(rt2x00dev));
|
||||
struct ieee80211_hdr *ieee80211hdr = (struct ieee80211_hdr*)skb->data;
|
||||
struct data_entry *entry = rt2x00_get_data_entry(ring);
|
||||
struct data_desc *txd;
|
||||
u32 length = skb->len;
|
||||
int pipe = usb_sndbulkpipe(usb_dev, 1);
|
||||
u32 length;
|
||||
|
||||
if (rt2x00_ring_full(ring)) {
|
||||
ieee80211_stop_queue(rt2x00dev->hw, control->queue);
|
||||
@ -255,34 +171,36 @@ int rt2x00usb_write_tx_data(struct rt2x00_dev *rt2x00dev,
|
||||
"Arrived at non-free entry in the non-full queue %d.\n"
|
||||
"Please file bug report to %s.\n",
|
||||
control->queue, DRV_PROJECT);
|
||||
ieee80211_stop_queue( rt2x00dev->hw, control->queue);
|
||||
ieee80211_stop_queue(rt2x00dev->hw, control->queue);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
skb_push(skb, rt2x00dev->hw->extra_tx_headroom);
|
||||
txd = (struct data_desc*)skb->data;
|
||||
rt2x00lib_write_tx_desc(rt2x00dev, entry, txd, ieee80211hdr,
|
||||
length, control);
|
||||
/*
|
||||
* Add the descriptor in front of the skb.
|
||||
*/
|
||||
skb_push(skb, ring->desc_size);
|
||||
memset(skb->data, 0, ring->desc_size);
|
||||
|
||||
rt2x00lib_write_tx_desc(rt2x00dev, (struct data_desc *)skb->data,
|
||||
(struct ieee80211_hdr *)(skb->data +
|
||||
ring->desc_size),
|
||||
skb->len - ring->desc_size, control);
|
||||
memcpy(&entry->tx_status.control, control, sizeof(*control));
|
||||
entry->skb = skb;
|
||||
|
||||
/*
|
||||
* Length passed to usb_fill_urb cannot be an odd number,
|
||||
* so add 1 byte to make it even.
|
||||
* USB devices cannot blindly pass the skb->len as the
|
||||
* length of the data to usb_fill_bulk_urb. Pass the skb
|
||||
* to the driver to determine what the length should be.
|
||||
*/
|
||||
length += rt2x00dev->hw->extra_tx_headroom;
|
||||
if (length % 2)
|
||||
length++;
|
||||
length = rt2x00dev->ops->lib->get_tx_data_len(rt2x00dev, skb);
|
||||
|
||||
/*
|
||||
* Initialize URB and send the frame to the device.
|
||||
*/
|
||||
__set_bit(ENTRY_OWNER_NIC, &entry->flags);
|
||||
usb_fill_bulk_urb(
|
||||
entry->priv,
|
||||
usb_dev,
|
||||
usb_sndbulkpipe(usb_dev, 1),
|
||||
skb->data,
|
||||
length,
|
||||
rt2x00usb_interrupt_txdone,
|
||||
entry);
|
||||
usb_fill_bulk_urb(entry->priv, usb_dev, pipe,
|
||||
skb->data, length, rt2x00usb_interrupt_txdone, entry);
|
||||
usb_submit_urb(entry->priv, GFP_ATOMIC);
|
||||
|
||||
rt2x00_ring_index_inc(ring);
|
||||
@ -299,13 +217,14 @@ EXPORT_SYMBOL_GPL(rt2x00usb_write_tx_data);
|
||||
*/
|
||||
static void rt2x00usb_interrupt_rxdone(struct urb *urb)
|
||||
{
|
||||
struct data_entry *entry = (struct data_entry*)urb->context;
|
||||
struct data_entry *entry = (struct data_entry *)urb->context;
|
||||
struct data_ring *ring = entry->ring;
|
||||
struct rt2x00_dev *rt2x00dev = ring->rt2x00dev;
|
||||
int signal;
|
||||
int rssi;
|
||||
int ofdm;
|
||||
int size;
|
||||
struct sk_buff *skb;
|
||||
struct ieee80211_hdr *hdr;
|
||||
struct rxdata_entry_desc desc;
|
||||
int header_size;
|
||||
int frame_size;
|
||||
|
||||
if (!test_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags) ||
|
||||
!test_and_clear_bit(ENTRY_OWNER_NIC, &entry->flags))
|
||||
@ -319,21 +238,56 @@ static void rt2x00usb_interrupt_rxdone(struct urb *urb)
|
||||
if (urb->actual_length < entry->ring->desc_size || urb->status)
|
||||
goto skip_entry;
|
||||
|
||||
size = rt2x00dev->ops->lib->fill_rxdone(entry, &signal, &rssi, &ofdm);
|
||||
if (size < 0)
|
||||
memset(&desc, 0x00, sizeof(desc));
|
||||
rt2x00dev->ops->lib->fill_rxdone(entry, &desc);
|
||||
|
||||
/*
|
||||
* Allocate a new sk buffer to replace the current one.
|
||||
* If allocation fails, we should drop the current frame
|
||||
* so we can recycle the existing sk buffer for the new frame.
|
||||
* As alignment we use 2 and not NET_IP_ALIGN because we need
|
||||
* to be sure we have 2 bytes room in the head. (NET_IP_ALIGN
|
||||
* can be 0 on some hardware). We use these 2 bytes for frame
|
||||
* alignment later, we assume that the chance that
|
||||
* header_size % 4 == 2 is bigger then header_size % 2 == 0
|
||||
* and thus optimize alignment by reserving the 2 bytes in
|
||||
* advance.
|
||||
*/
|
||||
frame_size = entry->ring->data_size + entry->ring->desc_size;
|
||||
skb = dev_alloc_skb(frame_size + 2);
|
||||
if (!skb)
|
||||
goto skip_entry;
|
||||
|
||||
/*
|
||||
* Trim the skb_buffer to only contain the valid
|
||||
* frame data (so ignore the device's descriptor).
|
||||
*/
|
||||
skb_trim(entry->skb, size);
|
||||
skb_reserve(skb, 2);
|
||||
skb_put(skb, frame_size);
|
||||
|
||||
/*
|
||||
* Send the packet to upper layer, and update urb.
|
||||
* The data behind the ieee80211 header must be
|
||||
* aligned on a 4 byte boundary.
|
||||
* After that trim the entire buffer down to only
|
||||
* contain the valid frame data excluding the device
|
||||
* descriptor.
|
||||
*/
|
||||
rt2x00lib_rxdone(entry, NULL, ring->data_size + ring->desc_size,
|
||||
signal, rssi, ofdm);
|
||||
hdr = (struct ieee80211_hdr *)entry->skb->data;
|
||||
header_size =
|
||||
ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_control));
|
||||
|
||||
if (header_size % 4 == 0) {
|
||||
skb_push(entry->skb, 2);
|
||||
memmove(entry->skb->data, entry->skb->data + 2, skb->len - 2);
|
||||
}
|
||||
skb_trim(entry->skb, desc.size);
|
||||
|
||||
/*
|
||||
* Send the frame to rt2x00lib for further processing.
|
||||
*/
|
||||
rt2x00lib_rxdone(entry, entry->skb, &desc);
|
||||
|
||||
/*
|
||||
* Replace current entry's skb with the newly allocated one,
|
||||
* and reinitialize the urb.
|
||||
*/
|
||||
entry->skb = skb;
|
||||
urb->transfer_buffer = entry->skb->data;
|
||||
urb->transfer_buffer_length = entry->skb->len;
|
||||
|
||||
@ -375,14 +329,10 @@ void rt2x00usb_enable_radio(struct rt2x00_dev *rt2x00dev)
|
||||
for (i = 0; i < rt2x00dev->rx->stats.limit; i++) {
|
||||
entry = &rt2x00dev->rx->entry[i];
|
||||
|
||||
usb_fill_bulk_urb(
|
||||
entry->priv,
|
||||
usb_dev,
|
||||
usb_fill_bulk_urb(entry->priv, usb_dev,
|
||||
usb_rcvbulkpipe(usb_dev, 1),
|
||||
entry->skb->data,
|
||||
entry->skb->len,
|
||||
rt2x00usb_interrupt_rxdone,
|
||||
entry);
|
||||
entry->skb->data, entry->skb->len,
|
||||
rt2x00usb_interrupt_rxdone, entry);
|
||||
|
||||
__set_bit(ENTRY_OWNER_NIC, &entry->flags);
|
||||
usb_submit_urb(entry->priv, GFP_ATOMIC);
|
||||
@ -395,8 +345,8 @@ void rt2x00usb_disable_radio(struct rt2x00_dev *rt2x00dev)
|
||||
struct data_ring *ring;
|
||||
unsigned int i;
|
||||
|
||||
rt2x00usb_vendor_request(rt2x00dev, USB_RX_CONTROL,
|
||||
USB_VENDOR_REQUEST_OUT, 0x00, 0x00, NULL, 0, REGISTER_TIMEOUT);
|
||||
rt2x00usb_vendor_request_sw(rt2x00dev, USB_RX_CONTROL, 0x0000, 0x0000,
|
||||
REGISTER_TIMEOUT);
|
||||
|
||||
/*
|
||||
* Cancel all rings.
|
||||
@ -411,7 +361,7 @@ EXPORT_SYMBOL_GPL(rt2x00usb_disable_radio);
|
||||
/*
|
||||
* Device initialization handlers.
|
||||
*/
|
||||
static int rt2x00usb_alloc_ring(struct rt2x00_dev *rt2x00dev,
|
||||
static int rt2x00usb_alloc_urb(struct rt2x00_dev *rt2x00dev,
|
||||
struct data_ring *ring)
|
||||
{
|
||||
unsigned int i;
|
||||
@ -428,6 +378,22 @@ static int rt2x00usb_alloc_ring(struct rt2x00_dev *rt2x00dev,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void rt2x00usb_free_urb(struct rt2x00_dev *rt2x00dev,
|
||||
struct data_ring *ring)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
if (!ring->entry)
|
||||
return;
|
||||
|
||||
for (i = 0; i < ring->stats.limit; i++) {
|
||||
usb_kill_urb(ring->entry[i].priv);
|
||||
usb_free_urb(ring->entry[i].priv);
|
||||
if (ring->entry[i].skb)
|
||||
kfree_skb(ring->entry[i].skb);
|
||||
}
|
||||
}
|
||||
|
||||
int rt2x00usb_initialize(struct rt2x00_dev *rt2x00dev)
|
||||
{
|
||||
struct data_ring *ring;
|
||||
@ -440,7 +406,7 @@ int rt2x00usb_initialize(struct rt2x00_dev *rt2x00dev)
|
||||
* Allocate DMA
|
||||
*/
|
||||
ring_for_each(rt2x00dev, ring) {
|
||||
status = rt2x00usb_alloc_ring(rt2x00dev, ring);
|
||||
status = rt2x00usb_alloc_urb(rt2x00dev, ring);
|
||||
if (status)
|
||||
goto exit;
|
||||
}
|
||||
@ -448,7 +414,7 @@ int rt2x00usb_initialize(struct rt2x00_dev *rt2x00dev)
|
||||
/*
|
||||
* For the RX ring, skb's should be allocated.
|
||||
*/
|
||||
entry_size = ring->data_size + ring->desc_size;
|
||||
entry_size = rt2x00dev->rx->data_size + rt2x00dev->rx->desc_size;
|
||||
for (i = 0; i < rt2x00dev->rx->stats.limit; i++) {
|
||||
skb = dev_alloc_skb(NET_IP_ALIGN + entry_size);
|
||||
if (!skb)
|
||||
@ -472,30 +438,56 @@ EXPORT_SYMBOL_GPL(rt2x00usb_initialize);
|
||||
void rt2x00usb_uninitialize(struct rt2x00_dev *rt2x00dev)
|
||||
{
|
||||
struct data_ring *ring;
|
||||
unsigned int i;
|
||||
|
||||
ring_for_each(rt2x00dev, ring) {
|
||||
if (!ring->entry)
|
||||
continue;
|
||||
|
||||
for (i = 0; i < ring->stats.limit; i++) {
|
||||
usb_kill_urb(ring->entry[i].priv);
|
||||
usb_free_urb(ring->entry[i].priv);
|
||||
if (ring->entry[i].skb)
|
||||
kfree_skb(ring->entry[i].skb);
|
||||
}
|
||||
}
|
||||
ring_for_each(rt2x00dev, ring)
|
||||
rt2x00usb_free_urb(rt2x00dev, ring);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rt2x00usb_uninitialize);
|
||||
|
||||
/*
|
||||
* USB driver handlers.
|
||||
*/
|
||||
static void rt2x00usb_free_reg(struct rt2x00_dev *rt2x00dev)
|
||||
{
|
||||
kfree(rt2x00dev->rf);
|
||||
rt2x00dev->rf = NULL;
|
||||
|
||||
kfree(rt2x00dev->eeprom);
|
||||
rt2x00dev->eeprom = NULL;
|
||||
|
||||
kfree(rt2x00dev->csr_cache);
|
||||
rt2x00dev->csr_cache = NULL;
|
||||
}
|
||||
|
||||
static int rt2x00usb_alloc_reg(struct rt2x00_dev *rt2x00dev)
|
||||
{
|
||||
rt2x00dev->csr_cache = kzalloc(CSR_CACHE_SIZE, GFP_KERNEL);
|
||||
if (!rt2x00dev->csr_cache)
|
||||
goto exit;
|
||||
|
||||
rt2x00dev->eeprom = kzalloc(rt2x00dev->ops->eeprom_size, GFP_KERNEL);
|
||||
if (!rt2x00dev->eeprom)
|
||||
goto exit;
|
||||
|
||||
rt2x00dev->rf = kzalloc(rt2x00dev->ops->rf_size, GFP_KERNEL);
|
||||
if (!rt2x00dev->rf)
|
||||
goto exit;
|
||||
|
||||
return 0;
|
||||
|
||||
exit:
|
||||
ERROR_PROBE("Failed to allocate registers.\n");
|
||||
|
||||
rt2x00usb_free_reg(rt2x00dev);
|
||||
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
int rt2x00usb_probe(struct usb_interface *usb_intf,
|
||||
const struct usb_device_id *id)
|
||||
{
|
||||
struct usb_device *usb_dev = interface_to_usbdev(usb_intf);
|
||||
struct rt2x00_ops *ops = (struct rt2x00_ops*)id->driver_info;
|
||||
struct rt2x00_ops *ops = (struct rt2x00_ops *)id->driver_info;
|
||||
struct ieee80211_hw *hw;
|
||||
struct rt2x00_dev *rt2x00dev;
|
||||
int retval;
|
||||
@ -516,12 +508,24 @@ int rt2x00usb_probe(struct usb_interface *usb_intf,
|
||||
rt2x00dev->ops = ops;
|
||||
rt2x00dev->hw = hw;
|
||||
|
||||
retval = rt2x00lib_probe_dev(rt2x00dev);
|
||||
rt2x00dev->usb_maxpacket =
|
||||
usb_maxpacket(usb_dev, usb_sndbulkpipe(usb_dev, 1), 1);
|
||||
if (!rt2x00dev->usb_maxpacket)
|
||||
rt2x00dev->usb_maxpacket = 1;
|
||||
|
||||
retval = rt2x00usb_alloc_reg(rt2x00dev);
|
||||
if (retval)
|
||||
goto exit_free_device;
|
||||
|
||||
retval = rt2x00lib_probe_dev(rt2x00dev);
|
||||
if (retval)
|
||||
goto exit_free_reg;
|
||||
|
||||
return 0;
|
||||
|
||||
exit_free_reg:
|
||||
rt2x00usb_free_reg(rt2x00dev);
|
||||
|
||||
exit_free_device:
|
||||
ieee80211_free_hw(hw);
|
||||
|
||||
@ -543,6 +547,7 @@ void rt2x00usb_disconnect(struct usb_interface *usb_intf)
|
||||
* Free all allocated data.
|
||||
*/
|
||||
rt2x00lib_remove_dev(rt2x00dev);
|
||||
rt2x00usb_free_reg(rt2x00dev);
|
||||
ieee80211_free_hw(hw);
|
||||
|
||||
/*
|
||||
@ -564,6 +569,8 @@ int rt2x00usb_suspend(struct usb_interface *usb_intf, pm_message_t state)
|
||||
if (retval)
|
||||
return retval;
|
||||
|
||||
rt2x00usb_free_reg(rt2x00dev);
|
||||
|
||||
/*
|
||||
* Decrease usbdev refcount.
|
||||
*/
|
||||
@ -577,10 +584,24 @@ int rt2x00usb_resume(struct usb_interface *usb_intf)
|
||||
{
|
||||
struct ieee80211_hw *hw = usb_get_intfdata(usb_intf);
|
||||
struct rt2x00_dev *rt2x00dev = hw->priv;
|
||||
int retval;
|
||||
|
||||
usb_get_dev(interface_to_usbdev(usb_intf));
|
||||
|
||||
return rt2x00lib_resume(rt2x00dev);
|
||||
retval = rt2x00usb_alloc_reg(rt2x00dev);
|
||||
if (retval)
|
||||
return retval;
|
||||
|
||||
retval = rt2x00lib_resume(rt2x00dev);
|
||||
if (retval)
|
||||
goto exit_free_reg;
|
||||
|
||||
return 0;
|
||||
|
||||
exit_free_reg:
|
||||
rt2x00usb_free_reg(rt2x00dev);
|
||||
|
||||
return retval;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rt2x00usb_resume);
|
||||
#endif /* CONFIG_PM */
|
||||
|
@ -21,7 +21,6 @@
|
||||
/*
|
||||
Module: rt2x00usb
|
||||
Abstract: Data structures for the rt2x00usb module.
|
||||
Supported chipsets: rt2570, rt2571W & rt2671.
|
||||
*/
|
||||
|
||||
#ifndef RT2X00USB_H
|
||||
@ -35,19 +34,25 @@
|
||||
|
||||
/*
|
||||
* Register defines.
|
||||
* When register access attempts should be repeated
|
||||
* only REGISTER_BUSY_COUNT attempts with a delay
|
||||
* of REGISTER_BUSY_DELAY us should be taken.
|
||||
* Some registers require multiple attempts before success,
|
||||
* in those cases REGISTER_BUSY_COUNT attempts should be
|
||||
* taken with a REGISTER_BUSY_DELAY interval.
|
||||
* For USB vendor requests we need to pass a timeout
|
||||
* time in ms, for this we use the REGISTER_TIMEOUT,
|
||||
* however when loading firmware a higher value is
|
||||
* required. For that we use the REGISTER_TIMEOUT_FIRMWARE.
|
||||
* required. In that case we use the REGISTER_TIMEOUT_FIRMWARE.
|
||||
*/
|
||||
#define REGISTER_BUSY_COUNT 5
|
||||
#define REGISTER_BUSY_DELAY 100
|
||||
#define REGISTER_TIMEOUT 20
|
||||
#define REGISTER_TIMEOUT 500
|
||||
#define REGISTER_TIMEOUT_FIRMWARE 1000
|
||||
|
||||
/*
|
||||
* Cache size
|
||||
*/
|
||||
#define CSR_CACHE_SIZE 8
|
||||
#define CSR_CACHE_SIZE_FIRMWARE 64
|
||||
|
||||
/*
|
||||
* USB request types.
|
||||
*/
|
||||
@ -80,17 +85,64 @@
|
||||
#define USB_MODE_WAKEUP 0x09 /* RT73USB */
|
||||
|
||||
/*
|
||||
* USB devices need an additional Beacon (guardian beacon) to be generated.
|
||||
*/
|
||||
#undef BEACON_ENTRIES
|
||||
#define BEACON_ENTRIES 2
|
||||
|
||||
/*
|
||||
* Interfacing with the HW.
|
||||
* Used to read/write from/to the device.
|
||||
* This is the main function to communicate with the device,
|
||||
* the buffer argument _must_ either be NULL or point to
|
||||
* a buffer allocated by kmalloc. Failure to do so can lead
|
||||
* to unexpected behavior depending on the architecture.
|
||||
*/
|
||||
int rt2x00usb_vendor_request(const struct rt2x00_dev *rt2x00dev,
|
||||
const u8 request, const u8 type, const u16 offset,
|
||||
u32 value, void *buffer, const u16 buffer_length, const u16 timeout);
|
||||
const u8 request, const u8 requesttype,
|
||||
const u16 offset, const u16 value,
|
||||
void *buffer, const u16 buffer_length,
|
||||
const int timeout);
|
||||
|
||||
/*
|
||||
* Used to read/write from/to the device.
|
||||
* This function will use a previously with kmalloc allocated cache
|
||||
* to communicate with the device. The contents of the buffer pointer
|
||||
* will be copied to this cache when writing, or read from the cache
|
||||
* when reading.
|
||||
* Buffers send to rt2x00usb_vendor_request _must_ be allocated with
|
||||
* kmalloc. Hence the reason for using a previously allocated cache
|
||||
* which has been allocated properly.
|
||||
*/
|
||||
int rt2x00usb_vendor_request_buff(const struct rt2x00_dev *rt2x00dev,
|
||||
const u8 request, const u8 requesttype,
|
||||
const u16 offset, void *buffer,
|
||||
const u16 buffer_length, const int timeout);
|
||||
|
||||
/*
|
||||
* Simple wrapper around rt2x00usb_vendor_request to write a single
|
||||
* command to the device. Since we don't use the buffer argument we
|
||||
* don't have to worry about kmalloc here.
|
||||
*/
|
||||
static inline int rt2x00usb_vendor_request_sw(const struct rt2x00_dev
|
||||
*rt2x00dev,
|
||||
const u8 request,
|
||||
const u16 offset,
|
||||
const u16 value,
|
||||
const int timeout)
|
||||
{
|
||||
return rt2x00usb_vendor_request(rt2x00dev, request,
|
||||
USB_VENDOR_REQUEST_OUT, offset,
|
||||
value, NULL, 0, timeout);
|
||||
}
|
||||
|
||||
/*
|
||||
* Simple wrapper around rt2x00usb_vendor_request to read the eeprom
|
||||
* from the device. Note that the eeprom argument _must_ be allocated using
|
||||
* kmalloc for correct handling inside the kernel USB layer.
|
||||
*/
|
||||
static inline int rt2x00usb_eeprom_read(const struct rt2x00_dev *rt2x00dev,
|
||||
__le16 *eeprom, const u16 lenght)
|
||||
{
|
||||
int timeout = REGISTER_TIMEOUT * (lenght / sizeof(u16));
|
||||
|
||||
return rt2x00usb_vendor_request(rt2x00dev, USB_EEPROM_READ,
|
||||
USB_VENDOR_REQUEST_IN, 0x0000,
|
||||
0x0000, eeprom, lenght, timeout);
|
||||
}
|
||||
|
||||
/*
|
||||
* Radio handlers
|
||||
@ -98,13 +150,6 @@ int rt2x00usb_vendor_request(const struct rt2x00_dev *rt2x00dev,
|
||||
void rt2x00usb_enable_radio(struct rt2x00_dev *rt2x00dev);
|
||||
void rt2x00usb_disable_radio(struct rt2x00_dev *rt2x00dev);
|
||||
|
||||
/*
|
||||
* Beacon handlers.
|
||||
*/
|
||||
int rt2x00usb_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb,
|
||||
struct ieee80211_tx_control *control);
|
||||
void rt2x00usb_beacondone(struct urb *urb);
|
||||
|
||||
/*
|
||||
* TX data handlers.
|
||||
*/
|
||||
@ -127,6 +172,9 @@ void rt2x00usb_disconnect(struct usb_interface *usb_intf);
|
||||
#ifdef CONFIG_PM
|
||||
int rt2x00usb_suspend(struct usb_interface *usb_intf, pm_message_t state);
|
||||
int rt2x00usb_resume(struct usb_interface *usb_intf);
|
||||
#else
|
||||
#define rt2x00usb_suspend NULL
|
||||
#define rt2x00usb_resume NULL
|
||||
#endif /* CONFIG_PM */
|
||||
|
||||
#endif /* RT2X00USB_H */
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -37,9 +37,10 @@
|
||||
|
||||
/*
|
||||
* Signal information.
|
||||
* Defaul offset is required for RSSI <-> dBm conversion.
|
||||
*/
|
||||
#define MAX_SIGNAL 100
|
||||
#define MAX_RX_SSI -1
|
||||
#define MAX_RX_NOISE -110
|
||||
#define DEFAULT_RSSI_OFFSET 120
|
||||
|
||||
/*
|
||||
@ -50,6 +51,7 @@
|
||||
#define EEPROM_BASE 0x0000
|
||||
#define EEPROM_SIZE 0x0100
|
||||
#define BBP_SIZE 0x0080
|
||||
#define RF_SIZE 0x0014
|
||||
|
||||
/*
|
||||
* PCI registers.
|
||||
@ -260,7 +262,7 @@ struct hw_pairwise_ta_entry {
|
||||
* MAC_CSR6: Maximum frame length register.
|
||||
*/
|
||||
#define MAC_CSR6 0x3018
|
||||
#define MAC_CSR6_MAX_FRAME_UNIT FIELD32(0x000007ff)
|
||||
#define MAC_CSR6_MAX_FRAME_UNIT FIELD32(0x00000fff)
|
||||
|
||||
/*
|
||||
* MAC_CSR7: Reserved
|
||||
@ -330,6 +332,11 @@ struct hw_pairwise_ta_entry {
|
||||
#define MAC_CSR13_BIT5 FIELD32(0x00000020)
|
||||
#define MAC_CSR13_BIT6 FIELD32(0x00000040)
|
||||
#define MAC_CSR13_BIT7 FIELD32(0x00000080)
|
||||
#define MAC_CSR13_BIT8 FIELD32(0x00000100)
|
||||
#define MAC_CSR13_BIT9 FIELD32(0x00000200)
|
||||
#define MAC_CSR13_BIT10 FIELD32(0x00000400)
|
||||
#define MAC_CSR13_BIT11 FIELD32(0x00000800)
|
||||
#define MAC_CSR13_BIT12 FIELD32(0x00001000)
|
||||
|
||||
/*
|
||||
* MAC_CSR14: LED control register.
|
||||
@ -392,16 +399,40 @@ struct hw_pairwise_ta_entry {
|
||||
* TXRX_CSR1
|
||||
*/
|
||||
#define TXRX_CSR1 0x3044
|
||||
#define TXRX_CSR1_BBP_ID0 FIELD32(0x0000007f)
|
||||
#define TXRX_CSR1_BBP_ID0_VALID FIELD32(0x00000080)
|
||||
#define TXRX_CSR1_BBP_ID1 FIELD32(0x00007f00)
|
||||
#define TXRX_CSR1_BBP_ID1_VALID FIELD32(0x00008000)
|
||||
#define TXRX_CSR1_BBP_ID2 FIELD32(0x007f0000)
|
||||
#define TXRX_CSR1_BBP_ID2_VALID FIELD32(0x00800000)
|
||||
#define TXRX_CSR1_BBP_ID3 FIELD32(0x7f000000)
|
||||
#define TXRX_CSR1_BBP_ID3_VALID FIELD32(0x80000000)
|
||||
|
||||
/*
|
||||
* TXRX_CSR2
|
||||
*/
|
||||
#define TXRX_CSR2 0x3048
|
||||
#define TXRX_CSR2_BBP_ID0 FIELD32(0x0000007f)
|
||||
#define TXRX_CSR2_BBP_ID0_VALID FIELD32(0x00000080)
|
||||
#define TXRX_CSR2_BBP_ID1 FIELD32(0x00007f00)
|
||||
#define TXRX_CSR2_BBP_ID1_VALID FIELD32(0x00008000)
|
||||
#define TXRX_CSR2_BBP_ID2 FIELD32(0x007f0000)
|
||||
#define TXRX_CSR2_BBP_ID2_VALID FIELD32(0x00800000)
|
||||
#define TXRX_CSR2_BBP_ID3 FIELD32(0x7f000000)
|
||||
#define TXRX_CSR2_BBP_ID3_VALID FIELD32(0x80000000)
|
||||
|
||||
/*
|
||||
* TXRX_CSR3
|
||||
*/
|
||||
#define TXRX_CSR3 0x304c
|
||||
#define TXRX_CSR3_BBP_ID0 FIELD32(0x0000007f)
|
||||
#define TXRX_CSR3_BBP_ID0_VALID FIELD32(0x00000080)
|
||||
#define TXRX_CSR3_BBP_ID1 FIELD32(0x00007f00)
|
||||
#define TXRX_CSR3_BBP_ID1_VALID FIELD32(0x00008000)
|
||||
#define TXRX_CSR3_BBP_ID2 FIELD32(0x007f0000)
|
||||
#define TXRX_CSR3_BBP_ID2_VALID FIELD32(0x00800000)
|
||||
#define TXRX_CSR3_BBP_ID3 FIELD32(0x7f000000)
|
||||
#define TXRX_CSR3_BBP_ID3_VALID FIELD32(0x80000000)
|
||||
|
||||
/*
|
||||
* TXRX_CSR4: Auto-Responder/Tx-retry register.
|
||||
@ -428,11 +459,27 @@ struct hw_pairwise_ta_entry {
|
||||
#define TXRX_CSR5 0x3054
|
||||
|
||||
/*
|
||||
* ACK/CTS payload consumed time registers.
|
||||
* TXRX_CSR6: ACK/CTS payload consumed time
|
||||
*/
|
||||
#define TXRX_CSR6 0x3058
|
||||
|
||||
/*
|
||||
* TXRX_CSR7: OFDM ACK/CTS payload consumed time for 6/9/12/18 mbps.
|
||||
*/
|
||||
#define TXRX_CSR7 0x305c
|
||||
#define TXRX_CSR7_ACK_CTS_6MBS FIELD32(0x000000ff)
|
||||
#define TXRX_CSR7_ACK_CTS_9MBS FIELD32(0x0000ff00)
|
||||
#define TXRX_CSR7_ACK_CTS_12MBS FIELD32(0x00ff0000)
|
||||
#define TXRX_CSR7_ACK_CTS_18MBS FIELD32(0xff000000)
|
||||
|
||||
/*
|
||||
* TXRX_CSR8: OFDM ACK/CTS payload consumed time for 24/36/48/54 mbps.
|
||||
*/
|
||||
#define TXRX_CSR8 0x3060
|
||||
#define TXRX_CSR8_ACK_CTS_24MBS FIELD32(0x000000ff)
|
||||
#define TXRX_CSR8_ACK_CTS_36MBS FIELD32(0x0000ff00)
|
||||
#define TXRX_CSR8_ACK_CTS_48MBS FIELD32(0x00ff0000)
|
||||
#define TXRX_CSR8_ACK_CTS_54MBS FIELD32(0xff000000)
|
||||
|
||||
/*
|
||||
* TXRX_CSR9: Synchronization control register.
|
||||
@ -481,7 +528,6 @@ struct hw_pairwise_ta_entry {
|
||||
*/
|
||||
#define TXRX_CSR15 0x307c
|
||||
|
||||
|
||||
/*
|
||||
* PHY control registers.
|
||||
* Some values are set in TU, whereas 1 TU == 1024 us.
|
||||
@ -536,11 +582,13 @@ struct hw_pairwise_ta_entry {
|
||||
* PHY_CSR5: RX to TX signal switch timing control.
|
||||
*/
|
||||
#define PHY_CSR5 0x3094
|
||||
#define PHY_CSR5_IQ_FLIP FIELD32(0x00000004)
|
||||
|
||||
/*
|
||||
* PHY_CSR6: TX to RX signal timing control.
|
||||
*/
|
||||
#define PHY_CSR6 0x3098
|
||||
#define PHY_CSR6_IQ_FLIP FIELD32(0x00000004)
|
||||
|
||||
/*
|
||||
* PHY_CSR7: TX DAC switching timing control.
|
||||
@ -555,6 +603,22 @@ struct hw_pairwise_ta_entry {
|
||||
* SEC_CSR0: Shared key table control.
|
||||
*/
|
||||
#define SEC_CSR0 0x30a0
|
||||
#define SEC_CSR0_BSS0_KEY0_VALID FIELD32(0x00000001)
|
||||
#define SEC_CSR0_BSS0_KEY1_VALID FIELD32(0x00000002)
|
||||
#define SEC_CSR0_BSS0_KEY2_VALID FIELD32(0x00000004)
|
||||
#define SEC_CSR0_BSS0_KEY3_VALID FIELD32(0x00000008)
|
||||
#define SEC_CSR0_BSS1_KEY0_VALID FIELD32(0x00000010)
|
||||
#define SEC_CSR0_BSS1_KEY1_VALID FIELD32(0x00000020)
|
||||
#define SEC_CSR0_BSS1_KEY2_VALID FIELD32(0x00000040)
|
||||
#define SEC_CSR0_BSS1_KEY3_VALID FIELD32(0x00000080)
|
||||
#define SEC_CSR0_BSS2_KEY0_VALID FIELD32(0x00000100)
|
||||
#define SEC_CSR0_BSS2_KEY1_VALID FIELD32(0x00000200)
|
||||
#define SEC_CSR0_BSS2_KEY2_VALID FIELD32(0x00000400)
|
||||
#define SEC_CSR0_BSS2_KEY3_VALID FIELD32(0x00000800)
|
||||
#define SEC_CSR0_BSS3_KEY0_VALID FIELD32(0x00001000)
|
||||
#define SEC_CSR0_BSS3_KEY1_VALID FIELD32(0x00002000)
|
||||
#define SEC_CSR0_BSS3_KEY2_VALID FIELD32(0x00004000)
|
||||
#define SEC_CSR0_BSS3_KEY3_VALID FIELD32(0x00008000)
|
||||
|
||||
/*
|
||||
* SEC_CSR1: Shared key table security mode register.
|
||||
@ -768,9 +832,15 @@ struct hw_pairwise_ta_entry {
|
||||
#define CWMAX_CSR_CWMAX3 FIELD32(0x0000f000)
|
||||
|
||||
/*
|
||||
* TX_DMA_DST_CSR
|
||||
* TX_DMA_DST_CSR: TX DMA destination
|
||||
* 0: TX ring0, 1: TX ring1, 2: TX ring2 3: invalid
|
||||
*/
|
||||
#define TX_DMA_DST_CSR 0x342c
|
||||
#define TX_DMA_DST_CSR_DEST_AC0 FIELD32(0x00000003)
|
||||
#define TX_DMA_DST_CSR_DEST_AC1 FIELD32(0x0000000c)
|
||||
#define TX_DMA_DST_CSR_DEST_AC2 FIELD32(0x00000030)
|
||||
#define TX_DMA_DST_CSR_DEST_AC3 FIELD32(0x000000c0)
|
||||
#define TX_DMA_DST_CSR_DEST_MGMT FIELD32(0x00000300)
|
||||
|
||||
/*
|
||||
* TX_CNTL_CSR: KICK/Abort TX.
|
||||
@ -796,9 +866,14 @@ struct hw_pairwise_ta_entry {
|
||||
#define TX_CNTL_CSR_ABORT_TX_MGMT FIELD32(0x00100000)
|
||||
|
||||
/*
|
||||
* LOAD_TX_RING_CSR
|
||||
* LOAD_TX_RING_CSR: Load RX de
|
||||
*/
|
||||
#define LOAD_TX_RING_CSR 0x3434
|
||||
#define LOAD_TX_RING_CSR_LOAD_TXD_AC0 FIELD32(0x00000001)
|
||||
#define LOAD_TX_RING_CSR_LOAD_TXD_AC1 FIELD32(0x00000002)
|
||||
#define LOAD_TX_RING_CSR_LOAD_TXD_AC2 FIELD32(0x00000004)
|
||||
#define LOAD_TX_RING_CSR_LOAD_TXD_AC3 FIELD32(0x00000008)
|
||||
#define LOAD_TX_RING_CSR_LOAD_TXD_MGMT FIELD32(0x00000010)
|
||||
|
||||
/*
|
||||
* Several read-only registers, for debugging.
|
||||
@ -828,6 +903,8 @@ struct hw_pairwise_ta_entry {
|
||||
* RX_CNTL_CSR
|
||||
*/
|
||||
#define RX_CNTL_CSR 0x3458
|
||||
#define RX_CNTL_CSR_ENABLE_RX_DMA FIELD32(0x00000001)
|
||||
#define RX_CNTL_CSR_LOAD_RXD FIELD32(0x00000002)
|
||||
|
||||
/*
|
||||
* RXPTR_CSR: Read-only, for debugging.
|
||||
@ -981,10 +1058,45 @@ struct hw_pairwise_ta_entry {
|
||||
#define FIRMWARE_RT2661 "rt2661.bin"
|
||||
#define FIRMWARE_IMAGE_BASE 0x4000
|
||||
|
||||
/*
|
||||
* BBP registers.
|
||||
* The wordsize of the BBP is 8 bits.
|
||||
*/
|
||||
|
||||
/*
|
||||
* R2
|
||||
*/
|
||||
#define BBP_R2_BG_MODE FIELD8(0x20)
|
||||
|
||||
/*
|
||||
* R3
|
||||
*/
|
||||
#define BBP_R3_SMART_MODE FIELD8(0x01)
|
||||
|
||||
/*
|
||||
* R4: RX antenna control
|
||||
* FRAME_END: 1 - DPDT, 0 - SPDT (Only valid for 802.11G, RF2527 & RF2529)
|
||||
*/
|
||||
#define BBP_R4_RX_ANTENNA FIELD8(0x03)
|
||||
#define BBP_R4_RX_FRAME_END FIELD8(0x20)
|
||||
|
||||
/*
|
||||
* R77
|
||||
*/
|
||||
#define BBP_R77_PAIR FIELD8(0x03)
|
||||
|
||||
/*
|
||||
* RF registers
|
||||
*/
|
||||
|
||||
/*
|
||||
* RF 3
|
||||
*/
|
||||
#define RF3_TXPOWER FIELD32(0x00003e00)
|
||||
|
||||
/*
|
||||
* RF 4
|
||||
*/
|
||||
#define RF4_FREQ_OFFSET FIELD32(0x0003f000)
|
||||
|
||||
/*
|
||||
@ -1117,34 +1229,6 @@ struct hw_pairwise_ta_entry {
|
||||
#define EEPROM_RSSI_OFFSET_A_1 FIELD16(0x00ff)
|
||||
#define EEPROM_RSSI_OFFSET_A_2 FIELD16(0xff00)
|
||||
|
||||
/*
|
||||
* BBP content.
|
||||
* The wordsize of the BBP is 8 bits.
|
||||
*/
|
||||
|
||||
/*
|
||||
* BBP_R2
|
||||
*/
|
||||
#define BBP_R2_BG_MODE FIELD8(0x20)
|
||||
|
||||
/*
|
||||
* BBP_R3
|
||||
*/
|
||||
#define BBP_R3_SMART_MODE FIELD8(0x01)
|
||||
|
||||
/*
|
||||
* BBP_R4: RX antenna control
|
||||
* FRAME_END: 1 - DPDT, 0 - SPDT (Only valid for 802.11G, RF2527 & RF2529)
|
||||
*/
|
||||
#define BBP_R4_RX_ANTENNA FIELD8(0x03)
|
||||
#define BBP_R4_RX_FRAME_END FIELD8(0x10)
|
||||
#define BBP_R4_RX_BG_MODE FIELD8(0x20)
|
||||
|
||||
/*
|
||||
* BBP_R77
|
||||
*/
|
||||
#define BBP_R77_PAIR FIELD8(0x03)
|
||||
|
||||
/*
|
||||
* MCU mailbox commands.
|
||||
*/
|
||||
@ -1290,7 +1374,7 @@ struct hw_pairwise_ta_entry {
|
||||
#define RXD_W0_MULTICAST FIELD32(0x00000008)
|
||||
#define RXD_W0_BROADCAST FIELD32(0x00000010)
|
||||
#define RXD_W0_MY_BSS FIELD32(0x00000020)
|
||||
#define RXD_W0_CRC FIELD32(0x00000040)
|
||||
#define RXD_W0_CRC_ERROR FIELD32(0x00000040)
|
||||
#define RXD_W0_OFDM FIELD32(0x00000080)
|
||||
#define RXD_W0_CIPHER_ERROR FIELD32(0x00000300)
|
||||
#define RXD_W0_KEY_INDEX FIELD32(0x0000fc00)
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -37,9 +37,10 @@
|
||||
|
||||
/*
|
||||
* Signal information.
|
||||
* Defaul offset is required for RSSI <-> dBm conversion.
|
||||
*/
|
||||
#define MAX_SIGNAL 100
|
||||
#define MAX_RX_SSI -1
|
||||
#define MAX_RX_NOISE -110
|
||||
#define DEFAULT_RSSI_OFFSET 120
|
||||
|
||||
/*
|
||||
@ -50,6 +51,7 @@
|
||||
#define EEPROM_BASE 0x0000
|
||||
#define EEPROM_SIZE 0x0100
|
||||
#define BBP_SIZE 0x0080
|
||||
#define RF_SIZE 0x0014
|
||||
|
||||
/*
|
||||
* USB registers.
|
||||
@ -172,7 +174,7 @@ struct hw_pairwise_ta_entry {
|
||||
* MAC_CSR6: Maximum frame length register.
|
||||
*/
|
||||
#define MAC_CSR6 0x3018
|
||||
#define MAC_CSR6_MAX_FRAME_UNIT FIELD32(0x000007ff)
|
||||
#define MAC_CSR6_MAX_FRAME_UNIT FIELD32(0x00000fff)
|
||||
|
||||
/*
|
||||
* MAC_CSR7: Reserved
|
||||
@ -288,7 +290,7 @@ struct hw_pairwise_ta_entry {
|
||||
#define TXRX_CSR0_DROP_TO_DS FIELD32(0x00200000)
|
||||
#define TXRX_CSR0_DROP_VERSION_ERROR FIELD32(0x00400000)
|
||||
#define TXRX_CSR0_DROP_MULTICAST FIELD32(0x00800000)
|
||||
#define TXRX_CSR0_DROP_BORADCAST FIELD32(0x01000000)
|
||||
#define TXRX_CSR0_DROP_BROADCAST FIELD32(0x01000000)
|
||||
#define TXRX_CSR0_DROP_ACK_CTS FIELD32(0x02000000)
|
||||
#define TXRX_CSR0_TX_WITHOUT_WAITING FIELD32(0x04000000)
|
||||
|
||||
@ -296,16 +298,40 @@ struct hw_pairwise_ta_entry {
|
||||
* TXRX_CSR1
|
||||
*/
|
||||
#define TXRX_CSR1 0x3044
|
||||
#define TXRX_CSR1_BBP_ID0 FIELD32(0x0000007f)
|
||||
#define TXRX_CSR1_BBP_ID0_VALID FIELD32(0x00000080)
|
||||
#define TXRX_CSR1_BBP_ID1 FIELD32(0x00007f00)
|
||||
#define TXRX_CSR1_BBP_ID1_VALID FIELD32(0x00008000)
|
||||
#define TXRX_CSR1_BBP_ID2 FIELD32(0x007f0000)
|
||||
#define TXRX_CSR1_BBP_ID2_VALID FIELD32(0x00800000)
|
||||
#define TXRX_CSR1_BBP_ID3 FIELD32(0x7f000000)
|
||||
#define TXRX_CSR1_BBP_ID3_VALID FIELD32(0x80000000)
|
||||
|
||||
/*
|
||||
* TXRX_CSR2
|
||||
*/
|
||||
#define TXRX_CSR2 0x3048
|
||||
#define TXRX_CSR2_BBP_ID0 FIELD32(0x0000007f)
|
||||
#define TXRX_CSR2_BBP_ID0_VALID FIELD32(0x00000080)
|
||||
#define TXRX_CSR2_BBP_ID1 FIELD32(0x00007f00)
|
||||
#define TXRX_CSR2_BBP_ID1_VALID FIELD32(0x00008000)
|
||||
#define TXRX_CSR2_BBP_ID2 FIELD32(0x007f0000)
|
||||
#define TXRX_CSR2_BBP_ID2_VALID FIELD32(0x00800000)
|
||||
#define TXRX_CSR2_BBP_ID3 FIELD32(0x7f000000)
|
||||
#define TXRX_CSR2_BBP_ID3_VALID FIELD32(0x80000000)
|
||||
|
||||
/*
|
||||
* TXRX_CSR3
|
||||
*/
|
||||
#define TXRX_CSR3 0x304c
|
||||
#define TXRX_CSR3_BBP_ID0 FIELD32(0x0000007f)
|
||||
#define TXRX_CSR3_BBP_ID0_VALID FIELD32(0x00000080)
|
||||
#define TXRX_CSR3_BBP_ID1 FIELD32(0x00007f00)
|
||||
#define TXRX_CSR3_BBP_ID1_VALID FIELD32(0x00008000)
|
||||
#define TXRX_CSR3_BBP_ID2 FIELD32(0x007f0000)
|
||||
#define TXRX_CSR3_BBP_ID2_VALID FIELD32(0x00800000)
|
||||
#define TXRX_CSR3_BBP_ID3 FIELD32(0x7f000000)
|
||||
#define TXRX_CSR3_BBP_ID3_VALID FIELD32(0x80000000)
|
||||
|
||||
/*
|
||||
* TXRX_CSR4: Auto-Responder/Tx-retry register.
|
||||
@ -332,11 +358,27 @@ struct hw_pairwise_ta_entry {
|
||||
#define TXRX_CSR5 0x3054
|
||||
|
||||
/*
|
||||
* ACK/CTS payload consumed time registers.
|
||||
* TXRX_CSR6: ACK/CTS payload consumed time
|
||||
*/
|
||||
#define TXRX_CSR6 0x3058
|
||||
|
||||
/*
|
||||
* TXRX_CSR7: OFDM ACK/CTS payload consumed time for 6/9/12/18 mbps.
|
||||
*/
|
||||
#define TXRX_CSR7 0x305c
|
||||
#define TXRX_CSR7_ACK_CTS_6MBS FIELD32(0x000000ff)
|
||||
#define TXRX_CSR7_ACK_CTS_9MBS FIELD32(0x0000ff00)
|
||||
#define TXRX_CSR7_ACK_CTS_12MBS FIELD32(0x00ff0000)
|
||||
#define TXRX_CSR7_ACK_CTS_18MBS FIELD32(0xff000000)
|
||||
|
||||
/*
|
||||
* TXRX_CSR8: OFDM ACK/CTS payload consumed time for 24/36/48/54 mbps.
|
||||
*/
|
||||
#define TXRX_CSR8 0x3060
|
||||
#define TXRX_CSR8_ACK_CTS_24MBS FIELD32(0x000000ff)
|
||||
#define TXRX_CSR8_ACK_CTS_36MBS FIELD32(0x0000ff00)
|
||||
#define TXRX_CSR8_ACK_CTS_48MBS FIELD32(0x00ff0000)
|
||||
#define TXRX_CSR8_ACK_CTS_54MBS FIELD32(0xff000000)
|
||||
|
||||
/*
|
||||
* TXRX_CSR9: Synchronization control register.
|
||||
@ -403,7 +445,6 @@ struct hw_pairwise_ta_entry {
|
||||
#define PHY_CSR1 0x3084
|
||||
#define PHY_CSR1_RF_RPI FIELD32(0x00010000)
|
||||
|
||||
|
||||
/*
|
||||
* PHY_CSR2: Pre-TX BBP control.
|
||||
*/
|
||||
@ -441,11 +482,13 @@ struct hw_pairwise_ta_entry {
|
||||
* PHY_CSR5: RX to TX signal switch timing control.
|
||||
*/
|
||||
#define PHY_CSR5 0x3094
|
||||
#define PHY_CSR5_IQ_FLIP FIELD32(0x00000004)
|
||||
|
||||
/*
|
||||
* PHY_CSR6: TX to RX signal timing control.
|
||||
*/
|
||||
#define PHY_CSR6 0x3098
|
||||
#define PHY_CSR6_IQ_FLIP FIELD32(0x00000004)
|
||||
|
||||
/*
|
||||
* PHY_CSR7: TX DAC switching timing control.
|
||||
@ -460,6 +503,22 @@ struct hw_pairwise_ta_entry {
|
||||
* SEC_CSR0: Shared key table control.
|
||||
*/
|
||||
#define SEC_CSR0 0x30a0
|
||||
#define SEC_CSR0_BSS0_KEY0_VALID FIELD32(0x00000001)
|
||||
#define SEC_CSR0_BSS0_KEY1_VALID FIELD32(0x00000002)
|
||||
#define SEC_CSR0_BSS0_KEY2_VALID FIELD32(0x00000004)
|
||||
#define SEC_CSR0_BSS0_KEY3_VALID FIELD32(0x00000008)
|
||||
#define SEC_CSR0_BSS1_KEY0_VALID FIELD32(0x00000010)
|
||||
#define SEC_CSR0_BSS1_KEY1_VALID FIELD32(0x00000020)
|
||||
#define SEC_CSR0_BSS1_KEY2_VALID FIELD32(0x00000040)
|
||||
#define SEC_CSR0_BSS1_KEY3_VALID FIELD32(0x00000080)
|
||||
#define SEC_CSR0_BSS2_KEY0_VALID FIELD32(0x00000100)
|
||||
#define SEC_CSR0_BSS2_KEY1_VALID FIELD32(0x00000200)
|
||||
#define SEC_CSR0_BSS2_KEY2_VALID FIELD32(0x00000400)
|
||||
#define SEC_CSR0_BSS2_KEY3_VALID FIELD32(0x00000800)
|
||||
#define SEC_CSR0_BSS3_KEY0_VALID FIELD32(0x00001000)
|
||||
#define SEC_CSR0_BSS3_KEY1_VALID FIELD32(0x00002000)
|
||||
#define SEC_CSR0_BSS3_KEY2_VALID FIELD32(0x00004000)
|
||||
#define SEC_CSR0_BSS3_KEY3_VALID FIELD32(0x00008000)
|
||||
|
||||
/*
|
||||
* SEC_CSR1: Shared key table security mode register.
|
||||
@ -635,10 +694,45 @@ struct hw_pairwise_ta_entry {
|
||||
#define AC_TXOP_CSR1_AC2_TX_OP FIELD32(0x0000ffff)
|
||||
#define AC_TXOP_CSR1_AC3_TX_OP FIELD32(0xffff0000)
|
||||
|
||||
/*
|
||||
* BBP registers.
|
||||
* The wordsize of the BBP is 8 bits.
|
||||
*/
|
||||
|
||||
/*
|
||||
* R2
|
||||
*/
|
||||
#define BBP_R2_BG_MODE FIELD8(0x20)
|
||||
|
||||
/*
|
||||
* R3
|
||||
*/
|
||||
#define BBP_R3_SMART_MODE FIELD8(0x01)
|
||||
|
||||
/*
|
||||
* R4: RX antenna control
|
||||
* FRAME_END: 1 - DPDT, 0 - SPDT (Only valid for 802.11G, RF2527 & RF2529)
|
||||
*/
|
||||
#define BBP_R4_RX_ANTENNA FIELD8(0x03)
|
||||
#define BBP_R4_RX_FRAME_END FIELD8(0x20)
|
||||
|
||||
/*
|
||||
* R77
|
||||
*/
|
||||
#define BBP_R77_PAIR FIELD8(0x03)
|
||||
|
||||
/*
|
||||
* RF registers
|
||||
*/
|
||||
|
||||
/*
|
||||
* RF 3
|
||||
*/
|
||||
#define RF3_TXPOWER FIELD32(0x00003e00)
|
||||
|
||||
/*
|
||||
* RF 4
|
||||
*/
|
||||
#define RF4_FREQ_OFFSET FIELD32(0x0003f000)
|
||||
|
||||
/*
|
||||
@ -763,34 +857,6 @@ struct hw_pairwise_ta_entry {
|
||||
#define EEPROM_RSSI_OFFSET_A_1 FIELD16(0x00ff)
|
||||
#define EEPROM_RSSI_OFFSET_A_2 FIELD16(0xff00)
|
||||
|
||||
/*
|
||||
* BBP content.
|
||||
* The wordsize of the BBP is 8 bits.
|
||||
*/
|
||||
|
||||
/*
|
||||
* BBP_R2
|
||||
*/
|
||||
#define BBP_R2_BG_MODE FIELD8(0x20)
|
||||
|
||||
/*
|
||||
* BBP_R3
|
||||
*/
|
||||
#define BBP_R3_SMART_MODE FIELD8(0x01)
|
||||
|
||||
/*
|
||||
* BBP_R4: RX antenna control
|
||||
* FRAME_END: 1 - DPDT, 0 - SPDT (Only valid for 802.11G, RF2527 & RF2529)
|
||||
*/
|
||||
#define BBP_R4_RX_ANTENNA FIELD8(0x03)
|
||||
#define BBP_R4_RX_FRAME_END FIELD8(0x10)
|
||||
#define BBP_R4_RX_BG_MODE FIELD8(0x20)
|
||||
|
||||
/*
|
||||
* BBP_R77
|
||||
*/
|
||||
#define BBP_R77_PAIR FIELD8(0x03)
|
||||
|
||||
/*
|
||||
* DMA descriptor defines.
|
||||
*/
|
||||
@ -888,7 +954,7 @@ struct hw_pairwise_ta_entry {
|
||||
#define RXD_W0_MULTICAST FIELD32(0x00000008)
|
||||
#define RXD_W0_BROADCAST FIELD32(0x00000010)
|
||||
#define RXD_W0_MY_BSS FIELD32(0x00000020)
|
||||
#define RXD_W0_CRC FIELD32(0x00000040)
|
||||
#define RXD_W0_CRC_ERROR FIELD32(0x00000040)
|
||||
#define RXD_W0_OFDM FIELD32(0x00000080)
|
||||
#define RXD_W0_CIPHER_ERROR FIELD32(0x00000300)
|
||||
#define RXD_W0_KEY_INDEX FIELD32(0x0000fc00)
|
||||
|
Loading…
Reference in New Issue
Block a user