diff options
Diffstat (limited to 'drivers/net/wireless/zd1211rw')
-rw-r--r-- | drivers/net/wireless/zd1211rw/Makefile | 2 | ||||
-rw-r--r-- | drivers/net/wireless/zd1211rw/zd_chip.c | 75 | ||||
-rw-r--r-- | drivers/net/wireless/zd1211rw/zd_chip.h | 5 | ||||
-rw-r--r-- | drivers/net/wireless/zd1211rw/zd_def.h | 1 | ||||
-rw-r--r-- | drivers/net/wireless/zd1211rw/zd_ieee80211.h | 43 | ||||
-rw-r--r-- | drivers/net/wireless/zd1211rw/zd_mac.c | 155 | ||||
-rw-r--r-- | drivers/net/wireless/zd1211rw/zd_mac.h | 65 | ||||
-rw-r--r-- | drivers/net/wireless/zd1211rw/zd_netdev.c | 1 | ||||
-rw-r--r-- | drivers/net/wireless/zd1211rw/zd_usb.c | 5 | ||||
-rw-r--r-- | drivers/net/wireless/zd1211rw/zd_util.c | 82 | ||||
-rw-r--r-- | drivers/net/wireless/zd1211rw/zd_util.h | 29 |
11 files changed, 179 insertions, 284 deletions
diff --git a/drivers/net/wireless/zd1211rw/Makefile b/drivers/net/wireless/zd1211rw/Makefile index 4d505903352c..7a2f2a98edab 100644 --- a/drivers/net/wireless/zd1211rw/Makefile +++ b/drivers/net/wireless/zd1211rw/Makefile @@ -4,7 +4,7 @@ zd1211rw-objs := zd_chip.o zd_ieee80211.o \ zd_mac.o zd_netdev.o \ zd_rf_al2230.o zd_rf_rf2959.o \ zd_rf_al7230b.o zd_rf_uw2453.o \ - zd_rf.o zd_usb.o zd_util.o + zd_rf.o zd_usb.o ifeq ($(CONFIG_ZD1211RW_DEBUG),y) EXTRA_CFLAGS += -DDEBUG diff --git a/drivers/net/wireless/zd1211rw/zd_chip.c b/drivers/net/wireless/zd1211rw/zd_chip.c index c39f1984b84d..f831b68f1b9c 100644 --- a/drivers/net/wireless/zd1211rw/zd_chip.c +++ b/drivers/net/wireless/zd1211rw/zd_chip.c @@ -28,7 +28,6 @@ #include "zd_ieee80211.h" #include "zd_mac.h" #include "zd_rf.h" -#include "zd_util.h" void zd_chip_init(struct zd_chip *chip, struct net_device *netdev, @@ -106,7 +105,7 @@ int zd_ioread32v_locked(struct zd_chip *chip, u32 *values, const zd_addr_t *addr { int r; int i; - zd_addr_t *a16 = (zd_addr_t *)NULL; + zd_addr_t *a16; u16 *v16; unsigned int count16; @@ -377,6 +376,7 @@ int zd_write_mac_addr(struct zd_chip *chip, const u8 *mac_addr) [0] = { .addr = CR_MAC_ADDR_P1 }, [1] = { .addr = CR_MAC_ADDR_P2 }, }; + DECLARE_MAC_BUF(mac); reqs[0].value = (mac_addr[3] << 24) | (mac_addr[2] << 16) @@ -386,7 +386,7 @@ int zd_write_mac_addr(struct zd_chip *chip, const u8 *mac_addr) | mac_addr[4]; dev_dbg_f(zd_chip_dev(chip), - "mac addr " MAC_FMT "\n", MAC_ARG(mac_addr)); + "mac addr %s\n", print_mac(mac, mac_addr)); mutex_lock(&chip->mutex); r = zd_iowrite32a_locked(chip, reqs, ARRAY_SIZE(reqs)); @@ -500,8 +500,6 @@ int zd_chip_lock_phy_regs(struct zd_chip *chip) return r; } - dev_dbg_f(zd_chip_dev(chip), - "CR_REG1: 0x%02x -> 0x%02x\n", tmp, tmp & ~UNLOCK_PHY_REGS); tmp &= ~UNLOCK_PHY_REGS; r = zd_iowrite32_locked(chip, tmp, CR_REG1); @@ -523,8 +521,6 @@ int zd_chip_unlock_phy_regs(struct zd_chip *chip) return r; } - dev_dbg_f(zd_chip_dev(chip), - "CR_REG1: 0x%02x -> 0x%02x\n", tmp, tmp | UNLOCK_PHY_REGS); tmp |= UNLOCK_PHY_REGS; r = zd_iowrite32_locked(chip, tmp, CR_REG1); @@ -841,8 +837,6 @@ static int get_aw_pt_bi(struct zd_chip *chip, struct aw_pt_bi *s) s->atim_wnd_period = values[0]; s->pre_tbtt = values[1]; s->beacon_interval = values[2]; - dev_dbg_f(zd_chip_dev(chip), "aw %u pt %u bi %u\n", - s->atim_wnd_period, s->pre_tbtt, s->beacon_interval); return 0; } @@ -864,9 +858,6 @@ static int set_aw_pt_bi(struct zd_chip *chip, struct aw_pt_bi *s) reqs[2].addr = CR_BCN_INTERVAL; reqs[2].value = s->beacon_interval; - dev_dbg_f(zd_chip_dev(chip), - "aw %u pt %u bi %u\n", s->atim_wnd_period, s->pre_tbtt, - s->beacon_interval); return zd_iowrite32a_locked(chip, reqs, ARRAY_SIZE(reqs)); } @@ -1018,19 +1009,19 @@ int zd_chip_set_rts_cts_rate_locked(struct zd_chip *chip, u32 value = 0; /* Modulation bit */ - if (ZD_CS_TYPE(rts_rate) == ZD_CS_OFDM) + 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 |= rts_rate << RTSCTS_SH_RTS_RATE; + value |= ZD_PURE_RATE(rts_rate) << RTSCTS_SH_RTS_RATE; value |= rts_mod << RTSCTS_SH_RTS_MOD_TYPE; 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. */ - value |= ZD_CCK_RATE_11M << RTSCTS_SH_CTS_RATE; + value |= ZD_PURE_RATE(ZD_CCK_RATE_11M) << RTSCTS_SH_CTS_RATE; value |= ZD_RX_CCK << RTSCTS_SH_CTS_MOD_TYPE; return zd_iowrite32_locked(chip, value, CR_RTS_CTS_RATE); @@ -1160,16 +1151,12 @@ out: static int update_pwr_int(struct zd_chip *chip, u8 channel) { u8 value = chip->pwr_int_values[channel - 1]; - dev_dbg_f(zd_chip_dev(chip), "channel %d pwr_int %#04x\n", - channel, value); return zd_iowrite16_locked(chip, value, CR31); } static int update_pwr_cal(struct zd_chip *chip, u8 channel) { u8 value = chip->pwr_cal_values[channel-1]; - dev_dbg_f(zd_chip_dev(chip), "channel %d pwr_cal %#04x\n", - channel, value); return zd_iowrite16_locked(chip, value, CR68); } @@ -1184,9 +1171,6 @@ static int update_ofdm_cal(struct zd_chip *chip, u8 channel) ioreqs[2].addr = CR65; ioreqs[2].value = chip->ofdm_cal_values[OFDM_54M_INDEX][channel-1]; - dev_dbg_f(zd_chip_dev(chip), - "channel %d ofdm_cal 36M %#04x 48M %#04x 54M %#04x\n", - channel, ioreqs[0].value, ioreqs[1].value, ioreqs[2].value); return zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs)); } @@ -1344,7 +1328,7 @@ int zd_chip_set_basic_rates_locked(struct zd_chip *chip, u16 cr_rates) return zd_iowrite32_locked(chip, cr_rates, CR_BASIC_RATE_TBL); } -static int ofdm_qual_db(u8 status_quality, u8 rate, unsigned int size) +static int ofdm_qual_db(u8 status_quality, u8 zd_rate, unsigned int size) { static const u16 constants[] = { 715, 655, 585, 540, 470, 410, 360, 315, @@ -1358,7 +1342,7 @@ static int ofdm_qual_db(u8 status_quality, u8 rate, unsigned int size) /* It seems that their quality parameter is somehow per signal * and is now transferred per bit. */ - switch (rate) { + switch (zd_rate) { case ZD_OFDM_RATE_6M: case ZD_OFDM_RATE_12M: case ZD_OFDM_RATE_24M: @@ -1385,7 +1369,7 @@ static int ofdm_qual_db(u8 status_quality, u8 rate, unsigned int size) break; } - switch (rate) { + switch (zd_rate) { case ZD_OFDM_RATE_6M: case ZD_OFDM_RATE_9M: i += 3; @@ -1409,11 +1393,11 @@ static int ofdm_qual_db(u8 status_quality, u8 rate, unsigned int size) return i; } -static int ofdm_qual_percent(u8 status_quality, u8 rate, unsigned int size) +static int ofdm_qual_percent(u8 status_quality, u8 zd_rate, unsigned int size) { int r; - r = ofdm_qual_db(status_quality, rate, size); + r = ofdm_qual_db(status_quality, zd_rate, size); ZD_ASSERT(r >= 0); if (r < 0) r = 0; @@ -1474,12 +1458,17 @@ static int cck_qual_percent(u8 status_quality) return r <= 100 ? r : 100; } +static inline u8 zd_rate_from_ofdm_plcp_header(const void *rx_frame) +{ + return ZD_OFDM | zd_ofdm_plcp_header_rate(rx_frame); +} + u8 zd_rx_qual_percent(const void *rx_frame, unsigned int size, const struct rx_status *status) { return (status->frame_status&ZD_RX_OFDM) ? ofdm_qual_percent(status->signal_quality_ofdm, - zd_ofdm_plcp_header_rate(rx_frame), + zd_rate_from_ofdm_plcp_header(rx_frame), size) : cck_qual_percent(status->signal_quality_cck); } @@ -1495,32 +1484,32 @@ u8 zd_rx_strength_percent(u8 rssi) u16 zd_rx_rate(const void *rx_frame, const struct rx_status *status) { static const u16 ofdm_rates[] = { - [ZD_OFDM_RATE_6M] = 60, - [ZD_OFDM_RATE_9M] = 90, - [ZD_OFDM_RATE_12M] = 120, - [ZD_OFDM_RATE_18M] = 180, - [ZD_OFDM_RATE_24M] = 240, - [ZD_OFDM_RATE_36M] = 360, - [ZD_OFDM_RATE_48M] = 480, - [ZD_OFDM_RATE_54M] = 540, + [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; 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]; } else { - u8 cck_rate = zd_cck_plcp_header_rate(rx_frame); - switch (cck_rate) { - case ZD_CCK_SIGNAL_1M: + switch (zd_cck_plcp_header_signal(rx_frame)) { + case ZD_CCK_PLCP_SIGNAL_1M: rate = 10; break; - case ZD_CCK_SIGNAL_2M: + case ZD_CCK_PLCP_SIGNAL_2M: rate = 20; break; - case ZD_CCK_SIGNAL_5M5: + case ZD_CCK_PLCP_SIGNAL_5M5: rate = 55; break; - case ZD_CCK_SIGNAL_11M: + case ZD_CCK_PLCP_SIGNAL_11M: rate = 110; break; default: @@ -1638,7 +1627,5 @@ int zd_chip_set_multicast_hash(struct zd_chip *chip, { CR_GROUP_HASH_P2, hash->high }, }; - dev_dbg_f(zd_chip_dev(chip), "hash l 0x%08x h 0x%08x\n", - ioreqs[0].value, ioreqs[1].value); return zd_iowrite32a(chip, ioreqs, ARRAY_SIZE(ioreqs)); } diff --git a/drivers/net/wireless/zd1211rw/zd_chip.h b/drivers/net/wireless/zd1211rw/zd_chip.h index f4698576ab71..8009b70213e2 100644 --- a/drivers/net/wireless/zd1211rw/zd_chip.h +++ b/drivers/net/wireless/zd1211rw/zd_chip.h @@ -871,11 +871,6 @@ static inline int zd_chip_set_basic_rates(struct zd_chip *chip, u16 cr_rates) return r; } -static inline int zd_chip_set_rx_filter(struct zd_chip *chip, u32 filter) -{ - return zd_iowrite32(chip, CR_RX_FILTER, filter); -} - int zd_chip_lock_phy_regs(struct zd_chip *chip); int zd_chip_unlock_phy_regs(struct zd_chip *chip); diff --git a/drivers/net/wireless/zd1211rw/zd_def.h b/drivers/net/wireless/zd1211rw/zd_def.h index deb99d1eaa77..505b4d7dd0e2 100644 --- a/drivers/net/wireless/zd1211rw/zd_def.h +++ b/drivers/net/wireless/zd1211rw/zd_def.h @@ -21,7 +21,6 @@ #include <linux/kernel.h> #include <linux/stringify.h> #include <linux/device.h> -#include <linux/kernel.h> typedef u16 __nocast zd_addr_t; diff --git a/drivers/net/wireless/zd1211rw/zd_ieee80211.h b/drivers/net/wireless/zd1211rw/zd_ieee80211.h index c4f36d39642b..fbf6491dce7e 100644 --- a/drivers/net/wireless/zd1211rw/zd_ieee80211.h +++ b/drivers/net/wireless/zd1211rw/zd_ieee80211.h @@ -43,21 +43,25 @@ struct ofdm_plcp_header { __le16 service; } __attribute__((packed)); -static inline u8 zd_ofdm_plcp_header_rate( - const struct ofdm_plcp_header *header) +static inline u8 zd_ofdm_plcp_header_rate(const struct ofdm_plcp_header *header) { return header->prefix[0] & 0xf; } -/* These are referred to as zd_rates */ -#define ZD_OFDM_RATE_6M 0xb -#define ZD_OFDM_RATE_9M 0xf -#define ZD_OFDM_RATE_12M 0xa -#define ZD_OFDM_RATE_18M 0xe -#define ZD_OFDM_RATE_24M 0x9 -#define ZD_OFDM_RATE_36M 0xd -#define ZD_OFDM_RATE_48M 0x8 -#define ZD_OFDM_RATE_54M 0xc +/* 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; @@ -66,15 +70,22 @@ struct cck_plcp_header { __le16 crc16; } __attribute__((packed)); -static inline u8 zd_cck_plcp_header_rate(const struct cck_plcp_header *header) +static inline u8 zd_cck_plcp_header_signal(const struct cck_plcp_header *header) { return header->signal; } -#define ZD_CCK_SIGNAL_1M 0x0a -#define ZD_CCK_SIGNAL_2M 0x14 -#define ZD_CCK_SIGNAL_5M5 0x37 -#define ZD_CCK_SIGNAL_11M 0x6e +/* 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 enum ieee80211_std { IEEE80211B = 0x01, diff --git a/drivers/net/wireless/zd1211rw/zd_mac.c b/drivers/net/wireless/zd1211rw/zd_mac.c index 26869d107e52..a903645e157a 100644 --- a/drivers/net/wireless/zd1211rw/zd_mac.c +++ b/drivers/net/wireless/zd1211rw/zd_mac.c @@ -28,7 +28,6 @@ #include "zd_ieee80211.h" #include "zd_netdev.h" #include "zd_rf.h" -#include "zd_util.h" static void ieee_init(struct ieee80211_device *ieee); static void softmac_init(struct ieee80211softmac_device *sm); @@ -161,13 +160,33 @@ void zd_mac_clear(struct zd_mac *mac) ZD_MEMCLEAR(mac, sizeof(struct zd_mac)); } -static int reset_mode(struct zd_mac *mac) +static int set_rx_filter(struct zd_mac *mac) { struct ieee80211_device *ieee = zd_mac_to_ieee80211(mac); u32 filter = (ieee->iw_mode == IW_MODE_MONITOR) ? ~0 : STA_RX_FILTER; return zd_iowrite32(&mac->chip, CR_RX_FILTER, filter); } +static int set_sniffer(struct zd_mac *mac) +{ + struct ieee80211_device *ieee = zd_mac_to_ieee80211(mac); + return zd_iowrite32(&mac->chip, CR_SNIFFER_ON, + ieee->iw_mode == IW_MODE_MONITOR ? 1 : 0); + return 0; +} + +static int set_mc_hash(struct zd_mac *mac) +{ + struct zd_mc_hash hash; + struct ieee80211_device *ieee = zd_mac_to_ieee80211(mac); + + zd_mc_clear(&hash); + if (ieee->iw_mode == IW_MODE_MONITOR) + zd_mc_add_all(&hash); + + return zd_chip_set_multicast_hash(&mac->chip, &hash); +} + int zd_mac_open(struct net_device *netdev) { struct zd_mac *mac = zd_netdev_mac(netdev); @@ -194,7 +213,13 @@ int zd_mac_open(struct net_device *netdev) r = zd_chip_set_basic_rates(chip, CR_RATES_80211B | CR_RATES_80211G); if (r < 0) goto disable_int; - r = reset_mode(mac); + r = set_rx_filter(mac); + if (r) + goto disable_int; + r = set_sniffer(mac); + if (r) + goto disable_int; + r = set_mc_hash(mac); if (r) goto disable_int; r = zd_chip_switch_radio_on(chip); @@ -263,12 +288,13 @@ int zd_mac_set_mac_address(struct net_device *netdev, void *p) struct sockaddr *addr = p; struct zd_mac *mac = zd_netdev_mac(netdev); struct zd_chip *chip = &mac->chip; + DECLARE_MAC_BUF(mac2); if (!is_valid_ether_addr(addr->sa_data)) return -EADDRNOTAVAIL; dev_dbg_f(zd_mac_dev(mac), - "Setting MAC to " MAC_FMT "\n", MAC_ARG(addr->sa_data)); + "Setting MAC to %s\n", print_mac(mac2, addr->sa_data)); if (netdev->flags & IFF_UP) { r = zd_write_mac_addr(chip, addr->sa_data); @@ -298,18 +324,21 @@ static void set_multicast_hash_handler(struct work_struct *work) void zd_mac_set_multicast_list(struct net_device *dev) { - struct zd_mc_hash hash; struct zd_mac *mac = zd_netdev_mac(dev); + struct ieee80211_device *ieee = zd_mac_to_ieee80211(mac); + struct zd_mc_hash hash; struct dev_mc_list *mc; unsigned long flags; + DECLARE_MAC_BUF(mac2); - if (dev->flags & (IFF_PROMISC|IFF_ALLMULTI)) { + if (dev->flags & (IFF_PROMISC|IFF_ALLMULTI) || + ieee->iw_mode == IW_MODE_MONITOR) { zd_mc_add_all(&hash); } else { zd_mc_clear(&hash); for (mc = dev->mc_list; mc; mc = mc->next) { - dev_dbg_f(zd_mac_dev(mac), "mc addr " MAC_FMT "\n", - MAC_ARG(mc->dmi_addr)); + dev_dbg_f(zd_mac_dev(mac), "mc addr %s\n", + print_mac(mac2, mc->dmi_addr)); zd_mc_add_addr(&hash, mc->dmi_addr); } } @@ -582,28 +611,6 @@ u8 zd_mac_get_channel(struct zd_mac *mac) return channel; } -/* If wrong rate is given, we are falling back to the slowest rate: 1MBit/s */ -static u8 zd_rate_typed(u8 zd_rate) -{ - static const u8 typed_rates[16] = { - [ZD_CCK_RATE_1M] = ZD_CS_CCK|ZD_CCK_RATE_1M, - [ZD_CCK_RATE_2M] = ZD_CS_CCK|ZD_CCK_RATE_2M, - [ZD_CCK_RATE_5_5M] = ZD_CS_CCK|ZD_CCK_RATE_5_5M, - [ZD_CCK_RATE_11M] = ZD_CS_CCK|ZD_CCK_RATE_11M, - [ZD_OFDM_RATE_6M] = ZD_CS_OFDM|ZD_OFDM_RATE_6M, - [ZD_OFDM_RATE_9M] = ZD_CS_OFDM|ZD_OFDM_RATE_9M, - [ZD_OFDM_RATE_12M] = ZD_CS_OFDM|ZD_OFDM_RATE_12M, - [ZD_OFDM_RATE_18M] = ZD_CS_OFDM|ZD_OFDM_RATE_18M, - [ZD_OFDM_RATE_24M] = ZD_CS_OFDM|ZD_OFDM_RATE_24M, - [ZD_OFDM_RATE_36M] = ZD_CS_OFDM|ZD_OFDM_RATE_36M, - [ZD_OFDM_RATE_48M] = ZD_CS_OFDM|ZD_OFDM_RATE_48M, - [ZD_OFDM_RATE_54M] = ZD_CS_OFDM|ZD_OFDM_RATE_54M, - }; - - ZD_ASSERT(ZD_CS_RATE_MASK == 0x0f); - return typed_rates[zd_rate & ZD_CS_RATE_MASK]; -} - int zd_mac_set_mode(struct zd_mac *mac, u32 mode) { struct ieee80211_device *ieee; @@ -628,8 +635,12 @@ int zd_mac_set_mode(struct zd_mac *mac, u32 mode) ieee->iw_mode = mode; spin_unlock_irq(&ieee->lock); - if (netif_running(mac->netdev)) - return reset_mode(mac); + if (netif_running(mac->netdev)) { + int r = set_rx_filter(mac); + if (r) + return r; + return set_sniffer(mac); + } return 0; } @@ -707,25 +718,30 @@ int zd_mac_get_range(struct zd_mac *mac, struct iw_range *range) static int zd_calc_tx_length_us(u8 *service, u8 zd_rate, u16 tx_length) { + /* ZD_PURE_RATE() must be used to remove the modulation type flag of + * the zd-rate values. */ static const u8 rate_divisor[] = { - [ZD_CCK_RATE_1M] = 1, - [ZD_CCK_RATE_2M] = 2, - [ZD_CCK_RATE_5_5M] = 11, /* bits must be doubled */ - [ZD_CCK_RATE_11M] = 11, - [ZD_OFDM_RATE_6M] = 6, - [ZD_OFDM_RATE_9M] = 9, - [ZD_OFDM_RATE_12M] = 12, - [ZD_OFDM_RATE_18M] = 18, - [ZD_OFDM_RATE_24M] = 24, - [ZD_OFDM_RATE_36M] = 36, - [ZD_OFDM_RATE_48M] = 48, - [ZD_OFDM_RATE_54M] = 54, + [ZD_PURE_RATE(ZD_CCK_RATE_1M)] = 1, + [ZD_PURE_RATE(ZD_CCK_RATE_2M)] = 2, + + /* bits must be doubled */ + [ZD_PURE_RATE(ZD_CCK_RATE_5_5M)] = 11, + + [ZD_PURE_RATE(ZD_CCK_RATE_11M)] = 11, + [ZD_PURE_RATE(ZD_OFDM_RATE_6M)] = 6, + [ZD_PURE_RATE(ZD_OFDM_RATE_9M)] = 9, + [ZD_PURE_RATE(ZD_OFDM_RATE_12M)] = 12, + [ZD_PURE_RATE(ZD_OFDM_RATE_18M)] = 18, + [ZD_PURE_RATE(ZD_OFDM_RATE_24M)] = 24, + [ZD_PURE_RATE(ZD_OFDM_RATE_36M)] = 36, + [ZD_PURE_RATE(ZD_OFDM_RATE_48M)] = 48, + [ZD_PURE_RATE(ZD_OFDM_RATE_54M)] = 54, }; u32 bits = (u32)tx_length * 8; u32 divisor; - divisor = rate_divisor[zd_rate]; + divisor = rate_divisor[ZD_PURE_RATE(zd_rate)]; if (divisor == 0) return -EINVAL; @@ -748,52 +764,24 @@ static int zd_calc_tx_length_us(u8 *service, u8 zd_rate, u16 tx_length) return bits/divisor; } -enum { - R2M_SHORT_PREAMBLE = 0x01, - R2M_11A = 0x02, -}; - -static u8 zd_rate_to_modulation(u8 zd_rate, int flags) -{ - u8 modulation; - - modulation = zd_rate_typed(zd_rate); - if (flags & R2M_SHORT_PREAMBLE) { - switch (ZD_CS_RATE(modulation)) { - case ZD_CCK_RATE_2M: - case ZD_CCK_RATE_5_5M: - case ZD_CCK_RATE_11M: - modulation |= ZD_CS_CCK_PREA_SHORT; - return modulation; - } - } - if (flags & R2M_11A) { - if (ZD_CS_TYPE(modulation) == ZD_CS_OFDM) - modulation |= ZD_CS_OFDM_MODE_11A; - } - return modulation; -} - static void cs_set_modulation(struct zd_mac *mac, struct zd_ctrlset *cs, struct ieee80211_hdr_4addr *hdr) { struct ieee80211softmac_device *softmac = ieee80211_priv(mac->netdev); u16 ftype = WLAN_FC_GET_TYPE(le16_to_cpu(hdr->frame_ctl)); - u8 rate, zd_rate; + u8 rate; int is_mgt = (ftype == IEEE80211_FTYPE_MGMT) != 0; int is_multicast = is_multicast_ether_addr(hdr->addr1); int short_preamble = ieee80211softmac_short_preamble_ok(softmac, is_multicast, is_mgt); - int flags = 0; - /* FIXME: 802.11a? */ rate = ieee80211softmac_suggest_txrate(softmac, is_multicast, is_mgt); + cs->modulation = rate_to_zd_rate(rate); - if (short_preamble) - flags |= R2M_SHORT_PREAMBLE; - - zd_rate = rate_to_zd_rate(rate); - cs->modulation = zd_rate_to_modulation(zd_rate, flags); + /* Set short preamble bit when appropriate */ + if (short_preamble && ZD_MODULATION_TYPE(cs->modulation) == ZD_CCK + && cs->modulation != ZD_CCK_RATE_1M) + cs->modulation |= ZD_CCK_PREA_SHORT; } static void cs_set_control(struct zd_mac *mac, struct zd_ctrlset *cs, @@ -832,7 +820,7 @@ static void cs_set_control(struct zd_mac *mac, struct zd_ctrlset *cs, cs->control |= ZD_CS_RTS; /* Use CTS-to-self protection if required */ - if (ZD_CS_TYPE(cs->modulation) == ZD_CS_OFDM && + if (ZD_MODULATION_TYPE(cs->modulation) == ZD_OFDM && ieee80211softmac_protection_needed(softmac)) { /* FIXME: avoid sending RTS *and* self-CTS, is that correct? */ cs->control &= ~ZD_CS_RTS; @@ -893,7 +881,7 @@ static int fill_ctrlset(struct zd_mac *mac, * - see line 53 of zdinlinef.h */ cs->service = 0; - r = zd_calc_tx_length_us(&cs->service, ZD_CS_RATE(cs->modulation), + r = zd_calc_tx_length_us(&cs->service, ZD_RATE(cs->modulation), le16_to_cpu(cs->tx_length)); if (r < 0) return r; @@ -902,7 +890,7 @@ static int fill_ctrlset(struct zd_mac *mac, if (next_frag_len == 0) { cs->next_frame_length = 0; } else { - r = zd_calc_tx_length_us(NULL, ZD_CS_RATE(cs->modulation), + r = zd_calc_tx_length_us(NULL, ZD_RATE(cs->modulation), next_frag_len); if (r < 0) return r; @@ -1077,7 +1065,8 @@ static int fill_rx_stats(struct ieee80211_rx_stats *stats, { const struct rx_status *status; - *pstatus = status = zd_tail(buffer, length, sizeof(struct rx_status)); + *pstatus = status = (struct rx_status *) + (buffer + (length - sizeof(struct rx_status))); if (status->frame_status & ZD_RX_ERROR) { struct ieee80211_device *ieee = zd_mac_to_ieee80211(mac); ieee->stats.rx_errors++; diff --git a/drivers/net/wireless/zd1211rw/zd_mac.h b/drivers/net/wireless/zd1211rw/zd_mac.h index 9f9344eb50f9..1b15bde3ff60 100644 --- a/drivers/net/wireless/zd1211rw/zd_mac.h +++ b/drivers/net/wireless/zd1211rw/zd_mac.h @@ -40,28 +40,51 @@ struct zd_ctrlset { #define ZD_CS_RESERVED_SIZE 25 -/* zd_crtlset field modulation */ -#define ZD_CS_RATE_MASK 0x0f -#define ZD_CS_TYPE_MASK 0x10 -#define ZD_CS_RATE(modulation) ((modulation) & ZD_CS_RATE_MASK) -#define ZD_CS_TYPE(modulation) ((modulation) & ZD_CS_TYPE_MASK) - -#define ZD_CS_CCK 0x00 -#define ZD_CS_OFDM 0x10 - -/* These are referred to as zd_rates */ -#define ZD_CCK_RATE_1M 0x00 -#define ZD_CCK_RATE_2M 0x01 -#define ZD_CCK_RATE_5_5M 0x02 -#define ZD_CCK_RATE_11M 0x03 -/* The rates for OFDM are encoded as in the PLCP header. Use ZD_OFDM_RATE_*. +/* 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. */ - -/* bit 5 is preamble (when in CCK mode), or a/g selection (when in OFDM mode) */ -#define ZD_CS_CCK_PREA_LONG 0x00 -#define ZD_CS_CCK_PREA_SHORT 0x20 -#define ZD_CS_OFDM_MODE_11G 0x00 -#define ZD_CS_OFDM_MODE_11A 0x20 +#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 diff --git a/drivers/net/wireless/zd1211rw/zd_netdev.c b/drivers/net/wireless/zd1211rw/zd_netdev.c index 8bda48de31ef..047cab3d87df 100644 --- a/drivers/net/wireless/zd1211rw/zd_netdev.c +++ b/drivers/net/wireless/zd1211rw/zd_netdev.c @@ -233,7 +233,6 @@ struct net_device *zd_netdev_alloc(struct usb_interface *intf) return NULL; } - SET_MODULE_OWNER(netdev); SET_NETDEV_DEV(netdev, &intf->dev); dev_dbg_f(&intf->dev, "netdev->flags %#06hx\n", netdev->flags); diff --git a/drivers/net/wireless/zd1211rw/zd_usb.c b/drivers/net/wireless/zd1211rw/zd_usb.c index a9c339ef116a..b0684f965761 100644 --- a/drivers/net/wireless/zd1211rw/zd_usb.c +++ b/drivers/net/wireless/zd1211rw/zd_usb.c @@ -31,7 +31,6 @@ #include "zd_netdev.h" #include "zd_mac.h" #include "zd_usb.h" -#include "zd_util.h" static struct usb_device_id usb_ids[] = { /* ZD1211 */ @@ -55,6 +54,7 @@ static struct usb_device_id usb_ids[] = { { USB_DEVICE(0x14ea, 0xab13), .driver_info = DEVICE_ZD1211 }, { USB_DEVICE(0x13b1, 0x001e), .driver_info = DEVICE_ZD1211 }, { USB_DEVICE(0x0586, 0x3407), .driver_info = DEVICE_ZD1211 }, + { USB_DEVICE(0x129b, 0x1666), .driver_info = DEVICE_ZD1211 }, /* ZD1211B */ { USB_DEVICE(0x0ace, 0x1215), .driver_info = DEVICE_ZD1211B }, { USB_DEVICE(0x157e, 0x300d), .driver_info = DEVICE_ZD1211B }, @@ -74,6 +74,9 @@ static struct usb_device_id usb_ids[] = { { USB_DEVICE(0x0411, 0x00da), .driver_info = DEVICE_ZD1211B }, { USB_DEVICE(0x2019, 0x5303), .driver_info = DEVICE_ZD1211B }, { USB_DEVICE(0x129b, 0x1667), .driver_info = DEVICE_ZD1211B }, + { USB_DEVICE(0x0cde, 0x001a), .driver_info = DEVICE_ZD1211B }, + { USB_DEVICE(0x0586, 0x340a), .driver_info = DEVICE_ZD1211B }, + { USB_DEVICE(0x0471, 0x1237), .driver_info = DEVICE_ZD1211B }, /* "Driverless" devices that need ejecting */ { USB_DEVICE(0x0ace, 0x2011), .driver_info = DEVICE_INSTALLER }, { USB_DEVICE(0x0ace, 0x20ff), .driver_info = DEVICE_INSTALLER }, diff --git a/drivers/net/wireless/zd1211rw/zd_util.c b/drivers/net/wireless/zd1211rw/zd_util.c deleted file mode 100644 index d20036c15d11..000000000000 --- a/drivers/net/wireless/zd1211rw/zd_util.c +++ /dev/null @@ -1,82 +0,0 @@ -/* zd_util.c - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * Utility program - */ - -#include "zd_def.h" -#include "zd_util.h" - -#ifdef DEBUG -static char hex(u8 v) -{ - v &= 0xf; - return (v < 10 ? '0' : 'a' - 10) + v; -} - -static char hex_print(u8 c) -{ - return (0x20 <= c && c < 0x7f) ? c : '.'; -} - -static void dump_line(const u8 *bytes, size_t size) -{ - char c; - size_t i; - - size = size <= 8 ? size : 8; - printk(KERN_DEBUG "zd1211 %p ", bytes); - for (i = 0; i < 8; i++) { - switch (i) { - case 1: - case 5: - c = '.'; - break; - case 3: - c = ':'; - break; - default: - c = ' '; - } - if (i < size) { - printk("%c%c%c", hex(bytes[i] >> 4), hex(bytes[i]), c); - } else { - printk(" %c", c); - } - } - - for (i = 0; i < size; i++) - printk("%c", hex_print(bytes[i])); - printk("\n"); -} - -void zd_hexdump(const void *bytes, size_t size) -{ - size_t i = 0; - - do { - dump_line((u8 *)bytes + i, size-i); - i += 8; - } while (i < size); -} -#endif /* DEBUG */ - -void *zd_tail(const void *buffer, size_t buffer_size, size_t tail_size) -{ - if (buffer_size < tail_size) - return NULL; - return (u8 *)buffer + (buffer_size - tail_size); -} diff --git a/drivers/net/wireless/zd1211rw/zd_util.h b/drivers/net/wireless/zd1211rw/zd_util.h deleted file mode 100644 index ce26f7adea92..000000000000 --- a/drivers/net/wireless/zd1211rw/zd_util.h +++ /dev/null @@ -1,29 +0,0 @@ -/* zd_util.h - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef _ZD_UTIL_H -#define _ZD_UTIL_H - -void *zd_tail(const void *buffer, size_t buffer_size, size_t tail_size); - -#ifdef DEBUG -void zd_hexdump(const void *bytes, size_t size); -#else -#define zd_hexdump(bytes, size) -#endif /* DEBUG */ - -#endif /* _ZD_UTIL_H */ |