mirror of
https://github.com/AetherDroid/android_kernel_samsung_on5xelte.git
synced 2025-10-29 15:28:50 +01:00
Fixed MTP to work with TWRP
This commit is contained in:
commit
f6dfaef42e
50820 changed files with 20846062 additions and 0 deletions
19
drivers/net/wireless/zd1211rw/Kconfig
Normal file
19
drivers/net/wireless/zd1211rw/Kconfig
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
config ZD1211RW
|
||||
tristate "ZyDAS ZD1211/ZD1211B USB-wireless support"
|
||||
depends on USB && MAC80211
|
||||
select FW_LOADER
|
||||
---help---
|
||||
This is a driver for the ZyDAS ZD1211/ZD1211B wireless
|
||||
chip, present in many USB-wireless adapters.
|
||||
|
||||
Device firmware is required alongside this driver. You can download
|
||||
the firmware distribution from http://sf.net/projects/zd1211/files/
|
||||
|
||||
config ZD1211RW_DEBUG
|
||||
bool "ZyDAS ZD1211 debugging"
|
||||
depends on ZD1211RW
|
||||
---help---
|
||||
ZD1211 debugging messages. Choosing Y will result in additional debug
|
||||
messages being saved to your kernel logs, which may help debug any
|
||||
problems.
|
||||
|
||||
9
drivers/net/wireless/zd1211rw/Makefile
Normal file
9
drivers/net/wireless/zd1211rw/Makefile
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
obj-$(CONFIG_ZD1211RW) += zd1211rw.o
|
||||
|
||||
zd1211rw-objs := zd_chip.o zd_mac.o \
|
||||
zd_rf_al2230.o zd_rf_rf2959.o \
|
||||
zd_rf_al7230b.o zd_rf_uw2453.o \
|
||||
zd_rf.o zd_usb.o
|
||||
|
||||
ccflags-$(CONFIG_ZD1211RW_DEBUG) := -DDEBUG
|
||||
|
||||
1560
drivers/net/wireless/zd1211rw/zd_chip.c
Normal file
1560
drivers/net/wireless/zd1211rw/zd_chip.c
Normal file
File diff suppressed because it is too large
Load diff
983
drivers/net/wireless/zd1211rw/zd_chip.h
Normal file
983
drivers/net/wireless/zd1211rw/zd_chip.h
Normal file
|
|
@ -0,0 +1,983 @@
|
|||
/* ZD1211 USB-WLAN driver for Linux
|
||||
*
|
||||
* Copyright (C) 2005-2007 Ulrich Kunitz <kune@deine-taler.de>
|
||||
* Copyright (C) 2006-2007 Daniel Drake <dsd@gentoo.org>
|
||||
*
|
||||
* 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _ZD_CHIP_H
|
||||
#define _ZD_CHIP_H
|
||||
|
||||
#include <net/mac80211.h>
|
||||
|
||||
#include "zd_rf.h"
|
||||
#include "zd_usb.h"
|
||||
|
||||
/* Header for the Media Access Controller (MAC) and the Baseband Processor
|
||||
* (BBP). It appears that the ZD1211 wraps the old ZD1205 with USB glue and
|
||||
* adds a processor for handling the USB protocol.
|
||||
*/
|
||||
|
||||
/* Address space */
|
||||
enum {
|
||||
/* CONTROL REGISTERS */
|
||||
CR_START = 0x9000,
|
||||
|
||||
|
||||
/* FIRMWARE */
|
||||
FW_START = 0xee00,
|
||||
|
||||
|
||||
/* EEPROM */
|
||||
E2P_START = 0xf800,
|
||||
E2P_LEN = 0x800,
|
||||
|
||||
/* EEPROM layout */
|
||||
E2P_LOAD_CODE_LEN = 0xe, /* base 0xf800 */
|
||||
E2P_LOAD_VECT_LEN = 0x9, /* base 0xf80e */
|
||||
/* E2P_DATA indexes into this */
|
||||
E2P_DATA_LEN = 0x7e, /* base 0xf817 */
|
||||
E2P_BOOT_CODE_LEN = 0x760, /* base 0xf895 */
|
||||
E2P_INTR_VECT_LEN = 0xb, /* base 0xfff5 */
|
||||
|
||||
/* Some precomputed offsets into the EEPROM */
|
||||
E2P_DATA_OFFSET = E2P_LOAD_CODE_LEN + E2P_LOAD_VECT_LEN,
|
||||
E2P_BOOT_CODE_OFFSET = E2P_DATA_OFFSET + E2P_DATA_LEN,
|
||||
};
|
||||
|
||||
#define CTL_REG(offset) ((zd_addr_t)(CR_START + (offset)))
|
||||
#define E2P_DATA(offset) ((zd_addr_t)(E2P_START + E2P_DATA_OFFSET + (offset)))
|
||||
#define FWRAW_DATA(offset) ((zd_addr_t)(FW_START + (offset)))
|
||||
|
||||
/* 8-bit hardware registers */
|
||||
#define ZD_CR0 CTL_REG(0x0000)
|
||||
#define ZD_CR1 CTL_REG(0x0004)
|
||||
#define ZD_CR2 CTL_REG(0x0008)
|
||||
#define ZD_CR3 CTL_REG(0x000C)
|
||||
|
||||
#define ZD_CR5 CTL_REG(0x0010)
|
||||
/* bit 5: if set short preamble used
|
||||
* bit 6: filter band - Japan channel 14 on, else off
|
||||
*/
|
||||
#define ZD_CR6 CTL_REG(0x0014)
|
||||
#define ZD_CR7 CTL_REG(0x0018)
|
||||
#define ZD_CR8 CTL_REG(0x001C)
|
||||
|
||||
#define ZD_CR4 CTL_REG(0x0020)
|
||||
|
||||
#define ZD_CR9 CTL_REG(0x0024)
|
||||
/* bit 2: antenna switch (together with ZD_CR10) */
|
||||
#define ZD_CR10 CTL_REG(0x0028)
|
||||
/* bit 1: antenna switch (together with ZD_CR9)
|
||||
* RF2959 controls with ZD_CR11 radion on and off
|
||||
*/
|
||||
#define ZD_CR11 CTL_REG(0x002C)
|
||||
/* bit 6: TX power control for OFDM
|
||||
* RF2959 controls with ZD_CR10 radio on and off
|
||||
*/
|
||||
#define ZD_CR12 CTL_REG(0x0030)
|
||||
#define ZD_CR13 CTL_REG(0x0034)
|
||||
#define ZD_CR14 CTL_REG(0x0038)
|
||||
#define ZD_CR15 CTL_REG(0x003C)
|
||||
#define ZD_CR16 CTL_REG(0x0040)
|
||||
#define ZD_CR17 CTL_REG(0x0044)
|
||||
#define ZD_CR18 CTL_REG(0x0048)
|
||||
#define ZD_CR19 CTL_REG(0x004C)
|
||||
#define ZD_CR20 CTL_REG(0x0050)
|
||||
#define ZD_CR21 CTL_REG(0x0054)
|
||||
#define ZD_CR22 CTL_REG(0x0058)
|
||||
#define ZD_CR23 CTL_REG(0x005C)
|
||||
#define ZD_CR24 CTL_REG(0x0060) /* CCA threshold */
|
||||
#define ZD_CR25 CTL_REG(0x0064)
|
||||
#define ZD_CR26 CTL_REG(0x0068)
|
||||
#define ZD_CR27 CTL_REG(0x006C)
|
||||
#define ZD_CR28 CTL_REG(0x0070)
|
||||
#define ZD_CR29 CTL_REG(0x0074)
|
||||
#define ZD_CR30 CTL_REG(0x0078)
|
||||
#define ZD_CR31 CTL_REG(0x007C) /* TX power control for RF in
|
||||
* CCK mode
|
||||
*/
|
||||
#define ZD_CR32 CTL_REG(0x0080)
|
||||
#define ZD_CR33 CTL_REG(0x0084)
|
||||
#define ZD_CR34 CTL_REG(0x0088)
|
||||
#define ZD_CR35 CTL_REG(0x008C)
|
||||
#define ZD_CR36 CTL_REG(0x0090)
|
||||
#define ZD_CR37 CTL_REG(0x0094)
|
||||
#define ZD_CR38 CTL_REG(0x0098)
|
||||
#define ZD_CR39 CTL_REG(0x009C)
|
||||
#define ZD_CR40 CTL_REG(0x00A0)
|
||||
#define ZD_CR41 CTL_REG(0x00A4)
|
||||
#define ZD_CR42 CTL_REG(0x00A8)
|
||||
#define ZD_CR43 CTL_REG(0x00AC)
|
||||
#define ZD_CR44 CTL_REG(0x00B0)
|
||||
#define ZD_CR45 CTL_REG(0x00B4)
|
||||
#define ZD_CR46 CTL_REG(0x00B8)
|
||||
#define ZD_CR47 CTL_REG(0x00BC) /* CCK baseband gain
|
||||
* (patch value might be in EEPROM)
|
||||
*/
|
||||
#define ZD_CR48 CTL_REG(0x00C0)
|
||||
#define ZD_CR49 CTL_REG(0x00C4)
|
||||
#define ZD_CR50 CTL_REG(0x00C8)
|
||||
#define ZD_CR51 CTL_REG(0x00CC) /* TX power control for RF in
|
||||
* 6-36M modes
|
||||
*/
|
||||
#define ZD_CR52 CTL_REG(0x00D0) /* TX power control for RF in
|
||||
* 48M mode
|
||||
*/
|
||||
#define ZD_CR53 CTL_REG(0x00D4) /* TX power control for RF in
|
||||
* 54M mode
|
||||
*/
|
||||
#define ZD_CR54 CTL_REG(0x00D8)
|
||||
#define ZD_CR55 CTL_REG(0x00DC)
|
||||
#define ZD_CR56 CTL_REG(0x00E0)
|
||||
#define ZD_CR57 CTL_REG(0x00E4)
|
||||
#define ZD_CR58 CTL_REG(0x00E8)
|
||||
#define ZD_CR59 CTL_REG(0x00EC)
|
||||
#define ZD_CR60 CTL_REG(0x00F0)
|
||||
#define ZD_CR61 CTL_REG(0x00F4)
|
||||
#define ZD_CR62 CTL_REG(0x00F8)
|
||||
#define ZD_CR63 CTL_REG(0x00FC)
|
||||
#define ZD_CR64 CTL_REG(0x0100)
|
||||
#define ZD_CR65 CTL_REG(0x0104) /* OFDM 54M calibration */
|
||||
#define ZD_CR66 CTL_REG(0x0108) /* OFDM 48M calibration */
|
||||
#define ZD_CR67 CTL_REG(0x010C) /* OFDM 36M calibration */
|
||||
#define ZD_CR68 CTL_REG(0x0110) /* CCK calibration */
|
||||
#define ZD_CR69 CTL_REG(0x0114)
|
||||
#define ZD_CR70 CTL_REG(0x0118)
|
||||
#define ZD_CR71 CTL_REG(0x011C)
|
||||
#define ZD_CR72 CTL_REG(0x0120)
|
||||
#define ZD_CR73 CTL_REG(0x0124)
|
||||
#define ZD_CR74 CTL_REG(0x0128)
|
||||
#define ZD_CR75 CTL_REG(0x012C)
|
||||
#define ZD_CR76 CTL_REG(0x0130)
|
||||
#define ZD_CR77 CTL_REG(0x0134)
|
||||
#define ZD_CR78 CTL_REG(0x0138)
|
||||
#define ZD_CR79 CTL_REG(0x013C)
|
||||
#define ZD_CR80 CTL_REG(0x0140)
|
||||
#define ZD_CR81 CTL_REG(0x0144)
|
||||
#define ZD_CR82 CTL_REG(0x0148)
|
||||
#define ZD_CR83 CTL_REG(0x014C)
|
||||
#define ZD_CR84 CTL_REG(0x0150)
|
||||
#define ZD_CR85 CTL_REG(0x0154)
|
||||
#define ZD_CR86 CTL_REG(0x0158)
|
||||
#define ZD_CR87 CTL_REG(0x015C)
|
||||
#define ZD_CR88 CTL_REG(0x0160)
|
||||
#define ZD_CR89 CTL_REG(0x0164)
|
||||
#define ZD_CR90 CTL_REG(0x0168)
|
||||
#define ZD_CR91 CTL_REG(0x016C)
|
||||
#define ZD_CR92 CTL_REG(0x0170)
|
||||
#define ZD_CR93 CTL_REG(0x0174)
|
||||
#define ZD_CR94 CTL_REG(0x0178)
|
||||
#define ZD_CR95 CTL_REG(0x017C)
|
||||
#define ZD_CR96 CTL_REG(0x0180)
|
||||
#define ZD_CR97 CTL_REG(0x0184)
|
||||
#define ZD_CR98 CTL_REG(0x0188)
|
||||
#define ZD_CR99 CTL_REG(0x018C)
|
||||
#define ZD_CR100 CTL_REG(0x0190)
|
||||
#define ZD_CR101 CTL_REG(0x0194)
|
||||
#define ZD_CR102 CTL_REG(0x0198)
|
||||
#define ZD_CR103 CTL_REG(0x019C)
|
||||
#define ZD_CR104 CTL_REG(0x01A0)
|
||||
#define ZD_CR105 CTL_REG(0x01A4)
|
||||
#define ZD_CR106 CTL_REG(0x01A8)
|
||||
#define ZD_CR107 CTL_REG(0x01AC)
|
||||
#define ZD_CR108 CTL_REG(0x01B0)
|
||||
#define ZD_CR109 CTL_REG(0x01B4)
|
||||
#define ZD_CR110 CTL_REG(0x01B8)
|
||||
#define ZD_CR111 CTL_REG(0x01BC)
|
||||
#define ZD_CR112 CTL_REG(0x01C0)
|
||||
#define ZD_CR113 CTL_REG(0x01C4)
|
||||
#define ZD_CR114 CTL_REG(0x01C8)
|
||||
#define ZD_CR115 CTL_REG(0x01CC)
|
||||
#define ZD_CR116 CTL_REG(0x01D0)
|
||||
#define ZD_CR117 CTL_REG(0x01D4)
|
||||
#define ZD_CR118 CTL_REG(0x01D8)
|
||||
#define ZD_CR119 CTL_REG(0x01DC)
|
||||
#define ZD_CR120 CTL_REG(0x01E0)
|
||||
#define ZD_CR121 CTL_REG(0x01E4)
|
||||
#define ZD_CR122 CTL_REG(0x01E8)
|
||||
#define ZD_CR123 CTL_REG(0x01EC)
|
||||
#define ZD_CR124 CTL_REG(0x01F0)
|
||||
#define ZD_CR125 CTL_REG(0x01F4)
|
||||
#define ZD_CR126 CTL_REG(0x01F8)
|
||||
#define ZD_CR127 CTL_REG(0x01FC)
|
||||
#define ZD_CR128 CTL_REG(0x0200)
|
||||
#define ZD_CR129 CTL_REG(0x0204)
|
||||
#define ZD_CR130 CTL_REG(0x0208)
|
||||
#define ZD_CR131 CTL_REG(0x020C)
|
||||
#define ZD_CR132 CTL_REG(0x0210)
|
||||
#define ZD_CR133 CTL_REG(0x0214)
|
||||
#define ZD_CR134 CTL_REG(0x0218)
|
||||
#define ZD_CR135 CTL_REG(0x021C)
|
||||
#define ZD_CR136 CTL_REG(0x0220)
|
||||
#define ZD_CR137 CTL_REG(0x0224)
|
||||
#define ZD_CR138 CTL_REG(0x0228)
|
||||
#define ZD_CR139 CTL_REG(0x022C)
|
||||
#define ZD_CR140 CTL_REG(0x0230)
|
||||
#define ZD_CR141 CTL_REG(0x0234)
|
||||
#define ZD_CR142 CTL_REG(0x0238)
|
||||
#define ZD_CR143 CTL_REG(0x023C)
|
||||
#define ZD_CR144 CTL_REG(0x0240)
|
||||
#define ZD_CR145 CTL_REG(0x0244)
|
||||
#define ZD_CR146 CTL_REG(0x0248)
|
||||
#define ZD_CR147 CTL_REG(0x024C)
|
||||
#define ZD_CR148 CTL_REG(0x0250)
|
||||
#define ZD_CR149 CTL_REG(0x0254)
|
||||
#define ZD_CR150 CTL_REG(0x0258)
|
||||
#define ZD_CR151 CTL_REG(0x025C)
|
||||
#define ZD_CR152 CTL_REG(0x0260)
|
||||
#define ZD_CR153 CTL_REG(0x0264)
|
||||
#define ZD_CR154 CTL_REG(0x0268)
|
||||
#define ZD_CR155 CTL_REG(0x026C)
|
||||
#define ZD_CR156 CTL_REG(0x0270)
|
||||
#define ZD_CR157 CTL_REG(0x0274)
|
||||
#define ZD_CR158 CTL_REG(0x0278)
|
||||
#define ZD_CR159 CTL_REG(0x027C)
|
||||
#define ZD_CR160 CTL_REG(0x0280)
|
||||
#define ZD_CR161 CTL_REG(0x0284)
|
||||
#define ZD_CR162 CTL_REG(0x0288)
|
||||
#define ZD_CR163 CTL_REG(0x028C)
|
||||
#define ZD_CR164 CTL_REG(0x0290)
|
||||
#define ZD_CR165 CTL_REG(0x0294)
|
||||
#define ZD_CR166 CTL_REG(0x0298)
|
||||
#define ZD_CR167 CTL_REG(0x029C)
|
||||
#define ZD_CR168 CTL_REG(0x02A0)
|
||||
#define ZD_CR169 CTL_REG(0x02A4)
|
||||
#define ZD_CR170 CTL_REG(0x02A8)
|
||||
#define ZD_CR171 CTL_REG(0x02AC)
|
||||
#define ZD_CR172 CTL_REG(0x02B0)
|
||||
#define ZD_CR173 CTL_REG(0x02B4)
|
||||
#define ZD_CR174 CTL_REG(0x02B8)
|
||||
#define ZD_CR175 CTL_REG(0x02BC)
|
||||
#define ZD_CR176 CTL_REG(0x02C0)
|
||||
#define ZD_CR177 CTL_REG(0x02C4)
|
||||
#define ZD_CR178 CTL_REG(0x02C8)
|
||||
#define ZD_CR179 CTL_REG(0x02CC)
|
||||
#define ZD_CR180 CTL_REG(0x02D0)
|
||||
#define ZD_CR181 CTL_REG(0x02D4)
|
||||
#define ZD_CR182 CTL_REG(0x02D8)
|
||||
#define ZD_CR183 CTL_REG(0x02DC)
|
||||
#define ZD_CR184 CTL_REG(0x02E0)
|
||||
#define ZD_CR185 CTL_REG(0x02E4)
|
||||
#define ZD_CR186 CTL_REG(0x02E8)
|
||||
#define ZD_CR187 CTL_REG(0x02EC)
|
||||
#define ZD_CR188 CTL_REG(0x02F0)
|
||||
#define ZD_CR189 CTL_REG(0x02F4)
|
||||
#define ZD_CR190 CTL_REG(0x02F8)
|
||||
#define ZD_CR191 CTL_REG(0x02FC)
|
||||
#define ZD_CR192 CTL_REG(0x0300)
|
||||
#define ZD_CR193 CTL_REG(0x0304)
|
||||
#define ZD_CR194 CTL_REG(0x0308)
|
||||
#define ZD_CR195 CTL_REG(0x030C)
|
||||
#define ZD_CR196 CTL_REG(0x0310)
|
||||
#define ZD_CR197 CTL_REG(0x0314)
|
||||
#define ZD_CR198 CTL_REG(0x0318)
|
||||
#define ZD_CR199 CTL_REG(0x031C)
|
||||
#define ZD_CR200 CTL_REG(0x0320)
|
||||
#define ZD_CR201 CTL_REG(0x0324)
|
||||
#define ZD_CR202 CTL_REG(0x0328)
|
||||
#define ZD_CR203 CTL_REG(0x032C) /* I2C bus template value & flash
|
||||
* control
|
||||
*/
|
||||
#define ZD_CR204 CTL_REG(0x0330)
|
||||
#define ZD_CR205 CTL_REG(0x0334)
|
||||
#define ZD_CR206 CTL_REG(0x0338)
|
||||
#define ZD_CR207 CTL_REG(0x033C)
|
||||
#define ZD_CR208 CTL_REG(0x0340)
|
||||
#define ZD_CR209 CTL_REG(0x0344)
|
||||
#define ZD_CR210 CTL_REG(0x0348)
|
||||
#define ZD_CR211 CTL_REG(0x034C)
|
||||
#define ZD_CR212 CTL_REG(0x0350)
|
||||
#define ZD_CR213 CTL_REG(0x0354)
|
||||
#define ZD_CR214 CTL_REG(0x0358)
|
||||
#define ZD_CR215 CTL_REG(0x035C)
|
||||
#define ZD_CR216 CTL_REG(0x0360)
|
||||
#define ZD_CR217 CTL_REG(0x0364)
|
||||
#define ZD_CR218 CTL_REG(0x0368)
|
||||
#define ZD_CR219 CTL_REG(0x036C)
|
||||
#define ZD_CR220 CTL_REG(0x0370)
|
||||
#define ZD_CR221 CTL_REG(0x0374)
|
||||
#define ZD_CR222 CTL_REG(0x0378)
|
||||
#define ZD_CR223 CTL_REG(0x037C)
|
||||
#define ZD_CR224 CTL_REG(0x0380)
|
||||
#define ZD_CR225 CTL_REG(0x0384)
|
||||
#define ZD_CR226 CTL_REG(0x0388)
|
||||
#define ZD_CR227 CTL_REG(0x038C)
|
||||
#define ZD_CR228 CTL_REG(0x0390)
|
||||
#define ZD_CR229 CTL_REG(0x0394)
|
||||
#define ZD_CR230 CTL_REG(0x0398)
|
||||
#define ZD_CR231 CTL_REG(0x039C)
|
||||
#define ZD_CR232 CTL_REG(0x03A0)
|
||||
#define ZD_CR233 CTL_REG(0x03A4)
|
||||
#define ZD_CR234 CTL_REG(0x03A8)
|
||||
#define ZD_CR235 CTL_REG(0x03AC)
|
||||
#define ZD_CR236 CTL_REG(0x03B0)
|
||||
|
||||
#define ZD_CR240 CTL_REG(0x03C0)
|
||||
/* bit 7: host-controlled RF register writes
|
||||
* ZD_CR241-ZD_CR245: for hardware controlled writing of RF bits, not needed for
|
||||
* USB
|
||||
*/
|
||||
#define ZD_CR241 CTL_REG(0x03C4)
|
||||
#define ZD_CR242 CTL_REG(0x03C8)
|
||||
#define ZD_CR243 CTL_REG(0x03CC)
|
||||
#define ZD_CR244 CTL_REG(0x03D0)
|
||||
#define ZD_CR245 CTL_REG(0x03D4)
|
||||
|
||||
#define ZD_CR251 CTL_REG(0x03EC) /* only used for activation and
|
||||
* deactivation of Airoha RFs AL2230
|
||||
* and AL7230B
|
||||
*/
|
||||
#define ZD_CR252 CTL_REG(0x03F0)
|
||||
#define ZD_CR253 CTL_REG(0x03F4)
|
||||
#define ZD_CR254 CTL_REG(0x03F8)
|
||||
#define ZD_CR255 CTL_REG(0x03FC)
|
||||
|
||||
#define CR_MAX_PHY_REG 255
|
||||
|
||||
/* Taken from the ZYDAS driver, not all of them are relevant for the ZD1211
|
||||
* driver.
|
||||
*/
|
||||
|
||||
#define CR_RF_IF_CLK CTL_REG(0x0400)
|
||||
#define CR_RF_IF_DATA CTL_REG(0x0404)
|
||||
#define CR_PE1_PE2 CTL_REG(0x0408)
|
||||
#define CR_PE2_DLY CTL_REG(0x040C)
|
||||
#define CR_LE1 CTL_REG(0x0410)
|
||||
#define CR_LE2 CTL_REG(0x0414)
|
||||
/* Seems to enable/disable GPI (General Purpose IO?) */
|
||||
#define CR_GPI_EN CTL_REG(0x0418)
|
||||
#define CR_RADIO_PD CTL_REG(0x042C)
|
||||
#define CR_RF2948_PD CTL_REG(0x042C)
|
||||
#define CR_ENABLE_PS_MANUAL_AGC CTL_REG(0x043C)
|
||||
#define CR_CONFIG_PHILIPS CTL_REG(0x0440)
|
||||
#define CR_SA2400_SER_AP CTL_REG(0x0444)
|
||||
#define CR_I2C_WRITE CTL_REG(0x0444)
|
||||
#define CR_SA2400_SER_RP CTL_REG(0x0448)
|
||||
#define CR_RADIO_PE CTL_REG(0x0458)
|
||||
#define CR_RST_BUS_MASTER CTL_REG(0x045C)
|
||||
#define CR_RFCFG CTL_REG(0x0464)
|
||||
#define CR_HSTSCHG CTL_REG(0x046C)
|
||||
#define CR_PHY_ON CTL_REG(0x0474)
|
||||
#define CR_RX_DELAY CTL_REG(0x0478)
|
||||
#define CR_RX_PE_DELAY CTL_REG(0x047C)
|
||||
#define CR_GPIO_1 CTL_REG(0x0490)
|
||||
#define CR_GPIO_2 CTL_REG(0x0494)
|
||||
#define CR_EncryBufMux CTL_REG(0x04A8)
|
||||
#define CR_PS_CTRL CTL_REG(0x0500)
|
||||
#define CR_ADDA_PWR_DWN CTL_REG(0x0504)
|
||||
#define CR_ADDA_MBIAS_WARMTIME CTL_REG(0x0508)
|
||||
#define CR_MAC_PS_STATE CTL_REG(0x050C)
|
||||
|
||||
#define CR_INTERRUPT CTL_REG(0x0510)
|
||||
#define INT_TX_COMPLETE (1 << 0)
|
||||
#define INT_RX_COMPLETE (1 << 1)
|
||||
#define INT_RETRY_FAIL (1 << 2)
|
||||
#define INT_WAKEUP (1 << 3)
|
||||
#define INT_DTIM_NOTIFY (1 << 5)
|
||||
#define INT_CFG_NEXT_BCN (1 << 6)
|
||||
#define INT_BUS_ABORT (1 << 7)
|
||||
#define INT_TX_FIFO_READY (1 << 8)
|
||||
#define INT_UART (1 << 9)
|
||||
#define INT_TX_COMPLETE_EN (1 << 16)
|
||||
#define INT_RX_COMPLETE_EN (1 << 17)
|
||||
#define INT_RETRY_FAIL_EN (1 << 18)
|
||||
#define INT_WAKEUP_EN (1 << 19)
|
||||
#define INT_DTIM_NOTIFY_EN (1 << 21)
|
||||
#define INT_CFG_NEXT_BCN_EN (1 << 22)
|
||||
#define INT_BUS_ABORT_EN (1 << 23)
|
||||
#define INT_TX_FIFO_READY_EN (1 << 24)
|
||||
#define INT_UART_EN (1 << 25)
|
||||
|
||||
#define CR_TSF_LOW_PART CTL_REG(0x0514)
|
||||
#define CR_TSF_HIGH_PART CTL_REG(0x0518)
|
||||
|
||||
/* Following three values are in time units (1024us)
|
||||
* Following condition must be met:
|
||||
* atim < tbtt < bcn
|
||||
*/
|
||||
#define CR_ATIM_WND_PERIOD CTL_REG(0x051C)
|
||||
#define CR_BCN_INTERVAL CTL_REG(0x0520)
|
||||
#define CR_PRE_TBTT CTL_REG(0x0524)
|
||||
/* in units of TU(1024us) */
|
||||
|
||||
/* for UART support */
|
||||
#define CR_UART_RBR_THR_DLL CTL_REG(0x0540)
|
||||
#define CR_UART_DLM_IER CTL_REG(0x0544)
|
||||
#define CR_UART_IIR_FCR CTL_REG(0x0548)
|
||||
#define CR_UART_LCR CTL_REG(0x054c)
|
||||
#define CR_UART_MCR CTL_REG(0x0550)
|
||||
#define CR_UART_LSR CTL_REG(0x0554)
|
||||
#define CR_UART_MSR CTL_REG(0x0558)
|
||||
#define CR_UART_ECR CTL_REG(0x055c)
|
||||
#define CR_UART_STATUS CTL_REG(0x0560)
|
||||
|
||||
#define CR_PCI_TX_ADDR_P1 CTL_REG(0x0600)
|
||||
#define CR_PCI_TX_AddR_P2 CTL_REG(0x0604)
|
||||
#define CR_PCI_RX_AddR_P1 CTL_REG(0x0608)
|
||||
#define CR_PCI_RX_AddR_P2 CTL_REG(0x060C)
|
||||
|
||||
/* must be overwritten if custom MAC address will be used */
|
||||
#define CR_MAC_ADDR_P1 CTL_REG(0x0610)
|
||||
#define CR_MAC_ADDR_P2 CTL_REG(0x0614)
|
||||
#define CR_BSSID_P1 CTL_REG(0x0618)
|
||||
#define CR_BSSID_P2 CTL_REG(0x061C)
|
||||
#define CR_BCN_PLCP_CFG CTL_REG(0x0620)
|
||||
|
||||
/* Group hash table for filtering incoming packets.
|
||||
*
|
||||
* The group hash table is 64 bit large and split over two parts. The first
|
||||
* part is the lower part. The upper 6 bits of the last byte of the target
|
||||
* address are used as index. Packets are received if the hash table bit is
|
||||
* set. This is used for multicast handling, but for broadcasts (address
|
||||
* ff:ff:ff:ff:ff:ff) the highest bit in the second table must also be set.
|
||||
*/
|
||||
#define CR_GROUP_HASH_P1 CTL_REG(0x0624)
|
||||
#define CR_GROUP_HASH_P2 CTL_REG(0x0628)
|
||||
|
||||
#define CR_RX_TIMEOUT CTL_REG(0x062C)
|
||||
|
||||
/* Basic rates supported by the BSS. When producing ACK or CTS messages, the
|
||||
* device will use a rate in this table that is less than or equal to the rate
|
||||
* of the incoming frame which prompted the response. */
|
||||
#define CR_BASIC_RATE_TBL CTL_REG(0x0630)
|
||||
#define CR_RATE_1M (1 << 0) /* 802.11b */
|
||||
#define CR_RATE_2M (1 << 1) /* 802.11b */
|
||||
#define CR_RATE_5_5M (1 << 2) /* 802.11b */
|
||||
#define CR_RATE_11M (1 << 3) /* 802.11b */
|
||||
#define CR_RATE_6M (1 << 8) /* 802.11g */
|
||||
#define CR_RATE_9M (1 << 9) /* 802.11g */
|
||||
#define CR_RATE_12M (1 << 10) /* 802.11g */
|
||||
#define CR_RATE_18M (1 << 11) /* 802.11g */
|
||||
#define CR_RATE_24M (1 << 12) /* 802.11g */
|
||||
#define CR_RATE_36M (1 << 13) /* 802.11g */
|
||||
#define CR_RATE_48M (1 << 14) /* 802.11g */
|
||||
#define CR_RATE_54M (1 << 15) /* 802.11g */
|
||||
#define CR_RATES_80211G 0xff00
|
||||
#define CR_RATES_80211B 0x000f
|
||||
|
||||
/* Mandatory rates required in the BSS. When producing ACK or CTS messages, if
|
||||
* the device could not find an appropriate rate in CR_BASIC_RATE_TBL, it will
|
||||
* look for a rate in this table that is less than or equal to the rate of
|
||||
* the incoming frame. */
|
||||
#define CR_MANDATORY_RATE_TBL CTL_REG(0x0634)
|
||||
#define CR_RTS_CTS_RATE CTL_REG(0x0638)
|
||||
|
||||
/* These are all bit indexes in CR_RTS_CTS_RATE, so remember to shift. */
|
||||
#define RTSCTS_SH_RTS_RATE 0
|
||||
#define RTSCTS_SH_EXP_CTS_RATE 4
|
||||
#define RTSCTS_SH_RTS_MOD_TYPE 8
|
||||
#define RTSCTS_SH_RTS_PMB_TYPE 9
|
||||
#define RTSCTS_SH_CTS_RATE 16
|
||||
#define RTSCTS_SH_CTS_MOD_TYPE 24
|
||||
#define RTSCTS_SH_CTS_PMB_TYPE 25
|
||||
|
||||
#define CR_WEP_PROTECT CTL_REG(0x063C)
|
||||
#define CR_RX_THRESHOLD CTL_REG(0x0640)
|
||||
|
||||
/* register for controlling the LEDS */
|
||||
#define CR_LED CTL_REG(0x0644)
|
||||
/* masks for controlling LEDs */
|
||||
#define LED1 (1 << 8)
|
||||
#define LED2 (1 << 9)
|
||||
#define LED_SW (1 << 10)
|
||||
|
||||
/* Seems to indicate that the configuration is over.
|
||||
*/
|
||||
#define CR_AFTER_PNP CTL_REG(0x0648)
|
||||
#define CR_ACK_TIME_80211 CTL_REG(0x0658)
|
||||
|
||||
#define CR_RX_OFFSET CTL_REG(0x065c)
|
||||
|
||||
#define CR_BCN_LENGTH CTL_REG(0x0664)
|
||||
#define CR_PHY_DELAY CTL_REG(0x066C)
|
||||
#define CR_BCN_FIFO CTL_REG(0x0670)
|
||||
#define CR_SNIFFER_ON CTL_REG(0x0674)
|
||||
|
||||
#define CR_ENCRYPTION_TYPE CTL_REG(0x0678)
|
||||
#define NO_WEP 0
|
||||
#define WEP64 1
|
||||
#define WEP128 5
|
||||
#define WEP256 6
|
||||
#define ENC_SNIFFER 8
|
||||
|
||||
#define CR_ZD1211_RETRY_MAX CTL_REG(0x067C)
|
||||
|
||||
#define CR_REG1 CTL_REG(0x0680)
|
||||
/* Setting the bit UNLOCK_PHY_REGS disallows the write access to physical
|
||||
* registers, so one could argue it is a LOCK bit. But calling it
|
||||
* LOCK_PHY_REGS makes it confusing.
|
||||
*/
|
||||
#define UNLOCK_PHY_REGS (1 << 7)
|
||||
|
||||
#define CR_DEVICE_STATE CTL_REG(0x0684)
|
||||
#define CR_UNDERRUN_CNT CTL_REG(0x0688)
|
||||
|
||||
#define CR_RX_FILTER CTL_REG(0x068c)
|
||||
#define RX_FILTER_ASSOC_REQUEST (1 << 0)
|
||||
#define RX_FILTER_ASSOC_RESPONSE (1 << 1)
|
||||
#define RX_FILTER_REASSOC_REQUEST (1 << 2)
|
||||
#define RX_FILTER_REASSOC_RESPONSE (1 << 3)
|
||||
#define RX_FILTER_PROBE_REQUEST (1 << 4)
|
||||
#define RX_FILTER_PROBE_RESPONSE (1 << 5)
|
||||
/* bits 6 and 7 reserved */
|
||||
#define RX_FILTER_BEACON (1 << 8)
|
||||
#define RX_FILTER_ATIM (1 << 9)
|
||||
#define RX_FILTER_DISASSOC (1 << 10)
|
||||
#define RX_FILTER_AUTH (1 << 11)
|
||||
#define RX_FILTER_DEAUTH (1 << 12)
|
||||
#define RX_FILTER_PSPOLL (1 << 26)
|
||||
#define RX_FILTER_RTS (1 << 27)
|
||||
#define RX_FILTER_CTS (1 << 28)
|
||||
#define RX_FILTER_ACK (1 << 29)
|
||||
#define RX_FILTER_CFEND (1 << 30)
|
||||
#define RX_FILTER_CFACK (1 << 31)
|
||||
|
||||
/* Enable bits for all frames you are interested in. */
|
||||
#define STA_RX_FILTER (RX_FILTER_ASSOC_REQUEST | RX_FILTER_ASSOC_RESPONSE | \
|
||||
RX_FILTER_REASSOC_REQUEST | RX_FILTER_REASSOC_RESPONSE | \
|
||||
RX_FILTER_PROBE_REQUEST | RX_FILTER_PROBE_RESPONSE | \
|
||||
(0x3 << 6) /* vendor driver sets these reserved bits */ | \
|
||||
RX_FILTER_BEACON | RX_FILTER_ATIM | RX_FILTER_DISASSOC | \
|
||||
RX_FILTER_AUTH | RX_FILTER_DEAUTH | \
|
||||
(0x7 << 13) /* vendor driver sets these reserved bits */ | \
|
||||
RX_FILTER_PSPOLL | RX_FILTER_ACK) /* 0x2400ffff */
|
||||
|
||||
#define RX_FILTER_CTRL (RX_FILTER_RTS | RX_FILTER_CTS | \
|
||||
RX_FILTER_CFEND | RX_FILTER_CFACK)
|
||||
|
||||
#define BCN_MODE_AP 0x1000000
|
||||
#define BCN_MODE_IBSS 0x2000000
|
||||
|
||||
/* Monitor mode sets filter to 0xfffff */
|
||||
|
||||
#define CR_ACK_TIMEOUT_EXT CTL_REG(0x0690)
|
||||
#define CR_BCN_FIFO_SEMAPHORE CTL_REG(0x0694)
|
||||
|
||||
#define CR_IFS_VALUE CTL_REG(0x0698)
|
||||
#define IFS_VALUE_DIFS_SH 0
|
||||
#define IFS_VALUE_EIFS_SH 12
|
||||
#define IFS_VALUE_SIFS_SH 24
|
||||
#define IFS_VALUE_DEFAULT (( 50 << IFS_VALUE_DIFS_SH) | \
|
||||
(1148 << IFS_VALUE_EIFS_SH) | \
|
||||
( 10 << IFS_VALUE_SIFS_SH))
|
||||
|
||||
#define CR_RX_TIME_OUT CTL_REG(0x069C)
|
||||
#define CR_TOTAL_RX_FRM CTL_REG(0x06A0)
|
||||
#define CR_CRC32_CNT CTL_REG(0x06A4)
|
||||
#define CR_CRC16_CNT CTL_REG(0x06A8)
|
||||
#define CR_DECRYPTION_ERR_UNI CTL_REG(0x06AC)
|
||||
#define CR_RX_FIFO_OVERRUN CTL_REG(0x06B0)
|
||||
|
||||
#define CR_DECRYPTION_ERR_MUL CTL_REG(0x06BC)
|
||||
|
||||
#define CR_NAV_CNT CTL_REG(0x06C4)
|
||||
#define CR_NAV_CCA CTL_REG(0x06C8)
|
||||
#define CR_RETRY_CNT CTL_REG(0x06CC)
|
||||
|
||||
#define CR_READ_TCB_ADDR CTL_REG(0x06E8)
|
||||
#define CR_READ_RFD_ADDR CTL_REG(0x06EC)
|
||||
#define CR_CWMIN_CWMAX CTL_REG(0x06F0)
|
||||
#define CR_TOTAL_TX_FRM CTL_REG(0x06F4)
|
||||
|
||||
/* CAM: Continuous Access Mode (power management) */
|
||||
#define CR_CAM_MODE CTL_REG(0x0700)
|
||||
#define MODE_IBSS 0x0
|
||||
#define MODE_AP 0x1
|
||||
#define MODE_STA 0x2
|
||||
#define MODE_AP_WDS 0x3
|
||||
|
||||
#define CR_CAM_ROLL_TB_LOW CTL_REG(0x0704)
|
||||
#define CR_CAM_ROLL_TB_HIGH CTL_REG(0x0708)
|
||||
#define CR_CAM_ADDRESS CTL_REG(0x070C)
|
||||
#define CR_CAM_DATA CTL_REG(0x0710)
|
||||
|
||||
#define CR_ROMDIR CTL_REG(0x0714)
|
||||
|
||||
#define CR_DECRY_ERR_FLG_LOW CTL_REG(0x0714)
|
||||
#define CR_DECRY_ERR_FLG_HIGH CTL_REG(0x0718)
|
||||
|
||||
#define CR_WEPKEY0 CTL_REG(0x0720)
|
||||
#define CR_WEPKEY1 CTL_REG(0x0724)
|
||||
#define CR_WEPKEY2 CTL_REG(0x0728)
|
||||
#define CR_WEPKEY3 CTL_REG(0x072C)
|
||||
#define CR_WEPKEY4 CTL_REG(0x0730)
|
||||
#define CR_WEPKEY5 CTL_REG(0x0734)
|
||||
#define CR_WEPKEY6 CTL_REG(0x0738)
|
||||
#define CR_WEPKEY7 CTL_REG(0x073C)
|
||||
#define CR_WEPKEY8 CTL_REG(0x0740)
|
||||
#define CR_WEPKEY9 CTL_REG(0x0744)
|
||||
#define CR_WEPKEY10 CTL_REG(0x0748)
|
||||
#define CR_WEPKEY11 CTL_REG(0x074C)
|
||||
#define CR_WEPKEY12 CTL_REG(0x0750)
|
||||
#define CR_WEPKEY13 CTL_REG(0x0754)
|
||||
#define CR_WEPKEY14 CTL_REG(0x0758)
|
||||
#define CR_WEPKEY15 CTL_REG(0x075c)
|
||||
#define CR_TKIP_MODE CTL_REG(0x0760)
|
||||
|
||||
#define CR_EEPROM_PROTECT0 CTL_REG(0x0758)
|
||||
#define CR_EEPROM_PROTECT1 CTL_REG(0x075C)
|
||||
|
||||
#define CR_DBG_FIFO_RD CTL_REG(0x0800)
|
||||
#define CR_DBG_SELECT CTL_REG(0x0804)
|
||||
#define CR_FIFO_Length CTL_REG(0x0808)
|
||||
|
||||
|
||||
#define CR_RSSI_MGC CTL_REG(0x0810)
|
||||
|
||||
#define CR_PON CTL_REG(0x0818)
|
||||
#define CR_RX_ON CTL_REG(0x081C)
|
||||
#define CR_TX_ON CTL_REG(0x0820)
|
||||
#define CR_CHIP_EN CTL_REG(0x0824)
|
||||
#define CR_LO_SW CTL_REG(0x0828)
|
||||
#define CR_TXRX_SW CTL_REG(0x082C)
|
||||
#define CR_S_MD CTL_REG(0x0830)
|
||||
|
||||
#define CR_USB_DEBUG_PORT CTL_REG(0x0888)
|
||||
#define CR_ZD1211B_CWIN_MAX_MIN_AC0 CTL_REG(0x0b00)
|
||||
#define CR_ZD1211B_CWIN_MAX_MIN_AC1 CTL_REG(0x0b04)
|
||||
#define CR_ZD1211B_CWIN_MAX_MIN_AC2 CTL_REG(0x0b08)
|
||||
#define CR_ZD1211B_CWIN_MAX_MIN_AC3 CTL_REG(0x0b0c)
|
||||
#define CR_ZD1211B_AIFS_CTL1 CTL_REG(0x0b10)
|
||||
#define CR_ZD1211B_AIFS_CTL2 CTL_REG(0x0b14)
|
||||
#define CR_ZD1211B_TXOP CTL_REG(0x0b20)
|
||||
#define CR_ZD1211B_RETRY_MAX CTL_REG(0x0b28)
|
||||
|
||||
/* Value for CR_ZD1211_RETRY_MAX & CR_ZD1211B_RETRY_MAX. Vendor driver uses 2,
|
||||
* we use 0. The first rate is tried (count+2), then all next rates are tried
|
||||
* twice, until 1 Mbits is tried. */
|
||||
#define ZD1211_RETRY_COUNT 0
|
||||
#define ZD1211B_RETRY_COUNT \
|
||||
(ZD1211_RETRY_COUNT << 0)| \
|
||||
(ZD1211_RETRY_COUNT << 8)| \
|
||||
(ZD1211_RETRY_COUNT << 16)| \
|
||||
(ZD1211_RETRY_COUNT << 24)
|
||||
|
||||
/* Used to detect PLL lock */
|
||||
#define UW2453_INTR_REG ((zd_addr_t)0x85c1)
|
||||
|
||||
#define CWIN_SIZE 0x007f043f
|
||||
|
||||
|
||||
#define HWINT_ENABLED \
|
||||
(INT_TX_COMPLETE_EN| \
|
||||
INT_RX_COMPLETE_EN| \
|
||||
INT_RETRY_FAIL_EN| \
|
||||
INT_WAKEUP_EN| \
|
||||
INT_CFG_NEXT_BCN_EN)
|
||||
|
||||
#define HWINT_DISABLED 0
|
||||
|
||||
#define E2P_PWR_INT_GUARD 8
|
||||
#define E2P_CHANNEL_COUNT 14
|
||||
|
||||
/* If you compare this addresses with the ZYDAS orignal driver, please notify
|
||||
* that we use word mapping for the EEPROM.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Upper 16 bit contains the regulatory domain.
|
||||
*/
|
||||
#define E2P_SUBID E2P_DATA(0x00)
|
||||
#define E2P_POD E2P_DATA(0x02)
|
||||
#define E2P_MAC_ADDR_P1 E2P_DATA(0x04)
|
||||
#define E2P_MAC_ADDR_P2 E2P_DATA(0x06)
|
||||
#define E2P_PWR_CAL_VALUE1 E2P_DATA(0x08)
|
||||
#define E2P_PWR_CAL_VALUE2 E2P_DATA(0x0a)
|
||||
#define E2P_PWR_CAL_VALUE3 E2P_DATA(0x0c)
|
||||
#define E2P_PWR_CAL_VALUE4 E2P_DATA(0x0e)
|
||||
#define E2P_PWR_INT_VALUE1 E2P_DATA(0x10)
|
||||
#define E2P_PWR_INT_VALUE2 E2P_DATA(0x12)
|
||||
#define E2P_PWR_INT_VALUE3 E2P_DATA(0x14)
|
||||
#define E2P_PWR_INT_VALUE4 E2P_DATA(0x16)
|
||||
|
||||
/* Contains a bit for each allowed channel. It gives for Europe (ETSI 0x30)
|
||||
* also only 11 channels. */
|
||||
#define E2P_ALLOWED_CHANNEL E2P_DATA(0x18)
|
||||
|
||||
#define E2P_DEVICE_VER E2P_DATA(0x20)
|
||||
#define E2P_PHY_REG E2P_DATA(0x25)
|
||||
#define E2P_36M_CAL_VALUE1 E2P_DATA(0x28)
|
||||
#define E2P_36M_CAL_VALUE2 E2P_DATA(0x2a)
|
||||
#define E2P_36M_CAL_VALUE3 E2P_DATA(0x2c)
|
||||
#define E2P_36M_CAL_VALUE4 E2P_DATA(0x2e)
|
||||
#define E2P_11A_INT_VALUE1 E2P_DATA(0x30)
|
||||
#define E2P_11A_INT_VALUE2 E2P_DATA(0x32)
|
||||
#define E2P_11A_INT_VALUE3 E2P_DATA(0x34)
|
||||
#define E2P_11A_INT_VALUE4 E2P_DATA(0x36)
|
||||
#define E2P_48M_CAL_VALUE1 E2P_DATA(0x38)
|
||||
#define E2P_48M_CAL_VALUE2 E2P_DATA(0x3a)
|
||||
#define E2P_48M_CAL_VALUE3 E2P_DATA(0x3c)
|
||||
#define E2P_48M_CAL_VALUE4 E2P_DATA(0x3e)
|
||||
#define E2P_48M_INT_VALUE1 E2P_DATA(0x40)
|
||||
#define E2P_48M_INT_VALUE2 E2P_DATA(0x42)
|
||||
#define E2P_48M_INT_VALUE3 E2P_DATA(0x44)
|
||||
#define E2P_48M_INT_VALUE4 E2P_DATA(0x46)
|
||||
#define E2P_54M_CAL_VALUE1 E2P_DATA(0x48) /* ??? */
|
||||
#define E2P_54M_CAL_VALUE2 E2P_DATA(0x4a)
|
||||
#define E2P_54M_CAL_VALUE3 E2P_DATA(0x4c)
|
||||
#define E2P_54M_CAL_VALUE4 E2P_DATA(0x4e)
|
||||
#define E2P_54M_INT_VALUE1 E2P_DATA(0x50)
|
||||
#define E2P_54M_INT_VALUE2 E2P_DATA(0x52)
|
||||
#define E2P_54M_INT_VALUE3 E2P_DATA(0x54)
|
||||
#define E2P_54M_INT_VALUE4 E2P_DATA(0x56)
|
||||
|
||||
/* This word contains the base address of the FW_REG_ registers below */
|
||||
#define FWRAW_REGS_ADDR FWRAW_DATA(0x1d)
|
||||
|
||||
/* All 16 bit values, offset from the address in FWRAW_REGS_ADDR */
|
||||
enum {
|
||||
FW_REG_FIRMWARE_VER = 0,
|
||||
/* non-zero if USB high speed connection */
|
||||
FW_REG_USB_SPEED = 1,
|
||||
FW_REG_FIX_TX_RATE = 2,
|
||||
/* Seems to be able to control LEDs over the firmware */
|
||||
FW_REG_LED_LINK_STATUS = 3,
|
||||
FW_REG_SOFT_RESET = 4,
|
||||
FW_REG_FLASH_CHK = 5,
|
||||
};
|
||||
|
||||
/* Values for FW_LINK_STATUS */
|
||||
#define FW_LINK_OFF 0x0
|
||||
#define FW_LINK_TX 0x1
|
||||
/* 0x2 - link led on? */
|
||||
|
||||
enum {
|
||||
/* indices for ofdm_cal_values */
|
||||
OFDM_36M_INDEX = 0,
|
||||
OFDM_48M_INDEX = 1,
|
||||
OFDM_54M_INDEX = 2,
|
||||
};
|
||||
|
||||
struct zd_chip {
|
||||
struct zd_usb usb;
|
||||
struct zd_rf rf;
|
||||
struct mutex mutex;
|
||||
/* Base address of FW_REG_ registers */
|
||||
zd_addr_t fw_regs_base;
|
||||
/* EepSetPoint in the vendor driver */
|
||||
u8 pwr_cal_values[E2P_CHANNEL_COUNT];
|
||||
/* integration values in the vendor driver */
|
||||
u8 pwr_int_values[E2P_CHANNEL_COUNT];
|
||||
/* SetPointOFDM in the vendor driver */
|
||||
u8 ofdm_cal_values[3][E2P_CHANNEL_COUNT];
|
||||
u16 link_led;
|
||||
unsigned int pa_type:4,
|
||||
patch_cck_gain:1, patch_cr157:1, patch_6m_band_edge:1,
|
||||
new_phy_layout:1, al2230s_bit:1,
|
||||
supports_tx_led:1;
|
||||
};
|
||||
|
||||
static inline struct zd_chip *zd_usb_to_chip(struct zd_usb *usb)
|
||||
{
|
||||
return container_of(usb, struct zd_chip, usb);
|
||||
}
|
||||
|
||||
static inline struct zd_chip *zd_rf_to_chip(struct zd_rf *rf)
|
||||
{
|
||||
return container_of(rf, struct zd_chip, rf);
|
||||
}
|
||||
|
||||
#define zd_chip_dev(chip) (&(chip)->usb.intf->dev)
|
||||
|
||||
void zd_chip_init(struct zd_chip *chip,
|
||||
struct ieee80211_hw *hw,
|
||||
struct usb_interface *intf);
|
||||
void zd_chip_clear(struct zd_chip *chip);
|
||||
int zd_chip_read_mac_addr_fw(struct zd_chip *chip, u8 *addr);
|
||||
int zd_chip_init_hw(struct zd_chip *chip);
|
||||
int zd_chip_reset(struct zd_chip *chip);
|
||||
|
||||
static inline int zd_chip_is_zd1211b(struct zd_chip *chip)
|
||||
{
|
||||
return chip->usb.is_zd1211b;
|
||||
}
|
||||
|
||||
static inline int zd_ioread16v_locked(struct zd_chip *chip, u16 *values,
|
||||
const zd_addr_t *addresses,
|
||||
unsigned int count)
|
||||
{
|
||||
ZD_ASSERT(mutex_is_locked(&chip->mutex));
|
||||
return zd_usb_ioread16v(&chip->usb, values, addresses, count);
|
||||
}
|
||||
|
||||
static inline int zd_ioread16_locked(struct zd_chip *chip, u16 *value,
|
||||
const zd_addr_t addr)
|
||||
{
|
||||
ZD_ASSERT(mutex_is_locked(&chip->mutex));
|
||||
return zd_usb_ioread16(&chip->usb, value, addr);
|
||||
}
|
||||
|
||||
int zd_ioread32v_locked(struct zd_chip *chip, u32 *values,
|
||||
const zd_addr_t *addresses, unsigned int count);
|
||||
|
||||
static inline int zd_ioread32_locked(struct zd_chip *chip, u32 *value,
|
||||
const zd_addr_t addr)
|
||||
{
|
||||
return zd_ioread32v_locked(chip, value, &addr, 1);
|
||||
}
|
||||
|
||||
static inline int zd_iowrite16_locked(struct zd_chip *chip, u16 value,
|
||||
zd_addr_t addr)
|
||||
{
|
||||
struct zd_ioreq16 ioreq;
|
||||
|
||||
ZD_ASSERT(mutex_is_locked(&chip->mutex));
|
||||
ioreq.addr = addr;
|
||||
ioreq.value = value;
|
||||
|
||||
return zd_usb_iowrite16v(&chip->usb, &ioreq, 1);
|
||||
}
|
||||
|
||||
int zd_iowrite16a_locked(struct zd_chip *chip,
|
||||
const struct zd_ioreq16 *ioreqs, unsigned int count);
|
||||
|
||||
int _zd_iowrite32v_locked(struct zd_chip *chip, const struct zd_ioreq32 *ioreqs,
|
||||
unsigned int count);
|
||||
|
||||
static inline int zd_iowrite32_locked(struct zd_chip *chip, u32 value,
|
||||
zd_addr_t addr)
|
||||
{
|
||||
struct zd_ioreq32 ioreq;
|
||||
|
||||
ioreq.addr = addr;
|
||||
ioreq.value = value;
|
||||
|
||||
return _zd_iowrite32v_locked(chip, &ioreq, 1);
|
||||
}
|
||||
|
||||
int zd_iowrite32a_locked(struct zd_chip *chip,
|
||||
const struct zd_ioreq32 *ioreqs, unsigned int count);
|
||||
|
||||
static inline int zd_rfwrite_locked(struct zd_chip *chip, u32 value, u8 bits)
|
||||
{
|
||||
ZD_ASSERT(mutex_is_locked(&chip->mutex));
|
||||
return zd_usb_rfwrite(&chip->usb, value, bits);
|
||||
}
|
||||
|
||||
int zd_rfwrite_cr_locked(struct zd_chip *chip, u32 value);
|
||||
|
||||
int zd_rfwritev_locked(struct zd_chip *chip,
|
||||
const u32* values, unsigned int count, u8 bits);
|
||||
int zd_rfwritev_cr_locked(struct zd_chip *chip,
|
||||
const u32* values, unsigned int count);
|
||||
|
||||
/* Locking functions for reading and writing registers.
|
||||
* The different parameters are intentional.
|
||||
*/
|
||||
int zd_ioread16(struct zd_chip *chip, zd_addr_t addr, u16 *value);
|
||||
int zd_iowrite16(struct zd_chip *chip, zd_addr_t addr, u16 value);
|
||||
int zd_ioread32(struct zd_chip *chip, zd_addr_t addr, u32 *value);
|
||||
int zd_iowrite32(struct zd_chip *chip, zd_addr_t addr, u32 value);
|
||||
int zd_ioread32v(struct zd_chip *chip, const zd_addr_t *addresses,
|
||||
u32 *values, unsigned int count);
|
||||
int zd_iowrite32a(struct zd_chip *chip, const struct zd_ioreq32 *ioreqs,
|
||||
unsigned int count);
|
||||
|
||||
int zd_chip_set_channel(struct zd_chip *chip, u8 channel);
|
||||
static inline u8 _zd_chip_get_channel(struct zd_chip *chip)
|
||||
{
|
||||
return chip->rf.channel;
|
||||
}
|
||||
u8 zd_chip_get_channel(struct zd_chip *chip);
|
||||
int zd_read_regdomain(struct zd_chip *chip, u8 *regdomain);
|
||||
int zd_write_mac_addr(struct zd_chip *chip, const u8 *mac_addr);
|
||||
int zd_write_bssid(struct zd_chip *chip, const u8 *bssid);
|
||||
int zd_chip_switch_radio_on(struct zd_chip *chip);
|
||||
int zd_chip_switch_radio_off(struct zd_chip *chip);
|
||||
int zd_chip_enable_int(struct zd_chip *chip);
|
||||
void zd_chip_disable_int(struct zd_chip *chip);
|
||||
int zd_chip_enable_rxtx(struct zd_chip *chip);
|
||||
void zd_chip_disable_rxtx(struct zd_chip *chip);
|
||||
int zd_chip_enable_hwint(struct zd_chip *chip);
|
||||
int zd_chip_disable_hwint(struct zd_chip *chip);
|
||||
int zd_chip_generic_patch_6m_band(struct zd_chip *chip, int channel);
|
||||
int zd_chip_set_rts_cts_rate_locked(struct zd_chip *chip, int preamble);
|
||||
|
||||
static inline int zd_get_encryption_type(struct zd_chip *chip, u32 *type)
|
||||
{
|
||||
return zd_ioread32(chip, CR_ENCRYPTION_TYPE, type);
|
||||
}
|
||||
|
||||
static inline int zd_set_encryption_type(struct zd_chip *chip, u32 type)
|
||||
{
|
||||
return zd_iowrite32(chip, CR_ENCRYPTION_TYPE, type);
|
||||
}
|
||||
|
||||
static inline int zd_chip_get_basic_rates(struct zd_chip *chip, u16 *cr_rates)
|
||||
{
|
||||
return zd_ioread16(chip, CR_BASIC_RATE_TBL, cr_rates);
|
||||
}
|
||||
|
||||
int zd_chip_set_basic_rates(struct zd_chip *chip, u16 cr_rates);
|
||||
|
||||
int zd_chip_lock_phy_regs(struct zd_chip *chip);
|
||||
int zd_chip_unlock_phy_regs(struct zd_chip *chip);
|
||||
|
||||
enum led_status {
|
||||
ZD_LED_OFF = 0,
|
||||
ZD_LED_SCANNING = 1,
|
||||
ZD_LED_ASSOCIATED = 2,
|
||||
};
|
||||
|
||||
int zd_chip_control_leds(struct zd_chip *chip, enum led_status status);
|
||||
|
||||
int zd_set_beacon_interval(struct zd_chip *chip, u16 interval, u8 dtim_period,
|
||||
int type);
|
||||
|
||||
static inline int zd_get_beacon_interval(struct zd_chip *chip, u32 *interval)
|
||||
{
|
||||
return zd_ioread32(chip, CR_BCN_INTERVAL, interval);
|
||||
}
|
||||
|
||||
struct rx_status;
|
||||
|
||||
u8 zd_rx_rate(const void *rx_frame, const struct rx_status *status);
|
||||
|
||||
struct zd_mc_hash {
|
||||
u32 low;
|
||||
u32 high;
|
||||
};
|
||||
|
||||
static inline void zd_mc_clear(struct zd_mc_hash *hash)
|
||||
{
|
||||
hash->low = 0;
|
||||
/* The interfaces must always received broadcasts.
|
||||
* The hash of the broadcast address ff:ff:ff:ff:ff:ff is 63.
|
||||
*/
|
||||
hash->high = 0x80000000;
|
||||
}
|
||||
|
||||
static inline void zd_mc_add_all(struct zd_mc_hash *hash)
|
||||
{
|
||||
hash->low = hash->high = 0xffffffff;
|
||||
}
|
||||
|
||||
static inline void zd_mc_add_addr(struct zd_mc_hash *hash, u8 *addr)
|
||||
{
|
||||
unsigned int i = addr[5] >> 2;
|
||||
if (i < 32) {
|
||||
hash->low |= 1 << i;
|
||||
} else {
|
||||
hash->high |= 1 << (i-32);
|
||||
}
|
||||
}
|
||||
|
||||
int zd_chip_set_multicast_hash(struct zd_chip *chip,
|
||||
struct zd_mc_hash *hash);
|
||||
|
||||
u64 zd_chip_get_tsf(struct zd_chip *chip);
|
||||
|
||||
#endif /* _ZD_CHIP_H */
|
||||
69
drivers/net/wireless/zd1211rw/zd_def.h
Normal file
69
drivers/net/wireless/zd1211rw/zd_def.h
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
/* ZD1211 USB-WLAN driver for Linux
|
||||
*
|
||||
* Copyright (C) 2005-2007 Ulrich Kunitz <kune@deine-taler.de>
|
||||
* Copyright (C) 2006-2007 Daniel Drake <dsd@gentoo.org>
|
||||
*
|
||||
* 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _ZD_DEF_H
|
||||
#define _ZD_DEF_H
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/stringify.h>
|
||||
#include <linux/device.h>
|
||||
|
||||
typedef u16 __nocast zd_addr_t;
|
||||
|
||||
#define dev_printk_f(level, dev, fmt, args...) \
|
||||
dev_printk(level, dev, "%s() " fmt, __func__, ##args)
|
||||
|
||||
#ifdef DEBUG
|
||||
# define dev_dbg_f(dev, fmt, args...) \
|
||||
dev_printk_f(KERN_DEBUG, dev, fmt, ## args)
|
||||
# define dev_dbg_f_limit(dev, fmt, args...) do { \
|
||||
if (net_ratelimit()) \
|
||||
dev_printk_f(KERN_DEBUG, dev, fmt, ## args); \
|
||||
} while (0)
|
||||
# define dev_dbg_f_cond(dev, cond, fmt, args...) ({ \
|
||||
bool __cond = !!(cond); \
|
||||
if (unlikely(__cond)) \
|
||||
dev_printk_f(KERN_DEBUG, dev, fmt, ## args); \
|
||||
})
|
||||
#else
|
||||
# define dev_dbg_f(dev, fmt, args...) do { (void)(dev); } while (0)
|
||||
# define dev_dbg_f_limit(dev, fmt, args...) do { (void)(dev); } while (0)
|
||||
# define dev_dbg_f_cond(dev, cond, fmt, args...) do { (void)(dev); } while (0)
|
||||
#endif /* DEBUG */
|
||||
|
||||
#ifdef DEBUG
|
||||
# define ZD_ASSERT(x) \
|
||||
do { \
|
||||
if (unlikely(!(x))) { \
|
||||
pr_debug("%s:%d ASSERT %s VIOLATED!\n", \
|
||||
__FILE__, __LINE__, __stringify(x)); \
|
||||
dump_stack(); \
|
||||
} \
|
||||
} while (0)
|
||||
#else
|
||||
# define ZD_ASSERT(x) do { } while (0)
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG
|
||||
# define ZD_MEMCLEAR(pointer, size) memset((pointer), 0xff, (size))
|
||||
#else
|
||||
# define ZD_MEMCLEAR(pointer, size) do { } while (0)
|
||||
#endif
|
||||
|
||||
#endif /* _ZD_DEF_H */
|
||||
1550
drivers/net/wireless/zd1211rw/zd_mac.c
Normal file
1550
drivers/net/wireless/zd1211rw/zd_mac.c
Normal file
File diff suppressed because it is too large
Load diff
327
drivers/net/wireless/zd1211rw/zd_mac.h
Normal file
327
drivers/net/wireless/zd1211rw/zd_mac.h
Normal file
|
|
@ -0,0 +1,327 @@
|
|||
/* ZD1211 USB-WLAN driver for Linux
|
||||
*
|
||||
* Copyright (C) 2005-2007 Ulrich Kunitz <kune@deine-taler.de>
|
||||
* Copyright (C) 2006-2007 Daniel Drake <dsd@gentoo.org>
|
||||
*
|
||||
* 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _ZD_MAC_H
|
||||
#define _ZD_MAC_H
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <net/mac80211.h>
|
||||
|
||||
#include "zd_chip.h"
|
||||
|
||||
struct zd_ctrlset {
|
||||
u8 modulation;
|
||||
__le16 tx_length;
|
||||
u8 control;
|
||||
/* stores only the difference to tx_length on ZD1211B */
|
||||
__le16 packet_length;
|
||||
__le16 current_length;
|
||||
u8 service;
|
||||
__le16 next_frame_length;
|
||||
} __packed;
|
||||
|
||||
#define ZD_CS_RESERVED_SIZE 25
|
||||
|
||||
/* The field modulation of struct zd_ctrlset controls the bit rate, the use
|
||||
* of short or long preambles in 802.11b (CCK mode) or the use of 802.11a or
|
||||
* 802.11g in OFDM mode.
|
||||
*
|
||||
* The term zd-rate is used for the combination of the modulation type flag
|
||||
* and the "pure" rate value.
|
||||
*/
|
||||
#define ZD_PURE_RATE_MASK 0x0f
|
||||
#define ZD_MODULATION_TYPE_MASK 0x10
|
||||
#define ZD_RATE_MASK (ZD_PURE_RATE_MASK|ZD_MODULATION_TYPE_MASK)
|
||||
#define ZD_PURE_RATE(modulation) ((modulation) & ZD_PURE_RATE_MASK)
|
||||
#define ZD_MODULATION_TYPE(modulation) ((modulation) & ZD_MODULATION_TYPE_MASK)
|
||||
#define ZD_RATE(modulation) ((modulation) & ZD_RATE_MASK)
|
||||
|
||||
/* The two possible modulation types. Notify that 802.11b doesn't use the CCK
|
||||
* codeing for the 1 and 2 MBit/s rate. We stay with the term here to remain
|
||||
* consistent with uses the term at other places.
|
||||
*/
|
||||
#define ZD_CCK 0x00
|
||||
#define ZD_OFDM 0x10
|
||||
|
||||
/* The ZD1211 firmware uses proprietary encodings of the 802.11b (CCK) rates.
|
||||
* For OFDM the PLCP rate encodings are used. We combine these "pure" rates
|
||||
* with the modulation type flag and call the resulting values zd-rates.
|
||||
*/
|
||||
#define ZD_CCK_RATE_1M (ZD_CCK|0x00)
|
||||
#define ZD_CCK_RATE_2M (ZD_CCK|0x01)
|
||||
#define ZD_CCK_RATE_5_5M (ZD_CCK|0x02)
|
||||
#define ZD_CCK_RATE_11M (ZD_CCK|0x03)
|
||||
#define ZD_OFDM_RATE_6M (ZD_OFDM|ZD_OFDM_PLCP_RATE_6M)
|
||||
#define ZD_OFDM_RATE_9M (ZD_OFDM|ZD_OFDM_PLCP_RATE_9M)
|
||||
#define ZD_OFDM_RATE_12M (ZD_OFDM|ZD_OFDM_PLCP_RATE_12M)
|
||||
#define ZD_OFDM_RATE_18M (ZD_OFDM|ZD_OFDM_PLCP_RATE_18M)
|
||||
#define ZD_OFDM_RATE_24M (ZD_OFDM|ZD_OFDM_PLCP_RATE_24M)
|
||||
#define ZD_OFDM_RATE_36M (ZD_OFDM|ZD_OFDM_PLCP_RATE_36M)
|
||||
#define ZD_OFDM_RATE_48M (ZD_OFDM|ZD_OFDM_PLCP_RATE_48M)
|
||||
#define ZD_OFDM_RATE_54M (ZD_OFDM|ZD_OFDM_PLCP_RATE_54M)
|
||||
|
||||
/* The bit 5 of the zd_ctrlset modulation field controls the preamble in CCK
|
||||
* mode or the 802.11a/802.11g selection in OFDM mode.
|
||||
*/
|
||||
#define ZD_CCK_PREA_LONG 0x00
|
||||
#define ZD_CCK_PREA_SHORT 0x20
|
||||
#define ZD_OFDM_MODE_11G 0x00
|
||||
#define ZD_OFDM_MODE_11A 0x20
|
||||
|
||||
/* zd_ctrlset control field */
|
||||
#define ZD_CS_NEED_RANDOM_BACKOFF 0x01
|
||||
#define ZD_CS_NO_ACK 0x02
|
||||
|
||||
#define ZD_CS_FRAME_TYPE_MASK 0x0c
|
||||
#define ZD_CS_DATA_FRAME 0x00
|
||||
#define ZD_CS_PS_POLL_FRAME 0x04
|
||||
#define ZD_CS_MANAGEMENT_FRAME 0x08
|
||||
#define ZD_CS_NO_SEQUENCE_CTL_FRAME 0x0c
|
||||
|
||||
#define ZD_CS_WAKE_DESTINATION 0x10
|
||||
#define ZD_CS_RTS 0x20
|
||||
#define ZD_CS_ENCRYPT 0x40
|
||||
#define ZD_CS_SELF_CTS 0x80
|
||||
|
||||
/* Incoming frames are prepended by a PLCP header */
|
||||
#define ZD_PLCP_HEADER_SIZE 5
|
||||
|
||||
struct rx_length_info {
|
||||
__le16 length[3];
|
||||
__le16 tag;
|
||||
} __packed;
|
||||
|
||||
#define RX_LENGTH_INFO_TAG 0x697e
|
||||
|
||||
struct rx_status {
|
||||
u8 signal_quality_cck;
|
||||
/* rssi */
|
||||
u8 signal_strength;
|
||||
u8 signal_quality_ofdm;
|
||||
u8 decryption_type;
|
||||
u8 frame_status;
|
||||
} __packed;
|
||||
|
||||
/* rx_status field decryption_type */
|
||||
#define ZD_RX_NO_WEP 0
|
||||
#define ZD_RX_WEP64 1
|
||||
#define ZD_RX_TKIP 2
|
||||
#define ZD_RX_AES 4
|
||||
#define ZD_RX_WEP128 5
|
||||
#define ZD_RX_WEP256 6
|
||||
|
||||
/* rx_status field frame_status */
|
||||
#define ZD_RX_FRAME_MODULATION_MASK 0x01
|
||||
#define ZD_RX_CCK 0x00
|
||||
#define ZD_RX_OFDM 0x01
|
||||
|
||||
#define ZD_RX_TIMEOUT_ERROR 0x02
|
||||
#define ZD_RX_FIFO_OVERRUN_ERROR 0x04
|
||||
#define ZD_RX_DECRYPTION_ERROR 0x08
|
||||
#define ZD_RX_CRC32_ERROR 0x10
|
||||
#define ZD_RX_NO_ADDR1_MATCH_ERROR 0x20
|
||||
#define ZD_RX_CRC16_ERROR 0x40
|
||||
#define ZD_RX_ERROR 0x80
|
||||
|
||||
struct tx_retry_rate {
|
||||
int count; /* number of valid element in rate[] array */
|
||||
int rate[10]; /* retry rates, described by an index in zd_rates[] */
|
||||
};
|
||||
|
||||
struct tx_status {
|
||||
u8 type; /* must always be 0x01 : USB_INT_TYPE */
|
||||
u8 id; /* must always be 0xa0 : USB_INT_ID_RETRY_FAILED */
|
||||
u8 rate;
|
||||
u8 pad;
|
||||
u8 mac[ETH_ALEN];
|
||||
u8 retry;
|
||||
u8 failure;
|
||||
} __packed;
|
||||
|
||||
enum mac_flags {
|
||||
MAC_FIXED_CHANNEL = 0x01,
|
||||
};
|
||||
|
||||
struct housekeeping {
|
||||
struct delayed_work link_led_work;
|
||||
};
|
||||
|
||||
struct beacon {
|
||||
struct delayed_work watchdog_work;
|
||||
struct sk_buff *cur_beacon;
|
||||
unsigned long last_update;
|
||||
u16 interval;
|
||||
u8 period;
|
||||
};
|
||||
|
||||
enum zd_device_flags {
|
||||
ZD_DEVICE_RUNNING,
|
||||
};
|
||||
|
||||
#define ZD_MAC_STATS_BUFFER_SIZE 16
|
||||
|
||||
#define ZD_MAC_MAX_ACK_WAITERS 50
|
||||
|
||||
struct zd_mac {
|
||||
struct zd_chip chip;
|
||||
spinlock_t lock;
|
||||
spinlock_t intr_lock;
|
||||
struct ieee80211_hw *hw;
|
||||
struct ieee80211_vif *vif;
|
||||
struct housekeeping housekeeping;
|
||||
struct beacon beacon;
|
||||
struct work_struct set_rts_cts_work;
|
||||
struct work_struct process_intr;
|
||||
struct zd_mc_hash multicast_hash;
|
||||
u8 intr_buffer[USB_MAX_EP_INT_BUFFER];
|
||||
u8 regdomain;
|
||||
u8 default_regdomain;
|
||||
u8 channel;
|
||||
int type;
|
||||
int associated;
|
||||
unsigned long flags;
|
||||
struct sk_buff_head ack_wait_queue;
|
||||
struct ieee80211_channel channels[14];
|
||||
struct ieee80211_rate rates[12];
|
||||
struct ieee80211_supported_band band;
|
||||
|
||||
/* Short preamble (used for RTS/CTS) */
|
||||
unsigned int short_preamble:1;
|
||||
|
||||
/* whether to pass frames with CRC errors to stack */
|
||||
unsigned int pass_failed_fcs:1;
|
||||
|
||||
/* whether to pass control frames to stack */
|
||||
unsigned int pass_ctrl:1;
|
||||
|
||||
/* whether we have received a 802.11 ACK that is pending */
|
||||
unsigned int ack_pending:1;
|
||||
|
||||
/* signal strength of the last 802.11 ACK received */
|
||||
int ack_signal;
|
||||
};
|
||||
|
||||
#define ZD_REGDOMAIN_FCC 0x10
|
||||
#define ZD_REGDOMAIN_IC 0x20
|
||||
#define ZD_REGDOMAIN_ETSI 0x30
|
||||
#define ZD_REGDOMAIN_SPAIN 0x31
|
||||
#define ZD_REGDOMAIN_FRANCE 0x32
|
||||
#define ZD_REGDOMAIN_JAPAN_2 0x40
|
||||
#define ZD_REGDOMAIN_JAPAN 0x41
|
||||
#define ZD_REGDOMAIN_JAPAN_3 0x49
|
||||
|
||||
enum {
|
||||
MIN_CHANNEL24 = 1,
|
||||
MAX_CHANNEL24 = 14,
|
||||
};
|
||||
|
||||
#define ZD_PLCP_SERVICE_LENGTH_EXTENSION 0x80
|
||||
|
||||
struct ofdm_plcp_header {
|
||||
u8 prefix[3];
|
||||
__le16 service;
|
||||
} __packed;
|
||||
|
||||
static inline u8 zd_ofdm_plcp_header_rate(const struct ofdm_plcp_header *header)
|
||||
{
|
||||
return header->prefix[0] & 0xf;
|
||||
}
|
||||
|
||||
/* The following defines give the encoding of the 4-bit rate field in the
|
||||
* OFDM (802.11a/802.11g) PLCP header. Notify that these values are used to
|
||||
* define the zd-rate values for OFDM.
|
||||
*
|
||||
* See the struct zd_ctrlset definition in zd_mac.h.
|
||||
*/
|
||||
#define ZD_OFDM_PLCP_RATE_6M 0xb
|
||||
#define ZD_OFDM_PLCP_RATE_9M 0xf
|
||||
#define ZD_OFDM_PLCP_RATE_12M 0xa
|
||||
#define ZD_OFDM_PLCP_RATE_18M 0xe
|
||||
#define ZD_OFDM_PLCP_RATE_24M 0x9
|
||||
#define ZD_OFDM_PLCP_RATE_36M 0xd
|
||||
#define ZD_OFDM_PLCP_RATE_48M 0x8
|
||||
#define ZD_OFDM_PLCP_RATE_54M 0xc
|
||||
|
||||
struct cck_plcp_header {
|
||||
u8 signal;
|
||||
u8 service;
|
||||
__le16 length;
|
||||
__le16 crc16;
|
||||
} __packed;
|
||||
|
||||
static inline u8 zd_cck_plcp_header_signal(const struct cck_plcp_header *header)
|
||||
{
|
||||
return header->signal;
|
||||
}
|
||||
|
||||
/* These defines give the encodings of the signal field in the 802.11b PLCP
|
||||
* header. The signal field gives the bit rate of the following packet. Even
|
||||
* if technically wrong we use CCK here also for the 1 MBit/s and 2 MBit/s
|
||||
* rate to stay consistent with Zydas and our use of the term.
|
||||
*
|
||||
* Notify that these values are *not* used in the zd-rates.
|
||||
*/
|
||||
#define ZD_CCK_PLCP_SIGNAL_1M 0x0a
|
||||
#define ZD_CCK_PLCP_SIGNAL_2M 0x14
|
||||
#define ZD_CCK_PLCP_SIGNAL_5M5 0x37
|
||||
#define ZD_CCK_PLCP_SIGNAL_11M 0x6e
|
||||
|
||||
static inline struct zd_mac *zd_hw_mac(struct ieee80211_hw *hw)
|
||||
{
|
||||
return hw->priv;
|
||||
}
|
||||
|
||||
static inline struct zd_mac *zd_chip_to_mac(struct zd_chip *chip)
|
||||
{
|
||||
return container_of(chip, struct zd_mac, chip);
|
||||
}
|
||||
|
||||
static inline struct zd_mac *zd_usb_to_mac(struct zd_usb *usb)
|
||||
{
|
||||
return zd_chip_to_mac(zd_usb_to_chip(usb));
|
||||
}
|
||||
|
||||
static inline u8 *zd_mac_get_perm_addr(struct zd_mac *mac)
|
||||
{
|
||||
return mac->hw->wiphy->perm_addr;
|
||||
}
|
||||
|
||||
#define zd_mac_dev(mac) (zd_chip_dev(&(mac)->chip))
|
||||
|
||||
struct ieee80211_hw *zd_mac_alloc_hw(struct usb_interface *intf);
|
||||
void zd_mac_clear(struct zd_mac *mac);
|
||||
|
||||
int zd_mac_preinit_hw(struct ieee80211_hw *hw);
|
||||
int zd_mac_init_hw(struct ieee80211_hw *hw);
|
||||
|
||||
int zd_mac_rx(struct ieee80211_hw *hw, const u8 *buffer, unsigned int length);
|
||||
void zd_mac_tx_failed(struct urb *urb);
|
||||
void zd_mac_tx_to_dev(struct sk_buff *skb, int error);
|
||||
|
||||
int zd_op_start(struct ieee80211_hw *hw);
|
||||
void zd_op_stop(struct ieee80211_hw *hw);
|
||||
int zd_restore_settings(struct zd_mac *mac);
|
||||
|
||||
#ifdef DEBUG
|
||||
void zd_dump_rx_status(const struct rx_status *status);
|
||||
#else
|
||||
#define zd_dump_rx_status(status)
|
||||
#endif /* DEBUG */
|
||||
|
||||
#endif /* _ZD_MAC_H */
|
||||
181
drivers/net/wireless/zd1211rw/zd_rf.c
Normal file
181
drivers/net/wireless/zd1211rw/zd_rf.c
Normal file
|
|
@ -0,0 +1,181 @@
|
|||
/* ZD1211 USB-WLAN driver for Linux
|
||||
*
|
||||
* Copyright (C) 2005-2007 Ulrich Kunitz <kune@deine-taler.de>
|
||||
* Copyright (C) 2006-2007 Daniel Drake <dsd@gentoo.org>
|
||||
*
|
||||
* 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <linux/errno.h>
|
||||
#include <linux/string.h>
|
||||
|
||||
#include "zd_def.h"
|
||||
#include "zd_rf.h"
|
||||
#include "zd_mac.h"
|
||||
#include "zd_chip.h"
|
||||
|
||||
static const char * const rfs[] = {
|
||||
[0] = "unknown RF0",
|
||||
[1] = "unknown RF1",
|
||||
[UW2451_RF] = "UW2451_RF",
|
||||
[UCHIP_RF] = "UCHIP_RF",
|
||||
[AL2230_RF] = "AL2230_RF",
|
||||
[AL7230B_RF] = "AL7230B_RF",
|
||||
[THETA_RF] = "THETA_RF",
|
||||
[AL2210_RF] = "AL2210_RF",
|
||||
[MAXIM_NEW_RF] = "MAXIM_NEW_RF",
|
||||
[UW2453_RF] = "UW2453_RF",
|
||||
[AL2230S_RF] = "AL2230S_RF",
|
||||
[RALINK_RF] = "RALINK_RF",
|
||||
[INTERSIL_RF] = "INTERSIL_RF",
|
||||
[RF2959_RF] = "RF2959_RF",
|
||||
[MAXIM_NEW2_RF] = "MAXIM_NEW2_RF",
|
||||
[PHILIPS_RF] = "PHILIPS_RF",
|
||||
};
|
||||
|
||||
const char *zd_rf_name(u8 type)
|
||||
{
|
||||
if (type & 0xf0)
|
||||
type = 0;
|
||||
return rfs[type];
|
||||
}
|
||||
|
||||
void zd_rf_init(struct zd_rf *rf)
|
||||
{
|
||||
memset(rf, 0, sizeof(*rf));
|
||||
|
||||
/* default to update channel integration, as almost all RF's do want
|
||||
* this */
|
||||
rf->update_channel_int = 1;
|
||||
}
|
||||
|
||||
void zd_rf_clear(struct zd_rf *rf)
|
||||
{
|
||||
if (rf->clear)
|
||||
rf->clear(rf);
|
||||
ZD_MEMCLEAR(rf, sizeof(*rf));
|
||||
}
|
||||
|
||||
int zd_rf_init_hw(struct zd_rf *rf, u8 type)
|
||||
{
|
||||
int r = 0;
|
||||
int t;
|
||||
struct zd_chip *chip = zd_rf_to_chip(rf);
|
||||
|
||||
ZD_ASSERT(mutex_is_locked(&chip->mutex));
|
||||
switch (type) {
|
||||
case RF2959_RF:
|
||||
r = zd_rf_init_rf2959(rf);
|
||||
break;
|
||||
case AL2230_RF:
|
||||
case AL2230S_RF:
|
||||
r = zd_rf_init_al2230(rf);
|
||||
break;
|
||||
case AL7230B_RF:
|
||||
r = zd_rf_init_al7230b(rf);
|
||||
break;
|
||||
case MAXIM_NEW_RF:
|
||||
case UW2453_RF:
|
||||
r = zd_rf_init_uw2453(rf);
|
||||
break;
|
||||
default:
|
||||
dev_err(zd_chip_dev(chip),
|
||||
"RF %s %#x is not supported\n", zd_rf_name(type), type);
|
||||
rf->type = 0;
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
rf->type = type;
|
||||
|
||||
r = zd_chip_lock_phy_regs(chip);
|
||||
if (r)
|
||||
return r;
|
||||
t = rf->init_hw(rf);
|
||||
r = zd_chip_unlock_phy_regs(chip);
|
||||
if (t)
|
||||
r = t;
|
||||
return r;
|
||||
}
|
||||
|
||||
int zd_rf_scnprint_id(struct zd_rf *rf, char *buffer, size_t size)
|
||||
{
|
||||
return scnprintf(buffer, size, "%s", zd_rf_name(rf->type));
|
||||
}
|
||||
|
||||
int zd_rf_set_channel(struct zd_rf *rf, u8 channel)
|
||||
{
|
||||
int r;
|
||||
|
||||
ZD_ASSERT(mutex_is_locked(&zd_rf_to_chip(rf)->mutex));
|
||||
if (channel < MIN_CHANNEL24)
|
||||
return -EINVAL;
|
||||
if (channel > MAX_CHANNEL24)
|
||||
return -EINVAL;
|
||||
dev_dbg_f(zd_chip_dev(zd_rf_to_chip(rf)), "channel: %d\n", channel);
|
||||
|
||||
r = rf->set_channel(rf, channel);
|
||||
if (r >= 0)
|
||||
rf->channel = channel;
|
||||
return r;
|
||||
}
|
||||
|
||||
int zd_switch_radio_on(struct zd_rf *rf)
|
||||
{
|
||||
int r, t;
|
||||
struct zd_chip *chip = zd_rf_to_chip(rf);
|
||||
|
||||
ZD_ASSERT(mutex_is_locked(&chip->mutex));
|
||||
r = zd_chip_lock_phy_regs(chip);
|
||||
if (r)
|
||||
return r;
|
||||
t = rf->switch_radio_on(rf);
|
||||
r = zd_chip_unlock_phy_regs(chip);
|
||||
if (t)
|
||||
r = t;
|
||||
return r;
|
||||
}
|
||||
|
||||
int zd_switch_radio_off(struct zd_rf *rf)
|
||||
{
|
||||
int r, t;
|
||||
struct zd_chip *chip = zd_rf_to_chip(rf);
|
||||
|
||||
/* TODO: move phy regs handling to zd_chip */
|
||||
ZD_ASSERT(mutex_is_locked(&chip->mutex));
|
||||
r = zd_chip_lock_phy_regs(chip);
|
||||
if (r)
|
||||
return r;
|
||||
t = rf->switch_radio_off(rf);
|
||||
r = zd_chip_unlock_phy_regs(chip);
|
||||
if (t)
|
||||
r = t;
|
||||
return r;
|
||||
}
|
||||
|
||||
int zd_rf_patch_6m_band_edge(struct zd_rf *rf, u8 channel)
|
||||
{
|
||||
if (!rf->patch_6m_band_edge)
|
||||
return 0;
|
||||
|
||||
return rf->patch_6m_band_edge(rf, channel);
|
||||
}
|
||||
|
||||
int zd_rf_generic_patch_6m(struct zd_rf *rf, u8 channel)
|
||||
{
|
||||
return zd_chip_generic_patch_6m_band(zd_rf_to_chip(rf), channel);
|
||||
}
|
||||
|
||||
110
drivers/net/wireless/zd1211rw/zd_rf.h
Normal file
110
drivers/net/wireless/zd1211rw/zd_rf.h
Normal file
|
|
@ -0,0 +1,110 @@
|
|||
/* ZD1211 USB-WLAN driver for Linux
|
||||
*
|
||||
* Copyright (C) 2005-2007 Ulrich Kunitz <kune@deine-taler.de>
|
||||
* Copyright (C) 2006-2007 Daniel Drake <dsd@gentoo.org>
|
||||
*
|
||||
* 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _ZD_RF_H
|
||||
#define _ZD_RF_H
|
||||
|
||||
#define UW2451_RF 0x2
|
||||
#define UCHIP_RF 0x3
|
||||
#define AL2230_RF 0x4
|
||||
#define AL7230B_RF 0x5 /* a,b,g */
|
||||
#define THETA_RF 0x6
|
||||
#define AL2210_RF 0x7
|
||||
#define MAXIM_NEW_RF 0x8
|
||||
#define UW2453_RF 0x9
|
||||
#define AL2230S_RF 0xa
|
||||
#define RALINK_RF 0xb
|
||||
#define INTERSIL_RF 0xc
|
||||
#define RF2959_RF 0xd
|
||||
#define MAXIM_NEW2_RF 0xe
|
||||
#define PHILIPS_RF 0xf
|
||||
|
||||
#define RF_CHANNEL(ch) [(ch)-1]
|
||||
|
||||
/* Provides functions of the RF transceiver. */
|
||||
|
||||
enum {
|
||||
RF_REG_BITS = 6,
|
||||
RF_VALUE_BITS = 18,
|
||||
RF_RV_BITS = RF_REG_BITS + RF_VALUE_BITS,
|
||||
};
|
||||
|
||||
struct zd_rf {
|
||||
u8 type;
|
||||
|
||||
u8 channel;
|
||||
|
||||
/* whether channel integration and calibration should be updated
|
||||
* defaults to 1 (yes) */
|
||||
u8 update_channel_int:1;
|
||||
|
||||
/* whether ZD_CR47 should be patched from the EEPROM, if the appropriate
|
||||
* flag is set in the POD. The vendor driver suggests that this should
|
||||
* be done for all RF's, but a bug in their code prevents but their
|
||||
* HW_OverWritePhyRegFromE2P() routine from ever taking effect. */
|
||||
u8 patch_cck_gain:1;
|
||||
|
||||
/* private RF driver data */
|
||||
void *priv;
|
||||
|
||||
/* RF-specific functions */
|
||||
int (*init_hw)(struct zd_rf *rf);
|
||||
int (*set_channel)(struct zd_rf *rf, u8 channel);
|
||||
int (*switch_radio_on)(struct zd_rf *rf);
|
||||
int (*switch_radio_off)(struct zd_rf *rf);
|
||||
int (*patch_6m_band_edge)(struct zd_rf *rf, u8 channel);
|
||||
void (*clear)(struct zd_rf *rf);
|
||||
};
|
||||
|
||||
const char *zd_rf_name(u8 type);
|
||||
void zd_rf_init(struct zd_rf *rf);
|
||||
void zd_rf_clear(struct zd_rf *rf);
|
||||
int zd_rf_init_hw(struct zd_rf *rf, u8 type);
|
||||
|
||||
int zd_rf_scnprint_id(struct zd_rf *rf, char *buffer, size_t size);
|
||||
|
||||
int zd_rf_set_channel(struct zd_rf *rf, u8 channel);
|
||||
|
||||
int zd_switch_radio_on(struct zd_rf *rf);
|
||||
int zd_switch_radio_off(struct zd_rf *rf);
|
||||
|
||||
int zd_rf_patch_6m_band_edge(struct zd_rf *rf, u8 channel);
|
||||
int zd_rf_generic_patch_6m(struct zd_rf *rf, u8 channel);
|
||||
|
||||
static inline int zd_rf_should_update_pwr_int(struct zd_rf *rf)
|
||||
{
|
||||
return rf->update_channel_int;
|
||||
}
|
||||
|
||||
static inline int zd_rf_should_patch_cck_gain(struct zd_rf *rf)
|
||||
{
|
||||
return rf->patch_cck_gain;
|
||||
}
|
||||
|
||||
int zd_rf_patch_6m_band_edge(struct zd_rf *rf, u8 channel);
|
||||
int zd_rf_generic_patch_6m(struct zd_rf *rf, u8 channel);
|
||||
|
||||
/* Functions for individual RF chips */
|
||||
|
||||
int zd_rf_init_rf2959(struct zd_rf *rf);
|
||||
int zd_rf_init_al2230(struct zd_rf *rf);
|
||||
int zd_rf_init_al7230b(struct zd_rf *rf);
|
||||
int zd_rf_init_uw2453(struct zd_rf *rf);
|
||||
|
||||
#endif /* _ZD_RF_H */
|
||||
443
drivers/net/wireless/zd1211rw/zd_rf_al2230.c
Normal file
443
drivers/net/wireless/zd1211rw/zd_rf_al2230.c
Normal file
|
|
@ -0,0 +1,443 @@
|
|||
/* ZD1211 USB-WLAN driver for Linux
|
||||
*
|
||||
* Copyright (C) 2005-2007 Ulrich Kunitz <kune@deine-taler.de>
|
||||
* Copyright (C) 2006-2007 Daniel Drake <dsd@gentoo.org>
|
||||
*
|
||||
* 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
|
||||
#include "zd_rf.h"
|
||||
#include "zd_usb.h"
|
||||
#include "zd_chip.h"
|
||||
|
||||
#define IS_AL2230S(chip) ((chip)->al2230s_bit || (chip)->rf.type == AL2230S_RF)
|
||||
|
||||
static const u32 zd1211_al2230_table[][3] = {
|
||||
RF_CHANNEL( 1) = { 0x03f790, 0x033331, 0x00000d, },
|
||||
RF_CHANNEL( 2) = { 0x03f790, 0x0b3331, 0x00000d, },
|
||||
RF_CHANNEL( 3) = { 0x03e790, 0x033331, 0x00000d, },
|
||||
RF_CHANNEL( 4) = { 0x03e790, 0x0b3331, 0x00000d, },
|
||||
RF_CHANNEL( 5) = { 0x03f7a0, 0x033331, 0x00000d, },
|
||||
RF_CHANNEL( 6) = { 0x03f7a0, 0x0b3331, 0x00000d, },
|
||||
RF_CHANNEL( 7) = { 0x03e7a0, 0x033331, 0x00000d, },
|
||||
RF_CHANNEL( 8) = { 0x03e7a0, 0x0b3331, 0x00000d, },
|
||||
RF_CHANNEL( 9) = { 0x03f7b0, 0x033331, 0x00000d, },
|
||||
RF_CHANNEL(10) = { 0x03f7b0, 0x0b3331, 0x00000d, },
|
||||
RF_CHANNEL(11) = { 0x03e7b0, 0x033331, 0x00000d, },
|
||||
RF_CHANNEL(12) = { 0x03e7b0, 0x0b3331, 0x00000d, },
|
||||
RF_CHANNEL(13) = { 0x03f7c0, 0x033331, 0x00000d, },
|
||||
RF_CHANNEL(14) = { 0x03e7c0, 0x066661, 0x00000d, },
|
||||
};
|
||||
|
||||
static const u32 zd1211b_al2230_table[][3] = {
|
||||
RF_CHANNEL( 1) = { 0x09efc0, 0x8cccc0, 0xb00000, },
|
||||
RF_CHANNEL( 2) = { 0x09efc0, 0x8cccd0, 0xb00000, },
|
||||
RF_CHANNEL( 3) = { 0x09e7c0, 0x8cccc0, 0xb00000, },
|
||||
RF_CHANNEL( 4) = { 0x09e7c0, 0x8cccd0, 0xb00000, },
|
||||
RF_CHANNEL( 5) = { 0x05efc0, 0x8cccc0, 0xb00000, },
|
||||
RF_CHANNEL( 6) = { 0x05efc0, 0x8cccd0, 0xb00000, },
|
||||
RF_CHANNEL( 7) = { 0x05e7c0, 0x8cccc0, 0xb00000, },
|
||||
RF_CHANNEL( 8) = { 0x05e7c0, 0x8cccd0, 0xb00000, },
|
||||
RF_CHANNEL( 9) = { 0x0defc0, 0x8cccc0, 0xb00000, },
|
||||
RF_CHANNEL(10) = { 0x0defc0, 0x8cccd0, 0xb00000, },
|
||||
RF_CHANNEL(11) = { 0x0de7c0, 0x8cccc0, 0xb00000, },
|
||||
RF_CHANNEL(12) = { 0x0de7c0, 0x8cccd0, 0xb00000, },
|
||||
RF_CHANNEL(13) = { 0x03efc0, 0x8cccc0, 0xb00000, },
|
||||
RF_CHANNEL(14) = { 0x03e7c0, 0x866660, 0xb00000, },
|
||||
};
|
||||
|
||||
static const struct zd_ioreq16 zd1211b_ioreqs_shared_1[] = {
|
||||
{ ZD_CR240, 0x57 }, { ZD_CR9, 0xe0 },
|
||||
};
|
||||
|
||||
static const struct zd_ioreq16 ioreqs_init_al2230s[] = {
|
||||
{ ZD_CR47, 0x1e }, /* MARK_002 */
|
||||
{ ZD_CR106, 0x22 },
|
||||
{ ZD_CR107, 0x2a }, /* MARK_002 */
|
||||
{ ZD_CR109, 0x13 }, /* MARK_002 */
|
||||
{ ZD_CR118, 0xf8 }, /* MARK_002 */
|
||||
{ ZD_CR119, 0x12 }, { ZD_CR122, 0xe0 },
|
||||
{ ZD_CR128, 0x10 }, /* MARK_001 from 0xe->0x10 */
|
||||
{ ZD_CR129, 0x0e }, /* MARK_001 from 0xd->0x0e */
|
||||
{ ZD_CR130, 0x10 }, /* MARK_001 from 0xb->0x0d */
|
||||
};
|
||||
|
||||
static int zd1211b_al2230_finalize_rf(struct zd_chip *chip)
|
||||
{
|
||||
int r;
|
||||
static const struct zd_ioreq16 ioreqs[] = {
|
||||
{ ZD_CR80, 0x30 }, { ZD_CR81, 0x30 }, { ZD_CR79, 0x58 },
|
||||
{ ZD_CR12, 0xf0 }, { ZD_CR77, 0x1b }, { ZD_CR78, 0x58 },
|
||||
{ ZD_CR203, 0x06 },
|
||||
{ },
|
||||
|
||||
{ ZD_CR240, 0x80 },
|
||||
};
|
||||
|
||||
r = zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
/* related to antenna selection? */
|
||||
if (chip->new_phy_layout) {
|
||||
r = zd_iowrite16_locked(chip, 0xe1, ZD_CR9);
|
||||
if (r)
|
||||
return r;
|
||||
}
|
||||
|
||||
return zd_iowrite16_locked(chip, 0x06, ZD_CR203);
|
||||
}
|
||||
|
||||
static int zd1211_al2230_init_hw(struct zd_rf *rf)
|
||||
{
|
||||
int r;
|
||||
struct zd_chip *chip = zd_rf_to_chip(rf);
|
||||
|
||||
static const struct zd_ioreq16 ioreqs_init[] = {
|
||||
{ ZD_CR15, 0x20 }, { ZD_CR23, 0x40 }, { ZD_CR24, 0x20 },
|
||||
{ ZD_CR26, 0x11 }, { ZD_CR28, 0x3e }, { ZD_CR29, 0x00 },
|
||||
{ ZD_CR44, 0x33 }, { ZD_CR106, 0x2a }, { ZD_CR107, 0x1a },
|
||||
{ ZD_CR109, 0x09 }, { ZD_CR110, 0x27 }, { ZD_CR111, 0x2b },
|
||||
{ ZD_CR112, 0x2b }, { ZD_CR119, 0x0a }, { ZD_CR10, 0x89 },
|
||||
/* for newest (3rd cut) AL2300 */
|
||||
{ ZD_CR17, 0x28 },
|
||||
{ ZD_CR26, 0x93 }, { ZD_CR34, 0x30 },
|
||||
/* for newest (3rd cut) AL2300 */
|
||||
{ ZD_CR35, 0x3e },
|
||||
{ ZD_CR41, 0x24 }, { ZD_CR44, 0x32 },
|
||||
/* for newest (3rd cut) AL2300 */
|
||||
{ ZD_CR46, 0x96 },
|
||||
{ ZD_CR47, 0x1e }, { ZD_CR79, 0x58 }, { ZD_CR80, 0x30 },
|
||||
{ ZD_CR81, 0x30 }, { ZD_CR87, 0x0a }, { ZD_CR89, 0x04 },
|
||||
{ ZD_CR92, 0x0a }, { ZD_CR99, 0x28 }, { ZD_CR100, 0x00 },
|
||||
{ ZD_CR101, 0x13 }, { ZD_CR102, 0x27 }, { ZD_CR106, 0x24 },
|
||||
{ ZD_CR107, 0x2a }, { ZD_CR109, 0x09 }, { ZD_CR110, 0x13 },
|
||||
{ ZD_CR111, 0x1f }, { ZD_CR112, 0x1f }, { ZD_CR113, 0x27 },
|
||||
{ ZD_CR114, 0x27 },
|
||||
/* for newest (3rd cut) AL2300 */
|
||||
{ ZD_CR115, 0x24 },
|
||||
{ ZD_CR116, 0x24 }, { ZD_CR117, 0xf4 }, { ZD_CR118, 0xfc },
|
||||
{ ZD_CR119, 0x10 }, { ZD_CR120, 0x4f }, { ZD_CR121, 0x77 },
|
||||
{ ZD_CR122, 0xe0 }, { ZD_CR137, 0x88 }, { ZD_CR252, 0xff },
|
||||
{ ZD_CR253, 0xff },
|
||||
};
|
||||
|
||||
static const struct zd_ioreq16 ioreqs_pll[] = {
|
||||
/* shdnb(PLL_ON)=0 */
|
||||
{ ZD_CR251, 0x2f },
|
||||
/* shdnb(PLL_ON)=1 */
|
||||
{ ZD_CR251, 0x3f },
|
||||
{ ZD_CR138, 0x28 }, { ZD_CR203, 0x06 },
|
||||
};
|
||||
|
||||
static const u32 rv1[] = {
|
||||
/* Channel 1 */
|
||||
0x03f790,
|
||||
0x033331,
|
||||
0x00000d,
|
||||
|
||||
0x0b3331,
|
||||
0x03b812,
|
||||
0x00fff3,
|
||||
};
|
||||
|
||||
static const u32 rv2[] = {
|
||||
0x000da4,
|
||||
0x0f4dc5, /* fix freq shift, 0x04edc5 */
|
||||
0x0805b6,
|
||||
0x011687,
|
||||
0x000688,
|
||||
0x0403b9, /* external control TX power (ZD_CR31) */
|
||||
0x00dbba,
|
||||
0x00099b,
|
||||
0x0bdffc,
|
||||
0x00000d,
|
||||
0x00500f,
|
||||
};
|
||||
|
||||
static const u32 rv3[] = {
|
||||
0x00d00f,
|
||||
0x004c0f,
|
||||
0x00540f,
|
||||
0x00700f,
|
||||
0x00500f,
|
||||
};
|
||||
|
||||
r = zd_iowrite16a_locked(chip, ioreqs_init, ARRAY_SIZE(ioreqs_init));
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
if (IS_AL2230S(chip)) {
|
||||
r = zd_iowrite16a_locked(chip, ioreqs_init_al2230s,
|
||||
ARRAY_SIZE(ioreqs_init_al2230s));
|
||||
if (r)
|
||||
return r;
|
||||
}
|
||||
|
||||
r = zd_rfwritev_locked(chip, rv1, ARRAY_SIZE(rv1), RF_RV_BITS);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
/* improve band edge for AL2230S */
|
||||
if (IS_AL2230S(chip))
|
||||
r = zd_rfwrite_locked(chip, 0x000824, RF_RV_BITS);
|
||||
else
|
||||
r = zd_rfwrite_locked(chip, 0x0005a4, RF_RV_BITS);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
r = zd_rfwritev_locked(chip, rv2, ARRAY_SIZE(rv2), RF_RV_BITS);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
r = zd_iowrite16a_locked(chip, ioreqs_pll, ARRAY_SIZE(ioreqs_pll));
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
r = zd_rfwritev_locked(chip, rv3, ARRAY_SIZE(rv3), RF_RV_BITS);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int zd1211b_al2230_init_hw(struct zd_rf *rf)
|
||||
{
|
||||
int r;
|
||||
struct zd_chip *chip = zd_rf_to_chip(rf);
|
||||
|
||||
static const struct zd_ioreq16 ioreqs1[] = {
|
||||
{ ZD_CR10, 0x89 }, { ZD_CR15, 0x20 },
|
||||
{ ZD_CR17, 0x2B }, /* for newest(3rd cut) AL2230 */
|
||||
{ ZD_CR23, 0x40 }, { ZD_CR24, 0x20 }, { ZD_CR26, 0x93 },
|
||||
{ ZD_CR28, 0x3e }, { ZD_CR29, 0x00 },
|
||||
{ ZD_CR33, 0x28 }, /* 5621 */
|
||||
{ ZD_CR34, 0x30 },
|
||||
{ ZD_CR35, 0x3e }, /* for newest(3rd cut) AL2230 */
|
||||
{ ZD_CR41, 0x24 }, { ZD_CR44, 0x32 },
|
||||
{ ZD_CR46, 0x99 }, /* for newest(3rd cut) AL2230 */
|
||||
{ ZD_CR47, 0x1e },
|
||||
|
||||
/* ZD1211B 05.06.10 */
|
||||
{ ZD_CR48, 0x06 }, { ZD_CR49, 0xf9 }, { ZD_CR51, 0x01 },
|
||||
{ ZD_CR52, 0x80 }, { ZD_CR53, 0x7e }, { ZD_CR65, 0x00 },
|
||||
{ ZD_CR66, 0x00 }, { ZD_CR67, 0x00 }, { ZD_CR68, 0x00 },
|
||||
{ ZD_CR69, 0x28 },
|
||||
|
||||
{ ZD_CR79, 0x58 }, { ZD_CR80, 0x30 }, { ZD_CR81, 0x30 },
|
||||
{ ZD_CR87, 0x0a }, { ZD_CR89, 0x04 },
|
||||
{ ZD_CR91, 0x00 }, /* 5621 */
|
||||
{ ZD_CR92, 0x0a },
|
||||
{ ZD_CR98, 0x8d }, /* 4804, for 1212 new algorithm */
|
||||
{ ZD_CR99, 0x00 }, /* 5621 */
|
||||
{ ZD_CR101, 0x13 }, { ZD_CR102, 0x27 },
|
||||
{ ZD_CR106, 0x24 }, /* for newest(3rd cut) AL2230 */
|
||||
{ ZD_CR107, 0x2a },
|
||||
{ ZD_CR109, 0x13 }, /* 4804, for 1212 new algorithm */
|
||||
{ ZD_CR110, 0x1f }, /* 4804, for 1212 new algorithm */
|
||||
{ ZD_CR111, 0x1f }, { ZD_CR112, 0x1f }, { ZD_CR113, 0x27 },
|
||||
{ ZD_CR114, 0x27 },
|
||||
{ ZD_CR115, 0x26 }, /* 24->26 at 4902 for newest(3rd cut)
|
||||
* AL2230
|
||||
*/
|
||||
{ ZD_CR116, 0x24 },
|
||||
{ ZD_CR117, 0xfa }, /* for 1211b */
|
||||
{ ZD_CR118, 0xfa }, /* for 1211b */
|
||||
{ ZD_CR119, 0x10 },
|
||||
{ ZD_CR120, 0x4f },
|
||||
{ ZD_CR121, 0x6c }, /* for 1211b */
|
||||
{ ZD_CR122, 0xfc }, /* E0->FC at 4902 */
|
||||
{ ZD_CR123, 0x57 }, /* 5623 */
|
||||
{ ZD_CR125, 0xad }, /* 4804, for 1212 new algorithm */
|
||||
{ ZD_CR126, 0x6c }, /* 5614 */
|
||||
{ ZD_CR127, 0x03 }, /* 4804, for 1212 new algorithm */
|
||||
{ ZD_CR137, 0x50 }, /* 5614 */
|
||||
{ ZD_CR138, 0xa8 },
|
||||
{ ZD_CR144, 0xac }, /* 5621 */
|
||||
{ ZD_CR150, 0x0d }, { ZD_CR252, 0x34 }, { ZD_CR253, 0x34 },
|
||||
};
|
||||
|
||||
static const u32 rv1[] = {
|
||||
0x8cccd0,
|
||||
0x481dc0,
|
||||
0xcfff00,
|
||||
0x25a000,
|
||||
};
|
||||
|
||||
static const u32 rv2[] = {
|
||||
/* To improve AL2230 yield, improve phase noise, 4713 */
|
||||
0x25a000,
|
||||
0xa3b2f0,
|
||||
|
||||
0x6da010, /* Reg6 update for MP versio */
|
||||
0xe36280, /* Modified by jxiao for Bor-Chin on 2004/08/02 */
|
||||
0x116000,
|
||||
0x9dc020, /* External control TX power (ZD_CR31) */
|
||||
0x5ddb00, /* RegA update for MP version */
|
||||
0xd99000, /* RegB update for MP version */
|
||||
0x3ffbd0, /* RegC update for MP version */
|
||||
0xb00000, /* RegD update for MP version */
|
||||
|
||||
/* improve phase noise and remove phase calibration,4713 */
|
||||
0xf01a00,
|
||||
};
|
||||
|
||||
static const struct zd_ioreq16 ioreqs2[] = {
|
||||
{ ZD_CR251, 0x2f }, /* shdnb(PLL_ON)=0 */
|
||||
{ ZD_CR251, 0x7f }, /* shdnb(PLL_ON)=1 */
|
||||
};
|
||||
|
||||
static const u32 rv3[] = {
|
||||
/* To improve AL2230 yield, 4713 */
|
||||
0xf01b00,
|
||||
0xf01e00,
|
||||
0xf01a00,
|
||||
};
|
||||
|
||||
static const struct zd_ioreq16 ioreqs3[] = {
|
||||
/* related to 6M band edge patching, happens unconditionally */
|
||||
{ ZD_CR128, 0x14 }, { ZD_CR129, 0x12 }, { ZD_CR130, 0x10 },
|
||||
};
|
||||
|
||||
r = zd_iowrite16a_locked(chip, zd1211b_ioreqs_shared_1,
|
||||
ARRAY_SIZE(zd1211b_ioreqs_shared_1));
|
||||
if (r)
|
||||
return r;
|
||||
r = zd_iowrite16a_locked(chip, ioreqs1, ARRAY_SIZE(ioreqs1));
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
if (IS_AL2230S(chip)) {
|
||||
r = zd_iowrite16a_locked(chip, ioreqs_init_al2230s,
|
||||
ARRAY_SIZE(ioreqs_init_al2230s));
|
||||
if (r)
|
||||
return r;
|
||||
}
|
||||
|
||||
r = zd_rfwritev_cr_locked(chip, zd1211b_al2230_table[0], 3);
|
||||
if (r)
|
||||
return r;
|
||||
r = zd_rfwritev_cr_locked(chip, rv1, ARRAY_SIZE(rv1));
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
if (IS_AL2230S(chip))
|
||||
r = zd_rfwrite_locked(chip, 0x241000, RF_RV_BITS);
|
||||
else
|
||||
r = zd_rfwrite_locked(chip, 0x25a000, RF_RV_BITS);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
r = zd_rfwritev_cr_locked(chip, rv2, ARRAY_SIZE(rv2));
|
||||
if (r)
|
||||
return r;
|
||||
r = zd_iowrite16a_locked(chip, ioreqs2, ARRAY_SIZE(ioreqs2));
|
||||
if (r)
|
||||
return r;
|
||||
r = zd_rfwritev_cr_locked(chip, rv3, ARRAY_SIZE(rv3));
|
||||
if (r)
|
||||
return r;
|
||||
r = zd_iowrite16a_locked(chip, ioreqs3, ARRAY_SIZE(ioreqs3));
|
||||
if (r)
|
||||
return r;
|
||||
return zd1211b_al2230_finalize_rf(chip);
|
||||
}
|
||||
|
||||
static int zd1211_al2230_set_channel(struct zd_rf *rf, u8 channel)
|
||||
{
|
||||
int r;
|
||||
const u32 *rv = zd1211_al2230_table[channel-1];
|
||||
struct zd_chip *chip = zd_rf_to_chip(rf);
|
||||
static const struct zd_ioreq16 ioreqs[] = {
|
||||
{ ZD_CR138, 0x28 },
|
||||
{ ZD_CR203, 0x06 },
|
||||
};
|
||||
|
||||
r = zd_rfwritev_locked(chip, rv, 3, RF_RV_BITS);
|
||||
if (r)
|
||||
return r;
|
||||
return zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
|
||||
}
|
||||
|
||||
static int zd1211b_al2230_set_channel(struct zd_rf *rf, u8 channel)
|
||||
{
|
||||
int r;
|
||||
const u32 *rv = zd1211b_al2230_table[channel-1];
|
||||
struct zd_chip *chip = zd_rf_to_chip(rf);
|
||||
|
||||
r = zd_iowrite16a_locked(chip, zd1211b_ioreqs_shared_1,
|
||||
ARRAY_SIZE(zd1211b_ioreqs_shared_1));
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
r = zd_rfwritev_cr_locked(chip, rv, 3);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
return zd1211b_al2230_finalize_rf(chip);
|
||||
}
|
||||
|
||||
static int zd1211_al2230_switch_radio_on(struct zd_rf *rf)
|
||||
{
|
||||
struct zd_chip *chip = zd_rf_to_chip(rf);
|
||||
static const struct zd_ioreq16 ioreqs[] = {
|
||||
{ ZD_CR11, 0x00 },
|
||||
{ ZD_CR251, 0x3f },
|
||||
};
|
||||
|
||||
return zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
|
||||
}
|
||||
|
||||
static int zd1211b_al2230_switch_radio_on(struct zd_rf *rf)
|
||||
{
|
||||
struct zd_chip *chip = zd_rf_to_chip(rf);
|
||||
static const struct zd_ioreq16 ioreqs[] = {
|
||||
{ ZD_CR11, 0x00 },
|
||||
{ ZD_CR251, 0x7f },
|
||||
};
|
||||
|
||||
return zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
|
||||
}
|
||||
|
||||
static int al2230_switch_radio_off(struct zd_rf *rf)
|
||||
{
|
||||
struct zd_chip *chip = zd_rf_to_chip(rf);
|
||||
static const struct zd_ioreq16 ioreqs[] = {
|
||||
{ ZD_CR11, 0x04 },
|
||||
{ ZD_CR251, 0x2f },
|
||||
};
|
||||
|
||||
return zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
|
||||
}
|
||||
|
||||
int zd_rf_init_al2230(struct zd_rf *rf)
|
||||
{
|
||||
struct zd_chip *chip = zd_rf_to_chip(rf);
|
||||
|
||||
rf->switch_radio_off = al2230_switch_radio_off;
|
||||
if (zd_chip_is_zd1211b(chip)) {
|
||||
rf->init_hw = zd1211b_al2230_init_hw;
|
||||
rf->set_channel = zd1211b_al2230_set_channel;
|
||||
rf->switch_radio_on = zd1211b_al2230_switch_radio_on;
|
||||
} else {
|
||||
rf->init_hw = zd1211_al2230_init_hw;
|
||||
rf->set_channel = zd1211_al2230_set_channel;
|
||||
rf->switch_radio_on = zd1211_al2230_switch_radio_on;
|
||||
}
|
||||
rf->patch_6m_band_edge = zd_rf_generic_patch_6m;
|
||||
rf->patch_cck_gain = 1;
|
||||
return 0;
|
||||
}
|
||||
494
drivers/net/wireless/zd1211rw/zd_rf_al7230b.c
Normal file
494
drivers/net/wireless/zd1211rw/zd_rf_al7230b.c
Normal file
|
|
@ -0,0 +1,494 @@
|
|||
/* ZD1211 USB-WLAN driver for Linux
|
||||
*
|
||||
* Copyright (C) 2005-2007 Ulrich Kunitz <kune@deine-taler.de>
|
||||
* Copyright (C) 2006-2007 Daniel Drake <dsd@gentoo.org>
|
||||
*
|
||||
* 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
|
||||
#include "zd_rf.h"
|
||||
#include "zd_usb.h"
|
||||
#include "zd_chip.h"
|
||||
|
||||
static const u32 chan_rv[][2] = {
|
||||
RF_CHANNEL( 1) = { 0x09ec00, 0x8cccc8 },
|
||||
RF_CHANNEL( 2) = { 0x09ec00, 0x8cccd8 },
|
||||
RF_CHANNEL( 3) = { 0x09ec00, 0x8cccc0 },
|
||||
RF_CHANNEL( 4) = { 0x09ec00, 0x8cccd0 },
|
||||
RF_CHANNEL( 5) = { 0x05ec00, 0x8cccc8 },
|
||||
RF_CHANNEL( 6) = { 0x05ec00, 0x8cccd8 },
|
||||
RF_CHANNEL( 7) = { 0x05ec00, 0x8cccc0 },
|
||||
RF_CHANNEL( 8) = { 0x05ec00, 0x8cccd0 },
|
||||
RF_CHANNEL( 9) = { 0x0dec00, 0x8cccc8 },
|
||||
RF_CHANNEL(10) = { 0x0dec00, 0x8cccd8 },
|
||||
RF_CHANNEL(11) = { 0x0dec00, 0x8cccc0 },
|
||||
RF_CHANNEL(12) = { 0x0dec00, 0x8cccd0 },
|
||||
RF_CHANNEL(13) = { 0x03ec00, 0x8cccc8 },
|
||||
RF_CHANNEL(14) = { 0x03ec00, 0x866660 },
|
||||
};
|
||||
|
||||
static const u32 std_rv[] = {
|
||||
0x4ff821,
|
||||
0xc5fbfc,
|
||||
0x21ebfe,
|
||||
0xafd401, /* freq shift 0xaad401 */
|
||||
0x6cf56a,
|
||||
0xe04073,
|
||||
0x193d76,
|
||||
0x9dd844,
|
||||
0x500007,
|
||||
0xd8c010,
|
||||
};
|
||||
|
||||
static const u32 rv_init1[] = {
|
||||
0x3c9000,
|
||||
0xbfffff,
|
||||
0x700000,
|
||||
0xf15d58,
|
||||
};
|
||||
|
||||
static const u32 rv_init2[] = {
|
||||
0xf15d59,
|
||||
0xf15d5c,
|
||||
0xf15d58,
|
||||
};
|
||||
|
||||
static const struct zd_ioreq16 ioreqs_sw[] = {
|
||||
{ ZD_CR128, 0x14 }, { ZD_CR129, 0x12 }, { ZD_CR130, 0x10 },
|
||||
{ ZD_CR38, 0x38 }, { ZD_CR136, 0xdf },
|
||||
};
|
||||
|
||||
static int zd1211b_al7230b_finalize(struct zd_chip *chip)
|
||||
{
|
||||
int r;
|
||||
static const struct zd_ioreq16 ioreqs[] = {
|
||||
{ ZD_CR80, 0x30 }, { ZD_CR81, 0x30 }, { ZD_CR79, 0x58 },
|
||||
{ ZD_CR12, 0xf0 }, { ZD_CR77, 0x1b }, { ZD_CR78, 0x58 },
|
||||
{ ZD_CR203, 0x04 },
|
||||
{ },
|
||||
{ ZD_CR240, 0x80 },
|
||||
};
|
||||
|
||||
r = zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
if (chip->new_phy_layout) {
|
||||
/* antenna selection? */
|
||||
r = zd_iowrite16_locked(chip, 0xe5, ZD_CR9);
|
||||
if (r)
|
||||
return r;
|
||||
}
|
||||
|
||||
return zd_iowrite16_locked(chip, 0x04, ZD_CR203);
|
||||
}
|
||||
|
||||
static int zd1211_al7230b_init_hw(struct zd_rf *rf)
|
||||
{
|
||||
int r;
|
||||
struct zd_chip *chip = zd_rf_to_chip(rf);
|
||||
|
||||
/* All of these writes are identical to AL2230 unless otherwise
|
||||
* specified */
|
||||
static const struct zd_ioreq16 ioreqs_1[] = {
|
||||
/* This one is 7230-specific, and happens before the rest */
|
||||
{ ZD_CR240, 0x57 },
|
||||
{ },
|
||||
|
||||
{ ZD_CR15, 0x20 }, { ZD_CR23, 0x40 }, { ZD_CR24, 0x20 },
|
||||
{ ZD_CR26, 0x11 }, { ZD_CR28, 0x3e }, { ZD_CR29, 0x00 },
|
||||
{ ZD_CR44, 0x33 },
|
||||
/* This value is different for 7230 (was: 0x2a) */
|
||||
{ ZD_CR106, 0x22 },
|
||||
{ ZD_CR107, 0x1a }, { ZD_CR109, 0x09 }, { ZD_CR110, 0x27 },
|
||||
{ ZD_CR111, 0x2b }, { ZD_CR112, 0x2b }, { ZD_CR119, 0x0a },
|
||||
/* This happened further down in AL2230,
|
||||
* and the value changed (was: 0xe0) */
|
||||
{ ZD_CR122, 0xfc },
|
||||
{ ZD_CR10, 0x89 },
|
||||
/* for newest (3rd cut) AL2300 */
|
||||
{ ZD_CR17, 0x28 },
|
||||
{ ZD_CR26, 0x93 }, { ZD_CR34, 0x30 },
|
||||
/* for newest (3rd cut) AL2300 */
|
||||
{ ZD_CR35, 0x3e },
|
||||
{ ZD_CR41, 0x24 }, { ZD_CR44, 0x32 },
|
||||
/* for newest (3rd cut) AL2300 */
|
||||
{ ZD_CR46, 0x96 },
|
||||
{ ZD_CR47, 0x1e }, { ZD_CR79, 0x58 }, { ZD_CR80, 0x30 },
|
||||
{ ZD_CR81, 0x30 }, { ZD_CR87, 0x0a }, { ZD_CR89, 0x04 },
|
||||
{ ZD_CR92, 0x0a }, { ZD_CR99, 0x28 },
|
||||
/* This value is different for 7230 (was: 0x00) */
|
||||
{ ZD_CR100, 0x02 },
|
||||
{ ZD_CR101, 0x13 }, { ZD_CR102, 0x27 },
|
||||
/* This value is different for 7230 (was: 0x24) */
|
||||
{ ZD_CR106, 0x22 },
|
||||
/* This value is different for 7230 (was: 0x2a) */
|
||||
{ ZD_CR107, 0x3f },
|
||||
{ ZD_CR109, 0x09 },
|
||||
/* This value is different for 7230 (was: 0x13) */
|
||||
{ ZD_CR110, 0x1f },
|
||||
{ ZD_CR111, 0x1f }, { ZD_CR112, 0x1f }, { ZD_CR113, 0x27 },
|
||||
{ ZD_CR114, 0x27 },
|
||||
/* for newest (3rd cut) AL2300 */
|
||||
{ ZD_CR115, 0x24 },
|
||||
/* This value is different for 7230 (was: 0x24) */
|
||||
{ ZD_CR116, 0x3f },
|
||||
/* This value is different for 7230 (was: 0xf4) */
|
||||
{ ZD_CR117, 0xfa },
|
||||
{ ZD_CR118, 0xfc }, { ZD_CR119, 0x10 }, { ZD_CR120, 0x4f },
|
||||
{ ZD_CR121, 0x77 }, { ZD_CR137, 0x88 },
|
||||
/* This one is 7230-specific */
|
||||
{ ZD_CR138, 0xa8 },
|
||||
/* This value is different for 7230 (was: 0xff) */
|
||||
{ ZD_CR252, 0x34 },
|
||||
/* This value is different for 7230 (was: 0xff) */
|
||||
{ ZD_CR253, 0x34 },
|
||||
|
||||
/* PLL_OFF */
|
||||
{ ZD_CR251, 0x2f },
|
||||
};
|
||||
|
||||
static const struct zd_ioreq16 ioreqs_2[] = {
|
||||
{ ZD_CR251, 0x3f }, /* PLL_ON */
|
||||
{ ZD_CR128, 0x14 }, { ZD_CR129, 0x12 }, { ZD_CR130, 0x10 },
|
||||
{ ZD_CR38, 0x38 }, { ZD_CR136, 0xdf },
|
||||
};
|
||||
|
||||
r = zd_iowrite16a_locked(chip, ioreqs_1, ARRAY_SIZE(ioreqs_1));
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
r = zd_rfwritev_cr_locked(chip, chan_rv[0], ARRAY_SIZE(chan_rv[0]));
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
r = zd_rfwritev_cr_locked(chip, std_rv, ARRAY_SIZE(std_rv));
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
r = zd_rfwritev_cr_locked(chip, rv_init1, ARRAY_SIZE(rv_init1));
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
r = zd_iowrite16a_locked(chip, ioreqs_2, ARRAY_SIZE(ioreqs_2));
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
r = zd_rfwritev_cr_locked(chip, rv_init2, ARRAY_SIZE(rv_init2));
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
r = zd_iowrite16_locked(chip, 0x06, ZD_CR203);
|
||||
if (r)
|
||||
return r;
|
||||
r = zd_iowrite16_locked(chip, 0x80, ZD_CR240);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int zd1211b_al7230b_init_hw(struct zd_rf *rf)
|
||||
{
|
||||
int r;
|
||||
struct zd_chip *chip = zd_rf_to_chip(rf);
|
||||
|
||||
static const struct zd_ioreq16 ioreqs_1[] = {
|
||||
{ ZD_CR240, 0x57 }, { ZD_CR9, 0x9 },
|
||||
{ },
|
||||
{ ZD_CR10, 0x8b }, { ZD_CR15, 0x20 },
|
||||
{ ZD_CR17, 0x2B }, /* for newest (3rd cut) AL2230 */
|
||||
{ ZD_CR20, 0x10 }, /* 4N25->Stone Request */
|
||||
{ ZD_CR23, 0x40 }, { ZD_CR24, 0x20 }, { ZD_CR26, 0x93 },
|
||||
{ ZD_CR28, 0x3e }, { ZD_CR29, 0x00 },
|
||||
{ ZD_CR33, 0x28 }, /* 5613 */
|
||||
{ ZD_CR34, 0x30 },
|
||||
{ ZD_CR35, 0x3e }, /* for newest (3rd cut) AL2230 */
|
||||
{ ZD_CR41, 0x24 }, { ZD_CR44, 0x32 },
|
||||
{ ZD_CR46, 0x99 }, /* for newest (3rd cut) AL2230 */
|
||||
{ ZD_CR47, 0x1e },
|
||||
|
||||
/* ZD1215 5610 */
|
||||
{ ZD_CR48, 0x00 }, { ZD_CR49, 0x00 }, { ZD_CR51, 0x01 },
|
||||
{ ZD_CR52, 0x80 }, { ZD_CR53, 0x7e }, { ZD_CR65, 0x00 },
|
||||
{ ZD_CR66, 0x00 }, { ZD_CR67, 0x00 }, { ZD_CR68, 0x00 },
|
||||
{ ZD_CR69, 0x28 },
|
||||
|
||||
{ ZD_CR79, 0x58 }, { ZD_CR80, 0x30 }, { ZD_CR81, 0x30 },
|
||||
{ ZD_CR87, 0x0A }, { ZD_CR89, 0x04 },
|
||||
{ ZD_CR90, 0x58 }, /* 5112 */
|
||||
{ ZD_CR91, 0x00 }, /* 5613 */
|
||||
{ ZD_CR92, 0x0a },
|
||||
{ ZD_CR98, 0x8d }, /* 4804, for 1212 new algorithm */
|
||||
{ ZD_CR99, 0x00 }, { ZD_CR100, 0x02 }, { ZD_CR101, 0x13 },
|
||||
{ ZD_CR102, 0x27 },
|
||||
{ ZD_CR106, 0x20 }, /* change to 0x24 for AL7230B */
|
||||
{ ZD_CR109, 0x13 }, /* 4804, for 1212 new algorithm */
|
||||
{ ZD_CR112, 0x1f },
|
||||
};
|
||||
|
||||
static const struct zd_ioreq16 ioreqs_new_phy[] = {
|
||||
{ ZD_CR107, 0x28 },
|
||||
{ ZD_CR110, 0x1f }, /* 5127, 0x13->0x1f */
|
||||
{ ZD_CR111, 0x1f }, /* 0x13 to 0x1f for AL7230B */
|
||||
{ ZD_CR116, 0x2a }, { ZD_CR118, 0xfa }, { ZD_CR119, 0x12 },
|
||||
{ ZD_CR121, 0x6c }, /* 5613 */
|
||||
};
|
||||
|
||||
static const struct zd_ioreq16 ioreqs_old_phy[] = {
|
||||
{ ZD_CR107, 0x24 },
|
||||
{ ZD_CR110, 0x13 }, /* 5127, 0x13->0x1f */
|
||||
{ ZD_CR111, 0x13 }, /* 0x13 to 0x1f for AL7230B */
|
||||
{ ZD_CR116, 0x24 }, { ZD_CR118, 0xfc }, { ZD_CR119, 0x11 },
|
||||
{ ZD_CR121, 0x6a }, /* 5613 */
|
||||
};
|
||||
|
||||
static const struct zd_ioreq16 ioreqs_2[] = {
|
||||
{ ZD_CR113, 0x27 }, { ZD_CR114, 0x27 }, { ZD_CR115, 0x24 },
|
||||
{ ZD_CR117, 0xfa }, { ZD_CR120, 0x4f },
|
||||
{ ZD_CR122, 0xfc }, /* E0->FCh at 4901 */
|
||||
{ ZD_CR123, 0x57 }, /* 5613 */
|
||||
{ ZD_CR125, 0xad }, /* 4804, for 1212 new algorithm */
|
||||
{ ZD_CR126, 0x6c }, /* 5613 */
|
||||
{ ZD_CR127, 0x03 }, /* 4804, for 1212 new algorithm */
|
||||
{ ZD_CR130, 0x10 },
|
||||
{ ZD_CR131, 0x00 }, /* 5112 */
|
||||
{ ZD_CR137, 0x50 }, /* 5613 */
|
||||
{ ZD_CR138, 0xa8 }, /* 5112 */
|
||||
{ ZD_CR144, 0xac }, /* 5613 */
|
||||
{ ZD_CR148, 0x40 }, /* 5112 */
|
||||
{ ZD_CR149, 0x40 }, /* 4O07, 50->40 */
|
||||
{ ZD_CR150, 0x1a }, /* 5112, 0C->1A */
|
||||
{ ZD_CR252, 0x34 }, { ZD_CR253, 0x34 },
|
||||
{ ZD_CR251, 0x2f }, /* PLL_OFF */
|
||||
};
|
||||
|
||||
static const struct zd_ioreq16 ioreqs_3[] = {
|
||||
{ ZD_CR251, 0x7f }, /* PLL_ON */
|
||||
{ ZD_CR128, 0x14 }, { ZD_CR129, 0x12 }, { ZD_CR130, 0x10 },
|
||||
{ ZD_CR38, 0x38 }, { ZD_CR136, 0xdf },
|
||||
};
|
||||
|
||||
r = zd_iowrite16a_locked(chip, ioreqs_1, ARRAY_SIZE(ioreqs_1));
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
if (chip->new_phy_layout)
|
||||
r = zd_iowrite16a_locked(chip, ioreqs_new_phy,
|
||||
ARRAY_SIZE(ioreqs_new_phy));
|
||||
else
|
||||
r = zd_iowrite16a_locked(chip, ioreqs_old_phy,
|
||||
ARRAY_SIZE(ioreqs_old_phy));
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
r = zd_iowrite16a_locked(chip, ioreqs_2, ARRAY_SIZE(ioreqs_2));
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
r = zd_rfwritev_cr_locked(chip, chan_rv[0], ARRAY_SIZE(chan_rv[0]));
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
r = zd_rfwritev_cr_locked(chip, std_rv, ARRAY_SIZE(std_rv));
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
r = zd_rfwritev_cr_locked(chip, rv_init1, ARRAY_SIZE(rv_init1));
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
r = zd_iowrite16a_locked(chip, ioreqs_3, ARRAY_SIZE(ioreqs_3));
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
r = zd_rfwritev_cr_locked(chip, rv_init2, ARRAY_SIZE(rv_init2));
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
return zd1211b_al7230b_finalize(chip);
|
||||
}
|
||||
|
||||
static int zd1211_al7230b_set_channel(struct zd_rf *rf, u8 channel)
|
||||
{
|
||||
int r;
|
||||
const u32 *rv = chan_rv[channel-1];
|
||||
struct zd_chip *chip = zd_rf_to_chip(rf);
|
||||
|
||||
static const struct zd_ioreq16 ioreqs[] = {
|
||||
/* PLL_ON */
|
||||
{ ZD_CR251, 0x3f },
|
||||
{ ZD_CR203, 0x06 }, { ZD_CR240, 0x08 },
|
||||
};
|
||||
|
||||
r = zd_iowrite16_locked(chip, 0x57, ZD_CR240);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
/* PLL_OFF */
|
||||
r = zd_iowrite16_locked(chip, 0x2f, ZD_CR251);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
r = zd_rfwritev_cr_locked(chip, std_rv, ARRAY_SIZE(std_rv));
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
r = zd_rfwrite_cr_locked(chip, 0x3c9000);
|
||||
if (r)
|
||||
return r;
|
||||
r = zd_rfwrite_cr_locked(chip, 0xf15d58);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
r = zd_iowrite16a_locked(chip, ioreqs_sw, ARRAY_SIZE(ioreqs_sw));
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
r = zd_rfwritev_cr_locked(chip, rv, 2);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
r = zd_rfwrite_cr_locked(chip, 0x3c9000);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
return zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
|
||||
}
|
||||
|
||||
static int zd1211b_al7230b_set_channel(struct zd_rf *rf, u8 channel)
|
||||
{
|
||||
int r;
|
||||
const u32 *rv = chan_rv[channel-1];
|
||||
struct zd_chip *chip = zd_rf_to_chip(rf);
|
||||
|
||||
r = zd_iowrite16_locked(chip, 0x57, ZD_CR240);
|
||||
if (r)
|
||||
return r;
|
||||
r = zd_iowrite16_locked(chip, 0xe4, ZD_CR9);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
/* PLL_OFF */
|
||||
r = zd_iowrite16_locked(chip, 0x2f, ZD_CR251);
|
||||
if (r)
|
||||
return r;
|
||||
r = zd_rfwritev_cr_locked(chip, std_rv, ARRAY_SIZE(std_rv));
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
r = zd_rfwrite_cr_locked(chip, 0x3c9000);
|
||||
if (r)
|
||||
return r;
|
||||
r = zd_rfwrite_cr_locked(chip, 0xf15d58);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
r = zd_iowrite16a_locked(chip, ioreqs_sw, ARRAY_SIZE(ioreqs_sw));
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
r = zd_rfwritev_cr_locked(chip, rv, 2);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
r = zd_rfwrite_cr_locked(chip, 0x3c9000);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
r = zd_iowrite16_locked(chip, 0x7f, ZD_CR251);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
return zd1211b_al7230b_finalize(chip);
|
||||
}
|
||||
|
||||
static int zd1211_al7230b_switch_radio_on(struct zd_rf *rf)
|
||||
{
|
||||
struct zd_chip *chip = zd_rf_to_chip(rf);
|
||||
static const struct zd_ioreq16 ioreqs[] = {
|
||||
{ ZD_CR11, 0x00 },
|
||||
{ ZD_CR251, 0x3f },
|
||||
};
|
||||
|
||||
return zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
|
||||
}
|
||||
|
||||
static int zd1211b_al7230b_switch_radio_on(struct zd_rf *rf)
|
||||
{
|
||||
struct zd_chip *chip = zd_rf_to_chip(rf);
|
||||
static const struct zd_ioreq16 ioreqs[] = {
|
||||
{ ZD_CR11, 0x00 },
|
||||
{ ZD_CR251, 0x7f },
|
||||
};
|
||||
|
||||
return zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
|
||||
}
|
||||
|
||||
static int al7230b_switch_radio_off(struct zd_rf *rf)
|
||||
{
|
||||
struct zd_chip *chip = zd_rf_to_chip(rf);
|
||||
static const struct zd_ioreq16 ioreqs[] = {
|
||||
{ ZD_CR11, 0x04 },
|
||||
{ ZD_CR251, 0x2f },
|
||||
};
|
||||
|
||||
return zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
|
||||
}
|
||||
|
||||
/* ZD1211B+AL7230B 6m band edge patching differs slightly from other
|
||||
* configurations */
|
||||
static int zd1211b_al7230b_patch_6m(struct zd_rf *rf, u8 channel)
|
||||
{
|
||||
struct zd_chip *chip = zd_rf_to_chip(rf);
|
||||
struct zd_ioreq16 ioreqs[] = {
|
||||
{ ZD_CR128, 0x14 }, { ZD_CR129, 0x12 },
|
||||
};
|
||||
|
||||
/* FIXME: Channel 11 is not the edge for all regulatory domains. */
|
||||
if (channel == 1) {
|
||||
ioreqs[0].value = 0x0e;
|
||||
ioreqs[1].value = 0x10;
|
||||
} else if (channel == 11) {
|
||||
ioreqs[0].value = 0x10;
|
||||
ioreqs[1].value = 0x10;
|
||||
}
|
||||
|
||||
dev_dbg_f(zd_chip_dev(chip), "patching for channel %d\n", channel);
|
||||
return zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
|
||||
}
|
||||
|
||||
int zd_rf_init_al7230b(struct zd_rf *rf)
|
||||
{
|
||||
struct zd_chip *chip = zd_rf_to_chip(rf);
|
||||
|
||||
if (zd_chip_is_zd1211b(chip)) {
|
||||
rf->init_hw = zd1211b_al7230b_init_hw;
|
||||
rf->switch_radio_on = zd1211b_al7230b_switch_radio_on;
|
||||
rf->set_channel = zd1211b_al7230b_set_channel;
|
||||
rf->patch_6m_band_edge = zd1211b_al7230b_patch_6m;
|
||||
} else {
|
||||
rf->init_hw = zd1211_al7230b_init_hw;
|
||||
rf->switch_radio_on = zd1211_al7230b_switch_radio_on;
|
||||
rf->set_channel = zd1211_al7230b_set_channel;
|
||||
rf->patch_6m_band_edge = zd_rf_generic_patch_6m;
|
||||
rf->patch_cck_gain = 1;
|
||||
}
|
||||
|
||||
rf->switch_radio_off = al7230b_switch_radio_off;
|
||||
|
||||
return 0;
|
||||
}
|
||||
281
drivers/net/wireless/zd1211rw/zd_rf_rf2959.c
Normal file
281
drivers/net/wireless/zd1211rw/zd_rf_rf2959.c
Normal file
|
|
@ -0,0 +1,281 @@
|
|||
/* ZD1211 USB-WLAN driver for Linux
|
||||
*
|
||||
* Copyright (C) 2005-2007 Ulrich Kunitz <kune@deine-taler.de>
|
||||
* Copyright (C) 2006-2007 Daniel Drake <dsd@gentoo.org>
|
||||
*
|
||||
* 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
|
||||
#include "zd_rf.h"
|
||||
#include "zd_usb.h"
|
||||
#include "zd_chip.h"
|
||||
|
||||
static const u32 rf2959_table[][2] = {
|
||||
RF_CHANNEL( 1) = { 0x181979, 0x1e6666 },
|
||||
RF_CHANNEL( 2) = { 0x181989, 0x1e6666 },
|
||||
RF_CHANNEL( 3) = { 0x181999, 0x1e6666 },
|
||||
RF_CHANNEL( 4) = { 0x1819a9, 0x1e6666 },
|
||||
RF_CHANNEL( 5) = { 0x1819b9, 0x1e6666 },
|
||||
RF_CHANNEL( 6) = { 0x1819c9, 0x1e6666 },
|
||||
RF_CHANNEL( 7) = { 0x1819d9, 0x1e6666 },
|
||||
RF_CHANNEL( 8) = { 0x1819e9, 0x1e6666 },
|
||||
RF_CHANNEL( 9) = { 0x1819f9, 0x1e6666 },
|
||||
RF_CHANNEL(10) = { 0x181a09, 0x1e6666 },
|
||||
RF_CHANNEL(11) = { 0x181a19, 0x1e6666 },
|
||||
RF_CHANNEL(12) = { 0x181a29, 0x1e6666 },
|
||||
RF_CHANNEL(13) = { 0x181a39, 0x1e6666 },
|
||||
RF_CHANNEL(14) = { 0x181a60, 0x1c0000 },
|
||||
};
|
||||
|
||||
#if 0
|
||||
static int bits(u32 rw, int from, int to)
|
||||
{
|
||||
rw &= ~(0xffffffffU << (to+1));
|
||||
rw >>= from;
|
||||
return rw;
|
||||
}
|
||||
|
||||
static int bit(u32 rw, int bit)
|
||||
{
|
||||
return bits(rw, bit, bit);
|
||||
}
|
||||
|
||||
static void dump_regwrite(u32 rw)
|
||||
{
|
||||
int reg = bits(rw, 18, 22);
|
||||
int rw_flag = bits(rw, 23, 23);
|
||||
PDEBUG("rf2959 %#010x reg %d rw %d", rw, reg, rw_flag);
|
||||
|
||||
switch (reg) {
|
||||
case 0:
|
||||
PDEBUG("reg0 CFG1 ref_sel %d hybernate %d rf_vco_reg_en %d"
|
||||
" if_vco_reg_en %d if_vga_en %d",
|
||||
bits(rw, 14, 15), bit(rw, 3), bit(rw, 2), bit(rw, 1),
|
||||
bit(rw, 0));
|
||||
break;
|
||||
case 1:
|
||||
PDEBUG("reg1 IFPLL1 pll_en1 %d kv_en1 %d vtc_en1 %d lpf1 %d"
|
||||
" cpl1 %d pdp1 %d autocal_en1 %d ld_en1 %d ifloopr %d"
|
||||
" ifloopc %d dac1 %d",
|
||||
bit(rw, 17), bit(rw, 16), bit(rw, 15), bit(rw, 14),
|
||||
bit(rw, 13), bit(rw, 12), bit(rw, 11), bit(rw, 10),
|
||||
bits(rw, 7, 9), bits(rw, 4, 6), bits(rw, 0, 3));
|
||||
break;
|
||||
case 2:
|
||||
PDEBUG("reg2 IFPLL2 n1 %d num1 %d",
|
||||
bits(rw, 6, 17), bits(rw, 0, 5));
|
||||
break;
|
||||
case 3:
|
||||
PDEBUG("reg3 IFPLL3 num %d", bits(rw, 0, 17));
|
||||
break;
|
||||
case 4:
|
||||
PDEBUG("reg4 IFPLL4 dn1 %#04x ct_def1 %d kv_def1 %d",
|
||||
bits(rw, 8, 16), bits(rw, 4, 7), bits(rw, 0, 3));
|
||||
break;
|
||||
case 5:
|
||||
PDEBUG("reg5 RFPLL1 pll_en %d kv_en %d vtc_en %d lpf %d cpl %d"
|
||||
" pdp %d autocal_en %d ld_en %d rfloopr %d rfloopc %d"
|
||||
" dac %d",
|
||||
bit(rw, 17), bit(rw, 16), bit(rw, 15), bit(rw, 14),
|
||||
bit(rw, 13), bit(rw, 12), bit(rw, 11), bit(rw, 10),
|
||||
bits(rw, 7, 9), bits(rw, 4, 6), bits(rw, 0,3));
|
||||
break;
|
||||
case 6:
|
||||
PDEBUG("reg6 RFPLL2 n %d num %d",
|
||||
bits(rw, 6, 17), bits(rw, 0, 5));
|
||||
break;
|
||||
case 7:
|
||||
PDEBUG("reg7 RFPLL3 num2 %d", bits(rw, 0, 17));
|
||||
break;
|
||||
case 8:
|
||||
PDEBUG("reg8 RFPLL4 dn %#06x ct_def %d kv_def %d",
|
||||
bits(rw, 8, 16), bits(rw, 4, 7), bits(rw, 0, 3));
|
||||
break;
|
||||
case 9:
|
||||
PDEBUG("reg9 CAL1 tvco %d tlock %d m_ct_value %d ld_window %d",
|
||||
bits(rw, 13, 17), bits(rw, 8, 12), bits(rw, 3, 7),
|
||||
bits(rw, 0, 2));
|
||||
break;
|
||||
case 10:
|
||||
PDEBUG("reg10 TXRX1 rxdcfbbyps %d pcontrol %d txvgc %d"
|
||||
" rxlpfbw %d txlpfbw %d txdiffmode %d txenmode %d"
|
||||
" intbiasen %d tybypass %d",
|
||||
bit(rw, 17), bits(rw, 15, 16), bits(rw, 10, 14),
|
||||
bits(rw, 7, 9), bits(rw, 4, 6), bit(rw, 3), bit(rw, 2),
|
||||
bit(rw, 1), bit(rw, 0));
|
||||
break;
|
||||
case 11:
|
||||
PDEBUG("reg11 PCNT1 mid_bias %d p_desired %d pc_offset %d"
|
||||
" tx_delay %d",
|
||||
bits(rw, 15, 17), bits(rw, 9, 14), bits(rw, 3, 8),
|
||||
bits(rw, 0, 2));
|
||||
break;
|
||||
case 12:
|
||||
PDEBUG("reg12 PCNT2 max_power %d mid_power %d min_power %d",
|
||||
bits(rw, 12, 17), bits(rw, 6, 11), bits(rw, 0, 5));
|
||||
break;
|
||||
case 13:
|
||||
PDEBUG("reg13 VCOT1 rfpll vco comp %d ifpll vco comp %d"
|
||||
" lobias %d if_biasbuf %d if_biasvco %d rf_biasbuf %d"
|
||||
" rf_biasvco %d",
|
||||
bit(rw, 17), bit(rw, 16), bit(rw, 15),
|
||||
bits(rw, 8, 9), bits(rw, 5, 7), bits(rw, 3, 4),
|
||||
bits(rw, 0, 2));
|
||||
break;
|
||||
case 14:
|
||||
PDEBUG("reg14 IQCAL rx_acal %d rx_pcal %d"
|
||||
" tx_acal %d tx_pcal %d",
|
||||
bits(rw, 13, 17), bits(rw, 9, 12), bits(rw, 4, 8),
|
||||
bits(rw, 0, 3));
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif /* 0 */
|
||||
|
||||
static int rf2959_init_hw(struct zd_rf *rf)
|
||||
{
|
||||
int r;
|
||||
struct zd_chip *chip = zd_rf_to_chip(rf);
|
||||
|
||||
static const struct zd_ioreq16 ioreqs[] = {
|
||||
{ ZD_CR2, 0x1E }, { ZD_CR9, 0x20 }, { ZD_CR10, 0x89 },
|
||||
{ ZD_CR11, 0x00 }, { ZD_CR15, 0xD0 }, { ZD_CR17, 0x68 },
|
||||
{ ZD_CR19, 0x4a }, { ZD_CR20, 0x0c }, { ZD_CR21, 0x0E },
|
||||
{ ZD_CR23, 0x48 },
|
||||
/* normal size for cca threshold */
|
||||
{ ZD_CR24, 0x14 },
|
||||
/* { ZD_CR24, 0x20 }, */
|
||||
{ ZD_CR26, 0x90 }, { ZD_CR27, 0x30 }, { ZD_CR29, 0x20 },
|
||||
{ ZD_CR31, 0xb2 }, { ZD_CR32, 0x43 }, { ZD_CR33, 0x28 },
|
||||
{ ZD_CR38, 0x30 }, { ZD_CR34, 0x0f }, { ZD_CR35, 0xF0 },
|
||||
{ ZD_CR41, 0x2a }, { ZD_CR46, 0x7F }, { ZD_CR47, 0x1E },
|
||||
{ ZD_CR51, 0xc5 }, { ZD_CR52, 0xc5 }, { ZD_CR53, 0xc5 },
|
||||
{ ZD_CR79, 0x58 }, { ZD_CR80, 0x30 }, { ZD_CR81, 0x30 },
|
||||
{ ZD_CR82, 0x00 }, { ZD_CR83, 0x24 }, { ZD_CR84, 0x04 },
|
||||
{ ZD_CR85, 0x00 }, { ZD_CR86, 0x10 }, { ZD_CR87, 0x2A },
|
||||
{ ZD_CR88, 0x10 }, { ZD_CR89, 0x24 }, { ZD_CR90, 0x18 },
|
||||
/* { ZD_CR91, 0x18 }, */
|
||||
/* should solve continuous CTS frame problems */
|
||||
{ ZD_CR91, 0x00 },
|
||||
{ ZD_CR92, 0x0a }, { ZD_CR93, 0x00 }, { ZD_CR94, 0x01 },
|
||||
{ ZD_CR95, 0x00 }, { ZD_CR96, 0x40 }, { ZD_CR97, 0x37 },
|
||||
{ ZD_CR98, 0x05 }, { ZD_CR99, 0x28 }, { ZD_CR100, 0x00 },
|
||||
{ ZD_CR101, 0x13 }, { ZD_CR102, 0x27 }, { ZD_CR103, 0x27 },
|
||||
{ ZD_CR104, 0x18 }, { ZD_CR105, 0x12 },
|
||||
/* normal size */
|
||||
{ ZD_CR106, 0x1a },
|
||||
/* { ZD_CR106, 0x22 }, */
|
||||
{ ZD_CR107, 0x24 }, { ZD_CR108, 0x0a }, { ZD_CR109, 0x13 },
|
||||
{ ZD_CR110, 0x2F }, { ZD_CR111, 0x27 }, { ZD_CR112, 0x27 },
|
||||
{ ZD_CR113, 0x27 }, { ZD_CR114, 0x27 }, { ZD_CR115, 0x40 },
|
||||
{ ZD_CR116, 0x40 }, { ZD_CR117, 0xF0 }, { ZD_CR118, 0xF0 },
|
||||
{ ZD_CR119, 0x16 },
|
||||
/* no TX continuation */
|
||||
{ ZD_CR122, 0x00 },
|
||||
/* { ZD_CR122, 0xff }, */
|
||||
{ ZD_CR127, 0x03 }, { ZD_CR131, 0x08 }, { ZD_CR138, 0x28 },
|
||||
{ ZD_CR148, 0x44 }, { ZD_CR150, 0x10 }, { ZD_CR169, 0xBB },
|
||||
{ ZD_CR170, 0xBB },
|
||||
};
|
||||
|
||||
static const u32 rv[] = {
|
||||
0x000007, /* REG0(CFG1) */
|
||||
0x07dd43, /* REG1(IFPLL1) */
|
||||
0x080959, /* REG2(IFPLL2) */
|
||||
0x0e6666,
|
||||
0x116a57, /* REG4 */
|
||||
0x17dd43, /* REG5 */
|
||||
0x1819f9, /* REG6 */
|
||||
0x1e6666,
|
||||
0x214554,
|
||||
0x25e7fa,
|
||||
0x27fffa,
|
||||
/* The Zydas driver somehow forgets to set this value. It's
|
||||
* only set for Japan. We are using internal power control
|
||||
* for now.
|
||||
*/
|
||||
0x294128, /* internal power */
|
||||
/* 0x28252c, */ /* External control TX power */
|
||||
/* ZD_CR31_CCK, ZD_CR51_6-36M, ZD_CR52_48M, ZD_CR53_54M */
|
||||
0x2c0000,
|
||||
0x300000,
|
||||
0x340000, /* REG13(0xD) */
|
||||
0x381e0f, /* REG14(0xE) */
|
||||
/* Bogus, RF2959's data sheet doesn't know register 27, which is
|
||||
* actually referenced here. The commented 0x11 is 17.
|
||||
*/
|
||||
0x6c180f, /* REG27(0x11) */
|
||||
};
|
||||
|
||||
r = zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
return zd_rfwritev_locked(chip, rv, ARRAY_SIZE(rv), RF_RV_BITS);
|
||||
}
|
||||
|
||||
static int rf2959_set_channel(struct zd_rf *rf, u8 channel)
|
||||
{
|
||||
int i, r;
|
||||
const u32 *rv = rf2959_table[channel-1];
|
||||
struct zd_chip *chip = zd_rf_to_chip(rf);
|
||||
|
||||
for (i = 0; i < 2; i++) {
|
||||
r = zd_rfwrite_locked(chip, rv[i], RF_RV_BITS);
|
||||
if (r)
|
||||
return r;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rf2959_switch_radio_on(struct zd_rf *rf)
|
||||
{
|
||||
static const struct zd_ioreq16 ioreqs[] = {
|
||||
{ ZD_CR10, 0x89 },
|
||||
{ ZD_CR11, 0x00 },
|
||||
};
|
||||
struct zd_chip *chip = zd_rf_to_chip(rf);
|
||||
|
||||
return zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
|
||||
}
|
||||
|
||||
static int rf2959_switch_radio_off(struct zd_rf *rf)
|
||||
{
|
||||
static const struct zd_ioreq16 ioreqs[] = {
|
||||
{ ZD_CR10, 0x15 },
|
||||
{ ZD_CR11, 0x81 },
|
||||
};
|
||||
struct zd_chip *chip = zd_rf_to_chip(rf);
|
||||
|
||||
return zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
|
||||
}
|
||||
|
||||
int zd_rf_init_rf2959(struct zd_rf *rf)
|
||||
{
|
||||
struct zd_chip *chip = zd_rf_to_chip(rf);
|
||||
|
||||
if (zd_chip_is_zd1211b(chip)) {
|
||||
dev_err(zd_chip_dev(chip),
|
||||
"RF2959 is currently not supported for ZD1211B"
|
||||
" devices\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
rf->init_hw = rf2959_init_hw;
|
||||
rf->set_channel = rf2959_set_channel;
|
||||
rf->switch_radio_on = rf2959_switch_radio_on;
|
||||
rf->switch_radio_off = rf2959_switch_radio_off;
|
||||
return 0;
|
||||
}
|
||||
539
drivers/net/wireless/zd1211rw/zd_rf_uw2453.c
Normal file
539
drivers/net/wireless/zd1211rw/zd_rf_uw2453.c
Normal file
|
|
@ -0,0 +1,539 @@
|
|||
/* ZD1211 USB-WLAN driver for Linux
|
||||
*
|
||||
* Copyright (C) 2005-2007 Ulrich Kunitz <kune@deine-taler.de>
|
||||
* Copyright (C) 2006-2007 Daniel Drake <dsd@gentoo.org>
|
||||
*
|
||||
* 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
#include "zd_rf.h"
|
||||
#include "zd_usb.h"
|
||||
#include "zd_chip.h"
|
||||
|
||||
/* This RF programming code is based upon the code found in v2.16.0.0 of the
|
||||
* ZyDAS vendor driver. Unlike other RF's, Ubec publish full technical specs
|
||||
* for this RF on their website, so we're able to understand more than
|
||||
* usual as to what is going on. Thumbs up for Ubec for doing that. */
|
||||
|
||||
/* The 3-wire serial interface provides access to 8 write-only registers.
|
||||
* The data format is a 4 bit register address followed by a 20 bit value. */
|
||||
#define UW2453_REGWRITE(reg, val) ((((reg) & 0xf) << 20) | ((val) & 0xfffff))
|
||||
|
||||
/* For channel tuning, we have to configure registers 1 (synthesizer), 2 (synth
|
||||
* fractional divide ratio) and 3 (VCO config).
|
||||
*
|
||||
* We configure the RF to produce an interrupt when the PLL is locked onto
|
||||
* the configured frequency. During initialization, we run through a variety
|
||||
* of different VCO configurations on channel 1 until we detect a PLL lock.
|
||||
* When this happens, we remember which VCO configuration produced the lock
|
||||
* and use it later. Actually, we use the configuration *after* the one that
|
||||
* produced the lock, which seems odd, but it works.
|
||||
*
|
||||
* If we do not see a PLL lock on any standard VCO config, we fall back on an
|
||||
* autocal configuration, which has a fixed (as opposed to per-channel) VCO
|
||||
* config and different synth values from the standard set (divide ratio
|
||||
* is still shared with the standard set). */
|
||||
|
||||
/* The per-channel synth values for all standard VCO configurations. These get
|
||||
* written to register 1. */
|
||||
static const u8 uw2453_std_synth[] = {
|
||||
RF_CHANNEL( 1) = 0x47,
|
||||
RF_CHANNEL( 2) = 0x47,
|
||||
RF_CHANNEL( 3) = 0x67,
|
||||
RF_CHANNEL( 4) = 0x67,
|
||||
RF_CHANNEL( 5) = 0x67,
|
||||
RF_CHANNEL( 6) = 0x67,
|
||||
RF_CHANNEL( 7) = 0x57,
|
||||
RF_CHANNEL( 8) = 0x57,
|
||||
RF_CHANNEL( 9) = 0x57,
|
||||
RF_CHANNEL(10) = 0x57,
|
||||
RF_CHANNEL(11) = 0x77,
|
||||
RF_CHANNEL(12) = 0x77,
|
||||
RF_CHANNEL(13) = 0x77,
|
||||
RF_CHANNEL(14) = 0x4f,
|
||||
};
|
||||
|
||||
/* This table stores the synthesizer fractional divide ratio for *all* VCO
|
||||
* configurations (both standard and autocal). These get written to register 2.
|
||||
*/
|
||||
static const u16 uw2453_synth_divide[] = {
|
||||
RF_CHANNEL( 1) = 0x999,
|
||||
RF_CHANNEL( 2) = 0x99b,
|
||||
RF_CHANNEL( 3) = 0x998,
|
||||
RF_CHANNEL( 4) = 0x99a,
|
||||
RF_CHANNEL( 5) = 0x999,
|
||||
RF_CHANNEL( 6) = 0x99b,
|
||||
RF_CHANNEL( 7) = 0x998,
|
||||
RF_CHANNEL( 8) = 0x99a,
|
||||
RF_CHANNEL( 9) = 0x999,
|
||||
RF_CHANNEL(10) = 0x99b,
|
||||
RF_CHANNEL(11) = 0x998,
|
||||
RF_CHANNEL(12) = 0x99a,
|
||||
RF_CHANNEL(13) = 0x999,
|
||||
RF_CHANNEL(14) = 0xccc,
|
||||
};
|
||||
|
||||
/* Here is the data for all the standard VCO configurations. We shrink our
|
||||
* table a little by observing that both channels in a consecutive pair share
|
||||
* the same value. We also observe that the high 4 bits ([0:3] in the specs)
|
||||
* are all 'Reserved' and are always set to 0x4 - we chop them off in the data
|
||||
* below. */
|
||||
#define CHAN_TO_PAIRIDX(a) ((a - 1) / 2)
|
||||
#define RF_CHANPAIR(a,b) [CHAN_TO_PAIRIDX(a)]
|
||||
static const u16 uw2453_std_vco_cfg[][7] = {
|
||||
{ /* table 1 */
|
||||
RF_CHANPAIR( 1, 2) = 0x664d,
|
||||
RF_CHANPAIR( 3, 4) = 0x604d,
|
||||
RF_CHANPAIR( 5, 6) = 0x6675,
|
||||
RF_CHANPAIR( 7, 8) = 0x6475,
|
||||
RF_CHANPAIR( 9, 10) = 0x6655,
|
||||
RF_CHANPAIR(11, 12) = 0x6455,
|
||||
RF_CHANPAIR(13, 14) = 0x6665,
|
||||
},
|
||||
{ /* table 2 */
|
||||
RF_CHANPAIR( 1, 2) = 0x666d,
|
||||
RF_CHANPAIR( 3, 4) = 0x606d,
|
||||
RF_CHANPAIR( 5, 6) = 0x664d,
|
||||
RF_CHANPAIR( 7, 8) = 0x644d,
|
||||
RF_CHANPAIR( 9, 10) = 0x6675,
|
||||
RF_CHANPAIR(11, 12) = 0x6475,
|
||||
RF_CHANPAIR(13, 14) = 0x6655,
|
||||
},
|
||||
{ /* table 3 */
|
||||
RF_CHANPAIR( 1, 2) = 0x665d,
|
||||
RF_CHANPAIR( 3, 4) = 0x605d,
|
||||
RF_CHANPAIR( 5, 6) = 0x666d,
|
||||
RF_CHANPAIR( 7, 8) = 0x646d,
|
||||
RF_CHANPAIR( 9, 10) = 0x664d,
|
||||
RF_CHANPAIR(11, 12) = 0x644d,
|
||||
RF_CHANPAIR(13, 14) = 0x6675,
|
||||
},
|
||||
{ /* table 4 */
|
||||
RF_CHANPAIR( 1, 2) = 0x667d,
|
||||
RF_CHANPAIR( 3, 4) = 0x607d,
|
||||
RF_CHANPAIR( 5, 6) = 0x665d,
|
||||
RF_CHANPAIR( 7, 8) = 0x645d,
|
||||
RF_CHANPAIR( 9, 10) = 0x666d,
|
||||
RF_CHANPAIR(11, 12) = 0x646d,
|
||||
RF_CHANPAIR(13, 14) = 0x664d,
|
||||
},
|
||||
{ /* table 5 */
|
||||
RF_CHANPAIR( 1, 2) = 0x6643,
|
||||
RF_CHANPAIR( 3, 4) = 0x6043,
|
||||
RF_CHANPAIR( 5, 6) = 0x667d,
|
||||
RF_CHANPAIR( 7, 8) = 0x647d,
|
||||
RF_CHANPAIR( 9, 10) = 0x665d,
|
||||
RF_CHANPAIR(11, 12) = 0x645d,
|
||||
RF_CHANPAIR(13, 14) = 0x666d,
|
||||
},
|
||||
{ /* table 6 */
|
||||
RF_CHANPAIR( 1, 2) = 0x6663,
|
||||
RF_CHANPAIR( 3, 4) = 0x6063,
|
||||
RF_CHANPAIR( 5, 6) = 0x6643,
|
||||
RF_CHANPAIR( 7, 8) = 0x6443,
|
||||
RF_CHANPAIR( 9, 10) = 0x667d,
|
||||
RF_CHANPAIR(11, 12) = 0x647d,
|
||||
RF_CHANPAIR(13, 14) = 0x665d,
|
||||
},
|
||||
{ /* table 7 */
|
||||
RF_CHANPAIR( 1, 2) = 0x6653,
|
||||
RF_CHANPAIR( 3, 4) = 0x6053,
|
||||
RF_CHANPAIR( 5, 6) = 0x6663,
|
||||
RF_CHANPAIR( 7, 8) = 0x6463,
|
||||
RF_CHANPAIR( 9, 10) = 0x6643,
|
||||
RF_CHANPAIR(11, 12) = 0x6443,
|
||||
RF_CHANPAIR(13, 14) = 0x667d,
|
||||
},
|
||||
{ /* table 8 */
|
||||
RF_CHANPAIR( 1, 2) = 0x6673,
|
||||
RF_CHANPAIR( 3, 4) = 0x6073,
|
||||
RF_CHANPAIR( 5, 6) = 0x6653,
|
||||
RF_CHANPAIR( 7, 8) = 0x6453,
|
||||
RF_CHANPAIR( 9, 10) = 0x6663,
|
||||
RF_CHANPAIR(11, 12) = 0x6463,
|
||||
RF_CHANPAIR(13, 14) = 0x6643,
|
||||
},
|
||||
{ /* table 9 */
|
||||
RF_CHANPAIR( 1, 2) = 0x664b,
|
||||
RF_CHANPAIR( 3, 4) = 0x604b,
|
||||
RF_CHANPAIR( 5, 6) = 0x6673,
|
||||
RF_CHANPAIR( 7, 8) = 0x6473,
|
||||
RF_CHANPAIR( 9, 10) = 0x6653,
|
||||
RF_CHANPAIR(11, 12) = 0x6453,
|
||||
RF_CHANPAIR(13, 14) = 0x6663,
|
||||
},
|
||||
{ /* table 10 */
|
||||
RF_CHANPAIR( 1, 2) = 0x666b,
|
||||
RF_CHANPAIR( 3, 4) = 0x606b,
|
||||
RF_CHANPAIR( 5, 6) = 0x664b,
|
||||
RF_CHANPAIR( 7, 8) = 0x644b,
|
||||
RF_CHANPAIR( 9, 10) = 0x6673,
|
||||
RF_CHANPAIR(11, 12) = 0x6473,
|
||||
RF_CHANPAIR(13, 14) = 0x6653,
|
||||
},
|
||||
{ /* table 11 */
|
||||
RF_CHANPAIR( 1, 2) = 0x665b,
|
||||
RF_CHANPAIR( 3, 4) = 0x605b,
|
||||
RF_CHANPAIR( 5, 6) = 0x666b,
|
||||
RF_CHANPAIR( 7, 8) = 0x646b,
|
||||
RF_CHANPAIR( 9, 10) = 0x664b,
|
||||
RF_CHANPAIR(11, 12) = 0x644b,
|
||||
RF_CHANPAIR(13, 14) = 0x6673,
|
||||
},
|
||||
|
||||
};
|
||||
|
||||
/* The per-channel synth values for autocal. These get written to register 1. */
|
||||
static const u16 uw2453_autocal_synth[] = {
|
||||
RF_CHANNEL( 1) = 0x6847,
|
||||
RF_CHANNEL( 2) = 0x6847,
|
||||
RF_CHANNEL( 3) = 0x6867,
|
||||
RF_CHANNEL( 4) = 0x6867,
|
||||
RF_CHANNEL( 5) = 0x6867,
|
||||
RF_CHANNEL( 6) = 0x6867,
|
||||
RF_CHANNEL( 7) = 0x6857,
|
||||
RF_CHANNEL( 8) = 0x6857,
|
||||
RF_CHANNEL( 9) = 0x6857,
|
||||
RF_CHANNEL(10) = 0x6857,
|
||||
RF_CHANNEL(11) = 0x6877,
|
||||
RF_CHANNEL(12) = 0x6877,
|
||||
RF_CHANNEL(13) = 0x6877,
|
||||
RF_CHANNEL(14) = 0x684f,
|
||||
};
|
||||
|
||||
/* The VCO configuration for autocal (all channels) */
|
||||
static const u16 UW2453_AUTOCAL_VCO_CFG = 0x6662;
|
||||
|
||||
/* TX gain settings. The array index corresponds to the TX power integration
|
||||
* values found in the EEPROM. The values get written to register 7. */
|
||||
static u32 uw2453_txgain[] = {
|
||||
[0x00] = 0x0e313,
|
||||
[0x01] = 0x0fb13,
|
||||
[0x02] = 0x0e093,
|
||||
[0x03] = 0x0f893,
|
||||
[0x04] = 0x0ea93,
|
||||
[0x05] = 0x1f093,
|
||||
[0x06] = 0x1f493,
|
||||
[0x07] = 0x1f693,
|
||||
[0x08] = 0x1f393,
|
||||
[0x09] = 0x1f35b,
|
||||
[0x0a] = 0x1e6db,
|
||||
[0x0b] = 0x1ff3f,
|
||||
[0x0c] = 0x1ffff,
|
||||
[0x0d] = 0x361d7,
|
||||
[0x0e] = 0x37fbf,
|
||||
[0x0f] = 0x3ff8b,
|
||||
[0x10] = 0x3ff33,
|
||||
[0x11] = 0x3fb3f,
|
||||
[0x12] = 0x3ffff,
|
||||
};
|
||||
|
||||
/* RF-specific structure */
|
||||
struct uw2453_priv {
|
||||
/* index into synth/VCO config tables where PLL lock was found
|
||||
* -1 means autocal */
|
||||
int config;
|
||||
};
|
||||
|
||||
#define UW2453_PRIV(rf) ((struct uw2453_priv *) (rf)->priv)
|
||||
|
||||
static int uw2453_synth_set_channel(struct zd_chip *chip, int channel,
|
||||
bool autocal)
|
||||
{
|
||||
int r;
|
||||
int idx = channel - 1;
|
||||
u32 val;
|
||||
|
||||
if (autocal)
|
||||
val = UW2453_REGWRITE(1, uw2453_autocal_synth[idx]);
|
||||
else
|
||||
val = UW2453_REGWRITE(1, uw2453_std_synth[idx]);
|
||||
|
||||
r = zd_rfwrite_locked(chip, val, RF_RV_BITS);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
return zd_rfwrite_locked(chip,
|
||||
UW2453_REGWRITE(2, uw2453_synth_divide[idx]), RF_RV_BITS);
|
||||
}
|
||||
|
||||
static int uw2453_write_vco_cfg(struct zd_chip *chip, u16 value)
|
||||
{
|
||||
/* vendor driver always sets these upper bits even though the specs say
|
||||
* they are reserved */
|
||||
u32 val = 0x40000 | value;
|
||||
return zd_rfwrite_locked(chip, UW2453_REGWRITE(3, val), RF_RV_BITS);
|
||||
}
|
||||
|
||||
static int uw2453_init_mode(struct zd_chip *chip)
|
||||
{
|
||||
static const u32 rv[] = {
|
||||
UW2453_REGWRITE(0, 0x25f98), /* enter IDLE mode */
|
||||
UW2453_REGWRITE(0, 0x25f9a), /* enter CAL_VCO mode */
|
||||
UW2453_REGWRITE(0, 0x25f94), /* enter RX/TX mode */
|
||||
UW2453_REGWRITE(0, 0x27fd4), /* power down RSSI circuit */
|
||||
};
|
||||
|
||||
return zd_rfwritev_locked(chip, rv, ARRAY_SIZE(rv), RF_RV_BITS);
|
||||
}
|
||||
|
||||
static int uw2453_set_tx_gain_level(struct zd_chip *chip, int channel)
|
||||
{
|
||||
u8 int_value = chip->pwr_int_values[channel - 1];
|
||||
|
||||
if (int_value >= ARRAY_SIZE(uw2453_txgain)) {
|
||||
dev_dbg_f(zd_chip_dev(chip), "can't configure TX gain for "
|
||||
"int value %x on channel %d\n", int_value, channel);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return zd_rfwrite_locked(chip,
|
||||
UW2453_REGWRITE(7, uw2453_txgain[int_value]), RF_RV_BITS);
|
||||
}
|
||||
|
||||
static int uw2453_init_hw(struct zd_rf *rf)
|
||||
{
|
||||
int i, r;
|
||||
int found_config = -1;
|
||||
u16 intr_status;
|
||||
struct zd_chip *chip = zd_rf_to_chip(rf);
|
||||
|
||||
static const struct zd_ioreq16 ioreqs[] = {
|
||||
{ ZD_CR10, 0x89 }, { ZD_CR15, 0x20 },
|
||||
{ ZD_CR17, 0x28 }, /* 6112 no change */
|
||||
{ ZD_CR23, 0x38 }, { ZD_CR24, 0x20 }, { ZD_CR26, 0x93 },
|
||||
{ ZD_CR27, 0x15 }, { ZD_CR28, 0x3e }, { ZD_CR29, 0x00 },
|
||||
{ ZD_CR33, 0x28 }, { ZD_CR34, 0x30 },
|
||||
{ ZD_CR35, 0x43 }, /* 6112 3e->43 */
|
||||
{ ZD_CR41, 0x24 }, { ZD_CR44, 0x32 },
|
||||
{ ZD_CR46, 0x92 }, /* 6112 96->92 */
|
||||
{ ZD_CR47, 0x1e },
|
||||
{ ZD_CR48, 0x04 }, /* 5602 Roger */
|
||||
{ ZD_CR49, 0xfa }, { ZD_CR79, 0x58 }, { ZD_CR80, 0x30 },
|
||||
{ ZD_CR81, 0x30 }, { ZD_CR87, 0x0a }, { ZD_CR89, 0x04 },
|
||||
{ ZD_CR91, 0x00 }, { ZD_CR92, 0x0a }, { ZD_CR98, 0x8d },
|
||||
{ ZD_CR99, 0x28 }, { ZD_CR100, 0x02 },
|
||||
{ ZD_CR101, 0x09 }, /* 6112 13->1f 6220 1f->13 6407 13->9 */
|
||||
{ ZD_CR102, 0x27 },
|
||||
{ ZD_CR106, 0x1c }, /* 5d07 5112 1f->1c 6220 1c->1f
|
||||
* 6221 1f->1c
|
||||
*/
|
||||
{ ZD_CR107, 0x1c }, /* 6220 1c->1a 5221 1a->1c */
|
||||
{ ZD_CR109, 0x13 },
|
||||
{ ZD_CR110, 0x1f }, /* 6112 13->1f 6221 1f->13 6407 13->0x09 */
|
||||
{ ZD_CR111, 0x13 }, { ZD_CR112, 0x1f }, { ZD_CR113, 0x27 },
|
||||
{ ZD_CR114, 0x23 }, /* 6221 27->23 */
|
||||
{ ZD_CR115, 0x24 }, /* 6112 24->1c 6220 1c->24 */
|
||||
{ ZD_CR116, 0x24 }, /* 6220 1c->24 */
|
||||
{ ZD_CR117, 0xfa }, /* 6112 fa->f8 6220 f8->f4 6220 f4->fa */
|
||||
{ ZD_CR118, 0xf0 }, /* 5d07 6112 f0->f2 6220 f2->f0 */
|
||||
{ ZD_CR119, 0x1a }, /* 6112 1a->10 6220 10->14 6220 14->1a */
|
||||
{ ZD_CR120, 0x4f },
|
||||
{ ZD_CR121, 0x1f }, /* 6220 4f->1f */
|
||||
{ ZD_CR122, 0xf0 }, { ZD_CR123, 0x57 }, { ZD_CR125, 0xad },
|
||||
{ ZD_CR126, 0x6c }, { ZD_CR127, 0x03 },
|
||||
{ ZD_CR128, 0x14 }, /* 6302 12->11 */
|
||||
{ ZD_CR129, 0x12 }, /* 6301 10->0f */
|
||||
{ ZD_CR130, 0x10 }, { ZD_CR137, 0x50 }, { ZD_CR138, 0xa8 },
|
||||
{ ZD_CR144, 0xac }, { ZD_CR146, 0x20 }, { ZD_CR252, 0xff },
|
||||
{ ZD_CR253, 0xff },
|
||||
};
|
||||
|
||||
static const u32 rv[] = {
|
||||
UW2453_REGWRITE(4, 0x2b), /* configure receiver gain */
|
||||
UW2453_REGWRITE(5, 0x19e4f), /* configure transmitter gain */
|
||||
UW2453_REGWRITE(6, 0xf81ad), /* enable RX/TX filter tuning */
|
||||
UW2453_REGWRITE(7, 0x3fffe), /* disable TX gain in test mode */
|
||||
|
||||
/* enter CAL_FIL mode, TX gain set by registers, RX gain set by pins,
|
||||
* RSSI circuit powered down, reduced RSSI range */
|
||||
UW2453_REGWRITE(0, 0x25f9c), /* 5d01 cal_fil */
|
||||
|
||||
/* synthesizer configuration for channel 1 */
|
||||
UW2453_REGWRITE(1, 0x47),
|
||||
UW2453_REGWRITE(2, 0x999),
|
||||
|
||||
/* disable manual VCO band selection */
|
||||
UW2453_REGWRITE(3, 0x7602),
|
||||
|
||||
/* enable manual VCO band selection, configure current level */
|
||||
UW2453_REGWRITE(3, 0x46063),
|
||||
};
|
||||
|
||||
r = zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
r = zd_rfwritev_locked(chip, rv, ARRAY_SIZE(rv), RF_RV_BITS);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
r = uw2453_init_mode(chip);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
/* Try all standard VCO configuration settings on channel 1 */
|
||||
for (i = 0; i < ARRAY_SIZE(uw2453_std_vco_cfg) - 1; i++) {
|
||||
/* Configure synthesizer for channel 1 */
|
||||
r = uw2453_synth_set_channel(chip, 1, false);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
/* Write VCO config */
|
||||
r = uw2453_write_vco_cfg(chip, uw2453_std_vco_cfg[i][0]);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
/* ack interrupt event */
|
||||
r = zd_iowrite16_locked(chip, 0x0f, UW2453_INTR_REG);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
/* check interrupt status */
|
||||
r = zd_ioread16_locked(chip, &intr_status, UW2453_INTR_REG);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
if (!(intr_status & 0xf)) {
|
||||
dev_dbg_f(zd_chip_dev(chip),
|
||||
"PLL locked on configuration %d\n", i);
|
||||
found_config = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (found_config == -1) {
|
||||
/* autocal */
|
||||
dev_dbg_f(zd_chip_dev(chip),
|
||||
"PLL did not lock, using autocal\n");
|
||||
|
||||
r = uw2453_synth_set_channel(chip, 1, true);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
r = uw2453_write_vco_cfg(chip, UW2453_AUTOCAL_VCO_CFG);
|
||||
if (r)
|
||||
return r;
|
||||
}
|
||||
|
||||
/* To match the vendor driver behaviour, we use the configuration after
|
||||
* the one that produced a lock. */
|
||||
UW2453_PRIV(rf)->config = found_config + 1;
|
||||
|
||||
return zd_iowrite16_locked(chip, 0x06, ZD_CR203);
|
||||
}
|
||||
|
||||
static int uw2453_set_channel(struct zd_rf *rf, u8 channel)
|
||||
{
|
||||
int r;
|
||||
u16 vco_cfg;
|
||||
int config = UW2453_PRIV(rf)->config;
|
||||
bool autocal = (config == -1);
|
||||
struct zd_chip *chip = zd_rf_to_chip(rf);
|
||||
|
||||
static const struct zd_ioreq16 ioreqs[] = {
|
||||
{ ZD_CR80, 0x30 }, { ZD_CR81, 0x30 }, { ZD_CR79, 0x58 },
|
||||
{ ZD_CR12, 0xf0 }, { ZD_CR77, 0x1b }, { ZD_CR78, 0x58 },
|
||||
};
|
||||
|
||||
r = uw2453_synth_set_channel(chip, channel, autocal);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
if (autocal)
|
||||
vco_cfg = UW2453_AUTOCAL_VCO_CFG;
|
||||
else
|
||||
vco_cfg = uw2453_std_vco_cfg[config][CHAN_TO_PAIRIDX(channel)];
|
||||
|
||||
r = uw2453_write_vco_cfg(chip, vco_cfg);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
r = uw2453_init_mode(chip);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
r = zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
r = uw2453_set_tx_gain_level(chip, channel);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
return zd_iowrite16_locked(chip, 0x06, ZD_CR203);
|
||||
}
|
||||
|
||||
static int uw2453_switch_radio_on(struct zd_rf *rf)
|
||||
{
|
||||
int r;
|
||||
struct zd_chip *chip = zd_rf_to_chip(rf);
|
||||
struct zd_ioreq16 ioreqs[] = {
|
||||
{ ZD_CR11, 0x00 }, { ZD_CR251, 0x3f },
|
||||
};
|
||||
|
||||
/* enter RXTX mode */
|
||||
r = zd_rfwrite_locked(chip, UW2453_REGWRITE(0, 0x25f94), RF_RV_BITS);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
if (zd_chip_is_zd1211b(chip))
|
||||
ioreqs[1].value = 0x7f;
|
||||
|
||||
return zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
|
||||
}
|
||||
|
||||
static int uw2453_switch_radio_off(struct zd_rf *rf)
|
||||
{
|
||||
int r;
|
||||
struct zd_chip *chip = zd_rf_to_chip(rf);
|
||||
static const struct zd_ioreq16 ioreqs[] = {
|
||||
{ ZD_CR11, 0x04 }, { ZD_CR251, 0x2f },
|
||||
};
|
||||
|
||||
/* enter IDLE mode */
|
||||
/* FIXME: shouldn't we go to SLEEP? sent email to zydas */
|
||||
r = zd_rfwrite_locked(chip, UW2453_REGWRITE(0, 0x25f90), RF_RV_BITS);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
return zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
|
||||
}
|
||||
|
||||
static void uw2453_clear(struct zd_rf *rf)
|
||||
{
|
||||
kfree(rf->priv);
|
||||
}
|
||||
|
||||
int zd_rf_init_uw2453(struct zd_rf *rf)
|
||||
{
|
||||
rf->init_hw = uw2453_init_hw;
|
||||
rf->set_channel = uw2453_set_channel;
|
||||
rf->switch_radio_on = uw2453_switch_radio_on;
|
||||
rf->switch_radio_off = uw2453_switch_radio_off;
|
||||
rf->patch_6m_band_edge = zd_rf_generic_patch_6m;
|
||||
rf->clear = uw2453_clear;
|
||||
/* we have our own TX integration code */
|
||||
rf->update_channel_int = 0;
|
||||
|
||||
rf->priv = kmalloc(sizeof(struct uw2453_priv), GFP_KERNEL);
|
||||
if (rf->priv == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
2060
drivers/net/wireless/zd1211rw/zd_usb.c
Normal file
2060
drivers/net/wireless/zd1211rw/zd_usb.c
Normal file
File diff suppressed because it is too large
Load diff
292
drivers/net/wireless/zd1211rw/zd_usb.h
Normal file
292
drivers/net/wireless/zd1211rw/zd_usb.h
Normal file
|
|
@ -0,0 +1,292 @@
|
|||
/* ZD1211 USB-WLAN driver for Linux
|
||||
*
|
||||
* Copyright (C) 2005-2007 Ulrich Kunitz <kune@deine-taler.de>
|
||||
* Copyright (C) 2006-2007 Daniel Drake <dsd@gentoo.org>
|
||||
*
|
||||
* 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _ZD_USB_H
|
||||
#define _ZD_USB_H
|
||||
|
||||
#include <linux/completion.h>
|
||||
#include <linux/netdevice.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/skbuff.h>
|
||||
#include <linux/usb.h>
|
||||
|
||||
#include "zd_def.h"
|
||||
|
||||
#define ZD_USB_TX_HIGH 5
|
||||
#define ZD_USB_TX_LOW 2
|
||||
|
||||
#define ZD_TX_TIMEOUT (HZ * 5)
|
||||
#define ZD_TX_WATCHDOG_INTERVAL round_jiffies_relative(HZ)
|
||||
#define ZD_RX_IDLE_INTERVAL round_jiffies_relative(30 * HZ)
|
||||
|
||||
enum devicetype {
|
||||
DEVICE_ZD1211 = 0,
|
||||
DEVICE_ZD1211B = 1,
|
||||
DEVICE_INSTALLER = 2,
|
||||
};
|
||||
|
||||
enum endpoints {
|
||||
EP_CTRL = 0,
|
||||
EP_DATA_OUT = 1,
|
||||
EP_DATA_IN = 2,
|
||||
EP_INT_IN = 3,
|
||||
EP_REGS_OUT = 4,
|
||||
};
|
||||
|
||||
enum {
|
||||
USB_MAX_TRANSFER_SIZE = 4096, /* bytes */
|
||||
/* FIXME: The original driver uses this value. We have to check,
|
||||
* whether the MAX_TRANSFER_SIZE is sufficient and this needs only be
|
||||
* used if one combined frame is split over two USB transactions.
|
||||
*/
|
||||
USB_MAX_RX_SIZE = 4800, /* bytes */
|
||||
USB_MAX_IOWRITE16_COUNT = 15,
|
||||
USB_MAX_IOWRITE32_COUNT = USB_MAX_IOWRITE16_COUNT/2,
|
||||
USB_MAX_IOREAD16_COUNT = 15,
|
||||
USB_MAX_IOREAD32_COUNT = USB_MAX_IOREAD16_COUNT/2,
|
||||
USB_MIN_RFWRITE_BIT_COUNT = 16,
|
||||
USB_MAX_RFWRITE_BIT_COUNT = 28,
|
||||
USB_MAX_EP_INT_BUFFER = 64,
|
||||
USB_ZD1211B_BCD_DEVICE = 0x4810,
|
||||
};
|
||||
|
||||
enum control_requests {
|
||||
USB_REQ_WRITE_REGS = 0x21,
|
||||
USB_REQ_READ_REGS = 0x22,
|
||||
USB_REQ_WRITE_RF = 0x23,
|
||||
USB_REQ_PROG_FLASH = 0x24,
|
||||
USB_REQ_EEPROM_START = 0x0128, /* ? request is a byte */
|
||||
USB_REQ_EEPROM_MID = 0x28,
|
||||
USB_REQ_EEPROM_END = 0x0228, /* ? request is a byte */
|
||||
USB_REQ_FIRMWARE_DOWNLOAD = 0x30,
|
||||
USB_REQ_FIRMWARE_CONFIRM = 0x31,
|
||||
USB_REQ_FIRMWARE_READ_DATA = 0x32,
|
||||
};
|
||||
|
||||
struct usb_req_read_regs {
|
||||
__le16 id;
|
||||
__le16 addr[0];
|
||||
} __packed;
|
||||
|
||||
struct reg_data {
|
||||
__le16 addr;
|
||||
__le16 value;
|
||||
} __packed;
|
||||
|
||||
struct usb_req_write_regs {
|
||||
__le16 id;
|
||||
struct reg_data reg_writes[0];
|
||||
} __packed;
|
||||
|
||||
enum {
|
||||
RF_IF_LE = 0x02,
|
||||
RF_CLK = 0x04,
|
||||
RF_DATA = 0x08,
|
||||
};
|
||||
|
||||
struct usb_req_rfwrite {
|
||||
__le16 id;
|
||||
__le16 value;
|
||||
/* 1: 3683a */
|
||||
/* 2: other (default) */
|
||||
__le16 bits;
|
||||
/* RF2595: 24 */
|
||||
__le16 bit_values[0];
|
||||
/* (ZD_CR203 & ~(RF_IF_LE | RF_CLK | RF_DATA)) | (bit ? RF_DATA : 0) */
|
||||
} __packed;
|
||||
|
||||
/* USB interrupt */
|
||||
|
||||
enum usb_int_id {
|
||||
USB_INT_TYPE = 0x01,
|
||||
USB_INT_ID_REGS = 0x90,
|
||||
USB_INT_ID_RETRY_FAILED = 0xa0,
|
||||
};
|
||||
|
||||
enum usb_int_flags {
|
||||
USB_INT_READ_REGS_EN = 0x01,
|
||||
};
|
||||
|
||||
struct usb_int_header {
|
||||
u8 type; /* must always be 1 */
|
||||
u8 id;
|
||||
} __packed;
|
||||
|
||||
struct usb_int_regs {
|
||||
struct usb_int_header hdr;
|
||||
struct reg_data regs[0];
|
||||
} __packed;
|
||||
|
||||
struct usb_int_retry_fail {
|
||||
struct usb_int_header hdr;
|
||||
u8 new_rate;
|
||||
u8 _dummy;
|
||||
u8 addr[ETH_ALEN];
|
||||
u8 ibss_wakeup_dest;
|
||||
} __packed;
|
||||
|
||||
struct read_regs_int {
|
||||
struct completion completion;
|
||||
struct usb_req_read_regs *req;
|
||||
unsigned int req_count;
|
||||
/* Stores the USB int structure and contains the USB address of the
|
||||
* first requested register before request.
|
||||
*/
|
||||
u8 buffer[USB_MAX_EP_INT_BUFFER];
|
||||
int length;
|
||||
__le16 cr_int_addr;
|
||||
};
|
||||
|
||||
struct zd_ioreq16 {
|
||||
zd_addr_t addr;
|
||||
u16 value;
|
||||
};
|
||||
|
||||
struct zd_ioreq32 {
|
||||
zd_addr_t addr;
|
||||
u32 value;
|
||||
};
|
||||
|
||||
struct zd_usb_interrupt {
|
||||
struct read_regs_int read_regs;
|
||||
spinlock_t lock;
|
||||
struct urb *urb;
|
||||
void *buffer;
|
||||
dma_addr_t buffer_dma;
|
||||
int interval;
|
||||
atomic_t read_regs_enabled;
|
||||
u8 read_regs_int_overridden:1;
|
||||
};
|
||||
|
||||
static inline struct usb_int_regs *get_read_regs(struct zd_usb_interrupt *intr)
|
||||
{
|
||||
return (struct usb_int_regs *)intr->read_regs.buffer;
|
||||
}
|
||||
|
||||
#define RX_URBS_COUNT 5
|
||||
|
||||
struct zd_usb_rx {
|
||||
spinlock_t lock;
|
||||
struct mutex setup_mutex;
|
||||
struct delayed_work idle_work;
|
||||
struct tasklet_struct reset_timer_tasklet;
|
||||
u8 fragment[2 * USB_MAX_RX_SIZE];
|
||||
unsigned int fragment_length;
|
||||
unsigned int usb_packet_size;
|
||||
struct urb **urbs;
|
||||
int urbs_count;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct zd_usb_tx - structure used for transmitting frames
|
||||
* @enabled: atomic enabled flag, indicates whether tx is enabled
|
||||
* @lock: lock for transmission
|
||||
* @submitted: anchor for URBs sent to device
|
||||
* @submitted_urbs: atomic integer that counts the URBs having sent to the
|
||||
* device, which haven't been completed
|
||||
* @stopped: indicates whether higher level tx queues are stopped
|
||||
*/
|
||||
struct zd_usb_tx {
|
||||
atomic_t enabled;
|
||||
spinlock_t lock;
|
||||
struct delayed_work watchdog_work;
|
||||
struct sk_buff_head submitted_skbs;
|
||||
struct usb_anchor submitted;
|
||||
int submitted_urbs;
|
||||
u8 stopped:1, watchdog_enabled:1;
|
||||
};
|
||||
|
||||
/* Contains the usb parts. The structure doesn't require a lock because intf
|
||||
* will not be changed after initialization.
|
||||
*/
|
||||
struct zd_usb {
|
||||
struct zd_usb_interrupt intr;
|
||||
struct zd_usb_rx rx;
|
||||
struct zd_usb_tx tx;
|
||||
struct usb_interface *intf;
|
||||
struct usb_anchor submitted_cmds;
|
||||
struct urb *urb_async_waiting;
|
||||
int cmd_error;
|
||||
u8 req_buf[64]; /* zd_usb_iowrite16v needs 62 bytes */
|
||||
u8 is_zd1211b:1, initialized:1, was_running:1, in_async:1;
|
||||
};
|
||||
|
||||
#define zd_usb_dev(usb) (&usb->intf->dev)
|
||||
|
||||
static inline struct usb_device *zd_usb_to_usbdev(struct zd_usb *usb)
|
||||
{
|
||||
return interface_to_usbdev(usb->intf);
|
||||
}
|
||||
|
||||
static inline struct ieee80211_hw *zd_intf_to_hw(struct usb_interface *intf)
|
||||
{
|
||||
return usb_get_intfdata(intf);
|
||||
}
|
||||
|
||||
static inline struct ieee80211_hw *zd_usb_to_hw(struct zd_usb *usb)
|
||||
{
|
||||
return zd_intf_to_hw(usb->intf);
|
||||
}
|
||||
|
||||
void zd_usb_init(struct zd_usb *usb, struct ieee80211_hw *hw,
|
||||
struct usb_interface *intf);
|
||||
int zd_usb_init_hw(struct zd_usb *usb);
|
||||
void zd_usb_clear(struct zd_usb *usb);
|
||||
|
||||
int zd_usb_scnprint_id(struct zd_usb *usb, char *buffer, size_t size);
|
||||
|
||||
void zd_tx_watchdog_enable(struct zd_usb *usb);
|
||||
void zd_tx_watchdog_disable(struct zd_usb *usb);
|
||||
|
||||
int zd_usb_enable_int(struct zd_usb *usb);
|
||||
void zd_usb_disable_int(struct zd_usb *usb);
|
||||
|
||||
int zd_usb_enable_rx(struct zd_usb *usb);
|
||||
void zd_usb_disable_rx(struct zd_usb *usb);
|
||||
|
||||
void zd_usb_reset_rx_idle_timer(struct zd_usb *usb);
|
||||
|
||||
void zd_usb_enable_tx(struct zd_usb *usb);
|
||||
void zd_usb_disable_tx(struct zd_usb *usb);
|
||||
|
||||
int zd_usb_tx(struct zd_usb *usb, struct sk_buff *skb);
|
||||
|
||||
int zd_usb_ioread16v(struct zd_usb *usb, u16 *values,
|
||||
const zd_addr_t *addresses, unsigned int count);
|
||||
|
||||
static inline int zd_usb_ioread16(struct zd_usb *usb, u16 *value,
|
||||
const zd_addr_t addr)
|
||||
{
|
||||
return zd_usb_ioread16v(usb, value, &addr, 1);
|
||||
}
|
||||
|
||||
void zd_usb_iowrite16v_async_start(struct zd_usb *usb);
|
||||
int zd_usb_iowrite16v_async_end(struct zd_usb *usb, unsigned int timeout);
|
||||
int zd_usb_iowrite16v_async(struct zd_usb *usb, const struct zd_ioreq16 *ioreqs,
|
||||
unsigned int count);
|
||||
int zd_usb_iowrite16v(struct zd_usb *usb, const struct zd_ioreq16 *ioreqs,
|
||||
unsigned int count);
|
||||
|
||||
int zd_usb_rfwrite(struct zd_usb *usb, u32 value, u8 bits);
|
||||
|
||||
int zd_usb_read_fw(struct zd_usb *usb, zd_addr_t addr, u8 *data, u16 len);
|
||||
|
||||
extern struct workqueue_struct *zd_workqueue;
|
||||
|
||||
#endif /* _ZD_USB_H */
|
||||
Loading…
Add table
Add a link
Reference in a new issue