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)
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 r;
......@@ -1355,17 +1380,12 @@ int zd_chip_control_leds(struct zd_chip *chip, enum led_status status)
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;
if (cr_rates & ~(CR_RATES_80211B|CR_RATES_80211G))
return -EINVAL;
ZD_ASSERT((cr_rates & ~(CR_RATES_80211B | CR_RATES_80211G)) == 0);
dev_dbg_f(zd_chip_dev(chip), "%x\n", cr_rates);
mutex_lock(&chip->mutex);
r = zd_iowrite32_locked(chip, cr_rates, CR_BASIC_RATE_TBL);
mutex_unlock(&chip->mutex);
return r;
return zd_iowrite32_locked(chip, cr_rates, CR_BASIC_RATE_TBL);
}
static int ofdm_qual_db(u8 status_quality, u8 rate, unsigned int size)
......
......@@ -420,6 +420,15 @@
#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)
......@@ -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_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)
{
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)
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)
{
......
This diff is collapsed.
......@@ -20,6 +20,7 @@
#include <linux/wireless.h>
#include <linux/kernel.h>
#include <linux/workqueue.h>
#include <net/ieee80211.h>
#include <net/ieee80211softmac.h>
......@@ -127,15 +128,33 @@ struct zd_mac {
struct zd_chip chip;
spinlock_t lock;
struct net_device *netdev;
/* Unlocked reading possible */
struct iw_statistics iw_stats;
struct housekeeping housekeeping;
struct work_struct set_rts_cts_work;
struct work_struct set_basic_rates_work;
unsigned int stats_count;
u8 qual_buffer[ZD_MAC_STATS_BUFFER_SIZE];
u8 rssi_buffer[ZD_MAC_STATS_BUFFER_SIZE];
u8 regdomain;
u8 default_regdomain;
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)
......
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