Skip to content

Commit

Permalink
zd1211rw: port to mac80211
Browse files Browse the repository at this point in the history
This seems to be working smoothly now. Let's not hold back the mac80211
transition any further. This patch ports the existing driver from softmac
to mac80211.

Many thanks to everyone who helped out with the porting efforts.

Signed-off-by: Daniel Drake <dsd@gentoo.org>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
  • Loading branch information
Daniel Drake authored and David S. Miller committed Jan 28, 2008
1 parent 0765af4 commit 459c51a
Show file tree
Hide file tree
Showing 12 changed files with 1,008 additions and 1,668 deletions.
7 changes: 3 additions & 4 deletions drivers/net/wireless/zd1211rw/Kconfig
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
config ZD1211RW
tristate "ZyDAS ZD1211/ZD1211B USB-wireless support"
depends on USB && IEEE80211_SOFTMAC && WLAN_80211 && EXPERIMENTAL
select WIRELESS_EXT
depends on USB && MAC80211 && WLAN_80211 && EXPERIMENTAL
select FW_LOADER
---help---
This is an experimental 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://zd1211.ath.cx/get-firmware
Device firmware is required alongside this driver. You can download
the firmware distribution from http://zd1211.ath.cx/get-firmware

config ZD1211RW_DEBUG
bool "ZyDAS ZD1211 debugging"
Expand Down
3 changes: 1 addition & 2 deletions drivers/net/wireless/zd1211rw/Makefile
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
obj-$(CONFIG_ZD1211RW) += zd1211rw.o

zd1211rw-objs := zd_chip.o zd_ieee80211.o \
zd_mac.o zd_netdev.o \
zd1211rw-objs := zd_chip.o zd_ieee80211.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
Expand Down
121 changes: 56 additions & 65 deletions drivers/net/wireless/zd1211rw/zd_chip.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,12 @@
#include "zd_rf.h"

void zd_chip_init(struct zd_chip *chip,
struct net_device *netdev,
struct ieee80211_hw *hw,
struct usb_interface *intf)
{
memset(chip, 0, sizeof(*chip));
mutex_init(&chip->mutex);
zd_usb_init(&chip->usb, netdev, intf);
zd_usb_init(&chip->usb, hw, intf);
zd_rf_init(&chip->rf);
}

Expand All @@ -50,7 +50,7 @@ void zd_chip_clear(struct zd_chip *chip)

static int scnprint_mac_oui(struct zd_chip *chip, char *buffer, size_t size)
{
u8 *addr = zd_usb_to_netdev(&chip->usb)->dev_addr;
u8 *addr = zd_mac_get_perm_addr(zd_chip_to_mac(chip));
return scnprintf(buffer, size, "%02x-%02x-%02x",
addr[0], addr[1], addr[2]);
}
Expand Down Expand Up @@ -378,15 +378,18 @@ int zd_write_mac_addr(struct zd_chip *chip, const u8 *mac_addr)
};
DECLARE_MAC_BUF(mac);

reqs[0].value = (mac_addr[3] << 24)
| (mac_addr[2] << 16)
| (mac_addr[1] << 8)
| mac_addr[0];
reqs[1].value = (mac_addr[5] << 8)
| mac_addr[4];

dev_dbg_f(zd_chip_dev(chip),
"mac addr %s\n", print_mac(mac, mac_addr));
if (mac_addr) {
reqs[0].value = (mac_addr[3] << 24)
| (mac_addr[2] << 16)
| (mac_addr[1] << 8)
| mac_addr[0];
reqs[1].value = (mac_addr[5] << 8)
| mac_addr[4];
dev_dbg_f(zd_chip_dev(chip),
"mac addr %s\n", print_mac(mac, mac_addr));
} else {
dev_dbg_f(zd_chip_dev(chip), "set NULL mac\n");
}

mutex_lock(&chip->mutex);
r = zd_iowrite32a_locked(chip, reqs, ARRAY_SIZE(reqs));
Expand Down Expand Up @@ -980,19 +983,19 @@ static int print_fw_version(struct zd_chip *chip)
return 0;
}

static int set_mandatory_rates(struct zd_chip *chip, enum ieee80211_std std)
static int set_mandatory_rates(struct zd_chip *chip, int mode)
{
u32 rates;
ZD_ASSERT(mutex_is_locked(&chip->mutex));
/* This sets the mandatory rates, which only depend from the standard
* that the device is supporting. Until further notice we should try
* to support 802.11g also for full speed USB.
*/
switch (std) {
case IEEE80211B:
switch (mode) {
case MODE_IEEE80211B:
rates = CR_RATE_1M|CR_RATE_2M|CR_RATE_5_5M|CR_RATE_11M;
break;
case IEEE80211G:
case MODE_IEEE80211G:
rates = CR_RATE_1M|CR_RATE_2M|CR_RATE_5_5M|CR_RATE_11M|
CR_RATE_6M|CR_RATE_12M|CR_RATE_24M;
break;
Expand All @@ -1003,24 +1006,17 @@ static int set_mandatory_rates(struct zd_chip *chip, enum ieee80211_std std)
}

int zd_chip_set_rts_cts_rate_locked(struct zd_chip *chip,
u8 rts_rate, int preamble)
int preamble)
{
int rts_mod = ZD_RX_CCK;
u32 value = 0;

/* Modulation bit */
if (ZD_MODULATION_TYPE(rts_rate) == ZD_OFDM)
rts_mod = ZD_RX_OFDM;

dev_dbg_f(zd_chip_dev(chip), "rts_rate=%x preamble=%x\n",
rts_rate, preamble);

value |= ZD_PURE_RATE(rts_rate) << RTSCTS_SH_RTS_RATE;
value |= rts_mod << RTSCTS_SH_RTS_MOD_TYPE;
dev_dbg_f(zd_chip_dev(chip), "preamble=%x\n", preamble);
value |= preamble << RTSCTS_SH_RTS_PMB_TYPE;
value |= preamble << RTSCTS_SH_CTS_PMB_TYPE;

/* We always send 11M self-CTS messages, like the vendor driver. */
/* We always send 11M RTS/self-CTS messages, like the vendor driver. */
value |= ZD_PURE_RATE(ZD_CCK_RATE_11M) << RTSCTS_SH_RTS_RATE;
value |= ZD_RX_CCK << RTSCTS_SH_RTS_MOD_TYPE;
value |= ZD_PURE_RATE(ZD_CCK_RATE_11M) << RTSCTS_SH_CTS_RATE;
value |= ZD_RX_CCK << RTSCTS_SH_CTS_MOD_TYPE;

Expand Down Expand Up @@ -1109,7 +1105,7 @@ int zd_chip_init_hw(struct zd_chip *chip)
* It might be discussed, whether we should suppport pure b mode for
* full speed USB.
*/
r = set_mandatory_rates(chip, IEEE80211G);
r = set_mandatory_rates(chip, MODE_IEEE80211G);
if (r)
goto out;
/* Disabling interrupts is certainly a smart thing here.
Expand Down Expand Up @@ -1320,12 +1316,17 @@ int zd_chip_control_leds(struct zd_chip *chip, enum led_status status)
return r;
}

int zd_chip_set_basic_rates_locked(struct zd_chip *chip, u16 cr_rates)
int zd_chip_set_basic_rates(struct zd_chip *chip, u16 cr_rates)
{
ZD_ASSERT((cr_rates & ~(CR_RATES_80211B | CR_RATES_80211G)) == 0);
dev_dbg_f(zd_chip_dev(chip), "%x\n", cr_rates);
int r;

if (cr_rates & ~(CR_RATES_80211B|CR_RATES_80211G))
return -EINVAL;

return zd_iowrite32_locked(chip, cr_rates, CR_BASIC_RATE_TBL);
mutex_lock(&chip->mutex);
r = zd_iowrite32_locked(chip, cr_rates, CR_BASIC_RATE_TBL);
mutex_unlock(&chip->mutex);
return r;
}

static int ofdm_qual_db(u8 status_quality, u8 zd_rate, unsigned int size)
Expand Down Expand Up @@ -1468,56 +1469,44 @@ u8 zd_rx_qual_percent(const void *rx_frame, unsigned int size,
{
return (status->frame_status&ZD_RX_OFDM) ?
ofdm_qual_percent(status->signal_quality_ofdm,
zd_rate_from_ofdm_plcp_header(rx_frame),
zd_rate_from_ofdm_plcp_header(rx_frame),
size) :
cck_qual_percent(status->signal_quality_cck);
}

u8 zd_rx_strength_percent(u8 rssi)
{
int r = (rssi*100) / 41;
if (r > 100)
r = 100;
return (u8) r;
}

u16 zd_rx_rate(const void *rx_frame, const struct rx_status *status)
/**
* zd_rx_rate - report zd-rate
* @rx_frame - received frame
* @rx_status - rx_status as given by the device
*
* This function converts the rate as encoded in the received packet to the
* zd-rate, we are using on other places in the driver.
*/
u8 zd_rx_rate(const void *rx_frame, const struct rx_status *status)
{
static const u16 ofdm_rates[] = {
[ZD_OFDM_PLCP_RATE_6M] = 60,
[ZD_OFDM_PLCP_RATE_9M] = 90,
[ZD_OFDM_PLCP_RATE_12M] = 120,
[ZD_OFDM_PLCP_RATE_18M] = 180,
[ZD_OFDM_PLCP_RATE_24M] = 240,
[ZD_OFDM_PLCP_RATE_36M] = 360,
[ZD_OFDM_PLCP_RATE_48M] = 480,
[ZD_OFDM_PLCP_RATE_54M] = 540,
};
u16 rate;
u8 zd_rate;
if (status->frame_status & ZD_RX_OFDM) {
/* Deals with PLCP OFDM rate (not zd_rates) */
u8 ofdm_rate = zd_ofdm_plcp_header_rate(rx_frame);
rate = ofdm_rates[ofdm_rate & 0xf];
zd_rate = zd_rate_from_ofdm_plcp_header(rx_frame);
} else {
switch (zd_cck_plcp_header_signal(rx_frame)) {
case ZD_CCK_PLCP_SIGNAL_1M:
rate = 10;
zd_rate = ZD_CCK_RATE_1M;
break;
case ZD_CCK_PLCP_SIGNAL_2M:
rate = 20;
zd_rate = ZD_CCK_RATE_2M;
break;
case ZD_CCK_PLCP_SIGNAL_5M5:
rate = 55;
zd_rate = ZD_CCK_RATE_5_5M;
break;
case ZD_CCK_PLCP_SIGNAL_11M:
rate = 110;
zd_rate = ZD_CCK_RATE_11M;
break;
default:
rate = 0;
zd_rate = 0;
}
}

return rate;
return zd_rate;
}

int zd_chip_switch_radio_on(struct zd_chip *chip)
Expand Down Expand Up @@ -1557,20 +1546,22 @@ void zd_chip_disable_int(struct zd_chip *chip)
mutex_unlock(&chip->mutex);
}

int zd_chip_enable_rx(struct zd_chip *chip)
int zd_chip_enable_rxtx(struct zd_chip *chip)
{
int r;

mutex_lock(&chip->mutex);
zd_usb_enable_tx(&chip->usb);
r = zd_usb_enable_rx(&chip->usb);
mutex_unlock(&chip->mutex);
return r;
}

void zd_chip_disable_rx(struct zd_chip *chip)
void zd_chip_disable_rxtx(struct zd_chip *chip)
{
mutex_lock(&chip->mutex);
zd_usb_disable_rx(&chip->usb);
zd_usb_disable_tx(&chip->usb);
mutex_unlock(&chip->mutex);
}

Expand Down
55 changes: 33 additions & 22 deletions drivers/net/wireless/zd1211rw/zd_chip.h
Original file line number Diff line number Diff line change
Expand Up @@ -433,9 +433,10 @@ enum {
#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 */
* 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 */
Expand Down Expand Up @@ -509,14 +510,37 @@ enum {
#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 AP_RX_FILTER 0x0400feff
#define STA_RX_FILTER 0x0000ffff
#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)

/* Monitor mode sets filter to 0xfffff */

Expand Down Expand Up @@ -730,7 +754,7 @@ static inline struct zd_chip *zd_rf_to_chip(struct zd_rf *rf)
#define zd_chip_dev(chip) (&(chip)->usb.intf->dev)

void zd_chip_init(struct zd_chip *chip,
struct net_device *netdev,
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);
Expand Down Expand Up @@ -835,14 +859,12 @@ 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_rx(struct zd_chip *chip);
void zd_chip_disable_rx(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,
u8 rts_rate, int preamble);
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)
{
Expand All @@ -859,17 +881,7 @@ 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_locked(struct zd_chip *chip, u16 cr_rates);

static inline int zd_chip_set_basic_rates(struct zd_chip *chip, u16 cr_rates)
{
int r;

mutex_lock(&chip->mutex);
r = zd_chip_set_basic_rates_locked(chip, cr_rates);
mutex_unlock(&chip->mutex);
return r;
}
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);
Expand All @@ -893,9 +905,8 @@ struct rx_status;

u8 zd_rx_qual_percent(const void *rx_frame, unsigned int size,
const struct rx_status *status);
u8 zd_rx_strength_percent(u8 rssi);

u16 zd_rx_rate(const void *rx_frame, const struct rx_status *status);
u8 zd_rx_rate(const void *rx_frame, const struct rx_status *status);

struct zd_mc_hash {
u32 low;
Expand Down
Loading

0 comments on commit 459c51a

Please sign in to comment.