SVN-Revision: 10573master
parent
3d66117ef0
commit
fef15a956c
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,205 @@ |
|||||||
|
/*
|
||||||
|
Copyright (C) 2004 - 2007 rt2x00 SourceForge Project |
||||||
|
<http://rt2x00.serialmonkey.com>
|
||||||
|
|
||||||
|
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. |
||||||
|
*/ |
||||||
|
|
||||||
|
/*
|
||||||
|
Module: rt2x00lib |
||||||
|
Abstract: rt2x00 generic configuration routines. |
||||||
|
*/ |
||||||
|
|
||||||
|
/*
|
||||||
|
* Set enviroment defines for rt2x00.h |
||||||
|
*/ |
||||||
|
#define DRV_NAME "rt2x00lib" |
||||||
|
|
||||||
|
#include <linux/kernel.h> |
||||||
|
#include <linux/module.h> |
||||||
|
|
||||||
|
#include "rt2x00.h" |
||||||
|
#include "rt2x00lib.h" |
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The MAC and BSSID addressess are simple array of bytes, |
||||||
|
* these arrays are little endian, so when sending the addressess |
||||||
|
* to the drivers, copy the it into a endian-signed variable. |
||||||
|
* |
||||||
|
* Note that all devices (except rt2500usb) have 32 bits |
||||||
|
* register word sizes. This means that whatever variable we |
||||||
|
* pass _must_ be a multiple of 32 bits. Otherwise the device |
||||||
|
* might not accept what we are sending to it. |
||||||
|
* This will also make it easier for the driver to write |
||||||
|
* the data to the device. |
||||||
|
* |
||||||
|
* Also note that when NULL is passed as address the |
||||||
|
* we will send 00:00:00:00:00 to the device to clear the address. |
||||||
|
* This will prevent the device being confused when it wants |
||||||
|
* to ACK frames or consideres itself associated. |
||||||
|
*/ |
||||||
|
void rt2x00lib_config_mac_addr(struct rt2x00_dev *rt2x00dev, u8 *mac) |
||||||
|
{ |
||||||
|
__le32 reg[2]; |
||||||
|
|
||||||
|
memset(®, 0, sizeof(reg)); |
||||||
|
if (mac) |
||||||
|
memcpy(®, mac, ETH_ALEN); |
||||||
|
|
||||||
|
rt2x00dev->ops->lib->config_mac_addr(rt2x00dev, ®[0]); |
||||||
|
} |
||||||
|
|
||||||
|
void rt2x00lib_config_bssid(struct rt2x00_dev *rt2x00dev, u8 *bssid) |
||||||
|
{ |
||||||
|
__le32 reg[2]; |
||||||
|
|
||||||
|
memset(®, 0, sizeof(reg)); |
||||||
|
if (bssid) |
||||||
|
memcpy(®, bssid, ETH_ALEN); |
||||||
|
|
||||||
|
rt2x00dev->ops->lib->config_bssid(rt2x00dev, ®[0]); |
||||||
|
} |
||||||
|
|
||||||
|
void rt2x00lib_config_type(struct rt2x00_dev *rt2x00dev, const int type) |
||||||
|
{ |
||||||
|
int tsf_sync; |
||||||
|
|
||||||
|
switch (type) { |
||||||
|
case IEEE80211_IF_TYPE_IBSS: |
||||||
|
case IEEE80211_IF_TYPE_AP: |
||||||
|
tsf_sync = TSF_SYNC_BEACON; |
||||||
|
break; |
||||||
|
case IEEE80211_IF_TYPE_STA: |
||||||
|
tsf_sync = TSF_SYNC_INFRA; |
||||||
|
break; |
||||||
|
default: |
||||||
|
tsf_sync = TSF_SYNC_NONE; |
||||||
|
break; |
||||||
|
} |
||||||
|
|
||||||
|
rt2x00dev->ops->lib->config_type(rt2x00dev, type, tsf_sync); |
||||||
|
} |
||||||
|
|
||||||
|
void rt2x00lib_config(struct rt2x00_dev *rt2x00dev, |
||||||
|
struct ieee80211_conf *conf, const int force_config) |
||||||
|
{ |
||||||
|
struct rt2x00lib_conf libconf; |
||||||
|
struct ieee80211_hw_mode *mode; |
||||||
|
struct ieee80211_rate *rate; |
||||||
|
int flags = 0; |
||||||
|
int short_slot_time; |
||||||
|
|
||||||
|
/*
|
||||||
|
* In some situations we want to force all configurations |
||||||
|
* to be reloaded (When resuming for instance). |
||||||
|
*/ |
||||||
|
if (force_config) { |
||||||
|
flags = CONFIG_UPDATE_ALL; |
||||||
|
goto config; |
||||||
|
} |
||||||
|
|
||||||
|
/*
|
||||||
|
* Check which configuration options have been |
||||||
|
* updated and should be send to the device. |
||||||
|
*/ |
||||||
|
if (rt2x00dev->rx_status.phymode != conf->phymode) |
||||||
|
flags |= CONFIG_UPDATE_PHYMODE; |
||||||
|
if (rt2x00dev->rx_status.channel != conf->channel) |
||||||
|
flags |= CONFIG_UPDATE_CHANNEL; |
||||||
|
if (rt2x00dev->tx_power != conf->power_level) |
||||||
|
flags |= CONFIG_UPDATE_TXPOWER; |
||||||
|
if (rt2x00dev->rx_status.antenna == conf->antenna_sel_rx) |
||||||
|
flags |= CONFIG_UPDATE_ANTENNA; |
||||||
|
|
||||||
|
/*
|
||||||
|
* The following configuration options are never |
||||||
|
* stored anywhere and will always be updated. |
||||||
|
*/ |
||||||
|
flags |= CONFIG_UPDATE_SLOT_TIME; |
||||||
|
flags |= CONFIG_UPDATE_BEACON_INT; |
||||||
|
|
||||||
|
/*
|
||||||
|
* We have determined what options should be updated, |
||||||
|
* now precalculate device configuration values depending |
||||||
|
* on what configuration options need to be updated. |
||||||
|
*/ |
||||||
|
config: |
||||||
|
memset(&libconf, 0, sizeof(libconf)); |
||||||
|
|
||||||
|
if (flags & CONFIG_UPDATE_PHYMODE) { |
||||||
|
switch (conf->phymode) { |
||||||
|
case MODE_IEEE80211A: |
||||||
|
libconf.phymode = HWMODE_A; |
||||||
|
break; |
||||||
|
case MODE_IEEE80211B: |
||||||
|
libconf.phymode = HWMODE_B; |
||||||
|
break; |
||||||
|
case MODE_IEEE80211G: |
||||||
|
libconf.phymode = HWMODE_G; |
||||||
|
break; |
||||||
|
default: |
||||||
|
ERROR(rt2x00dev, |
||||||
|
"Attempt to configure unsupported mode (%d)" |
||||||
|
"Defaulting to 802.11b", conf->phymode); |
||||||
|
libconf.phymode = HWMODE_B; |
||||||
|
} |
||||||
|
|
||||||
|
mode = &rt2x00dev->hwmodes[libconf.phymode]; |
||||||
|
rate = &mode->rates[mode->num_rates - 1]; |
||||||
|
|
||||||
|
libconf.basic_rates = |
||||||
|
DEVICE_GET_RATE_FIELD(rate->val, RATEMASK) & DEV_BASIC_RATEMASK; |
||||||
|
} |
||||||
|
|
||||||
|
if (flags & CONFIG_UPDATE_CHANNEL) { |
||||||
|
memcpy(&libconf.rf, |
||||||
|
&rt2x00dev->spec.channels[conf->channel_val], |
||||||
|
sizeof(libconf.rf)); |
||||||
|
} |
||||||
|
|
||||||
|
if (flags & CONFIG_UPDATE_SLOT_TIME) { |
||||||
|
short_slot_time = conf->flags & IEEE80211_CONF_SHORT_SLOT_TIME; |
||||||
|
|
||||||
|
libconf.slot_time = |
||||||
|
short_slot_time ? SHORT_SLOT_TIME : SLOT_TIME; |
||||||
|
libconf.sifs = SIFS; |
||||||
|
libconf.pifs = short_slot_time ? SHORT_PIFS : PIFS; |
||||||
|
libconf.difs = short_slot_time ? SHORT_DIFS : DIFS; |
||||||
|
libconf.eifs = EIFS; |
||||||
|
} |
||||||
|
|
||||||
|
libconf.conf = conf; |
||||||
|
|
||||||
|
/*
|
||||||
|
* Start configuration. |
||||||
|
*/ |
||||||
|
rt2x00dev->ops->lib->config(rt2x00dev, flags, &libconf); |
||||||
|
|
||||||
|
/*
|
||||||
|
* Some configuration changes affect the link quality |
||||||
|
* which means we need to reset the link tuner. |
||||||
|
*/ |
||||||
|
if (flags & (CONFIG_UPDATE_CHANNEL | CONFIG_UPDATE_ANTENNA)) |
||||||
|
rt2x00lib_reset_link_tuner(rt2x00dev); |
||||||
|
|
||||||
|
rt2x00dev->curr_hwmode = libconf.phymode; |
||||||
|
rt2x00dev->rx_status.phymode = conf->phymode; |
||||||
|
rt2x00dev->rx_status.freq = conf->freq; |
||||||
|
rt2x00dev->rx_status.channel = conf->channel; |
||||||
|
rt2x00dev->tx_power = conf->power_level; |
||||||
|
rt2x00dev->rx_status.antenna = conf->antenna_sel_rx; |
||||||
|
} |
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,292 @@ |
|||||||
|
/*
|
||||||
|
Copyright (C) 2004 - 2007 rt2x00 SourceForge Project |
||||||
|
<http://rt2x00.serialmonkey.com>
|
||||||
|
|
||||||
|
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. |
||||||
|
*/ |
||||||
|
|
||||||
|
/*
|
||||||
|
Module: rt2x00 |
||||||
|
Abstract: rt2x00 generic register information. |
||||||
|
*/ |
||||||
|
|
||||||
|
#ifndef RT2X00REG_H |
||||||
|
#define RT2X00REG_H |
||||||
|
|
||||||
|
/*
|
||||||
|
* TX result flags. |
||||||
|
*/ |
||||||
|
enum TX_STATUS { |
||||||
|
TX_SUCCESS = 0, |
||||||
|
TX_SUCCESS_RETRY = 1, |
||||||
|
TX_FAIL_RETRY = 2, |
||||||
|
TX_FAIL_INVALID = 3, |
||||||
|
TX_FAIL_OTHER = 4, |
||||||
|
}; |
||||||
|
|
||||||
|
/*
|
||||||
|
* Antenna values |
||||||
|
*/ |
||||||
|
enum antenna { |
||||||
|
ANTENNA_SW_DIVERSITY = 0, |
||||||
|
ANTENNA_A = 1, |
||||||
|
ANTENNA_B = 2, |
||||||
|
ANTENNA_HW_DIVERSITY = 3, |
||||||
|
}; |
||||||
|
|
||||||
|
/*
|
||||||
|
* Led mode values. |
||||||
|
*/ |
||||||
|
enum led_mode { |
||||||
|
LED_MODE_DEFAULT = 0, |
||||||
|
LED_MODE_TXRX_ACTIVITY = 1, |
||||||
|
LED_MODE_SIGNAL_STRENGTH = 2, |
||||||
|
LED_MODE_ASUS = 3, |
||||||
|
LED_MODE_ALPHA = 4, |
||||||
|
}; |
||||||
|
|
||||||
|
/*
|
||||||
|
* TSF sync values |
||||||
|
*/ |
||||||
|
enum tsf_sync { |
||||||
|
TSF_SYNC_NONE = 0, |
||||||
|
TSF_SYNC_INFRA = 1, |
||||||
|
TSF_SYNC_BEACON = 2, |
||||||
|
}; |
||||||
|
|
||||||
|
/*
|
||||||
|
* Device states |
||||||
|
*/ |
||||||
|
enum dev_state { |
||||||
|
STATE_DEEP_SLEEP = 0, |
||||||
|
STATE_SLEEP = 1, |
||||||
|
STATE_STANDBY = 2, |
||||||
|
STATE_AWAKE = 3, |
||||||
|
|
||||||
|
/*
|
||||||
|
* Additional device states, these values are |
||||||
|
* not strict since they are not directly passed |
||||||
|
* into the device. |
||||||
|
*/ |
||||||
|
STATE_RADIO_ON, |
||||||
|
STATE_RADIO_OFF, |
||||||
|
STATE_RADIO_RX_ON, |
||||||
|
STATE_RADIO_RX_OFF, |
||||||
|
STATE_RADIO_IRQ_ON, |
||||||
|
STATE_RADIO_IRQ_OFF, |
||||||
|
}; |
||||||
|
|
||||||
|
/*
|
||||||
|
* IFS backoff values |
||||||
|
*/ |
||||||
|
enum ifs { |
||||||
|
IFS_BACKOFF = 0, |
||||||
|
IFS_SIFS = 1, |
||||||
|
IFS_NEW_BACKOFF = 2, |
||||||
|
IFS_NONE = 3, |
||||||
|
}; |
||||||
|
|
||||||
|
/*
|
||||||
|
* Cipher types for hardware encryption |
||||||
|
*/ |
||||||
|
enum cipher { |
||||||
|
CIPHER_NONE = 0, |
||||||
|
CIPHER_WEP64 = 1, |
||||||
|
CIPHER_WEP128 = 2, |
||||||
|
CIPHER_TKIP = 3, |
||||||
|
CIPHER_AES = 4, |
||||||
|
/*
|
||||||
|
* The following fields were added by rt61pci and rt73usb. |
||||||
|
*/ |
||||||
|
CIPHER_CKIP64 = 5, |
||||||
|
CIPHER_CKIP128 = 6, |
||||||
|
CIPHER_TKIP_NO_MIC = 7, |
||||||
|
}; |
||||||
|
|
||||||
|
/*
|
||||||
|
* Register handlers. |
||||||
|
* We store the position of a register field inside a field structure, |
||||||
|
* This will simplify the process of setting and reading a certain field |
||||||
|
* inside the register while making sure the process remains byte order safe. |
||||||
|
*/ |
||||||
|
struct rt2x00_field8 { |
||||||
|
u8 bit_offset; |
||||||
|
u8 bit_mask; |
||||||
|
}; |
||||||
|
|
||||||
|
struct rt2x00_field16 { |
||||||
|
u16 bit_offset; |
||||||
|
u16 bit_mask; |
||||||
|
}; |
||||||
|
|
||||||
|
struct rt2x00_field32 { |
||||||
|
u32 bit_offset; |
||||||
|
u32 bit_mask; |
||||||
|
}; |
||||||
|
|
||||||
|
/*
|
||||||
|
* Power of two check, this will check |
||||||
|
* if the mask that has been given contains |
||||||
|
* and contiguous set of bits. |
||||||
|
*/ |
||||||
|
#define is_power_of_two(x) ( !((x) & ((x)-1)) ) |
||||||
|
#define low_bit_mask(x) ( ((x)-1) & ~(x) ) |
||||||
|
#define is_valid_mask(x) is_power_of_two(1 + (x) + low_bit_mask(x)) |
||||||
|
|
||||||
|
#define FIELD8(__mask) \ |
||||||
|
({ \
|
||||||
|
BUILD_BUG_ON(!(__mask) || \
|
||||||
|
!is_valid_mask(__mask) || \
|
||||||
|
(__mask) != (u8)(__mask)); \
|
||||||
|
(struct rt2x00_field8) { \
|
||||||
|
__ffs(__mask), (__mask) \
|
||||||
|
}; \
|
||||||
|
}) |
||||||
|
|
||||||
|
#define FIELD16(__mask) \ |
||||||
|
({ \
|
||||||
|
BUILD_BUG_ON(!(__mask) || \
|
||||||
|
!is_valid_mask(__mask) || \
|
||||||
|
(__mask) != (u16)(__mask));\
|
||||||
|
(struct rt2x00_field16) { \
|
||||||
|
__ffs(__mask), (__mask) \
|
||||||
|
}; \
|
||||||
|
}) |
||||||
|
|
||||||
|
#define FIELD32(__mask) \ |
||||||
|
({ \
|
||||||
|
BUILD_BUG_ON(!(__mask) || \
|
||||||
|
!is_valid_mask(__mask) || \
|
||||||
|
(__mask) != (u32)(__mask));\
|
||||||
|
(struct rt2x00_field32) { \
|
||||||
|
__ffs(__mask), (__mask) \
|
||||||
|
}; \
|
||||||
|
}) |
||||||
|
|
||||||
|
static inline void rt2x00_set_field32(u32 *reg, |
||||||
|
const struct rt2x00_field32 field, |
||||||
|
const u32 value) |
||||||
|
{ |
||||||
|
*reg &= ~(field.bit_mask); |
||||||
|
*reg |= (value << field.bit_offset) & field.bit_mask; |
||||||
|
} |
||||||
|
|
||||||
|
static inline u32 rt2x00_get_field32(const u32 reg, |
||||||
|
const struct rt2x00_field32 field) |
||||||
|
{ |
||||||
|
return (reg & field.bit_mask) >> field.bit_offset; |
||||||
|
} |
||||||
|
|
||||||
|
static inline void rt2x00_set_field16(u16 *reg, |
||||||
|
const struct rt2x00_field16 field, |
||||||
|
const u16 value) |
||||||
|
{ |
||||||
|
*reg &= ~(field.bit_mask); |
||||||
|
*reg |= (value << field.bit_offset) & field.bit_mask; |
||||||
|
} |
||||||
|
|
||||||
|
static inline u16 rt2x00_get_field16(const u16 reg, |
||||||
|
const struct rt2x00_field16 field) |
||||||
|
{ |
||||||
|
return (reg & field.bit_mask) >> field.bit_offset; |
||||||
|
} |
||||||
|
|
||||||
|
static inline void rt2x00_set_field8(u8 *reg, |
||||||
|
const struct rt2x00_field8 field, |
||||||
|
const u8 value) |
||||||
|
{ |
||||||
|
*reg &= ~(field.bit_mask); |
||||||
|
*reg |= (value << field.bit_offset) & field.bit_mask; |
||||||
|
} |
||||||
|
|
||||||
|
static inline u8 rt2x00_get_field8(const u8 reg, |
||||||
|
const struct rt2x00_field8 field) |
||||||
|
{ |
||||||
|
return (reg & field.bit_mask) >> field.bit_offset; |
||||||
|
} |
||||||
|
|
||||||
|
/*
|
||||||
|
* Device specific rate value. |
||||||
|
* We will have to create the device specific rate value |
||||||
|
* passed to the ieee80211 kernel. We need to make it a consist of |
||||||
|
* multiple fields because we want to store more then 1 device specific |
||||||
|
* values inside the value. |
||||||
|
* 1 - rate, stored as 100 kbit/s. |
||||||
|
* 2 - preamble, short_preamble enabled flag. |
||||||
|
* 3 - MASK_RATE, which rates are enabled in this mode, this mask |
||||||
|
* corresponds with the TX register format for the current device. |
||||||
|
* 4 - plcp, 802.11b rates are device specific, |
||||||
|
* 802.11g rates are set according to the ieee802.11a-1999 p.14. |
||||||
|
* The bit to enable preamble is set in a seperate define. |
||||||
|
*/ |
||||||
|
#define DEV_RATE FIELD32(0x000007ff) |
||||||
|
#define DEV_PREAMBLE FIELD32(0x00000800) |
||||||
|
#define DEV_RATEMASK FIELD32(0x00fff000) |
||||||
|
#define DEV_PLCP FIELD32(0xff000000) |
||||||
|
|
||||||
|
/*
|
||||||
|
* Bitfields |
||||||
|
*/ |
||||||
|
#define DEV_RATEBIT_1MB ( 1 << 0 ) |
||||||
|
#define DEV_RATEBIT_2MB ( 1 << 1 ) |
||||||
|
#define DEV_RATEBIT_5_5MB ( 1 << 2 ) |
||||||
|
#define DEV_RATEBIT_11MB ( 1 << 3 ) |
||||||
|
#define DEV_RATEBIT_6MB ( 1 << 4 ) |
||||||
|
#define DEV_RATEBIT_9MB ( 1 << 5 ) |
||||||
|
#define DEV_RATEBIT_12MB ( 1 << 6 ) |
||||||
|
#define DEV_RATEBIT_18MB ( 1 << 7 ) |
||||||
|
#define DEV_RATEBIT_24MB ( 1 << 8 ) |
||||||
|
#define DEV_RATEBIT_36MB ( 1 << 9 ) |
||||||
|
#define DEV_RATEBIT_48MB ( 1 << 10 ) |
||||||
|
#define DEV_RATEBIT_54MB ( 1 << 11 ) |
||||||
|
|
||||||
|
/*
|
||||||
|
* Bitmasks for DEV_RATEMASK |
||||||
|
*/ |
||||||
|
#define DEV_RATEMASK_1MB ( (DEV_RATEBIT_1MB << 1) -1 ) |
||||||
|
#define DEV_RATEMASK_2MB ( (DEV_RATEBIT_2MB << 1) -1 ) |
||||||
|
#define DEV_RATEMASK_5_5MB ( (DEV_RATEBIT_5_5MB << 1) -1 ) |
||||||
|
#define DEV_RATEMASK_11MB ( (DEV_RATEBIT_11MB << 1) -1 ) |
||||||
|
#define DEV_RATEMASK_6MB ( (DEV_RATEBIT_6MB << 1) -1 ) |
||||||
|
#define DEV_RATEMASK_9MB ( (DEV_RATEBIT_9MB << 1) -1 ) |
||||||
|
#define DEV_RATEMASK_12MB ( (DEV_RATEBIT_12MB << 1) -1 ) |
||||||
|
#define DEV_RATEMASK_18MB ( (DEV_RATEBIT_18MB << 1) -1 ) |
||||||
|
#define DEV_RATEMASK_24MB ( (DEV_RATEBIT_24MB << 1) -1 ) |
||||||
|
#define DEV_RATEMASK_36MB ( (DEV_RATEBIT_36MB << 1) -1 ) |
||||||
|
#define DEV_RATEMASK_48MB ( (DEV_RATEBIT_48MB << 1) -1 ) |
||||||
|
#define DEV_RATEMASK_54MB ( (DEV_RATEBIT_54MB << 1) -1 ) |
||||||
|
|
||||||
|
/*
|
||||||
|
* Bitmask groups of bitrates |
||||||
|
*/ |
||||||
|
#define DEV_BASIC_RATEMASK \ |
||||||
|
( DEV_RATEMASK_11MB | \
|
||||||
|
DEV_RATEBIT_6MB | DEV_RATEBIT_12MB | DEV_RATEBIT_24MB ) |
||||||
|
|
||||||
|
#define DEV_CCK_RATEMASK ( DEV_RATEMASK_11MB ) |
||||||
|
#define DEV_OFDM_RATEMASK ( DEV_RATEMASK_54MB & ~DEV_CCK_RATEMASK ) |
||||||
|
|
||||||
|
/*
|
||||||
|
* Macro's to set and get specific fields from the device specific val and val2 |
||||||
|
* fields inside the ieee80211_rate entry. |
||||||
|
*/ |
||||||
|
#define DEVICE_SET_RATE_FIELD(__value, __mask) \ |
||||||
|
(int)( ((__value) << DEV_##__mask.bit_offset) & DEV_##__mask.bit_mask ) |
||||||
|
|
||||||
|
#define DEVICE_GET_RATE_FIELD(__value, __mask) \ |
||||||
|
(int)( ((__value) & DEV_##__mask.bit_mask) >> DEV_##__mask.bit_offset ) |
||||||
|
|
||||||
|
#endif /* RT2X00REG_H */ |
@ -0,0 +1,268 @@ |
|||||||
|
/*
|
||||||
|
Copyright (C) 2004 - 2007 rt2x00 SourceForge Project |
||||||
|
<http://rt2x00.serialmonkey.com>
|
||||||
|
|
||||||
|
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. |
||||||
|
*/ |
||||||
|
|
||||||
|
/*
|
||||||
|
Module: rt2x00 |
||||||
|
Abstract: rt2x00 ring datastructures and routines |
||||||
|
*/ |
||||||
|
|
||||||
|
#ifndef RT2X00RING_H |
||||||
|
#define RT2X00RING_H |
||||||
|
|
||||||
|
/*
|
||||||
|
* data_desc |
||||||
|
* Each data entry also contains a descriptor which is used by the |
||||||
|
* device to determine what should be done with the packet and |
||||||
|
* what the current status is. |
||||||
|
* This structure is greatly simplified, but the descriptors |
||||||
|
* are basically a list of little endian 32 bit values. |
||||||
|
* Make the array by default 1 word big, this will allow us |
||||||
|
* to use sizeof() correctly. |
||||||
|
*/ |
||||||
|
struct data_desc { |
||||||
|
__le32 word[1]; |
||||||
|
}; |
||||||
|
|
||||||
|
/*
|
||||||
|
* rxdata_entry_desc |
||||||
|
* Summary of information that has been read from the |
||||||
|
* RX frame descriptor. |
||||||
|
*/ |
||||||
|
struct rxdata_entry_desc { |
||||||
|
int signal; |
||||||
|
int rssi; |
||||||
|
int ofdm; |
||||||
|
int size; |
||||||
|
int flags; |
||||||
|
}; |
||||||
|
|
||||||
|
/*
|
||||||
|
* txdata_entry_desc |
||||||
|
* Summary of information that should be written into the |
||||||
|
* descriptor for sending a TX frame. |
||||||
|
*/ |
||||||
|
struct txdata_entry_desc { |
||||||
|
unsigned long flags; |
||||||
|
#define ENTRY_TXDONE 1 |
||||||
|
#define ENTRY_TXD_RTS_FRAME 2 |
||||||
|
#define ENTRY_TXD_OFDM_RATE 3 |
||||||
|
#define ENTRY_TXD_MORE_FRAG 4 |
||||||
|
#define ENTRY_TXD_REQ_TIMESTAMP 5 |
||||||
|
#define ENTRY_TXD_BURST 6 |
||||||
|
|
||||||
|
/*
|
||||||
|
* Queue ID. ID's 0-4 are data TX rings |
||||||
|
*/ |
||||||
|
int queue; |
||||||
|
#define QUEUE_MGMT 13 |
||||||
|
#define QUEUE_RX 14 |
||||||
|
#define QUEUE_OTHER 15 |
||||||
|
|
||||||
|
/*
|
||||||
|
* PLCP values. |
||||||
|
*/ |
||||||
|
u16 length_high; |
||||||
|
u16 length_low; |
||||||
|
u16 signal; |
||||||
|
u16 service; |
||||||
|
|
||||||
|
/*
|
||||||
|
* Timing information |
||||||
|
*/ |
||||||
|
int aifs; |
||||||
|
int ifs; |
||||||
|
int cw_min; |
||||||
|
int cw_max; |
||||||
|
}; |
||||||
|
|
||||||
|
/*
|
||||||
|
* data_entry |
||||||
|
* The data ring is a list of data entries. |
||||||
|
* Each entry holds a reference to the descriptor |
||||||
|
* and the data buffer. For TX rings the reference to the |
||||||
|
* sk_buff of the packet being transmitted is also stored here. |
||||||
|
*/ |
||||||
|
struct data_entry { |
||||||
|
/*
|
||||||
|
* Status flags |
||||||
|
*/ |
||||||
|
unsigned long flags; |
||||||
|
#define ENTRY_OWNER_NIC 1 |
||||||
|
|
||||||
|
/*
|
||||||
|
* Ring we belong to. |
||||||
|
*/ |
||||||
|
struct data_ring *ring; |
||||||
|
|
||||||
|
/*
|
||||||
|
* sk_buff for the packet which is being transmitted |
||||||
|
* in this entry (Only used with TX related rings). |
||||||
|
*/ |
||||||
|
struct sk_buff *skb; |
||||||
|
|
||||||
|
/*
|
||||||
|
* Store a ieee80211_tx_status structure in each |
||||||
|
* ring entry, this will optimize the txdone |
||||||
|
* handler. |
||||||
|
*/ |
||||||
|
struct ieee80211_tx_status tx_status; |
||||||
|
|
||||||
|
/*
|
||||||
|
* private pointer specific to driver. |
||||||
|
*/ |
||||||
|
void *priv; |
||||||
|
|
||||||
|
/*
|
||||||
|
* Data address for this entry. |
||||||
|
*/ |
||||||
|
void *data_addr; |
||||||
|
dma_addr_t data_dma; |
||||||
|
}; |
||||||
|
|
||||||
|
/*
|
||||||
|
* data_ring |
||||||
|
* Data rings are used by the device to send and receive packets. |
||||||
|
* The data_addr is the base address of the data memory. |
||||||
|
* To determine at which point in the ring we are, |
||||||
|
* have to use the rt2x00_ring_index_*() functions. |
||||||
|
*/ |
||||||
|
struct data_ring { |
||||||
|
/*
|
||||||
|
* Pointer to main rt2x00dev structure where this |
||||||
|
* ring belongs to. |
||||||
|
*/ |
||||||
|
struct rt2x00_dev *rt2x00dev; |
||||||
|
|
||||||
|
/*
|
||||||
|
* Base address for the device specific data entries. |
||||||
|
*/ |
||||||
|
struct data_entry *entry; |
||||||
|
|
||||||
|
/*
|
||||||
|
* TX queue statistic info. |
||||||
|
*/ |
||||||
|
struct ieee80211_tx_queue_stats_data stats; |
||||||
|
|
||||||
|
/*
|
||||||
|
* TX Queue parameters. |
||||||
|
*/ |
||||||
|
struct ieee80211_tx_queue_params tx_params; |
||||||
|
|
||||||
|
/*
|
||||||
|
* Base address for data ring. |
||||||
|
*/ |
||||||
|
dma_addr_t data_dma; |
||||||
|
void *data_addr; |
||||||
|
|
||||||
|
/*
|
||||||
|
* Index variables. |
||||||
|
*/ |
||||||
|
u16 index; |
||||||
|
u16 index_done; |
||||||
|
|
||||||
|
/*
|
||||||
|
* Size of packet and descriptor in bytes. |
||||||
|
*/ |
||||||
|
u16 data_size; |
||||||
|
u16 desc_size; |
||||||
|
}; |
||||||
|
|
||||||
|
/*
|
||||||
|
* Handlers to determine the address of the current device specific |
||||||
|
* data entry, where either index or index_done points to. |
||||||
|
*/ |
||||||
|
static inline struct data_entry *rt2x00_get_data_entry(struct data_ring *ring) |
||||||
|
{ |
||||||
|
return &ring->entry[ring->index]; |
||||||
|
} |
||||||
|
|
||||||
|
static inline struct data_entry *rt2x00_get_data_entry_done(struct data_ring |
||||||
|
*ring) |
||||||
|
{ |
||||||
|
return &ring->entry[ring->index_done]; |
||||||
|
} |
||||||
|
|
||||||
|
/*
|
||||||
|
* Total ring memory |
||||||
|
*/ |
||||||
|
static inline int rt2x00_get_ring_size(struct data_ring *ring) |
||||||
|
{ |
||||||
|
return ring->stats.limit * (ring->desc_size + ring->data_size); |
||||||
|
} |
||||||
|
|
||||||
|
/*
|
||||||
|
* Ring index manipulation functions. |
||||||
|
*/ |
||||||
|
static inline void rt2x00_ring_index_inc(struct data_ring *ring) |
||||||
|
{ |
||||||
|
ring->index++; |
||||||
|
if (ring->index >= ring->stats.limit) |
||||||
|
ring->index = 0; |
||||||
|
ring->stats.len++; |
||||||
|
} |
||||||
|
|
||||||
|
static inline void rt2x00_ring_index_done_inc(struct data_ring *ring) |
||||||
|
{ |
||||||
|
ring->index_done++; |
||||||
|
if (ring->index_done >= ring->stats.limit) |
||||||
|
ring->index_done = 0; |
||||||
|
ring->stats.len--; |
||||||
|
ring->stats.count++; |
||||||
|
} |
||||||
|
|
||||||
|
static inline void rt2x00_ring_index_clear(struct data_ring *ring) |
||||||
|
{ |
||||||
|
ring->index = 0; |
||||||
|
ring->index_done = 0; |
||||||
|
ring->stats.len = 0; |
||||||
|
ring->stats.count = 0; |
||||||
|
} |
||||||
|
|
||||||
|
static inline int rt2x00_ring_empty(struct data_ring *ring) |
||||||
|
{ |
||||||
|
return ring->stats.len == 0; |
||||||
|
} |
||||||
|
|
||||||
|
static inline int rt2x00_ring_full(struct data_ring *ring) |
||||||
|
{ |
||||||
|
return ring->stats.len == ring->stats.limit; |
||||||
|
} |
||||||
|
|
||||||
|
static inline int rt2x00_ring_free(struct data_ring *ring) |
||||||
|
{ |
||||||
|
return ring->stats.limit - ring->stats.len; |
||||||
|
} |
||||||
|
|
||||||
|
/*
|
||||||
|
* TX/RX Descriptor access functions. |
||||||
|
*/ |
||||||
|
static inline void rt2x00_desc_read(struct data_desc *desc, |
||||||
|
const u8 word, u32 *value) |
||||||
|
{ |
||||||
|
*value = le32_to_cpu(desc->word[word]); |
||||||
|
} |
||||||
|
|
||||||
|
static inline void rt2x00_desc_write(struct data_desc *desc, |
||||||
|
const u8 word, const u32 value) |
||||||
|
{ |
||||||
|
desc->word[word] = cpu_to_le32(value); |
||||||
|
} |
||||||
|
|
||||||
|
#endif /* RT2X00RING_H */ |
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Loading…
Reference in new issue