Commit b1382ede authored by Daniel Drake's avatar Daniel Drake Committed by Jeff Garzik

[PATCH] zd1211rw: Use softmac ERP handling functionality

This adds zd1211rw driver support for the softmac functionality I
added a while back. We now obey changes in basic rates, use short
preamble if it is available (but long if the AP says it's not),
and send self-CTS in the proper situations.

Locking fixed and improved by Ulrich Kunitz.
Signed-off-by: default avatarDaniel Drake <dsd@gentoo.org>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent b1cd8416
...@@ -1076,6 +1076,31 @@ static int set_mandatory_rates(struct zd_chip *chip, enum ieee80211_std std) ...@@ -1076,6 +1076,31 @@ static int set_mandatory_rates(struct zd_chip *chip, enum ieee80211_std std)
return zd_iowrite32_locked(chip, rates, CR_MANDATORY_RATE_TBL); return zd_iowrite32_locked(chip, rates, CR_MANDATORY_RATE_TBL);
} }
int zd_chip_set_rts_cts_rate_locked(struct zd_chip *chip,
u8 rts_rate, int preamble)
{
int rts_mod = ZD_RX_CCK;
u32 value = 0;
/* Modulation bit */
if (ZD_CS_TYPE(rts_rate) == ZD_CS_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 |= 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_RX_CCK << RTSCTS_SH_CTS_MOD_TYPE;
return zd_iowrite32_locked(chip, value, CR_RTS_CTS_RATE);
}
int zd_chip_enable_hwint(struct zd_chip *chip) int zd_chip_enable_hwint(struct zd_chip *chip)
{ {
int r; int r;
...@@ -1355,17 +1380,12 @@ int zd_chip_control_leds(struct zd_chip *chip, enum led_status status) ...@@ -1355,17 +1380,12 @@ int zd_chip_control_leds(struct zd_chip *chip, enum led_status status)
return r; return r;
} }
int zd_chip_set_basic_rates(struct zd_chip *chip, u16 cr_rates) int zd_chip_set_basic_rates_locked(struct zd_chip *chip, u16 cr_rates)
{ {
int r; ZD_ASSERT((cr_rates & ~(CR_RATES_80211B | CR_RATES_80211G)) == 0);
dev_dbg_f(zd_chip_dev(chip), "%x\n", cr_rates);
if (cr_rates & ~(CR_RATES_80211B|CR_RATES_80211G))
return -EINVAL;
mutex_lock(&chip->mutex); return zd_iowrite32_locked(chip, cr_rates, CR_BASIC_RATE_TBL);
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 rate, unsigned int size) static int ofdm_qual_db(u8 status_quality, u8 rate, unsigned int size)
......
...@@ -420,6 +420,15 @@ ...@@ -420,6 +420,15 @@
#define CR_MANDATORY_RATE_TBL CTL_REG(0x0634) #define CR_MANDATORY_RATE_TBL CTL_REG(0x0634)
#define CR_RTS_CTS_RATE CTL_REG(0x0638) #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_WEP_PROTECT CTL_REG(0x063C)
#define CR_RX_THRESHOLD CTL_REG(0x0640) #define CR_RX_THRESHOLD CTL_REG(0x0640)
...@@ -794,6 +803,9 @@ void zd_chip_disable_rx(struct zd_chip *chip); ...@@ -794,6 +803,9 @@ void zd_chip_disable_rx(struct zd_chip *chip);
int zd_chip_enable_hwint(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_disable_hwint(struct zd_chip *chip);
int zd_chip_set_rts_cts_rate_locked(struct zd_chip *chip,
u8 rts_rate, int preamble);
static inline int zd_get_encryption_type(struct zd_chip *chip, u32 *type) static inline int zd_get_encryption_type(struct zd_chip *chip, u32 *type)
{ {
return zd_ioread32(chip, CR_ENCRYPTION_TYPE, type); return zd_ioread32(chip, CR_ENCRYPTION_TYPE, type);
...@@ -809,7 +821,17 @@ static inline int zd_chip_get_basic_rates(struct zd_chip *chip, u16 *cr_rates) ...@@ -809,7 +821,17 @@ 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); 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_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;
}
static inline int zd_chip_set_rx_filter(struct zd_chip *chip, u32 filter) static inline int zd_chip_set_rx_filter(struct zd_chip *chip, u32 filter)
{ {
......
This diff is collapsed.
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
#include <linux/wireless.h> #include <linux/wireless.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/workqueue.h>
#include <net/ieee80211.h> #include <net/ieee80211.h>
#include <net/ieee80211softmac.h> #include <net/ieee80211softmac.h>
...@@ -127,15 +128,33 @@ struct zd_mac { ...@@ -127,15 +128,33 @@ struct zd_mac {
struct zd_chip chip; struct zd_chip chip;
spinlock_t lock; spinlock_t lock;
struct net_device *netdev; struct net_device *netdev;
/* Unlocked reading possible */ /* Unlocked reading possible */
struct iw_statistics iw_stats; struct iw_statistics iw_stats;
struct housekeeping housekeeping; struct housekeeping housekeeping;
struct work_struct set_rts_cts_work;
struct work_struct set_basic_rates_work;
unsigned int stats_count; unsigned int stats_count;
u8 qual_buffer[ZD_MAC_STATS_BUFFER_SIZE]; u8 qual_buffer[ZD_MAC_STATS_BUFFER_SIZE];
u8 rssi_buffer[ZD_MAC_STATS_BUFFER_SIZE]; u8 rssi_buffer[ZD_MAC_STATS_BUFFER_SIZE];
u8 regdomain; u8 regdomain;
u8 default_regdomain; u8 default_regdomain;
u8 requested_channel; u8 requested_channel;
/* A bitpattern of cr_rates */
u16 basic_rates;
/* A zd_rate */
u8 rts_rate;
/* Short preamble (used for RTS/CTS) */
unsigned int short_preamble:1;
/* flags to indicate update in progress */
unsigned int updating_rts_rate:1;
unsigned int updating_basic_rates:1;
}; };
static inline struct ieee80211_device *zd_mac_to_ieee80211(struct zd_mac *mac) static inline struct ieee80211_device *zd_mac_to_ieee80211(struct zd_mac *mac)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment