Merge branch 'no-ath9k' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-2.6

This commit is contained in:
David S. Miller 2008-08-05 01:28:35 -07:00
commit 33e334950a
37 changed files with 794 additions and 723 deletions

View File

@ -14,18 +14,49 @@ config IWLWIFI_LEDS
default n default n
config IWLWIFI_RFKILL config IWLWIFI_RFKILL
boolean "IWLWIFI RF kill support" boolean "Iwlwifi RF kill support"
depends on IWLCORE depends on IWLCORE
config IWL4965 config IWLWIFI_DEBUG
tristate "Intel Wireless WiFi 4965AGN" bool "Enable full debugging output in iwlagn driver"
depends on IWLCORE
---help---
This option will enable debug tracing output for the iwlwifi drivers
This will result in the kernel module being ~100k larger. You can
control which debug output is sent to the kernel log by setting the
value in
/sys/class/net/wlan0/device/debug_level
This entry will only exist if this option is enabled.
To set a value, simply echo an 8-byte hex value to the same file:
% echo 0x43fff > /sys/class/net/wlan0/device/debug_level
You can find the list of debug mask values in:
drivers/net/wireless/iwlwifi/iwl-debug.h
If this is your first time using this driver, you should say Y here
as the debug information can assist others in helping you resolve
any problems you may encounter.
config IWLWIFI_DEBUGFS
bool "Iwlwifi debugfs support"
depends on IWLCORE && IWLWIFI_DEBUG && MAC80211_DEBUGFS
---help---
Enable creation of debugfs files for the iwlwifi drivers.
config IWLAGN
tristate "Intel Wireless WiFi Next Gen AGN"
depends on PCI && MAC80211 && WLAN_80211 && EXPERIMENTAL depends on PCI && MAC80211 && WLAN_80211 && EXPERIMENTAL
select FW_LOADER select FW_LOADER
select IWLCORE select IWLCORE
---help--- ---help---
Select to build the driver supporting the: Select to build the driver supporting the:
Intel Wireless WiFi Link 4965AGN Intel Wireless WiFi Link Next-Gen AGN
This driver uses the kernel's mac80211 subsystem. This driver uses the kernel's mac80211 subsystem.
@ -42,60 +73,33 @@ config IWL4965
If you want to compile the driver as a module ( = code which can be If you want to compile the driver as a module ( = code which can be
inserted in and removed from the running kernel whenever you want), inserted in and removed from the running kernel whenever you want),
say M here and read <file:Documentation/kbuild/modules.txt>. The say M here and read <file:Documentation/kbuild/modules.txt>. The
module will be called iwl4965.ko. module will be called iwlagn.ko.
config IWL4965_LEDS config IWLAGN_SPECTRUM_MEASUREMENT
bool "Enable LEDS features in iwl4965 driver" bool "Enable Spectrum Measurement in iwlagn driver"
depends on IWL4965 depends on IWLAGN
---help---
This option will enable spectrum measurement for the iwlagn driver.
config IWLAGN_LEDS
bool "Enable LEDS features in iwlagn driver"
depends on IWLAGN
select IWLWIFI_LEDS select IWLWIFI_LEDS
---help--- ---help---
This option enables LEDS for the iwlwifi drivers This option enables LEDS for the iwlagn drivers
config IWL4965_SPECTRUM_MEASUREMENT config IWL4965
bool "Enable Spectrum Measurement in iwl4965 driver" bool "Intel Wireless WiFi 4965AGN"
depends on IWL4965 depends on IWLAGN
---help--- ---help---
This option will enable spectrum measurement for the iwl4965 driver. This option enables support for Intel Wireless WiFi Link 4965AGN
config IWLWIFI_DEBUG
bool "Enable full debugging output in iwl4965 driver"
depends on IWL4965
---help---
This option will enable debug tracing output for the iwl4965
driver.
This will result in the kernel module being ~100k larger. You can
control which debug output is sent to the kernel log by setting the
value in
/sys/class/net/wlan0/device/debug_level
This entry will only exist if this option is enabled.
To set a value, simply echo an 8-byte hex value to the same file:
% echo 0x43fff > /sys/class/net/wlan0/device/debug_level
You can find the list of debug mask values in:
drivers/net/wireless/iwlwifi/iwl-4965-debug.h
If this is your first time using this driver, you should say Y here
as the debug information can assist others in helping you resolve
any problems you may encounter.
config IWL5000 config IWL5000
bool "Intel Wireless WiFi 5000AGN" bool "Intel Wireless WiFi 5000AGN"
depends on IWL4965 depends on IWLAGN
---help--- ---help---
This option enables support for Intel Wireless WiFi Link 5000AGN Family This option enables support for Intel Wireless WiFi Link 5000AGN Family
Dependency on 4965 is temporary
config IWLWIFI_DEBUGFS
bool "Iwlwifi debugfs support"
depends on IWLCORE && IWLWIFI_DEBUG && MAC80211_DEBUGFS
---help---
Enable creation of debugfs files for the iwlwifi drivers.
config IWL3945 config IWL3945
tristate "Intel PRO/Wireless 3945ABG/BG Network Connection" tristate "Intel PRO/Wireless 3945ABG/BG Network Connection"

View File

@ -6,15 +6,14 @@ iwlcore-$(CONFIG_IWLWIFI_DEBUGFS) += iwl-debugfs.o
iwlcore-$(CONFIG_IWLWIFI_LEDS) += iwl-led.o iwlcore-$(CONFIG_IWLWIFI_LEDS) += iwl-led.o
iwlcore-$(CONFIG_IWLWIFI_RFKILL) += iwl-rfkill.o iwlcore-$(CONFIG_IWLWIFI_RFKILL) += iwl-rfkill.o
obj-$(CONFIG_IWLAGN) += iwlagn.o
iwlagn-objs := iwl-agn.o iwl-agn-rs.o
iwlagn-$(CONFIG_IWL4965) += iwl-4965.o
iwlagn-$(CONFIG_IWL5000) += iwl-5000.o
obj-$(CONFIG_IWL3945) += iwl3945.o obj-$(CONFIG_IWL3945) += iwl3945.o
iwl3945-objs := iwl3945-base.o iwl-3945.o iwl-3945-rs.o iwl3945-objs := iwl3945-base.o iwl-3945.o iwl-3945-rs.o
iwl3945-$(CONFIG_IWL3945_LEDS) += iwl-3945-led.o iwl3945-$(CONFIG_IWL3945_LEDS) += iwl-3945-led.o
obj-$(CONFIG_IWL4965) += iwl4965.o
iwl4965-objs := iwl4965-base.o iwl-4965.o iwl-4965-rs.o
ifeq ($(CONFIG_IWL5000),y)
iwl4965-objs += iwl-5000.o
endif

View File

@ -206,12 +206,12 @@ static void iwl3945_led_brightness_set(struct led_classdev *led_cdev,
static int iwl3945_led_register_led(struct iwl3945_priv *priv, static int iwl3945_led_register_led(struct iwl3945_priv *priv,
struct iwl3945_led *led, struct iwl3945_led *led,
enum led_type type, u8 set_led, enum led_type type, u8 set_led,
const char *name, char *trigger) char *trigger)
{ {
struct device *device = wiphy_dev(priv->hw->wiphy); struct device *device = wiphy_dev(priv->hw->wiphy);
int ret; int ret;
led->led_dev.name = name; led->led_dev.name = led->name;
led->led_dev.brightness_set = iwl3945_led_brightness_set; led->led_dev.brightness_set = iwl3945_led_brightness_set;
led->led_dev.default_trigger = trigger; led->led_dev.default_trigger = trigger;
@ -308,7 +308,6 @@ void iwl3945_led_background(struct iwl3945_priv *priv)
int iwl3945_led_register(struct iwl3945_priv *priv) int iwl3945_led_register(struct iwl3945_priv *priv)
{ {
char *trigger; char *trigger;
char name[32];
int ret; int ret;
priv->last_blink_rate = 0; priv->last_blink_rate = 0;
@ -318,7 +317,8 @@ int iwl3945_led_register(struct iwl3945_priv *priv)
priv->allow_blinking = 0; priv->allow_blinking = 0;
trigger = ieee80211_get_radio_led_name(priv->hw); trigger = ieee80211_get_radio_led_name(priv->hw);
snprintf(name, sizeof(name), "iwl-%s:radio", snprintf(priv->led[IWL_LED_TRG_RADIO].name,
sizeof(priv->led[IWL_LED_TRG_RADIO].name), "iwl-%s:radio",
wiphy_name(priv->hw->wiphy)); wiphy_name(priv->hw->wiphy));
priv->led[IWL_LED_TRG_RADIO].led_on = iwl3945_led_on; priv->led[IWL_LED_TRG_RADIO].led_on = iwl3945_led_on;
@ -327,19 +327,20 @@ int iwl3945_led_register(struct iwl3945_priv *priv)
ret = iwl3945_led_register_led(priv, ret = iwl3945_led_register_led(priv,
&priv->led[IWL_LED_TRG_RADIO], &priv->led[IWL_LED_TRG_RADIO],
IWL_LED_TRG_RADIO, 1, IWL_LED_TRG_RADIO, 1, trigger);
name, trigger);
if (ret) if (ret)
goto exit_fail; goto exit_fail;
trigger = ieee80211_get_assoc_led_name(priv->hw); trigger = ieee80211_get_assoc_led_name(priv->hw);
snprintf(name, sizeof(name), "iwl-%s:assoc", snprintf(priv->led[IWL_LED_TRG_ASSOC].name,
sizeof(priv->led[IWL_LED_TRG_ASSOC].name), "iwl-%s:assoc",
wiphy_name(priv->hw->wiphy)); wiphy_name(priv->hw->wiphy));
ret = iwl3945_led_register_led(priv, ret = iwl3945_led_register_led(priv,
&priv->led[IWL_LED_TRG_ASSOC], &priv->led[IWL_LED_TRG_ASSOC],
IWL_LED_TRG_ASSOC, 0, IWL_LED_TRG_ASSOC, 0, trigger);
name, trigger);
/* for assoc always turn led on */ /* for assoc always turn led on */
priv->led[IWL_LED_TRG_ASSOC].led_on = iwl3945_led_on; priv->led[IWL_LED_TRG_ASSOC].led_on = iwl3945_led_on;
priv->led[IWL_LED_TRG_ASSOC].led_off = iwl3945_led_on; priv->led[IWL_LED_TRG_ASSOC].led_off = iwl3945_led_on;
@ -349,14 +350,13 @@ int iwl3945_led_register(struct iwl3945_priv *priv)
goto exit_fail; goto exit_fail;
trigger = ieee80211_get_rx_led_name(priv->hw); trigger = ieee80211_get_rx_led_name(priv->hw);
snprintf(name, sizeof(name), "iwl-%s:RX", snprintf(priv->led[IWL_LED_TRG_RX].name,
sizeof(priv->led[IWL_LED_TRG_RX].name), "iwl-%s:RX",
wiphy_name(priv->hw->wiphy)); wiphy_name(priv->hw->wiphy));
ret = iwl3945_led_register_led(priv, ret = iwl3945_led_register_led(priv,
&priv->led[IWL_LED_TRG_RX], &priv->led[IWL_LED_TRG_RX],
IWL_LED_TRG_RX, 0, IWL_LED_TRG_RX, 0, trigger);
name, trigger);
priv->led[IWL_LED_TRG_RX].led_on = iwl3945_led_associated; priv->led[IWL_LED_TRG_RX].led_on = iwl3945_led_associated;
priv->led[IWL_LED_TRG_RX].led_off = iwl3945_led_associated; priv->led[IWL_LED_TRG_RX].led_off = iwl3945_led_associated;
@ -366,13 +366,14 @@ int iwl3945_led_register(struct iwl3945_priv *priv)
goto exit_fail; goto exit_fail;
trigger = ieee80211_get_tx_led_name(priv->hw); trigger = ieee80211_get_tx_led_name(priv->hw);
snprintf(name, sizeof(name), "iwl-%s:TX", snprintf(priv->led[IWL_LED_TRG_TX].name,
sizeof(priv->led[IWL_LED_TRG_TX].name), "iwl-%s:TX",
wiphy_name(priv->hw->wiphy)); wiphy_name(priv->hw->wiphy));
ret = iwl3945_led_register_led(priv, ret = iwl3945_led_register_led(priv,
&priv->led[IWL_LED_TRG_TX], &priv->led[IWL_LED_TRG_TX],
IWL_LED_TRG_TX, 0, IWL_LED_TRG_TX, 0, trigger);
name, trigger);
priv->led[IWL_LED_TRG_TX].led_on = iwl3945_led_associated; priv->led[IWL_LED_TRG_TX].led_on = iwl3945_led_associated;
priv->led[IWL_LED_TRG_TX].led_off = iwl3945_led_associated; priv->led[IWL_LED_TRG_TX].led_off = iwl3945_led_associated;
priv->led[IWL_LED_TRG_TX].led_pattern = iwl3945_led_pattern; priv->led[IWL_LED_TRG_TX].led_pattern = iwl3945_led_pattern;

View File

@ -50,6 +50,7 @@ enum led_type {
struct iwl3945_led { struct iwl3945_led {
struct iwl3945_priv *priv; struct iwl3945_priv *priv;
struct led_classdev led_dev; struct led_classdev led_dev;
char name[32];
int (*led_on) (struct iwl3945_priv *priv, int led_id); int (*led_on) (struct iwl3945_priv *priv, int led_id);
int (*led_off) (struct iwl3945_priv *priv, int led_id); int (*led_off) (struct iwl3945_priv *priv, int led_id);

View File

@ -795,8 +795,7 @@ static void iwl3945_rx_reply_rx(struct iwl3945_priv *priv,
struct ieee80211_mgmt *mgmt = struct ieee80211_mgmt *mgmt =
(struct ieee80211_mgmt *)header; (struct ieee80211_mgmt *)header;
__le32 *pos; __le32 *pos;
pos = pos = (__le32 *)&mgmt->u.beacon.
(__le32 *) & mgmt->u.beacon.
timestamp; timestamp;
priv->timestamp0 = le32_to_cpu(pos[0]); priv->timestamp0 = le32_to_cpu(pos[0]);
priv->timestamp1 = le32_to_cpu(pos[1]); priv->timestamp1 = le32_to_cpu(pos[1]);
@ -1509,7 +1508,7 @@ static int iwl3945_hw_reg_adjust_power_by_temp(int new_reading, int old_reading)
*/ */
static inline int iwl3945_hw_reg_temp_out_of_range(int temperature) static inline int iwl3945_hw_reg_temp_out_of_range(int temperature)
{ {
return (((temperature < -260) || (temperature > 25)) ? 1 : 0); return ((temperature < -260) || (temperature > 25)) ? 1 : 0;
} }
int iwl3945_hw_get_temperature(struct iwl3945_priv *priv) int iwl3945_hw_get_temperature(struct iwl3945_priv *priv)
@ -2630,7 +2629,7 @@ unsigned int iwl3945_hw_get_beacon_cmd(struct iwl3945_priv *priv,
tx_beacon_cmd->tx.supp_rates[1] = tx_beacon_cmd->tx.supp_rates[1] =
(IWL_CCK_BASIC_RATES_MASK & 0xF); (IWL_CCK_BASIC_RATES_MASK & 0xF);
return (sizeof(struct iwl3945_tx_beacon_cmd) + frame_size); return sizeof(struct iwl3945_tx_beacon_cmd) + frame_size;
} }
void iwl3945_hw_rx_handler_setup(struct iwl3945_priv *priv) void iwl3945_hw_rx_handler_setup(struct iwl3945_priv *priv)

View File

@ -341,39 +341,6 @@ static int iwl4965_eeprom_check_version(struct iwl_priv *priv)
return -EINVAL; return -EINVAL;
} }
int iwl4965_set_pwr_src(struct iwl_priv *priv, enum iwl_pwr_src src)
{
int ret;
unsigned long flags;
spin_lock_irqsave(&priv->lock, flags);
ret = iwl_grab_nic_access(priv);
if (ret) {
spin_unlock_irqrestore(&priv->lock, flags);
return ret;
}
if (src == IWL_PWR_SRC_VAUX) {
u32 val;
ret = pci_read_config_dword(priv->pci_dev, PCI_POWER_SOURCE,
&val);
if (val & PCI_CFG_PMC_PME_FROM_D3COLD_SUPPORT) {
iwl_set_bits_mask_prph(priv, APMG_PS_CTRL_REG,
APMG_PS_CTRL_VAL_PWR_SRC_VAUX,
~APMG_PS_CTRL_MSK_PWR_SRC);
}
} else {
iwl_set_bits_mask_prph(priv, APMG_PS_CTRL_REG,
APMG_PS_CTRL_VAL_PWR_SRC_VMAIN,
~APMG_PS_CTRL_MSK_PWR_SRC);
}
iwl_release_nic_access(priv);
spin_unlock_irqrestore(&priv->lock, flags);
return ret;
}
/* /*
* Activate/Deactivat Tx DMA/FIFO channels according tx fifos mask * Activate/Deactivat Tx DMA/FIFO channels according tx fifos mask
@ -875,18 +842,6 @@ static int iwl4965_hw_set_hw_params(struct iwl_priv *priv)
return 0; return 0;
} }
/* set card power command */
static int iwl4965_set_power(struct iwl_priv *priv,
void *cmd)
{
int ret = 0;
ret = iwl_send_cmd_pdu_async(priv, POWER_TABLE_CMD,
sizeof(struct iwl4965_powertable_cmd),
cmd, NULL);
return ret;
}
static s32 iwl4965_math_div_round(s32 num, s32 denom, s32 *res) static s32 iwl4965_math_div_round(s32 num, s32 denom, s32 *res)
{ {
s32 sign = 1; s32 sign = 1;
@ -1560,11 +1515,11 @@ static int iwl4965_fill_txpower_tbl(struct iwl_priv *priv, u8 band, u16 channel,
c, atten_value, power_index, c, atten_value, power_index,
tx_power.s.radio_tx_gain[c], tx_power.s.radio_tx_gain[c],
tx_power.s.dsp_predis_atten[c]); tx_power.s.dsp_predis_atten[c]);
}/* for each chain */ } /* for each chain */
tx_power_tbl->power_tbl[i].dw = cpu_to_le32(tx_power.dw); tx_power_tbl->power_tbl[i].dw = cpu_to_le32(tx_power.dw);
}/* for each rate */ } /* for each rate */
return 0; return 0;
} }
@ -1701,38 +1656,6 @@ static int iwl4965_shared_mem_rx_idx(struct iwl_priv *priv)
return le32_to_cpu(s->rb_closed) & 0xFFF; return le32_to_cpu(s->rb_closed) & 0xFFF;
} }
unsigned int iwl4965_hw_get_beacon_cmd(struct iwl_priv *priv,
struct iwl_frame *frame, u8 rate)
{
struct iwl4965_tx_beacon_cmd *tx_beacon_cmd;
unsigned int frame_size;
tx_beacon_cmd = &frame->u.beacon;
memset(tx_beacon_cmd, 0, sizeof(*tx_beacon_cmd));
tx_beacon_cmd->tx.sta_id = priv->hw_params.bcast_sta_id;
tx_beacon_cmd->tx.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE;
frame_size = iwl4965_fill_beacon_frame(priv,
tx_beacon_cmd->frame,
iwl_bcast_addr,
sizeof(frame->u) - sizeof(*tx_beacon_cmd));
BUG_ON(frame_size > MAX_MPDU_SIZE);
tx_beacon_cmd->tx.len = cpu_to_le16((u16)frame_size);
if ((rate == IWL_RATE_1M_PLCP) || (rate >= IWL_RATE_2M_PLCP))
tx_beacon_cmd->tx.rate_n_flags =
iwl_hw_set_rate_n_flags(rate, RATE_MCS_CCK_MSK);
else
tx_beacon_cmd->tx.rate_n_flags =
iwl_hw_set_rate_n_flags(rate, 0);
tx_beacon_cmd->tx.tx_flags = (TX_CMD_FLG_SEQ_CTL_MSK |
TX_CMD_FLG_TSF_MSK | TX_CMD_FLG_STA_RATE_MSK);
return (sizeof(*tx_beacon_cmd) + frame_size);
}
static int iwl4965_alloc_shared_mem(struct iwl_priv *priv) static int iwl4965_alloc_shared_mem(struct iwl_priv *priv)
{ {
priv->shared_virt = pci_alloc_consistent(priv->pci_dev, priv->shared_virt = pci_alloc_consistent(priv->pci_dev,
@ -2079,39 +2002,6 @@ static int iwl4965_txq_agg_enable(struct iwl_priv *priv, int txq_id,
return 0; return 0;
} }
int iwl4965_mac_ampdu_action(struct ieee80211_hw *hw,
enum ieee80211_ampdu_mlme_action action,
const u8 *addr, u16 tid, u16 *ssn)
{
struct iwl_priv *priv = hw->priv;
DECLARE_MAC_BUF(mac);
IWL_DEBUG_HT("A-MPDU action on addr %s tid %d\n",
print_mac(mac, addr), tid);
if (!(priv->cfg->sku & IWL_SKU_N))
return -EACCES;
switch (action) {
case IEEE80211_AMPDU_RX_START:
IWL_DEBUG_HT("start Rx\n");
return iwl_rx_agg_start(priv, addr, tid, *ssn);
case IEEE80211_AMPDU_RX_STOP:
IWL_DEBUG_HT("stop Rx\n");
return iwl_rx_agg_stop(priv, addr, tid);
case IEEE80211_AMPDU_TX_START:
IWL_DEBUG_HT("start Tx\n");
return iwl_tx_agg_start(priv, addr, tid, ssn);
case IEEE80211_AMPDU_TX_STOP:
IWL_DEBUG_HT("stop Tx\n");
return iwl_tx_agg_stop(priv, addr, tid);
default:
IWL_DEBUG_HT("unknown\n");
return -EINVAL;
break;
}
return 0;
}
static u16 iwl4965_get_hcmd_size(u8 cmd_id, u16 len) static u16 iwl4965_get_hcmd_size(u8 cmd_id, u16 len)
{ {
@ -2240,9 +2130,9 @@ static int iwl4965_tx_status_reply_tx(struct iwl_priv *priv,
bitmap = bitmap << sh; bitmap = bitmap << sh;
sh = 0; sh = 0;
} }
bitmap |= (1 << sh); bitmap |= 1ULL << sh;
IWL_DEBUG_TX_REPLY("start=%d bitmap=0x%x\n", IWL_DEBUG_TX_REPLY("start=%d bitmap=0x%llx\n",
start, (u32)(bitmap & 0xFFFFFFFF)); start, (unsigned long long)bitmap);
} }
agg->bitmap = bitmap; agg->bitmap = bitmap;
@ -2368,6 +2258,40 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv,
IWL_ERROR("TODO: Implement Tx ABORT REQUIRED!!!\n"); IWL_ERROR("TODO: Implement Tx ABORT REQUIRED!!!\n");
} }
static int iwl4965_calc_rssi(struct iwl_priv *priv,
struct iwl_rx_phy_res *rx_resp)
{
/* data from PHY/DSP regarding signal strength, etc.,
* contents are always there, not configurable by host. */
struct iwl4965_rx_non_cfg_phy *ncphy =
(struct iwl4965_rx_non_cfg_phy *)rx_resp->non_cfg_phy_buf;
u32 agc = (le16_to_cpu(ncphy->agc_info) & IWL49_AGC_DB_MASK)
>> IWL49_AGC_DB_POS;
u32 valid_antennae =
(le16_to_cpu(rx_resp->phy_flags) & IWL49_RX_PHY_FLAGS_ANTENNAE_MASK)
>> IWL49_RX_PHY_FLAGS_ANTENNAE_OFFSET;
u8 max_rssi = 0;
u32 i;
/* Find max rssi among 3 possible receivers.
* These values are measured by the digital signal processor (DSP).
* They should stay fairly constant even as the signal strength varies,
* if the radio's automatic gain control (AGC) is working right.
* AGC value (see below) will provide the "interesting" info. */
for (i = 0; i < 3; i++)
if (valid_antennae & (1 << i))
max_rssi = max(ncphy->rssi_info[i << 1], max_rssi);
IWL_DEBUG_STATS("Rssi In A %d B %d C %d Max %d AGC dB %d\n",
ncphy->rssi_info[0], ncphy->rssi_info[2], ncphy->rssi_info[4],
max_rssi, agc);
/* dBm = max_rssi dB - agc dB - constant.
* Higher AGC (higher radio gain) means lower signal. */
return max_rssi - agc - IWL_RSSI_OFFSET;
}
/* Set up 4965-specific Rx frame reply handlers */ /* Set up 4965-specific Rx frame reply handlers */
static void iwl4965_rx_handler_setup(struct iwl_priv *priv) static void iwl4965_rx_handler_setup(struct iwl_priv *priv)
@ -2399,6 +2323,7 @@ static struct iwl_hcmd_utils_ops iwl4965_hcmd_utils = {
.chain_noise_reset = iwl4965_chain_noise_reset, .chain_noise_reset = iwl4965_chain_noise_reset,
.gain_computation = iwl4965_gain_computation, .gain_computation = iwl4965_gain_computation,
.rts_tx_cmd_flag = iwl4965_rts_tx_cmd_flag, .rts_tx_cmd_flag = iwl4965_rts_tx_cmd_flag,
.calc_rssi = iwl4965_calc_rssi,
}; };
static struct iwl_lib_ops iwl4965_lib = { static struct iwl_lib_ops iwl4965_lib = {
@ -2440,7 +2365,6 @@ static struct iwl_lib_ops iwl4965_lib = {
.check_version = iwl4965_eeprom_check_version, .check_version = iwl4965_eeprom_check_version,
.query_addr = iwlcore_eeprom_query_addr, .query_addr = iwlcore_eeprom_query_addr,
}, },
.set_power = iwl4965_set_power,
.send_tx_power = iwl4965_send_tx_power, .send_tx_power = iwl4965_send_tx_power,
.update_chain_flags = iwl4965_update_chain_flags, .update_chain_flags = iwl4965_update_chain_flags,
.temperature = iwl4965_temperature_calib, .temperature = iwl4965_temperature_calib,

View File

@ -93,6 +93,13 @@ static int iwl5000_apm_init(struct iwl_priv *priv)
iwl_set_bit(priv, CSR_GIO_CHICKEN_BITS, iwl_set_bit(priv, CSR_GIO_CHICKEN_BITS,
CSR_GIO_CHICKEN_BITS_REG_BIT_L1A_NO_L0S_RX); CSR_GIO_CHICKEN_BITS_REG_BIT_L1A_NO_L0S_RX);
/* Set FH wait treshold to maximum (HW error during stress W/A) */
iwl_set_bit(priv, CSR_DBG_HPET_MEM_REG, CSR_DBG_HPET_MEM_REG_VAL);
/* enable HAP INTA to move device L1a -> L0s */
iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG,
CSR_HW_IF_CONFIG_REG_BIT_HAP_WAKE_L1A);
iwl_set_bit(priv, CSR_ANA_PLL_CFG, CSR50_ANA_PLL_CFG_VAL); iwl_set_bit(priv, CSR_ANA_PLL_CFG, CSR50_ANA_PLL_CFG_VAL);
/* set "initialization complete" bit to move adapter /* set "initialization complete" bit to move adapter
@ -230,6 +237,16 @@ static void iwl5000_nic_config(struct iwl_priv *priv)
CSR_HW_IF_CONFIG_REG_BIT_RADIO_SI | CSR_HW_IF_CONFIG_REG_BIT_RADIO_SI |
CSR_HW_IF_CONFIG_REG_BIT_MAC_SI); CSR_HW_IF_CONFIG_REG_BIT_MAC_SI);
/* W/A : NIC is stuck in a reset state after Early PCIe power off
* (PCIe power is lost before PERST# is asserted),
* causing ME FW to lose ownership and not being able to obtain it back.
*/
iwl_grab_nic_access(priv);
iwl_set_bits_mask_prph(priv, APMG_PS_CTRL_REG,
APMG_PS_CTRL_EARLY_PWR_OFF_RESET_DIS,
~APMG_PS_CTRL_EARLY_PWR_OFF_RESET_DIS);
iwl_release_nic_access(priv);
spin_unlock_irqrestore(&priv->lock, flags); spin_unlock_irqrestore(&priv->lock, flags);
} }
@ -924,8 +941,8 @@ static void iwl5000_txq_update_byte_cnt_tbl(struct iwl_priv *priv,
len = byte_cnt + IWL_TX_CRC_SIZE + IWL_TX_DELIMITER_SIZE; len = byte_cnt + IWL_TX_CRC_SIZE + IWL_TX_DELIMITER_SIZE;
if (txq_id != IWL_CMD_QUEUE_NUM) { if (txq_id != IWL_CMD_QUEUE_NUM) {
sta = txq->cmd[txq->q.write_ptr].cmd.tx.sta_id; sta = txq->cmd[txq->q.write_ptr]->cmd.tx.sta_id;
sec_ctl = txq->cmd[txq->q.write_ptr].cmd.tx.sec_ctl; sec_ctl = txq->cmd[txq->q.write_ptr]->cmd.tx.sec_ctl;
switch (sec_ctl & TX_CMD_SEC_MSK) { switch (sec_ctl & TX_CMD_SEC_MSK) {
case TX_CMD_SEC_CCM: case TX_CMD_SEC_CCM:
@ -964,7 +981,7 @@ static void iwl5000_txq_inval_byte_cnt_tbl(struct iwl_priv *priv,
u8 sta = 0; u8 sta = 0;
if (txq_id != IWL_CMD_QUEUE_NUM) if (txq_id != IWL_CMD_QUEUE_NUM)
sta = txq->cmd[txq->q.read_ptr].cmd.tx.sta_id; sta = txq->cmd[txq->q.read_ptr]->cmd.tx.sta_id;
shared_data->queues_byte_cnt_tbls[txq_id].tfd_offset[txq->q.read_ptr]. shared_data->queues_byte_cnt_tbls[txq_id].tfd_offset[txq->q.read_ptr].
val = cpu_to_le16(1 | (sta << 12)); val = cpu_to_le16(1 | (sta << 12));
@ -1131,7 +1148,7 @@ static void iwl5000_txq_set_sched(struct iwl_priv *priv, u32 mask)
static inline u32 iwl5000_get_scd_ssn(struct iwl5000_tx_resp *tx_resp) static inline u32 iwl5000_get_scd_ssn(struct iwl5000_tx_resp *tx_resp)
{ {
return le32_to_cpup((__le32*)&tx_resp->status + return le32_to_cpup((__le32 *)&tx_resp->status +
tx_resp->frame_count) & MAX_SN; tx_resp->frame_count) & MAX_SN;
} }
@ -1228,9 +1245,9 @@ static int iwl5000_tx_status_reply_tx(struct iwl_priv *priv,
bitmap = bitmap << sh; bitmap = bitmap << sh;
sh = 0; sh = 0;
} }
bitmap |= (1 << sh); bitmap |= 1ULL << sh;
IWL_DEBUG_TX_REPLY("start=%d bitmap=0x%x\n", IWL_DEBUG_TX_REPLY("start=%d bitmap=0x%llx\n",
start, (u32)(bitmap & 0xFFFFFFFF)); start, (unsigned long long)bitmap);
} }
agg->bitmap = bitmap; agg->bitmap = bitmap;
@ -1444,6 +1461,44 @@ static void iwl5000_temperature(struct iwl_priv *priv)
priv->temperature = le32_to_cpu(priv->statistics.general.temperature); priv->temperature = le32_to_cpu(priv->statistics.general.temperature);
} }
/* Calc max signal level (dBm) among 3 possible receivers */
static int iwl5000_calc_rssi(struct iwl_priv *priv,
struct iwl_rx_phy_res *rx_resp)
{
/* data from PHY/DSP regarding signal strength, etc.,
* contents are always there, not configurable by host
*/
struct iwl5000_non_cfg_phy *ncphy =
(struct iwl5000_non_cfg_phy *)rx_resp->non_cfg_phy_buf;
u32 val, rssi_a, rssi_b, rssi_c, max_rssi;
u8 agc;
val = le32_to_cpu(ncphy->non_cfg_phy[IWL50_RX_RES_AGC_IDX]);
agc = (val & IWL50_OFDM_AGC_MSK) >> IWL50_OFDM_AGC_BIT_POS;
/* Find max rssi among 3 possible receivers.
* These values are measured by the digital signal processor (DSP).
* They should stay fairly constant even as the signal strength varies,
* if the radio's automatic gain control (AGC) is working right.
* AGC value (see below) will provide the "interesting" info.
*/
val = le32_to_cpu(ncphy->non_cfg_phy[IWL50_RX_RES_RSSI_AB_IDX]);
rssi_a = (val & IWL50_OFDM_RSSI_A_MSK) >> IWL50_OFDM_RSSI_A_BIT_POS;
rssi_b = (val & IWL50_OFDM_RSSI_B_MSK) >> IWL50_OFDM_RSSI_B_BIT_POS;
val = le32_to_cpu(ncphy->non_cfg_phy[IWL50_RX_RES_RSSI_C_IDX]);
rssi_c = (val & IWL50_OFDM_RSSI_C_MSK) >> IWL50_OFDM_RSSI_C_BIT_POS;
max_rssi = max_t(u32, rssi_a, rssi_b);
max_rssi = max_t(u32, max_rssi, rssi_c);
IWL_DEBUG_STATS("Rssi In A %d B %d C %d Max %d AGC dB %d\n",
rssi_a, rssi_b, rssi_c, max_rssi, agc);
/* dBm = max_rssi dB - agc dB - constant.
* Higher AGC (higher radio gain) means lower signal. */
return max_rssi - agc - IWL_RSSI_OFFSET;
}
static struct iwl_hcmd_ops iwl5000_hcmd = { static struct iwl_hcmd_ops iwl5000_hcmd = {
.rxon_assoc = iwl5000_send_rxon_assoc, .rxon_assoc = iwl5000_send_rxon_assoc,
}; };
@ -1454,6 +1509,7 @@ static struct iwl_hcmd_utils_ops iwl5000_hcmd_utils = {
.gain_computation = iwl5000_gain_computation, .gain_computation = iwl5000_gain_computation,
.chain_noise_reset = iwl5000_chain_noise_reset, .chain_noise_reset = iwl5000_chain_noise_reset,
.rts_tx_cmd_flag = iwl5000_rts_tx_cmd_flag, .rts_tx_cmd_flag = iwl5000_rts_tx_cmd_flag,
.calc_rssi = iwl5000_calc_rssi,
}; };
static struct iwl_lib_ops iwl5000_lib = { static struct iwl_lib_ops iwl5000_lib = {
@ -1474,6 +1530,7 @@ static struct iwl_lib_ops iwl5000_lib = {
.alive_notify = iwl5000_alive_notify, .alive_notify = iwl5000_alive_notify,
.send_tx_power = iwl5000_send_tx_power, .send_tx_power = iwl5000_send_tx_power,
.temperature = iwl5000_temperature, .temperature = iwl5000_temperature,
.update_chain_flags = iwl4965_update_chain_flags,
.apm_ops = { .apm_ops = {
.init = iwl5000_apm_init, .init = iwl5000_apm_init,
.reset = iwl5000_apm_reset, .reset = iwl5000_apm_reset,

View File

@ -42,7 +42,7 @@
#include "iwl-core.h" #include "iwl-core.h"
#include "iwl-helpers.h" #include "iwl-helpers.h"
#define RS_NAME "iwl-4965-rs" #define RS_NAME "iwl-agn-rs"
#define NUM_TRY_BEFORE_ANT_TOGGLE 1 #define NUM_TRY_BEFORE_ANT_TOGGLE 1
#define IWL_NUMBER_TRY 1 #define IWL_NUMBER_TRY 1
@ -77,9 +77,9 @@ static const u8 ant_toggle_lookup[] = {
}; };
/** /**
* struct iwl4965_rate_scale_data -- tx success history for one rate * struct iwl_rate_scale_data -- tx success history for one rate
*/ */
struct iwl4965_rate_scale_data { struct iwl_rate_scale_data {
u64 data; /* bitmap of successful frames */ u64 data; /* bitmap of successful frames */
s32 success_counter; /* number of frames successful */ s32 success_counter; /* number of frames successful */
s32 success_ratio; /* per-cent * 128 */ s32 success_ratio; /* per-cent * 128 */
@ -89,12 +89,12 @@ struct iwl4965_rate_scale_data {
}; };
/** /**
* struct iwl4965_scale_tbl_info -- tx params and success history for all rates * struct iwl_scale_tbl_info -- tx params and success history for all rates
* *
* There are two of these in struct iwl4965_lq_sta, * There are two of these in struct iwl_lq_sta,
* one for "active", and one for "search". * one for "active", and one for "search".
*/ */
struct iwl4965_scale_tbl_info { struct iwl_scale_tbl_info {
enum iwl_table_type lq_type; enum iwl_table_type lq_type;
u8 ant_type; u8 ant_type;
u8 is_SGI; /* 1 = short guard interval */ u8 is_SGI; /* 1 = short guard interval */
@ -103,10 +103,10 @@ struct iwl4965_scale_tbl_info {
u8 action; /* change modulation; IWL_[LEGACY/SISO/MIMO]_SWITCH_* */ u8 action; /* change modulation; IWL_[LEGACY/SISO/MIMO]_SWITCH_* */
s32 *expected_tpt; /* throughput metrics; expected_tpt_G, etc. */ s32 *expected_tpt; /* throughput metrics; expected_tpt_G, etc. */
u32 current_rate; /* rate_n_flags, uCode API format */ u32 current_rate; /* rate_n_flags, uCode API format */
struct iwl4965_rate_scale_data win[IWL_RATE_COUNT]; /* rate histories */ struct iwl_rate_scale_data win[IWL_RATE_COUNT]; /* rate histories */
}; };
struct iwl4965_traffic_load { struct iwl_traffic_load {
unsigned long time_stamp; /* age of the oldest statistics */ unsigned long time_stamp; /* age of the oldest statistics */
u32 packet_count[TID_QUEUE_MAX_SIZE]; /* packet count in this time u32 packet_count[TID_QUEUE_MAX_SIZE]; /* packet count in this time
* slice */ * slice */
@ -118,11 +118,11 @@ struct iwl4965_traffic_load {
}; };
/** /**
* struct iwl4965_lq_sta -- driver's rate scaling private structure * struct iwl_lq_sta -- driver's rate scaling private structure
* *
* Pointer to this gets passed back and forth between driver and mac80211. * Pointer to this gets passed back and forth between driver and mac80211.
*/ */
struct iwl4965_lq_sta { struct iwl_lq_sta {
u8 active_tbl; /* index of active table, range 0-1 */ u8 active_tbl; /* index of active table, range 0-1 */
u8 enable_counter; /* indicates HT mode */ u8 enable_counter; /* indicates HT mode */
u8 stay_in_tbl; /* 1: disallow, 0: allow search for new mode */ u8 stay_in_tbl; /* 1: disallow, 0: allow search for new mode */
@ -153,8 +153,8 @@ struct iwl4965_lq_sta {
u16 active_rate_basic; u16 active_rate_basic;
struct iwl_link_quality_cmd lq; struct iwl_link_quality_cmd lq;
struct iwl4965_scale_tbl_info lq_info[LQ_SIZE]; /* "active", "search" */ struct iwl_scale_tbl_info lq_info[LQ_SIZE]; /* "active", "search" */
struct iwl4965_traffic_load load[TID_MAX_LOAD_COUNT]; struct iwl_traffic_load load[TID_MAX_LOAD_COUNT];
u8 tx_agg_tid_en; u8 tx_agg_tid_en;
#ifdef CONFIG_MAC80211_DEBUGFS #ifdef CONFIG_MAC80211_DEBUGFS
struct dentry *rs_sta_dbgfs_scale_table_file; struct dentry *rs_sta_dbgfs_scale_table_file;
@ -170,16 +170,15 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
struct ieee80211_hdr *hdr, struct ieee80211_hdr *hdr,
struct sta_info *sta); struct sta_info *sta);
static void rs_fill_link_cmd(const struct iwl_priv *priv, static void rs_fill_link_cmd(const struct iwl_priv *priv,
struct iwl4965_lq_sta *lq_sta, struct iwl_lq_sta *lq_sta, u32 rate_n_flags);
u32 rate_n_flags);
#ifdef CONFIG_MAC80211_DEBUGFS #ifdef CONFIG_MAC80211_DEBUGFS
static void rs_dbgfs_set_mcs(struct iwl4965_lq_sta *lq_sta, static void rs_dbgfs_set_mcs(struct iwl_lq_sta *lq_sta,
u32 *rate_n_flags, int index); u32 *rate_n_flags, int index);
#else #else
static void rs_dbgfs_set_mcs(struct iwl4965_lq_sta *lq_sta, static void rs_dbgfs_set_mcs(struct iwl_lq_sta *lq_sta,
u32 *rate_n_flags, int index) u32 *rate_n_flags, int index)
{} {}
#endif #endif
@ -234,7 +233,7 @@ static inline u8 rs_extract_rate(u32 rate_n_flags)
return (u8)(rate_n_flags & 0xFF); return (u8)(rate_n_flags & 0xFF);
} }
static void rs_rate_scale_clear_window(struct iwl4965_rate_scale_data *window) static void rs_rate_scale_clear_window(struct iwl_rate_scale_data *window)
{ {
window->data = 0; window->data = 0;
window->success_counter = 0; window->success_counter = 0;
@ -246,14 +245,14 @@ static void rs_rate_scale_clear_window(struct iwl4965_rate_scale_data *window)
static inline u8 rs_is_valid_ant(u8 valid_antenna, u8 ant_type) static inline u8 rs_is_valid_ant(u8 valid_antenna, u8 ant_type)
{ {
return ((ant_type & valid_antenna) == ant_type); return (ant_type & valid_antenna) == ant_type;
} }
/* /*
* removes the old data from the statistics. All data that is older than * removes the old data from the statistics. All data that is older than
* TID_MAX_TIME_DIFF, will be deleted. * TID_MAX_TIME_DIFF, will be deleted.
*/ */
static void rs_tl_rm_old_stats(struct iwl4965_traffic_load *tl, u32 curr_time) static void rs_tl_rm_old_stats(struct iwl_traffic_load *tl, u32 curr_time)
{ {
/* The oldest age we want to keep */ /* The oldest age we want to keep */
u32 oldest_time = curr_time - TID_MAX_TIME_DIFF; u32 oldest_time = curr_time - TID_MAX_TIME_DIFF;
@ -274,13 +273,13 @@ static void rs_tl_rm_old_stats(struct iwl4965_traffic_load *tl, u32 curr_time)
* increment traffic load value for tid and also remove * increment traffic load value for tid and also remove
* any old values if passed the certain time period * any old values if passed the certain time period
*/ */
static u8 rs_tl_add_packet(struct iwl4965_lq_sta *lq_data, static u8 rs_tl_add_packet(struct iwl_lq_sta *lq_data,
struct ieee80211_hdr *hdr) struct ieee80211_hdr *hdr)
{ {
u32 curr_time = jiffies_to_msecs(jiffies); u32 curr_time = jiffies_to_msecs(jiffies);
u32 time_diff; u32 time_diff;
s32 index; s32 index;
struct iwl4965_traffic_load *tl = NULL; struct iwl_traffic_load *tl = NULL;
__le16 fc = hdr->frame_control; __le16 fc = hdr->frame_control;
u8 tid; u8 tid;
@ -325,12 +324,12 @@ static u8 rs_tl_add_packet(struct iwl4965_lq_sta *lq_data,
/* /*
get the traffic load value for tid get the traffic load value for tid
*/ */
static u32 rs_tl_get_load(struct iwl4965_lq_sta *lq_data, u8 tid) static u32 rs_tl_get_load(struct iwl_lq_sta *lq_data, u8 tid)
{ {
u32 curr_time = jiffies_to_msecs(jiffies); u32 curr_time = jiffies_to_msecs(jiffies);
u32 time_diff; u32 time_diff;
s32 index; s32 index;
struct iwl4965_traffic_load *tl = NULL; struct iwl_traffic_load *tl = NULL;
if (tid >= TID_MAX_LOAD_COUNT) if (tid >= TID_MAX_LOAD_COUNT)
return 0; return 0;
@ -354,8 +353,8 @@ static u32 rs_tl_get_load(struct iwl4965_lq_sta *lq_data, u8 tid)
} }
static void rs_tl_turn_on_agg_for_tid(struct iwl_priv *priv, static void rs_tl_turn_on_agg_for_tid(struct iwl_priv *priv,
struct iwl4965_lq_sta *lq_data, u8 tid, struct iwl_lq_sta *lq_data, u8 tid,
struct sta_info *sta) struct sta_info *sta)
{ {
unsigned long state; unsigned long state;
DECLARE_MAC_BUF(mac); DECLARE_MAC_BUF(mac);
@ -373,8 +372,8 @@ static void rs_tl_turn_on_agg_for_tid(struct iwl_priv *priv,
} }
static void rs_tl_turn_on_agg(struct iwl_priv *priv, u8 tid, static void rs_tl_turn_on_agg(struct iwl_priv *priv, u8 tid,
struct iwl4965_lq_sta *lq_data, struct iwl_lq_sta *lq_data,
struct sta_info *sta) struct sta_info *sta)
{ {
if ((tid < TID_MAX_LOAD_COUNT)) if ((tid < TID_MAX_LOAD_COUNT))
rs_tl_turn_on_agg_for_tid(priv, lq_data, tid, sta); rs_tl_turn_on_agg_for_tid(priv, lq_data, tid, sta);
@ -385,9 +384,9 @@ static void rs_tl_turn_on_agg(struct iwl_priv *priv, u8 tid,
static inline int get_num_of_ant_from_rate(u32 rate_n_flags) static inline int get_num_of_ant_from_rate(u32 rate_n_flags)
{ {
return (!!(rate_n_flags & RATE_MCS_ANT_A_MSK) + return !!(rate_n_flags & RATE_MCS_ANT_A_MSK) +
!!(rate_n_flags & RATE_MCS_ANT_B_MSK) + !!(rate_n_flags & RATE_MCS_ANT_B_MSK) +
!!(rate_n_flags & RATE_MCS_ANT_C_MSK)); !!(rate_n_flags & RATE_MCS_ANT_C_MSK);
} }
/** /**
@ -397,11 +396,11 @@ static inline int get_num_of_ant_from_rate(u32 rate_n_flags)
* at this rate. window->data contains the bitmask of successful * at this rate. window->data contains the bitmask of successful
* packets. * packets.
*/ */
static int rs_collect_tx_data(struct iwl4965_rate_scale_data *windows, static int rs_collect_tx_data(struct iwl_rate_scale_data *windows,
int scale_index, s32 tpt, int retries, int scale_index, s32 tpt, int retries,
int successes) int successes)
{ {
struct iwl4965_rate_scale_data *window = NULL; struct iwl_rate_scale_data *window = NULL;
static const u64 mask = (((u64)1) << (IWL_RATE_MAX_WINDOW - 1)); static const u64 mask = (((u64)1) << (IWL_RATE_MAX_WINDOW - 1));
s32 fail_count; s32 fail_count;
@ -473,7 +472,7 @@ static int rs_collect_tx_data(struct iwl4965_rate_scale_data *windows,
* Fill uCode API rate_n_flags field, based on "search" or "active" table. * Fill uCode API rate_n_flags field, based on "search" or "active" table.
*/ */
/* FIXME:RS:remove this function and put the flags statically in the table */ /* FIXME:RS:remove this function and put the flags statically in the table */
static u32 rate_n_flags_from_tbl(struct iwl4965_scale_tbl_info *tbl, static u32 rate_n_flags_from_tbl(struct iwl_scale_tbl_info *tbl,
int index, u8 use_green) int index, u8 use_green)
{ {
u32 rate_n_flags = 0; u32 rate_n_flags = 0;
@ -530,7 +529,7 @@ static u32 rate_n_flags_from_tbl(struct iwl4965_scale_tbl_info *tbl,
*/ */
static int rs_get_tbl_info_from_mcs(const u32 rate_n_flags, static int rs_get_tbl_info_from_mcs(const u32 rate_n_flags,
enum ieee80211_band band, enum ieee80211_band band,
struct iwl4965_scale_tbl_info *tbl, struct iwl_scale_tbl_info *tbl,
int *rate_idx) int *rate_idx)
{ {
u32 ant_msk = (rate_n_flags & RATE_MCS_ANT_ABC_MSK); u32 ant_msk = (rate_n_flags & RATE_MCS_ANT_ABC_MSK);
@ -591,7 +590,7 @@ static int rs_get_tbl_info_from_mcs(const u32 rate_n_flags,
/* switch to another antenna/antennas and return 1 */ /* switch to another antenna/antennas and return 1 */
/* if no other valid antenna found, return 0 */ /* if no other valid antenna found, return 0 */
static int rs_toggle_antenna(u32 valid_ant, u32 *rate_n_flags, static int rs_toggle_antenna(u32 valid_ant, u32 *rate_n_flags,
struct iwl4965_scale_tbl_info *tbl) struct iwl_scale_tbl_info *tbl)
{ {
u8 new_ant_type; u8 new_ant_type;
@ -621,9 +620,9 @@ static int rs_toggle_antenna(u32 valid_ant, u32 *rate_n_flags,
#if 0 #if 0
static inline u8 rs_use_green(struct iwl_priv *priv, struct ieee80211_conf *conf) static inline u8 rs_use_green(struct iwl_priv *priv, struct ieee80211_conf *conf)
{ {
return ((conf->flags & IEEE80211_CONF_SUPPORT_HT_MODE) && return (conf->flags & IEEE80211_CONF_SUPPORT_HT_MODE) &&
priv->current_ht_config.is_green_field && priv->current_ht_config.is_green_field &&
!priv->current_ht_config.non_GF_STA_present); !priv->current_ht_config.non_GF_STA_present;
} }
#endif #endif
static inline u8 rs_use_green(struct iwl_priv *priv, struct ieee80211_conf *conf) static inline u8 rs_use_green(struct iwl_priv *priv, struct ieee80211_conf *conf)
@ -638,9 +637,9 @@ static inline u8 rs_use_green(struct iwl_priv *priv, struct ieee80211_conf *conf
* basic available rates. * basic available rates.
* *
*/ */
static u16 rs_get_supported_rates(struct iwl4965_lq_sta *lq_sta, static u16 rs_get_supported_rates(struct iwl_lq_sta *lq_sta,
struct ieee80211_hdr *hdr, struct ieee80211_hdr *hdr,
enum iwl_table_type rate_type) enum iwl_table_type rate_type)
{ {
if (hdr && is_multicast_ether_addr(hdr->addr1) && if (hdr && is_multicast_ether_addr(hdr->addr1) &&
lq_sta->active_rate_basic) lq_sta->active_rate_basic)
@ -714,9 +713,9 @@ static u16 rs_get_adjacent_rate(struct iwl_priv *priv, u8 index, u16 rate_mask,
return (high << 8) | low; return (high << 8) | low;
} }
static u32 rs_get_lower_rate(struct iwl4965_lq_sta *lq_sta, static u32 rs_get_lower_rate(struct iwl_lq_sta *lq_sta,
struct iwl4965_scale_tbl_info *tbl, u8 scale_index, struct iwl_scale_tbl_info *tbl,
u8 ht_possible) u8 scale_index, u8 ht_possible)
{ {
s32 low; s32 low;
u16 rate_mask; u16 rate_mask;
@ -780,7 +779,7 @@ static void rs_tx_status(void *priv_rate, struct net_device *dev,
int status; int status;
u8 retries; u8 retries;
int rs_index, index = 0; int rs_index, index = 0;
struct iwl4965_lq_sta *lq_sta; struct iwl_lq_sta *lq_sta;
struct iwl_link_quality_cmd *table; struct iwl_link_quality_cmd *table;
struct sta_info *sta; struct sta_info *sta;
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
@ -788,11 +787,11 @@ static void rs_tx_status(void *priv_rate, struct net_device *dev,
struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
struct ieee80211_hw *hw = local_to_hw(local); struct ieee80211_hw *hw = local_to_hw(local);
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
struct iwl4965_rate_scale_data *window = NULL; struct iwl_rate_scale_data *window = NULL;
struct iwl4965_rate_scale_data *search_win = NULL; struct iwl_rate_scale_data *search_win = NULL;
u32 tx_rate; u32 tx_rate;
struct iwl4965_scale_tbl_info tbl_type; struct iwl_scale_tbl_info tbl_type;
struct iwl4965_scale_tbl_info *curr_tbl, *search_tbl; struct iwl_scale_tbl_info *curr_tbl, *search_tbl;
u8 active_index = 0; u8 active_index = 0;
__le16 fc = hdr->frame_control; __le16 fc = hdr->frame_control;
s32 tpt = 0; s32 tpt = 0;
@ -820,7 +819,7 @@ static void rs_tx_status(void *priv_rate, struct net_device *dev,
goto out; goto out;
lq_sta = (struct iwl4965_lq_sta *)sta->rate_ctrl_priv; lq_sta = (struct iwl_lq_sta *)sta->rate_ctrl_priv;
if ((priv->iw_mode == IEEE80211_IF_TYPE_IBSS) && if ((priv->iw_mode == IEEE80211_IF_TYPE_IBSS) &&
!lq_sta->ibss_sta_added) !lq_sta->ibss_sta_added)
@ -831,10 +830,8 @@ static void rs_tx_status(void *priv_rate, struct net_device *dev,
curr_tbl = &(lq_sta->lq_info[active_index]); curr_tbl = &(lq_sta->lq_info[active_index]);
search_tbl = &(lq_sta->lq_info[(1 - active_index)]); search_tbl = &(lq_sta->lq_info[(1 - active_index)]);
window = (struct iwl4965_rate_scale_data *) window = (struct iwl_rate_scale_data *)&(curr_tbl->win[0]);
&(curr_tbl->win[0]); search_win = (struct iwl_rate_scale_data *)&(search_tbl->win[0]);
search_win = (struct iwl4965_rate_scale_data *)
&(search_tbl->win[0]);
/* /*
* Ignore this Tx frame response if its initial rate doesn't match * Ignore this Tx frame response if its initial rate doesn't match
@ -983,7 +980,7 @@ static void rs_tx_status(void *priv_rate, struct net_device *dev,
* searching for a new mode. * searching for a new mode.
*/ */
static void rs_set_stay_in_table(struct iwl_priv *priv, u8 is_legacy, static void rs_set_stay_in_table(struct iwl_priv *priv, u8 is_legacy,
struct iwl4965_lq_sta *lq_sta) struct iwl_lq_sta *lq_sta)
{ {
IWL_DEBUG_RATE("we are staying in the same table\n"); IWL_DEBUG_RATE("we are staying in the same table\n");
lq_sta->stay_in_tbl = 1; /* only place this gets set */ lq_sta->stay_in_tbl = 1; /* only place this gets set */
@ -1004,8 +1001,8 @@ static void rs_set_stay_in_table(struct iwl_priv *priv, u8 is_legacy,
/* /*
* Find correct throughput table for given mode of modulation * Find correct throughput table for given mode of modulation
*/ */
static void rs_set_expected_tpt_table(struct iwl4965_lq_sta *lq_sta, static void rs_set_expected_tpt_table(struct iwl_lq_sta *lq_sta,
struct iwl4965_scale_tbl_info *tbl) struct iwl_scale_tbl_info *tbl)
{ {
if (is_legacy(tbl->lq_type)) { if (is_legacy(tbl->lq_type)) {
if (!is_a_band(tbl->lq_type)) if (!is_a_band(tbl->lq_type))
@ -1050,12 +1047,12 @@ static void rs_set_expected_tpt_table(struct iwl4965_lq_sta *lq_sta,
* bit rate will typically need to increase, but not if performance was bad. * bit rate will typically need to increase, but not if performance was bad.
*/ */
static s32 rs_get_best_rate(struct iwl_priv *priv, static s32 rs_get_best_rate(struct iwl_priv *priv,
struct iwl4965_lq_sta *lq_sta, struct iwl_lq_sta *lq_sta,
struct iwl4965_scale_tbl_info *tbl, /* "search" */ struct iwl_scale_tbl_info *tbl, /* "search" */
u16 rate_mask, s8 index) u16 rate_mask, s8 index)
{ {
/* "active" values */ /* "active" values */
struct iwl4965_scale_tbl_info *active_tbl = struct iwl_scale_tbl_info *active_tbl =
&(lq_sta->lq_info[lq_sta->active_tbl]); &(lq_sta->lq_info[lq_sta->active_tbl]);
s32 active_sr = active_tbl->win[index].success_ratio; s32 active_sr = active_tbl->win[index].success_ratio;
s32 active_tpt = active_tbl->expected_tpt[index]; s32 active_tpt = active_tbl->expected_tpt[index];
@ -1143,10 +1140,10 @@ static s32 rs_get_best_rate(struct iwl_priv *priv,
* Set up search table for MIMO * Set up search table for MIMO
*/ */
static int rs_switch_to_mimo2(struct iwl_priv *priv, static int rs_switch_to_mimo2(struct iwl_priv *priv,
struct iwl4965_lq_sta *lq_sta, struct iwl_lq_sta *lq_sta,
struct ieee80211_conf *conf, struct ieee80211_conf *conf,
struct sta_info *sta, struct sta_info *sta,
struct iwl4965_scale_tbl_info *tbl, int index) struct iwl_scale_tbl_info *tbl, int index)
{ {
u16 rate_mask; u16 rate_mask;
s32 rate; s32 rate;
@ -1210,10 +1207,10 @@ static int rs_switch_to_mimo2(struct iwl_priv *priv,
* Set up search table for SISO * Set up search table for SISO
*/ */
static int rs_switch_to_siso(struct iwl_priv *priv, static int rs_switch_to_siso(struct iwl_priv *priv,
struct iwl4965_lq_sta *lq_sta, struct iwl_lq_sta *lq_sta,
struct ieee80211_conf *conf, struct ieee80211_conf *conf,
struct sta_info *sta, struct sta_info *sta,
struct iwl4965_scale_tbl_info *tbl, int index) struct iwl_scale_tbl_info *tbl, int index)
{ {
u16 rate_mask; u16 rate_mask;
u8 is_green = lq_sta->is_green; u8 is_green = lq_sta->is_green;
@ -1270,18 +1267,17 @@ static int rs_switch_to_siso(struct iwl_priv *priv,
* Try to switch to new modulation mode from legacy * Try to switch to new modulation mode from legacy
*/ */
static int rs_move_legacy_other(struct iwl_priv *priv, static int rs_move_legacy_other(struct iwl_priv *priv,
struct iwl4965_lq_sta *lq_sta, struct iwl_lq_sta *lq_sta,
struct ieee80211_conf *conf, struct ieee80211_conf *conf,
struct sta_info *sta, struct sta_info *sta,
int index) int index)
{ {
struct iwl4965_scale_tbl_info *tbl = struct iwl_scale_tbl_info *tbl = &(lq_sta->lq_info[lq_sta->active_tbl]);
&(lq_sta->lq_info[lq_sta->active_tbl]); struct iwl_scale_tbl_info *search_tbl =
struct iwl4965_scale_tbl_info *search_tbl = &(lq_sta->lq_info[(1 - lq_sta->active_tbl)]);
&(lq_sta->lq_info[(1 - lq_sta->active_tbl)]); struct iwl_rate_scale_data *window = &(tbl->win[index]);
struct iwl4965_rate_scale_data *window = &(tbl->win[index]); u32 sz = (sizeof(struct iwl_scale_tbl_info) -
u32 sz = (sizeof(struct iwl4965_scale_tbl_info) - (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT));
(sizeof(struct iwl4965_rate_scale_data) * IWL_RATE_COUNT));
u8 start_action = tbl->action; u8 start_action = tbl->action;
u8 valid_tx_ant = priv->hw_params.valid_tx_ant; u8 valid_tx_ant = priv->hw_params.valid_tx_ant;
int ret = 0; int ret = 0;
@ -1360,19 +1356,17 @@ static int rs_move_legacy_other(struct iwl_priv *priv,
* Try to switch to new modulation mode from SISO * Try to switch to new modulation mode from SISO
*/ */
static int rs_move_siso_to_other(struct iwl_priv *priv, static int rs_move_siso_to_other(struct iwl_priv *priv,
struct iwl4965_lq_sta *lq_sta, struct iwl_lq_sta *lq_sta,
struct ieee80211_conf *conf, struct ieee80211_conf *conf,
struct sta_info *sta, struct sta_info *sta, int index)
int index)
{ {
u8 is_green = lq_sta->is_green; u8 is_green = lq_sta->is_green;
struct iwl4965_scale_tbl_info *tbl = struct iwl_scale_tbl_info *tbl = &(lq_sta->lq_info[lq_sta->active_tbl]);
&(lq_sta->lq_info[lq_sta->active_tbl]); struct iwl_scale_tbl_info *search_tbl =
struct iwl4965_scale_tbl_info *search_tbl = &(lq_sta->lq_info[(1 - lq_sta->active_tbl)]);
&(lq_sta->lq_info[(1 - lq_sta->active_tbl)]); struct iwl_rate_scale_data *window = &(tbl->win[index]);
struct iwl4965_rate_scale_data *window = &(tbl->win[index]); u32 sz = (sizeof(struct iwl_scale_tbl_info) -
u32 sz = (sizeof(struct iwl4965_scale_tbl_info) - (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT));
(sizeof(struct iwl4965_rate_scale_data) * IWL_RATE_COUNT));
u8 start_action = tbl->action; u8 start_action = tbl->action;
u8 valid_tx_ant = priv->hw_params.valid_tx_ant; u8 valid_tx_ant = priv->hw_params.valid_tx_ant;
int ret; int ret;
@ -1455,18 +1449,16 @@ static int rs_move_siso_to_other(struct iwl_priv *priv,
* Try to switch to new modulation mode from MIMO * Try to switch to new modulation mode from MIMO
*/ */
static int rs_move_mimo_to_other(struct iwl_priv *priv, static int rs_move_mimo_to_other(struct iwl_priv *priv,
struct iwl4965_lq_sta *lq_sta, struct iwl_lq_sta *lq_sta,
struct ieee80211_conf *conf, struct ieee80211_conf *conf,
struct sta_info *sta, struct sta_info *sta, int index)
int index)
{ {
s8 is_green = lq_sta->is_green; s8 is_green = lq_sta->is_green;
struct iwl4965_scale_tbl_info *tbl = struct iwl_scale_tbl_info *tbl = &(lq_sta->lq_info[lq_sta->active_tbl]);
&(lq_sta->lq_info[lq_sta->active_tbl]); struct iwl_scale_tbl_info *search_tbl =
struct iwl4965_scale_tbl_info *search_tbl = &(lq_sta->lq_info[(1 - lq_sta->active_tbl)]);
&(lq_sta->lq_info[(1 - lq_sta->active_tbl)]); u32 sz = (sizeof(struct iwl_scale_tbl_info) -
u32 sz = (sizeof(struct iwl4965_scale_tbl_info) - (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT));
(sizeof(struct iwl4965_rate_scale_data) * IWL_RATE_COUNT));
u8 start_action = tbl->action; u8 start_action = tbl->action;
/*u8 valid_tx_ant = priv->hw_params.valid_tx_ant;*/ /*u8 valid_tx_ant = priv->hw_params.valid_tx_ant;*/
int ret; int ret;
@ -1552,9 +1544,9 @@ static int rs_move_mimo_to_other(struct iwl_priv *priv,
* 2) # times calling this function * 2) # times calling this function
* 3) elapsed time in this mode (not used, for now) * 3) elapsed time in this mode (not used, for now)
*/ */
static void rs_stay_in_table(struct iwl4965_lq_sta *lq_sta) static void rs_stay_in_table(struct iwl_lq_sta *lq_sta)
{ {
struct iwl4965_scale_tbl_info *tbl; struct iwl_scale_tbl_info *tbl;
int i; int i;
int active_tbl; int active_tbl;
int flush_interval_passed = 0; int flush_interval_passed = 0;
@ -1642,7 +1634,7 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
int high = IWL_RATE_INVALID; int high = IWL_RATE_INVALID;
int index; int index;
int i; int i;
struct iwl4965_rate_scale_data *window = NULL; struct iwl_rate_scale_data *window = NULL;
int current_tpt = IWL_INVALID_VALUE; int current_tpt = IWL_INVALID_VALUE;
int low_tpt = IWL_INVALID_VALUE; int low_tpt = IWL_INVALID_VALUE;
int high_tpt = IWL_INVALID_VALUE; int high_tpt = IWL_INVALID_VALUE;
@ -1651,8 +1643,8 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
__le16 fc; __le16 fc;
u16 rate_mask; u16 rate_mask;
u8 update_lq = 0; u8 update_lq = 0;
struct iwl4965_lq_sta *lq_sta; struct iwl_lq_sta *lq_sta;
struct iwl4965_scale_tbl_info *tbl, *tbl1; struct iwl_scale_tbl_info *tbl, *tbl1;
u16 rate_scale_index_msk = 0; u16 rate_scale_index_msk = 0;
u32 rate; u32 rate;
u8 is_green = 0; u8 is_green = 0;
@ -1675,7 +1667,7 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
if (!sta || !sta->rate_ctrl_priv) if (!sta || !sta->rate_ctrl_priv)
return; return;
lq_sta = (struct iwl4965_lq_sta *)sta->rate_ctrl_priv; lq_sta = (struct iwl_lq_sta *)sta->rate_ctrl_priv;
tid = rs_tl_add_packet(lq_sta, hdr); tid = rs_tl_add_packet(lq_sta, hdr);
@ -2030,8 +2022,8 @@ static void rs_initialize_lq(struct iwl_priv *priv,
struct ieee80211_conf *conf, struct ieee80211_conf *conf,
struct sta_info *sta) struct sta_info *sta)
{ {
struct iwl4965_lq_sta *lq_sta; struct iwl_lq_sta *lq_sta;
struct iwl4965_scale_tbl_info *tbl; struct iwl_scale_tbl_info *tbl;
int rate_idx; int rate_idx;
int i; int i;
u32 rate; u32 rate;
@ -2042,7 +2034,7 @@ static void rs_initialize_lq(struct iwl_priv *priv,
if (!sta || !sta->rate_ctrl_priv) if (!sta || !sta->rate_ctrl_priv)
goto out; goto out;
lq_sta = (struct iwl4965_lq_sta *)sta->rate_ctrl_priv; lq_sta = (struct iwl_lq_sta *)sta->rate_ctrl_priv;
i = sta->last_txrate_idx; i = sta->last_txrate_idx;
if ((lq_sta->lq.sta_id == 0xff) && if ((lq_sta->lq.sta_id == 0xff) &&
@ -2096,7 +2088,7 @@ static void rs_get_rate(void *priv_rate, struct net_device *dev,
struct sta_info *sta; struct sta_info *sta;
__le16 fc; __le16 fc;
struct iwl_priv *priv = (struct iwl_priv *)priv_rate; struct iwl_priv *priv = (struct iwl_priv *)priv_rate;
struct iwl4965_lq_sta *lq_sta; struct iwl_lq_sta *lq_sta;
IWL_DEBUG_RATE_LIMIT("rate scale calculate new rate for skb\n"); IWL_DEBUG_RATE_LIMIT("rate scale calculate new rate for skb\n");
@ -2113,7 +2105,7 @@ static void rs_get_rate(void *priv_rate, struct net_device *dev,
goto out; goto out;
} }
lq_sta = (struct iwl4965_lq_sta *)sta->rate_ctrl_priv; lq_sta = (struct iwl_lq_sta *)sta->rate_ctrl_priv;
i = sta->last_txrate_idx; i = sta->last_txrate_idx;
if ((priv->iw_mode == IEEE80211_IF_TYPE_IBSS) && if ((priv->iw_mode == IEEE80211_IF_TYPE_IBSS) &&
@ -2149,14 +2141,14 @@ static void rs_get_rate(void *priv_rate, struct net_device *dev,
static void *rs_alloc_sta(void *priv_rate, gfp_t gfp) static void *rs_alloc_sta(void *priv_rate, gfp_t gfp)
{ {
struct iwl4965_lq_sta *lq_sta; struct iwl_lq_sta *lq_sta;
struct iwl_priv *priv; struct iwl_priv *priv;
int i, j; int i, j;
priv = (struct iwl_priv *)priv_rate; priv = (struct iwl_priv *)priv_rate;
IWL_DEBUG_RATE("create station rate scale window\n"); IWL_DEBUG_RATE("create station rate scale window\n");
lq_sta = kzalloc(sizeof(struct iwl4965_lq_sta), gfp); lq_sta = kzalloc(sizeof(struct iwl_lq_sta), gfp);
if (lq_sta == NULL) if (lq_sta == NULL)
return NULL; return NULL;
@ -2165,7 +2157,7 @@ static void *rs_alloc_sta(void *priv_rate, gfp_t gfp)
for (j = 0; j < LQ_SIZE; j++) for (j = 0; j < LQ_SIZE; j++)
for (i = 0; i < IWL_RATE_COUNT; i++) for (i = 0; i < IWL_RATE_COUNT; i++)
rs_rate_scale_clear_window(&(lq_sta->lq_info[j].win[i])); rs_rate_scale_clear_window(&lq_sta->lq_info[j].win[i]);
return lq_sta; return lq_sta;
} }
@ -2178,7 +2170,7 @@ static void rs_rate_init(void *priv_rate, void *priv_sta,
struct ieee80211_conf *conf = &local->hw.conf; struct ieee80211_conf *conf = &local->hw.conf;
struct ieee80211_supported_band *sband; struct ieee80211_supported_band *sband;
struct iwl_priv *priv = (struct iwl_priv *)priv_rate; struct iwl_priv *priv = (struct iwl_priv *)priv_rate;
struct iwl4965_lq_sta *lq_sta = priv_sta; struct iwl_lq_sta *lq_sta = priv_sta;
sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
@ -2187,7 +2179,7 @@ static void rs_rate_init(void *priv_rate, void *priv_sta,
sta->txrate_idx = 3; sta->txrate_idx = 3;
for (j = 0; j < LQ_SIZE; j++) for (j = 0; j < LQ_SIZE; j++)
for (i = 0; i < IWL_RATE_COUNT; i++) for (i = 0; i < IWL_RATE_COUNT; i++)
rs_rate_scale_clear_window(&(lq_sta->lq_info[j].win[i])); rs_rate_scale_clear_window(&lq_sta->lq_info[j].win[i]);
IWL_DEBUG_RATE("LQ: *** rate scale global init ***\n"); IWL_DEBUG_RATE("LQ: *** rate scale global init ***\n");
/* TODO: what is a good starting rate for STA? About middle? Maybe not /* TODO: what is a good starting rate for STA? About middle? Maybe not
@ -2271,10 +2263,9 @@ static void rs_rate_init(void *priv_rate, void *priv_sta,
} }
static void rs_fill_link_cmd(const struct iwl_priv *priv, static void rs_fill_link_cmd(const struct iwl_priv *priv,
struct iwl4965_lq_sta *lq_sta, struct iwl_lq_sta *lq_sta, u32 new_rate)
u32 new_rate)
{ {
struct iwl4965_scale_tbl_info tbl_type; struct iwl_scale_tbl_info tbl_type;
int index = 0; int index = 0;
int rate_idx; int rate_idx;
int repeat_rate = 0; int repeat_rate = 0;
@ -2402,6 +2393,7 @@ static void rs_free(void *priv_rate)
static void rs_clear(void *priv_rate) static void rs_clear(void *priv_rate)
{ {
#ifdef CONFIG_IWLWIFI_DEBUG
struct iwl_priv *priv = (struct iwl_priv *) priv_rate; struct iwl_priv *priv = (struct iwl_priv *) priv_rate;
IWL_DEBUG_RATE("enter\n"); IWL_DEBUG_RATE("enter\n");
@ -2409,11 +2401,12 @@ static void rs_clear(void *priv_rate)
/* TODO - add rate scale state reset */ /* TODO - add rate scale state reset */
IWL_DEBUG_RATE("leave\n"); IWL_DEBUG_RATE("leave\n");
#endif /* CONFIG_IWLWIFI_DEBUG */
} }
static void rs_free_sta(void *priv_rate, void *priv_sta) static void rs_free_sta(void *priv_rate, void *priv_sta)
{ {
struct iwl4965_lq_sta *lq_sta = priv_sta; struct iwl_lq_sta *lq_sta = priv_sta;
struct iwl_priv *priv; struct iwl_priv *priv;
priv = (struct iwl_priv *)priv_rate; priv = (struct iwl_priv *)priv_rate;
@ -2429,8 +2422,8 @@ static int open_file_generic(struct inode *inode, struct file *file)
file->private_data = inode->i_private; file->private_data = inode->i_private;
return 0; return 0;
} }
static void rs_dbgfs_set_mcs(struct iwl4965_lq_sta *lq_sta, static void rs_dbgfs_set_mcs(struct iwl_lq_sta *lq_sta,
u32 *rate_n_flags, int index) u32 *rate_n_flags, int index)
{ {
struct iwl_priv *priv; struct iwl_priv *priv;
@ -2453,7 +2446,7 @@ static void rs_dbgfs_set_mcs(struct iwl4965_lq_sta *lq_sta,
static ssize_t rs_sta_dbgfs_scale_table_write(struct file *file, static ssize_t rs_sta_dbgfs_scale_table_write(struct file *file,
const char __user *user_buf, size_t count, loff_t *ppos) const char __user *user_buf, size_t count, loff_t *ppos)
{ {
struct iwl4965_lq_sta *lq_sta = file->private_data; struct iwl_lq_sta *lq_sta = file->private_data;
struct iwl_priv *priv; struct iwl_priv *priv;
char buf[64]; char buf[64];
int buf_size; int buf_size;
@ -2493,7 +2486,7 @@ static ssize_t rs_sta_dbgfs_scale_table_read(struct file *file,
int desc = 0; int desc = 0;
int i = 0; int i = 0;
struct iwl4965_lq_sta *lq_sta = file->private_data; struct iwl_lq_sta *lq_sta = file->private_data;
desc += sprintf(buff+desc, "sta_id %d\n", lq_sta->lq.sta_id); desc += sprintf(buff+desc, "sta_id %d\n", lq_sta->lq.sta_id);
desc += sprintf(buff+desc, "failed=%d success=%d rate=0%X\n", desc += sprintf(buff+desc, "failed=%d success=%d rate=0%X\n",
@ -2541,7 +2534,7 @@ static ssize_t rs_sta_dbgfs_stats_table_read(struct file *file,
int desc = 0; int desc = 0;
int i, j; int i, j;
struct iwl4965_lq_sta *lq_sta = file->private_data; struct iwl_lq_sta *lq_sta = file->private_data;
for (i = 0; i < LQ_SIZE; i++) { for (i = 0; i < LQ_SIZE; i++) {
desc += sprintf(buff+desc, "%s type=%d SGI=%d FAT=%d DUP=%d\n" desc += sprintf(buff+desc, "%s type=%d SGI=%d FAT=%d DUP=%d\n"
"rate=0x%X\n", "rate=0x%X\n",
@ -2570,7 +2563,7 @@ static const struct file_operations rs_sta_dbgfs_stats_table_ops = {
static void rs_add_debugfs(void *priv, void *priv_sta, static void rs_add_debugfs(void *priv, void *priv_sta,
struct dentry *dir) struct dentry *dir)
{ {
struct iwl4965_lq_sta *lq_sta = priv_sta; struct iwl_lq_sta *lq_sta = priv_sta;
lq_sta->rs_sta_dbgfs_scale_table_file = lq_sta->rs_sta_dbgfs_scale_table_file =
debugfs_create_file("rate_scale_table", 0600, dir, debugfs_create_file("rate_scale_table", 0600, dir,
lq_sta, &rs_sta_dbgfs_scale_table_ops); lq_sta, &rs_sta_dbgfs_scale_table_ops);
@ -2585,7 +2578,7 @@ static void rs_add_debugfs(void *priv, void *priv_sta,
static void rs_remove_debugfs(void *priv, void *priv_sta) static void rs_remove_debugfs(void *priv, void *priv_sta)
{ {
struct iwl4965_lq_sta *lq_sta = priv_sta; struct iwl_lq_sta *lq_sta = priv_sta;
debugfs_remove(lq_sta->rs_sta_dbgfs_scale_table_file); debugfs_remove(lq_sta->rs_sta_dbgfs_scale_table_file);
debugfs_remove(lq_sta->rs_sta_dbgfs_stats_table_file); debugfs_remove(lq_sta->rs_sta_dbgfs_stats_table_file);
debugfs_remove(lq_sta->rs_sta_dbgfs_tx_agg_tid_en_file); debugfs_remove(lq_sta->rs_sta_dbgfs_tx_agg_tid_en_file);
@ -2609,104 +2602,12 @@ static struct rate_control_ops rs_ops = {
#endif #endif
}; };
int iwl4965_fill_rs_info(struct ieee80211_hw *hw, char *buf, u8 sta_id) int iwlagn_rate_control_register(void)
{
struct ieee80211_local *local = hw_to_local(hw);
struct iwl_priv *priv = hw->priv;
struct iwl4965_lq_sta *lq_sta;
struct sta_info *sta;
int cnt = 0, i;
u32 samples = 0, success = 0, good = 0;
unsigned long now = jiffies;
u32 max_time = 0;
u8 lq_type, antenna;
rcu_read_lock();
sta = sta_info_get(local, priv->stations[sta_id].sta.sta.addr);
if (!sta || !sta->rate_ctrl_priv) {
if (sta)
IWL_DEBUG_RATE("leave - no private rate data!\n");
else
IWL_DEBUG_RATE("leave - no station!\n");
rcu_read_unlock();
return sprintf(buf, "station %d not found\n", sta_id);
}
lq_sta = (void *)sta->rate_ctrl_priv;
lq_type = lq_sta->lq_info[lq_sta->active_tbl].lq_type;
antenna = lq_sta->lq_info[lq_sta->active_tbl].ant_type;
if (is_legacy(lq_type))
i = IWL_RATE_54M_INDEX;
else
i = IWL_RATE_60M_INDEX;
while (1) {
u64 mask;
int j;
int active = lq_sta->active_tbl;
cnt +=
sprintf(&buf[cnt], " %2dMbs: ", iwl_rates[i].ieee / 2);
mask = (1ULL << (IWL_RATE_MAX_WINDOW - 1));
for (j = 0; j < IWL_RATE_MAX_WINDOW; j++, mask >>= 1)
buf[cnt++] =
(lq_sta->lq_info[active].win[i].data & mask)
? '1' : '0';
samples += lq_sta->lq_info[active].win[i].counter;
good += lq_sta->lq_info[active].win[i].success_counter;
success += lq_sta->lq_info[active].win[i].success_counter *
iwl_rates[i].ieee;
if (lq_sta->lq_info[active].win[i].stamp) {
int delta =
jiffies_to_msecs(now -
lq_sta->lq_info[active].win[i].stamp);
if (delta > max_time)
max_time = delta;
cnt += sprintf(&buf[cnt], "%5dms\n", delta);
} else
buf[cnt++] = '\n';
j = iwl4965_get_prev_ieee_rate(i);
if (j == i)
break;
i = j;
}
/*
* Display the average rate of all samples taken.
* NOTE: We multiply # of samples by 2 since the IEEE measurement
* added from iwl_rates is actually 2X the rate.
*/
if (samples)
cnt += sprintf(&buf[cnt],
"\nAverage rate is %3d.%02dMbs over last %4dms\n"
"%3d%% success (%d good packets over %d tries)\n",
success / (2 * samples), (success * 5 / samples) % 10,
max_time, good * 100 / samples, good, samples);
else
cnt += sprintf(&buf[cnt], "\nAverage rate: 0Mbs\n");
cnt += sprintf(&buf[cnt], "\nrate scale type %d antenna %d "
"active_search %d rate index %d\n", lq_type, antenna,
lq_sta->search_better_tbl, sta->last_txrate_idx);
rcu_read_unlock();
return cnt;
}
int iwl4965_rate_control_register(void)
{ {
return ieee80211_rate_control_register(&rs_ops); return ieee80211_rate_control_register(&rs_ops);
} }
void iwl4965_rate_control_unregister(void) void iwlagn_rate_control_unregister(void)
{ {
ieee80211_rate_control_unregister(&rs_ops); ieee80211_rate_control_unregister(&rs_ops);
} }

View File

@ -24,8 +24,8 @@
* *
*****************************************************************************/ *****************************************************************************/
#ifndef __iwl_4965_rs_h__ #ifndef __iwl_agn_rs_h__
#define __iwl_4965_rs_h__ #define __iwl_agn_rs_h__
#include "iwl-dev.h" #include "iwl-dev.h"
@ -88,7 +88,7 @@ enum {
#define IWL_RATE_5M_MASK (1 << IWL_RATE_5M_INDEX) #define IWL_RATE_5M_MASK (1 << IWL_RATE_5M_INDEX)
#define IWL_RATE_11M_MASK (1 << IWL_RATE_11M_INDEX) #define IWL_RATE_11M_MASK (1 << IWL_RATE_11M_INDEX)
/* 4965 uCode API values for legacy bit rates, both OFDM and CCK */ /* uCode API values for legacy bit rates, both OFDM and CCK */
enum { enum {
IWL_RATE_6M_PLCP = 13, IWL_RATE_6M_PLCP = 13,
IWL_RATE_9M_PLCP = 15, IWL_RATE_9M_PLCP = 15,
@ -107,7 +107,7 @@ enum {
/*FIXME:RS:add IWL_RATE_LEGACY_INVM_PLCP = 0,*/ /*FIXME:RS:add IWL_RATE_LEGACY_INVM_PLCP = 0,*/
}; };
/* 4965 uCode API values for OFDM high-throughput (HT) bit rates */ /* uCode API values for OFDM high-throughput (HT) bit rates */
enum { enum {
IWL_RATE_SISO_6M_PLCP = 0, IWL_RATE_SISO_6M_PLCP = 0,
IWL_RATE_SISO_12M_PLCP = 1, IWL_RATE_SISO_12M_PLCP = 1,
@ -286,15 +286,6 @@ static inline u8 iwl4965_get_prev_ieee_rate(u8 rate_index)
return rate; return rate;
} }
/**
* iwl4965_fill_rs_info - Fill an output text buffer with the rate representation
*
* NOTE: This is provided as a quick mechanism for a user to visualize
* the performance of the rate control algorithm and is not meant to be
* parsed software.
*/
extern int iwl4965_fill_rs_info(struct ieee80211_hw *, char *buf, u8 sta_id);
/** /**
* iwl4965_rate_control_register - Register the rate control algorithm callbacks * iwl4965_rate_control_register - Register the rate control algorithm callbacks
* *
@ -305,7 +296,7 @@ extern int iwl4965_fill_rs_info(struct ieee80211_hw *, char *buf, u8 sta_id);
* ieee80211_register_hw * ieee80211_register_hw
* *
*/ */
extern int iwl4965_rate_control_register(void); extern int iwlagn_rate_control_register(void);
/** /**
* iwl4965_rate_control_unregister - Unregister the rate control callbacks * iwl4965_rate_control_unregister - Unregister the rate control callbacks
@ -313,6 +304,6 @@ extern int iwl4965_rate_control_register(void);
* This should be called after calling ieee80211_unregister_hw, but before * This should be called after calling ieee80211_unregister_hw, but before
* the driver is unloaded. * the driver is unloaded.
*/ */
extern void iwl4965_rate_control_unregister(void); extern void iwlagn_rate_control_unregister(void);
#endif #endif /* __iwl_agn__rs__ */

View File

@ -65,7 +65,7 @@
* NOTE: DRV_NAME is defined in iwlwifi.h for use by iwl-debug.h and printk * NOTE: DRV_NAME is defined in iwlwifi.h for use by iwl-debug.h and printk
*/ */
#define DRV_DESCRIPTION "Intel(R) Wireless WiFi Link 4965AGN driver for Linux" #define DRV_DESCRIPTION "Intel(R) Wireless WiFi Link AGN driver for Linux"
#ifdef CONFIG_IWLWIFI_DEBUG #ifdef CONFIG_IWLWIFI_DEBUG
#define VD "d" #define VD "d"
@ -73,7 +73,7 @@
#define VD #define VD
#endif #endif
#ifdef CONFIG_IWL4965_SPECTRUM_MEASUREMENT #ifdef CONFIG_IWLAGN_SPECTRUM_MEASUREMENT
#define VS "s" #define VS "s"
#else #else
#define VS #define VS
@ -86,6 +86,7 @@ MODULE_DESCRIPTION(DRV_DESCRIPTION);
MODULE_VERSION(DRV_VERSION); MODULE_VERSION(DRV_VERSION);
MODULE_AUTHOR(DRV_COPYRIGHT); MODULE_AUTHOR(DRV_COPYRIGHT);
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
MODULE_ALIAS("iwl4965");
/*************** STATION TABLE MANAGEMENT **** /*************** STATION TABLE MANAGEMENT ****
* mac80211 should be examined to determine if sta_info is duplicating * mac80211 should be examined to determine if sta_info is duplicating
@ -444,11 +445,10 @@ static void iwl_free_frame(struct iwl_priv *priv, struct iwl_frame *frame)
list_add(&frame->list, &priv->free_frames); list_add(&frame->list, &priv->free_frames);
} }
unsigned int iwl4965_fill_beacon_frame(struct iwl_priv *priv, static unsigned int iwl_fill_beacon_frame(struct iwl_priv *priv,
struct ieee80211_hdr *hdr, struct ieee80211_hdr *hdr,
const u8 *dest, int left) const u8 *dest, int left)
{ {
if (!iwl_is_associated(priv) || !priv->ibss_beacon || if (!iwl_is_associated(priv) || !priv->ibss_beacon ||
((priv->iw_mode != IEEE80211_IF_TYPE_IBSS) && ((priv->iw_mode != IEEE80211_IF_TYPE_IBSS) &&
(priv->iw_mode != IEEE80211_IF_TYPE_AP))) (priv->iw_mode != IEEE80211_IF_TYPE_AP)))
@ -487,6 +487,38 @@ static u8 iwl4965_rate_get_lowest_plcp(struct iwl_priv *priv)
return IWL_RATE_6M_PLCP; return IWL_RATE_6M_PLCP;
} }
unsigned int iwl4965_hw_get_beacon_cmd(struct iwl_priv *priv,
struct iwl_frame *frame, u8 rate)
{
struct iwl_tx_beacon_cmd *tx_beacon_cmd;
unsigned int frame_size;
tx_beacon_cmd = &frame->u.beacon;
memset(tx_beacon_cmd, 0, sizeof(*tx_beacon_cmd));
tx_beacon_cmd->tx.sta_id = priv->hw_params.bcast_sta_id;
tx_beacon_cmd->tx.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE;
frame_size = iwl_fill_beacon_frame(priv, tx_beacon_cmd->frame,
iwl_bcast_addr,
sizeof(frame->u) - sizeof(*tx_beacon_cmd));
BUG_ON(frame_size > MAX_MPDU_SIZE);
tx_beacon_cmd->tx.len = cpu_to_le16((u16)frame_size);
if ((rate == IWL_RATE_1M_PLCP) || (rate >= IWL_RATE_2M_PLCP))
tx_beacon_cmd->tx.rate_n_flags =
iwl_hw_set_rate_n_flags(rate, RATE_MCS_CCK_MSK);
else
tx_beacon_cmd->tx.rate_n_flags =
iwl_hw_set_rate_n_flags(rate, 0);
tx_beacon_cmd->tx.tx_flags = TX_CMD_FLG_SEQ_CTL_MSK |
TX_CMD_FLG_TSF_MSK |
TX_CMD_FLG_STA_RATE_MSK;
return sizeof(*tx_beacon_cmd) + frame_size;
}
static int iwl4965_send_beacon_cmd(struct iwl_priv *priv) static int iwl4965_send_beacon_cmd(struct iwl_priv *priv)
{ {
struct iwl_frame *frame; struct iwl_frame *frame;
@ -608,7 +640,6 @@ static void iwl_activate_qos(struct iwl_priv *priv, u8 force)
} }
#define MAX_UCODE_BEACON_INTERVAL 4096 #define MAX_UCODE_BEACON_INTERVAL 4096
#define INTEL_CONN_LISTEN_INTERVAL __constant_cpu_to_le16(0xA)
static __le16 iwl4965_adjust_beacon_interval(u16 beacon_val) static __le16 iwl4965_adjust_beacon_interval(u16 beacon_val)
{ {
@ -638,7 +669,7 @@ static void iwl4965_setup_rxon_timing(struct iwl_priv *priv)
priv->rxon_timing.timestamp.dw[0] = priv->rxon_timing.timestamp.dw[0] =
cpu_to_le32(priv->timestamp & 0xFFFFFFFF); cpu_to_le32(priv->timestamp & 0xFFFFFFFF);
priv->rxon_timing.listen_interval = INTEL_CONN_LISTEN_INTERVAL; priv->rxon_timing.listen_interval = cpu_to_le16(conf->listen_interval);
tsf = priv->timestamp; tsf = priv->timestamp;
@ -853,7 +884,7 @@ static void iwl4965_set_rate(struct iwl_priv *priv)
(IWL_OFDM_BASIC_RATES_MASK >> IWL_FIRST_OFDM_RATE) & 0xFF; (IWL_OFDM_BASIC_RATES_MASK >> IWL_FIRST_OFDM_RATE) & 0xFF;
} }
#ifdef CONFIG_IWL4965_SPECTRUM_MEASUREMENT #ifdef CONFIG_IWLAGN_SPECTRUM_MEASUREMENT
#include "iwl-spectrum.h" #include "iwl-spectrum.h"
@ -1057,7 +1088,7 @@ static void iwl4965_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
static void iwl4965_rx_spectrum_measure_notif(struct iwl_priv *priv, static void iwl4965_rx_spectrum_measure_notif(struct iwl_priv *priv,
struct iwl_rx_mem_buffer *rxb) struct iwl_rx_mem_buffer *rxb)
{ {
#ifdef CONFIG_IWL4965_SPECTRUM_MEASUREMENT #ifdef CONFIG_IWLAGN_SPECTRUM_MEASUREMENT
struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data; struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
struct iwl4965_spectrum_notification *report = &(pkt->u.spectrum_notif); struct iwl4965_spectrum_notification *report = &(pkt->u.spectrum_notif);
@ -1231,6 +1262,37 @@ static void iwl4965_rx_card_state_notif(struct iwl_priv *priv,
wake_up_interruptible(&priv->wait_command_queue); wake_up_interruptible(&priv->wait_command_queue);
} }
int iwl4965_set_pwr_src(struct iwl_priv *priv, enum iwl_pwr_src src)
{
int ret;
unsigned long flags;
spin_lock_irqsave(&priv->lock, flags);
ret = iwl_grab_nic_access(priv);
if (ret)
goto err;
if (src == IWL_PWR_SRC_VAUX) {
u32 val;
ret = pci_read_config_dword(priv->pci_dev, PCI_POWER_SOURCE,
&val);
if (val & PCI_CFG_PMC_PME_FROM_D3COLD_SUPPORT)
iwl_set_bits_mask_prph(priv, APMG_PS_CTRL_REG,
APMG_PS_CTRL_VAL_PWR_SRC_VAUX,
~APMG_PS_CTRL_MSK_PWR_SRC);
} else {
iwl_set_bits_mask_prph(priv, APMG_PS_CTRL_REG,
APMG_PS_CTRL_VAL_PWR_SRC_VMAIN,
~APMG_PS_CTRL_MSK_PWR_SRC);
}
iwl_release_nic_access(priv);
err:
spin_unlock_irqrestore(&priv->lock, flags);
return ret;
}
/** /**
* iwl4965_setup_rx_handlers - Initialize Rx handler callbacks * iwl4965_setup_rx_handlers - Initialize Rx handler callbacks
* *
@ -2170,17 +2232,16 @@ static int __iwl4965_up(struct iwl_priv *priv)
} }
/* If platform's RF_KILL switch is NOT set to KILL */ /* If platform's RF_KILL switch is NOT set to KILL */
if (iwl_read32(priv, CSR_GP_CNTRL) & if (iwl_read32(priv, CSR_GP_CNTRL) & CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW)
CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW)
clear_bit(STATUS_RF_KILL_HW, &priv->status); clear_bit(STATUS_RF_KILL_HW, &priv->status);
else else
set_bit(STATUS_RF_KILL_HW, &priv->status); set_bit(STATUS_RF_KILL_HW, &priv->status);
if (!test_bit(STATUS_IN_SUSPEND, &priv->status) && if (iwl_is_rfkill(priv)) {
iwl_is_rfkill(priv)) { iwl4965_enable_interrupts(priv);
IWL_WARNING("Radio disabled by %s RF Kill switch\n", IWL_WARNING("Radio disabled by %s RF Kill switch\n",
test_bit(STATUS_RF_KILL_HW, &priv->status) ? "HW" : "SW"); test_bit(STATUS_RF_KILL_HW, &priv->status) ? "HW" : "SW");
return -ENODEV; return 0;
} }
iwl_write32(priv, CSR_INT, 0xFFFFFFFF); iwl_write32(priv, CSR_INT, 0xFFFFFFFF);
@ -2216,11 +2277,6 @@ static int __iwl4965_up(struct iwl_priv *priv)
memcpy(priv->ucode_data_backup.v_addr, priv->ucode_data.v_addr, memcpy(priv->ucode_data_backup.v_addr, priv->ucode_data.v_addr,
priv->ucode_data.len); priv->ucode_data.len);
/* We return success when we resume from suspend and rf_kill is on. */
if (test_bit(STATUS_RF_KILL_HW, &priv->status) ||
test_bit(STATUS_RF_KILL_SW, &priv->status))
return 0;
for (i = 0; i < MAX_HW_RESTARTS; i++) { for (i = 0; i < MAX_HW_RESTARTS; i++) {
iwl_clear_stations_table(priv); iwl_clear_stations_table(priv);
@ -2415,7 +2471,7 @@ static void iwl4965_post_associate(struct iwl_priv *priv)
unsigned long flags; unsigned long flags;
if (priv->iw_mode == IEEE80211_IF_TYPE_AP) { if (priv->iw_mode == IEEE80211_IF_TYPE_AP) {
IWL_ERROR("%s Should not be called in AP mode\n", __FUNCTION__); IWL_ERROR("%s Should not be called in AP mode\n", __func__);
return; return;
} }
@ -2491,7 +2547,7 @@ static void iwl4965_post_associate(struct iwl_priv *priv)
default: default:
IWL_ERROR("%s Should not be called in %d mode\n", IWL_ERROR("%s Should not be called in %d mode\n",
__FUNCTION__, priv->iw_mode); __func__, priv->iw_mode);
break; break;
} }
@ -2589,6 +2645,9 @@ static int iwl4965_mac_start(struct ieee80211_hw *hw)
if (ret) if (ret)
goto out_release_irq; goto out_release_irq;
if (iwl_is_rfkill(priv))
goto out;
IWL_DEBUG_INFO("Start UP work done.\n"); IWL_DEBUG_INFO("Start UP work done.\n");
if (test_bit(STATUS_IN_SUSPEND, &priv->status)) if (test_bit(STATUS_IN_SUSPEND, &priv->status))
@ -2608,6 +2667,7 @@ static int iwl4965_mac_start(struct ieee80211_hw *hw)
} }
} }
out:
priv->is_open = 1; priv->is_open = 1;
IWL_DEBUG_MAC80211("leave\n"); IWL_DEBUG_MAC80211("leave\n");
return 0; return 0;
@ -2773,6 +2833,7 @@ static int iwl4965_mac_config(struct ieee80211_hw *hw, struct ieee80211_conf *co
spin_lock_irqsave(&priv->lock, flags); spin_lock_irqsave(&priv->lock, flags);
/* if we are switching from ht to 2.4 clear flags /* if we are switching from ht to 2.4 clear flags
* from any ht related info since 2.4 does not * from any ht related info since 2.4 does not
* support ht */ * support ht */
@ -3102,6 +3163,7 @@ static void iwl4965_bss_info_changed(struct ieee80211_hw *hw,
if (bss_conf->assoc) { if (bss_conf->assoc) {
priv->assoc_id = bss_conf->aid; priv->assoc_id = bss_conf->aid;
priv->beacon_int = bss_conf->beacon_int; priv->beacon_int = bss_conf->beacon_int;
priv->power_data.dtim_period = bss_conf->dtim_period;
priv->timestamp = bss_conf->timestamp; priv->timestamp = bss_conf->timestamp;
priv->assoc_capability = bss_conf->assoc_capability; priv->assoc_capability = bss_conf->assoc_capability;
priv->next_scan_jiffies = jiffies + priv->next_scan_jiffies = jiffies +
@ -3345,6 +3407,39 @@ static int iwl4965_mac_conf_tx(struct ieee80211_hw *hw, u16 queue,
return 0; return 0;
} }
static int iwl4965_mac_ampdu_action(struct ieee80211_hw *hw,
enum ieee80211_ampdu_mlme_action action,
const u8 *addr, u16 tid, u16 *ssn)
{
struct iwl_priv *priv = hw->priv;
DECLARE_MAC_BUF(mac);
IWL_DEBUG_HT("A-MPDU action on addr %s tid %d\n",
print_mac(mac, addr), tid);
if (!(priv->cfg->sku & IWL_SKU_N))
return -EACCES;
switch (action) {
case IEEE80211_AMPDU_RX_START:
IWL_DEBUG_HT("start Rx\n");
return iwl_rx_agg_start(priv, addr, tid, *ssn);
case IEEE80211_AMPDU_RX_STOP:
IWL_DEBUG_HT("stop Rx\n");
return iwl_rx_agg_stop(priv, addr, tid);
case IEEE80211_AMPDU_TX_START:
IWL_DEBUG_HT("start Tx\n");
return iwl_tx_agg_start(priv, addr, tid, ssn);
case IEEE80211_AMPDU_TX_STOP:
IWL_DEBUG_HT("stop Tx\n");
return iwl_tx_agg_stop(priv, addr, tid);
default:
IWL_DEBUG_HT("unknown\n");
return -EINVAL;
break;
}
return 0;
}
static int iwl4965_mac_get_tx_stats(struct ieee80211_hw *hw, static int iwl4965_mac_get_tx_stats(struct ieee80211_hw *hw,
struct ieee80211_tx_queue_stats *stats) struct ieee80211_tx_queue_stats *stats)
{ {
@ -3592,15 +3687,6 @@ static ssize_t show_temperature(struct device *d,
static DEVICE_ATTR(temperature, S_IRUGO, show_temperature, NULL); static DEVICE_ATTR(temperature, S_IRUGO, show_temperature, NULL);
static ssize_t show_rs_window(struct device *d,
struct device_attribute *attr,
char *buf)
{
struct iwl_priv *priv = d->driver_data;
return iwl4965_fill_rs_info(priv->hw, buf, IWL_AP_ID);
}
static DEVICE_ATTR(rs_window, S_IRUGO, show_rs_window, NULL);
static ssize_t show_tx_power(struct device *d, static ssize_t show_tx_power(struct device *d,
struct device_attribute *attr, char *buf) struct device_attribute *attr, char *buf)
{ {
@ -3699,7 +3785,7 @@ static ssize_t store_filter_flags(struct device *d,
static DEVICE_ATTR(filter_flags, S_IWUSR | S_IRUGO, show_filter_flags, static DEVICE_ATTR(filter_flags, S_IWUSR | S_IRUGO, show_filter_flags,
store_filter_flags); store_filter_flags);
#ifdef CONFIG_IWL4965_SPECTRUM_MEASUREMENT #ifdef CONFIG_IWLAGN_SPECTRUM_MEASUREMENT
static ssize_t show_measurement(struct device *d, static ssize_t show_measurement(struct device *d,
struct device_attribute *attr, char *buf) struct device_attribute *attr, char *buf)
@ -3707,7 +3793,7 @@ static ssize_t show_measurement(struct device *d,
struct iwl_priv *priv = dev_get_drvdata(d); struct iwl_priv *priv = dev_get_drvdata(d);
struct iwl4965_spectrum_notification measure_report; struct iwl4965_spectrum_notification measure_report;
u32 size = sizeof(measure_report), len = 0, ofs = 0; u32 size = sizeof(measure_report), len = 0, ofs = 0;
u8 *data = (u8 *) & measure_report; u8 *data = (u8 *)&measure_report;
unsigned long flags; unsigned long flags;
spin_lock_irqsave(&priv->lock, flags); spin_lock_irqsave(&priv->lock, flags);
@ -3770,7 +3856,7 @@ static ssize_t store_measurement(struct device *d,
static DEVICE_ATTR(measurement, S_IRUSR | S_IWUSR, static DEVICE_ATTR(measurement, S_IRUSR | S_IWUSR,
show_measurement, store_measurement); show_measurement, store_measurement);
#endif /* CONFIG_IWL4965_SPECTRUM_MEASUREMENT */ #endif /* CONFIG_IWLAGN_SPECTRUM_MEASUREMENT */
static ssize_t store_retry_rate(struct device *d, static ssize_t store_retry_rate(struct device *d,
struct device_attribute *attr, struct device_attribute *attr,
@ -3800,77 +3886,54 @@ static ssize_t store_power_level(struct device *d,
const char *buf, size_t count) const char *buf, size_t count)
{ {
struct iwl_priv *priv = dev_get_drvdata(d); struct iwl_priv *priv = dev_get_drvdata(d);
int rc; int ret;
int mode; int mode;
mode = simple_strtoul(buf, NULL, 0); mode = simple_strtoul(buf, NULL, 0);
mutex_lock(&priv->mutex); mutex_lock(&priv->mutex);
if (!iwl_is_ready(priv)) { if (!iwl_is_ready(priv)) {
rc = -EAGAIN; ret = -EAGAIN;
goto out; goto out;
} }
rc = iwl_power_set_user_mode(priv, mode); ret = iwl_power_set_user_mode(priv, mode);
if (rc) { if (ret) {
IWL_DEBUG_MAC80211("failed setting power mode.\n"); IWL_DEBUG_MAC80211("failed setting power mode.\n");
goto out; goto out;
} }
rc = count; ret = count;
out: out:
mutex_unlock(&priv->mutex); mutex_unlock(&priv->mutex);
return rc; return ret;
} }
#define MAX_WX_STRING 80
/* Values are in microsecond */
static const s32 timeout_duration[] = {
350000,
250000,
75000,
37000,
25000,
};
static const s32 period_duration[] = {
400000,
700000,
1000000,
1000000,
1000000
};
static ssize_t show_power_level(struct device *d, static ssize_t show_power_level(struct device *d,
struct device_attribute *attr, char *buf) struct device_attribute *attr, char *buf)
{ {
struct iwl_priv *priv = dev_get_drvdata(d); struct iwl_priv *priv = dev_get_drvdata(d);
int mode = priv->power_data.user_power_setting;
int system = priv->power_data.system_power_setting;
int level = priv->power_data.power_mode; int level = priv->power_data.power_mode;
char *p = buf; char *p = buf;
p += sprintf(p, "%d ", level); switch (system) {
switch (level) { case IWL_POWER_SYS_AUTO:
case IWL_POWER_MODE_CAM: p += sprintf(p, "SYSTEM:auto");
case IWL_POWER_AC:
p += sprintf(p, "(AC)");
break; break;
case IWL_POWER_BATTERY: case IWL_POWER_SYS_AC:
p += sprintf(p, "(BATTERY)"); p += sprintf(p, "SYSTEM:ac");
break;
case IWL_POWER_SYS_BATTERY:
p += sprintf(p, "SYSTEM:battery");
break; break;
default:
p += sprintf(p,
"(Timeout %dms, Period %dms)",
timeout_duration[level - 1] / 1000,
period_duration[level - 1] / 1000);
} }
/*
if (!(priv->power_mode & IWL_POWER_ENABLED)) p += sprintf(p, "\tMODE:%s", (mode < IWL_POWER_AUTO)?"fixed":"auto");
p += sprintf(p, " OFF\n"); p += sprintf(p, "\tINDEX:%d", level);
else p += sprintf(p, "\n");
p += sprintf(p, " \n"); return p - buf + 1;
*/
p += sprintf(p, " \n");
return (p - buf + 1);
} }
static DEVICE_ATTR(power_level, S_IWUSR | S_IRUSR, show_power_level, static DEVICE_ATTR(power_level, S_IWUSR | S_IRUSR, show_power_level,
@ -3945,7 +4008,7 @@ static ssize_t show_statistics(struct device *d,
struct iwl_priv *priv = dev_get_drvdata(d); struct iwl_priv *priv = dev_get_drvdata(d);
u32 size = sizeof(struct iwl_notif_statistics); u32 size = sizeof(struct iwl_notif_statistics);
u32 len = 0, ofs = 0; u32 len = 0, ofs = 0;
u8 *data = (u8 *) & priv->statistics; u8 *data = (u8 *)&priv->statistics;
int rc = 0; int rc = 0;
if (!iwl_is_alive(priv)) if (!iwl_is_alive(priv))
@ -4041,12 +4104,11 @@ static struct attribute *iwl4965_sysfs_entries[] = {
&dev_attr_channels.attr, &dev_attr_channels.attr,
&dev_attr_flags.attr, &dev_attr_flags.attr,
&dev_attr_filter_flags.attr, &dev_attr_filter_flags.attr,
#ifdef CONFIG_IWL4965_SPECTRUM_MEASUREMENT #ifdef CONFIG_IWLAGN_SPECTRUM_MEASUREMENT
&dev_attr_measurement.attr, &dev_attr_measurement.attr,
#endif #endif
&dev_attr_power_level.attr, &dev_attr_power_level.attr,
&dev_attr_retry_rate.attr, &dev_attr_retry_rate.attr,
&dev_attr_rs_window.attr,
&dev_attr_statistics.attr, &dev_attr_statistics.attr,
&dev_attr_status.attr, &dev_attr_status.attr,
&dev_attr_temperature.attr, &dev_attr_temperature.attr,
@ -4394,8 +4456,10 @@ static int iwl4965_pci_resume(struct pci_dev *pdev)
/* Hardware specific file defines the PCI IDs table for that hardware module */ /* Hardware specific file defines the PCI IDs table for that hardware module */
static struct pci_device_id iwl_hw_card_ids[] = { static struct pci_device_id iwl_hw_card_ids[] = {
#ifdef CONFIG_IWL4965
{IWL_PCI_DEVICE(0x4229, PCI_ANY_ID, iwl4965_agn_cfg)}, {IWL_PCI_DEVICE(0x4229, PCI_ANY_ID, iwl4965_agn_cfg)},
{IWL_PCI_DEVICE(0x4230, PCI_ANY_ID, iwl4965_agn_cfg)}, {IWL_PCI_DEVICE(0x4230, PCI_ANY_ID, iwl4965_agn_cfg)},
#endif /* CONFIG_IWL4965 */
#ifdef CONFIG_IWL5000 #ifdef CONFIG_IWL5000
{IWL_PCI_DEVICE(0x4232, 0x1205, iwl5100_bg_cfg)}, {IWL_PCI_DEVICE(0x4232, 0x1205, iwl5100_bg_cfg)},
{IWL_PCI_DEVICE(0x4232, 0x1305, iwl5100_bg_cfg)}, {IWL_PCI_DEVICE(0x4232, 0x1305, iwl5100_bg_cfg)},
@ -4431,7 +4495,7 @@ static int __init iwl4965_init(void)
printk(KERN_INFO DRV_NAME ": " DRV_DESCRIPTION ", " DRV_VERSION "\n"); printk(KERN_INFO DRV_NAME ": " DRV_DESCRIPTION ", " DRV_VERSION "\n");
printk(KERN_INFO DRV_NAME ": " DRV_COPYRIGHT "\n"); printk(KERN_INFO DRV_NAME ": " DRV_COPYRIGHT "\n");
ret = iwl4965_rate_control_register(); ret = iwlagn_rate_control_register();
if (ret) { if (ret) {
IWL_ERROR("Unable to register rate control algorithm: %d\n", ret); IWL_ERROR("Unable to register rate control algorithm: %d\n", ret);
return ret; return ret;
@ -4446,14 +4510,14 @@ static int __init iwl4965_init(void)
return ret; return ret;
error_register: error_register:
iwl4965_rate_control_unregister(); iwlagn_rate_control_unregister();
return ret; return ret;
} }
static void __exit iwl4965_exit(void) static void __exit iwl4965_exit(void)
{ {
pci_unregister_driver(&iwl_driver); pci_unregister_driver(&iwl_driver);
iwl4965_rate_control_unregister(); iwlagn_rate_control_unregister();
} }
module_exit(iwl4965_exit); module_exit(iwl4965_exit);

View File

@ -666,8 +666,7 @@ struct iwl4965_rxon_assoc_cmd {
__le16 reserved; __le16 reserved;
} __attribute__ ((packed)); } __attribute__ ((packed));
#define IWL_CONN_MAX_LISTEN_INTERVAL 10
/* /*
* REPLY_RXON_TIMING = 0x14 (command, has simple generic response) * REPLY_RXON_TIMING = 0x14 (command, has simple generic response)
@ -1076,10 +1075,12 @@ struct iwl4965_rx_frame {
} __attribute__ ((packed)); } __attribute__ ((packed));
/* Fixed (non-configurable) rx data from phy */ /* Fixed (non-configurable) rx data from phy */
#define RX_PHY_FLAGS_ANTENNAE_OFFSET (4)
#define RX_PHY_FLAGS_ANTENNAE_MASK (0x70) #define IWL49_RX_RES_PHY_CNT 14
#define IWL_AGC_DB_MASK (0x3f80) /* MASK(7,13) */ #define IWL49_RX_PHY_FLAGS_ANTENNAE_OFFSET (4)
#define IWL_AGC_DB_POS (7) #define IWL49_RX_PHY_FLAGS_ANTENNAE_MASK (0x70)
#define IWL49_AGC_DB_MASK (0x3f80) /* MASK(7,13) */
#define IWL49_AGC_DB_POS (7)
struct iwl4965_rx_non_cfg_phy { struct iwl4965_rx_non_cfg_phy {
__le16 ant_selection; /* ant A bit 4, ant B bit 5, ant C bit 6 */ __le16 ant_selection; /* ant A bit 4, ant B bit 5, ant C bit 6 */
__le16 agc_info; /* agc code 0:6, agc dB 7:13, reserved 14:15 */ __le16 agc_info; /* agc code 0:6, agc dB 7:13, reserved 14:15 */
@ -1087,12 +1088,30 @@ struct iwl4965_rx_non_cfg_phy {
u8 pad[0]; u8 pad[0];
} __attribute__ ((packed)); } __attribute__ ((packed));
#define IWL50_RX_RES_PHY_CNT 8
#define IWL50_RX_RES_AGC_IDX 1
#define IWL50_RX_RES_RSSI_AB_IDX 2
#define IWL50_RX_RES_RSSI_C_IDX 3
#define IWL50_OFDM_AGC_MSK 0xfe00
#define IWL50_OFDM_AGC_BIT_POS 9
#define IWL50_OFDM_RSSI_A_MSK 0x00ff
#define IWL50_OFDM_RSSI_A_BIT_POS 0
#define IWL50_OFDM_RSSI_B_MSK 0xff0000
#define IWL50_OFDM_RSSI_B_BIT_POS 16
#define IWL50_OFDM_RSSI_C_MSK 0x00ff
#define IWL50_OFDM_RSSI_C_BIT_POS 0
struct iwl5000_non_cfg_phy {
__le32 non_cfg_phy[IWL50_RX_RES_PHY_CNT]; /* upto 8 phy entries */
} __attribute__ ((packed));
/* /*
* REPLY_RX = 0xc3 (response only, not a command) * REPLY_RX = 0xc3 (response only, not a command)
* Used only for legacy (non 11n) frames. * Used only for legacy (non 11n) frames.
*/ */
#define RX_RES_PHY_CNT 14 struct iwl_rx_phy_res {
struct iwl4965_rx_phy_res {
u8 non_cfg_phy_cnt; /* non configurable DSP phy data byte count */ u8 non_cfg_phy_cnt; /* non configurable DSP phy data byte count */
u8 cfg_phy_cnt; /* configurable DSP phy data byte count */ u8 cfg_phy_cnt; /* configurable DSP phy data byte count */
u8 stat_id; /* configurable DSP phy data set ID */ u8 stat_id; /* configurable DSP phy data set ID */
@ -1101,8 +1120,7 @@ struct iwl4965_rx_phy_res {
__le32 beacon_time_stamp; /* beacon at on-air rise */ __le32 beacon_time_stamp; /* beacon at on-air rise */
__le16 phy_flags; /* general phy flags: band, modulation, ... */ __le16 phy_flags; /* general phy flags: band, modulation, ... */
__le16 channel; /* channel number */ __le16 channel; /* channel number */
__le16 non_cfg_phy[RX_RES_PHY_CNT]; /* upto 14 phy entries */ u8 non_cfg_phy_buf[32]; /* for various implementations of non_cfg_phy */
__le32 reserved2;
__le32 rate_n_flags; /* RATE_MCS_* */ __le32 rate_n_flags; /* RATE_MCS_* */
__le16 byte_count; /* frame's byte-count */ __le16 byte_count; /* frame's byte-count */
__le16 reserved3; __le16 reserved3;
@ -1993,7 +2011,7 @@ struct iwl4965_spectrum_notification {
*****************************************************************************/ *****************************************************************************/
/** /**
* struct iwl4965_powertable_cmd - Power Table Command * struct iwl_powertable_cmd - Power Table Command
* @flags: See below: * @flags: See below:
* *
* POWER_TABLE_CMD = 0x77 (command, has simple generic response) * POWER_TABLE_CMD = 0x77 (command, has simple generic response)
@ -2027,7 +2045,7 @@ struct iwl4965_spectrum_notification {
#define IWL_POWER_PCI_PM_MSK __constant_cpu_to_le16(1 << 3) #define IWL_POWER_PCI_PM_MSK __constant_cpu_to_le16(1 << 3)
#define IWL_POWER_FAST_PD __constant_cpu_to_le16(1 << 4) #define IWL_POWER_FAST_PD __constant_cpu_to_le16(1 << 4)
struct iwl4965_powertable_cmd { struct iwl_powertable_cmd {
__le16 flags; __le16 flags;
u8 keep_alive_seconds; u8 keep_alive_seconds;
u8 debug_flags; u8 debug_flags;
@ -2324,7 +2342,7 @@ struct iwl4965_beacon_notif {
/* /*
* REPLY_TX_BEACON = 0x91 (command, has simple generic response) * REPLY_TX_BEACON = 0x91 (command, has simple generic response)
*/ */
struct iwl4965_tx_beacon_cmd { struct iwl_tx_beacon_cmd {
struct iwl_tx_cmd tx; struct iwl_tx_cmd tx;
__le16 tim_idx; __le16 tim_idx;
u8 tim_size; u8 tim_size;

View File

@ -383,8 +383,8 @@ void iwl_reset_qos(struct iwl_priv *priv)
} }
EXPORT_SYMBOL(iwl_reset_qos); EXPORT_SYMBOL(iwl_reset_qos);
#define MAX_BIT_RATE_40_MHZ 0x96; /* 150 Mbps */ #define MAX_BIT_RATE_40_MHZ 0x96 /* 150 Mbps */
#define MAX_BIT_RATE_20_MHZ 0x48; /* 72 Mbps */ #define MAX_BIT_RATE_20_MHZ 0x48 /* 72 Mbps */
static void iwlcore_init_ht_hw_capab(const struct iwl_priv *priv, static void iwlcore_init_ht_hw_capab(const struct iwl_priv *priv,
struct ieee80211_ht_info *ht_info, struct ieee80211_ht_info *ht_info,
enum ieee80211_band band) enum ieee80211_band band)
@ -815,7 +815,7 @@ int iwl_setup_mac(struct iwl_priv *priv)
{ {
int ret; int ret;
struct ieee80211_hw *hw = priv->hw; struct ieee80211_hw *hw = priv->hw;
hw->rate_control_algorithm = "iwl-4965-rs"; hw->rate_control_algorithm = "iwl-agn-rs";
/* Tell mac80211 our characteristics */ /* Tell mac80211 our characteristics */
hw->flags = IEEE80211_HW_SIGNAL_DBM | hw->flags = IEEE80211_HW_SIGNAL_DBM |
@ -827,6 +827,7 @@ int iwl_setup_mac(struct iwl_priv *priv)
hw->ampdu_queues = priv->cfg->mod_params->num_of_ampdu_queues; hw->ampdu_queues = priv->cfg->mod_params->num_of_ampdu_queues;
hw->conf.beacon_int = 100; hw->conf.beacon_int = 100;
hw->max_listen_interval = IWL_CONN_MAX_LISTEN_INTERVAL;
if (priv->bands[IEEE80211_BAND_2GHZ].n_channels) if (priv->bands[IEEE80211_BAND_2GHZ].n_channels)
priv->hw->wiphy->bands[IEEE80211_BAND_2GHZ] = priv->hw->wiphy->bands[IEEE80211_BAND_2GHZ] =

View File

@ -95,6 +95,8 @@ struct iwl_hcmd_utils_ops {
void (*chain_noise_reset)(struct iwl_priv *priv); void (*chain_noise_reset)(struct iwl_priv *priv);
void (*rts_tx_cmd_flag)(struct ieee80211_tx_info *info, void (*rts_tx_cmd_flag)(struct ieee80211_tx_info *info,
__le32 *tx_flags); __le32 *tx_flags);
int (*calc_rssi)(struct iwl_priv *priv,
struct iwl_rx_phy_res *rx_resp);
}; };
struct iwl_lib_ops { struct iwl_lib_ops {
@ -139,7 +141,6 @@ struct iwl_lib_ops {
int (*set_pwr_src)(struct iwl_priv *priv, enum iwl_pwr_src src); int (*set_pwr_src)(struct iwl_priv *priv, enum iwl_pwr_src src);
} apm_ops; } apm_ops;
/* power */ /* power */
int (*set_power)(struct iwl_priv *priv, void *cmd);
int (*send_tx_power) (struct iwl_priv *priv); int (*send_tx_power) (struct iwl_priv *priv);
void (*update_chain_flags)(struct iwl_priv *priv); void (*update_chain_flags)(struct iwl_priv *priv);
void (*temperature) (struct iwl_priv *priv); void (*temperature) (struct iwl_priv *priv);

View File

@ -104,6 +104,7 @@
* 3-2: 0 = A, 1 = B, 2 = C, 3 = D step * 3-2: 0 = A, 1 = B, 2 = C, 3 = D step
*/ */
#define CSR_HW_REV_WA_REG (CSR_BASE+0x22C) #define CSR_HW_REV_WA_REG (CSR_BASE+0x22C)
#define CSR_DBG_HPET_MEM_REG (CSR_BASE+0x240)
/* Bits for CSR_HW_IF_CONFIG_REG */ /* Bits for CSR_HW_IF_CONFIG_REG */
#define CSR49_HW_IF_CONFIG_REG_BIT_4965_R (0x00000010) #define CSR49_HW_IF_CONFIG_REG_BIT_4965_R (0x00000010)
@ -118,7 +119,12 @@
#define CSR39_HW_IF_CONFIG_REG_BITS_SILICON_TYPE_A (0x00000000) #define CSR39_HW_IF_CONFIG_REG_BITS_SILICON_TYPE_A (0x00000000)
#define CSR39_HW_IF_CONFIG_REG_BITS_SILICON_TYPE_B (0x00001000) #define CSR39_HW_IF_CONFIG_REG_BITS_SILICON_TYPE_B (0x00001000)
#define CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM (0x00200000) #define CSR_HW_IF_CONFIG_REG_BIT_HAP_WAKE_L1A (0x00080000)
#define CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM (0x00200000)
#define CSR_HW_IF_CONFIG_REG_BIT_PCI_OWN_SEM (0x00400000)
#define CSR_HW_IF_CONFIG_REG_BIT_ME_OWN (0x02000000)
#define CSR_HW_IF_CONFIG_REG_BIT_WAKE_ME (0x08000000)
/* interrupt flags in INTA, set by uCode or hardware (e.g. dma), /* interrupt flags in INTA, set by uCode or hardware (e.g. dma),
* acknowledged (reset) by host writing "1" to flagged bits. */ * acknowledged (reset) by host writing "1" to flagged bits. */
@ -236,6 +242,8 @@
#define CSR39_ANA_PLL_CFG_VAL (0x01000000) #define CSR39_ANA_PLL_CFG_VAL (0x01000000)
#define CSR50_ANA_PLL_CFG_VAL (0x00880300) #define CSR50_ANA_PLL_CFG_VAL (0x00880300)
/* HPET MEM debug */
#define CSR_DBG_HPET_MEM_REG_VAL (0xFFFF0000)
/*=== HBUS (Host-side Bus) ===*/ /*=== HBUS (Host-side Bus) ===*/
#define HBUS_BASE (0x400) #define HBUS_BASE (0x400)
/* /*

View File

@ -33,12 +33,12 @@
#define IWL_DEBUG(level, fmt, args...) \ #define IWL_DEBUG(level, fmt, args...) \
do { if (priv->debug_level & (level)) \ do { if (priv->debug_level & (level)) \
dev_printk(KERN_ERR, &(priv->hw->wiphy->dev), "%c %s " fmt, \ dev_printk(KERN_ERR, &(priv->hw->wiphy->dev), "%c %s " fmt, \
in_interrupt() ? 'I' : 'U', __FUNCTION__ , ## args); } while (0) in_interrupt() ? 'I' : 'U', __func__ , ## args); } while (0)
#define IWL_DEBUG_LIMIT(level, fmt, args...) \ #define IWL_DEBUG_LIMIT(level, fmt, args...) \
do { if ((priv->debug_level & (level)) && net_ratelimit()) \ do { if ((priv->debug_level & (level)) && net_ratelimit()) \
dev_printk(KERN_ERR, &(priv->hw->wiphy->dev), "%c %s " fmt, \ dev_printk(KERN_ERR, &(priv->hw->wiphy->dev), "%c %s " fmt, \
in_interrupt() ? 'I' : 'U', __FUNCTION__ , ## args); } while (0) in_interrupt() ? 'I' : 'U', __func__ , ## args); } while (0)
#ifdef CONFIG_IWLWIFI_DEBUGFS #ifdef CONFIG_IWLWIFI_DEBUGFS
struct iwl_debugfs { struct iwl_debugfs {

View File

@ -231,7 +231,7 @@ static ssize_t iwl_dbgfs_stations_read(struct file *file, char __user *user_buf,
DECLARE_MAC_BUF(mac); DECLARE_MAC_BUF(mac);
buf = kmalloc(bufsz, GFP_KERNEL); buf = kmalloc(bufsz, GFP_KERNEL);
if(!buf) if (!buf)
return -ENOMEM; return -ENOMEM;
pos += scnprintf(buf + pos, bufsz - pos, "num of stations: %d\n\n", pos += scnprintf(buf + pos, bufsz - pos, "num of stations: %d\n\n",
@ -364,16 +364,19 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name)
{ {
struct iwl_debugfs *dbgfs; struct iwl_debugfs *dbgfs;
struct dentry *phyd = priv->hw->wiphy->debugfsdir; struct dentry *phyd = priv->hw->wiphy->debugfsdir;
int ret = 0;
dbgfs = kzalloc(sizeof(struct iwl_debugfs), GFP_KERNEL); dbgfs = kzalloc(sizeof(struct iwl_debugfs), GFP_KERNEL);
if (!dbgfs) { if (!dbgfs) {
ret = -ENOMEM;
goto err; goto err;
} }
priv->dbgfs = dbgfs; priv->dbgfs = dbgfs;
dbgfs->name = name; dbgfs->name = name;
dbgfs->dir_drv = debugfs_create_dir(name, phyd); dbgfs->dir_drv = debugfs_create_dir(name, phyd);
if (!dbgfs->dir_drv || IS_ERR(dbgfs->dir_drv)){ if (!dbgfs->dir_drv || IS_ERR(dbgfs->dir_drv)) {
ret = -ENOENT;
goto err; goto err;
} }
@ -394,7 +397,7 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name)
err: err:
IWL_ERROR("Can't open the debugfs directory\n"); IWL_ERROR("Can't open the debugfs directory\n");
iwl_dbgfs_unregister(priv); iwl_dbgfs_unregister(priv);
return -ENOENT; return ret;
} }
EXPORT_SYMBOL(iwl_dbgfs_register); EXPORT_SYMBOL(iwl_dbgfs_register);
@ -404,7 +407,7 @@ EXPORT_SYMBOL(iwl_dbgfs_register);
*/ */
void iwl_dbgfs_unregister(struct iwl_priv *priv) void iwl_dbgfs_unregister(struct iwl_priv *priv)
{ {
if (!(priv->dbgfs)) if (!priv->dbgfs)
return; return;
DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_eeprom); DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_eeprom);

View File

@ -36,7 +36,7 @@
#include <linux/kernel.h> #include <linux/kernel.h>
#include <net/ieee80211_radiotap.h> #include <net/ieee80211_radiotap.h>
#define DRV_NAME "iwl4965" #define DRV_NAME "iwlagn"
#include "iwl-rfkill.h" #include "iwl-rfkill.h"
#include "iwl-eeprom.h" #include "iwl-eeprom.h"
#include "iwl-4965-hw.h" #include "iwl-4965-hw.h"
@ -45,6 +45,7 @@
#include "iwl-debug.h" #include "iwl-debug.h"
#include "iwl-led.h" #include "iwl-led.h"
#include "iwl-power.h" #include "iwl-power.h"
#include "iwl-agn-rs.h"
/* configuration for the iwl4965 */ /* configuration for the iwl4965 */
extern struct iwl_cfg iwl4965_agn_cfg; extern struct iwl_cfg iwl4965_agn_cfg;
@ -134,8 +135,7 @@ struct iwl_tx_info {
struct iwl_tx_queue { struct iwl_tx_queue {
struct iwl_queue q; struct iwl_queue q;
struct iwl_tfd_frame *bd; struct iwl_tfd_frame *bd;
struct iwl_cmd *cmd; struct iwl_cmd *cmd[TFD_TX_CMD_SLOTS];
dma_addr_t dma_addr_cmd;
struct iwl_tx_info *txb; struct iwl_tx_info *txb;
int need_update; int need_update;
int sched_retry; int sched_retry;
@ -191,7 +191,6 @@ struct iwl4965_clip_group {
const s8 clip_powers[IWL_MAX_RATES]; const s8 clip_powers[IWL_MAX_RATES];
}; };
#include "iwl-4965-rs.h"
#define IWL_TX_FIFO_AC0 0 #define IWL_TX_FIFO_AC0 0
#define IWL_TX_FIFO_AC1 1 #define IWL_TX_FIFO_AC1 1
@ -219,7 +218,7 @@ enum iwl_pwr_src {
struct iwl_frame { struct iwl_frame {
union { union {
struct ieee80211_hdr frame; struct ieee80211_hdr frame;
struct iwl4965_tx_beacon_cmd beacon; struct iwl_tx_beacon_cmd beacon;
u8 raw[IEEE80211_FRAME_LEN]; u8 raw[IEEE80211_FRAME_LEN];
u8 cmd[360]; u8 cmd[360];
} u; } u;
@ -283,10 +282,9 @@ struct iwl_cmd {
u32 val32; u32 val32;
struct iwl4965_bt_cmd bt; struct iwl4965_bt_cmd bt;
struct iwl4965_rxon_time_cmd rxon_time; struct iwl4965_rxon_time_cmd rxon_time;
struct iwl4965_powertable_cmd powertable; struct iwl_powertable_cmd powertable;
struct iwl_qosparam_cmd qosparam; struct iwl_qosparam_cmd qosparam;
struct iwl_tx_cmd tx; struct iwl_tx_cmd tx;
struct iwl4965_tx_beacon_cmd tx_beacon;
struct iwl4965_rxon_assoc_cmd rxon_assoc; struct iwl4965_rxon_assoc_cmd rxon_assoc;
struct iwl_rem_sta_cmd rm_sta; struct iwl_rem_sta_cmd rm_sta;
u8 *indirect; u8 *indirect;
@ -590,6 +588,7 @@ extern unsigned int iwl4965_fill_beacon_frame(struct iwl_priv *priv,
const u8 *dest, int left); const u8 *dest, int left);
extern void iwl4965_update_chain_flags(struct iwl_priv *priv); extern void iwl4965_update_chain_flags(struct iwl_priv *priv);
int iwl4965_set_pwr_src(struct iwl_priv *priv, enum iwl_pwr_src src); int iwl4965_set_pwr_src(struct iwl_priv *priv, enum iwl_pwr_src src);
extern int iwl4965_set_power(struct iwl_priv *priv, void *cmd);
extern const u8 iwl_bcast_addr[ETH_ALEN]; extern const u8 iwl_bcast_addr[ETH_ALEN];
@ -642,10 +641,6 @@ struct iwl_priv;
* Forward declare iwl-4965.c functions for iwl-base.c * Forward declare iwl-4965.c functions for iwl-base.c
*/ */
extern void iwl4965_rf_kill_ct_config(struct iwl_priv *priv); extern void iwl4965_rf_kill_ct_config(struct iwl_priv *priv);
int iwl4965_mac_ampdu_action(struct ieee80211_hw *hw,
enum ieee80211_ampdu_mlme_action action,
const u8 *addr, u16 tid, u16 *ssn);
int iwl4965_check_empty_hw_queue(struct iwl_priv *priv, int sta_id, int iwl4965_check_empty_hw_queue(struct iwl_priv *priv, int sta_id,
u8 tid, int txq_id); u8 tid, int txq_id);
@ -812,14 +807,11 @@ struct iwl_chain_noise_data {
#define EEPROM_SEM_RETRY_LIMIT 1000 /* number of attempts (not time) */ #define EEPROM_SEM_RETRY_LIMIT 1000 /* number of attempts (not time) */
#ifdef CONFIG_IWL4965_SPECTRUM_MEASUREMENT
enum { enum {
MEASUREMENT_READY = (1 << 0), MEASUREMENT_READY = (1 << 0),
MEASUREMENT_ACTIVE = (1 << 1), MEASUREMENT_ACTIVE = (1 << 1),
}; };
#endif
#define IWL_MAX_NUM_QUEUES 20 /* FIXME: do dynamic allocation */ #define IWL_MAX_NUM_QUEUES 20 /* FIXME: do dynamic allocation */
@ -844,7 +836,7 @@ struct iwl_priv {
struct ieee80211_supported_band bands[IEEE80211_NUM_BANDS]; struct ieee80211_supported_band bands[IEEE80211_NUM_BANDS];
#ifdef CONFIG_IWL4965_SPECTRUM_MEASUREMENT #ifdef CONFIG_IWLAGN_SPECTRUM_MEASUREMENT
/* spectrum measurement report caching */ /* spectrum measurement report caching */
struct iwl4965_spectrum_notification measure_report; struct iwl4965_spectrum_notification measure_report;
u8 measurement_status; u8 measurement_status;

View File

@ -273,8 +273,7 @@ EXPORT_SYMBOL(iwl_eeprom_init);
void iwl_eeprom_free(struct iwl_priv *priv) void iwl_eeprom_free(struct iwl_priv *priv)
{ {
if(priv->eeprom) kfree(priv->eeprom);
kfree(priv->eeprom);
priv->eeprom = NULL; priv->eeprom = NULL;
} }
EXPORT_SYMBOL(iwl_eeprom_free); EXPORT_SYMBOL(iwl_eeprom_free);

View File

@ -228,7 +228,7 @@ int iwl_send_cmd_sync(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
* TX cmd queue. Otherwise in case the cmd comes * TX cmd queue. Otherwise in case the cmd comes
* in later, it will possibly set an invalid * in later, it will possibly set an invalid
* address (cmd->meta.source). */ * address (cmd->meta.source). */
qcmd = &priv->txq[IWL_CMD_QUEUE_NUM].cmd[cmd_idx]; qcmd = priv->txq[IWL_CMD_QUEUE_NUM].cmd[cmd_idx];
qcmd->meta.flags &= ~CMD_WANT_SKB; qcmd->meta.flags &= ~CMD_WANT_SKB;
} }
fail: fail:

View File

@ -161,11 +161,31 @@ int iwl4965_led_off(struct iwl_priv *priv, int led_id)
/* Set led register off */ /* Set led register off */
static int iwl4965_led_off_reg(struct iwl_priv *priv, int led_id) static int iwl4965_led_off_reg(struct iwl_priv *priv, int led_id)
{ {
IWL_DEBUG_LED("radio off\n"); IWL_DEBUG_LED("LED Reg off\n");
iwl_write32(priv, CSR_LED_REG, CSR_LED_REG_TRUN_OFF); iwl_write32(priv, CSR_LED_REG, CSR_LED_REG_TRUN_OFF);
return 0; return 0;
} }
/*
* Set led register in case of disassociation according to rfkill state
*/
static int iwl_led_associate(struct iwl_priv *priv, int led_id)
{
IWL_DEBUG_LED("Associated\n");
priv->allow_blinking = 1;
return iwl4965_led_on_reg(priv, led_id);
}
static int iwl_led_disassociate(struct iwl_priv *priv, int led_id)
{
priv->allow_blinking = 0;
if (iwl_is_rfkill(priv))
iwl4965_led_off_reg(priv, led_id);
else
iwl4965_led_on_reg(priv, led_id);
return 0;
}
/* /*
* brightness call back function for Tx/Rx LED * brightness call back function for Tx/Rx LED
*/ */
@ -199,16 +219,10 @@ static void iwl_led_brightness_set(struct led_classdev *led_cdev,
led_type_str[led->type], brightness); led_type_str[led->type], brightness);
switch (brightness) { switch (brightness) {
case LED_FULL: case LED_FULL:
if (led->type == IWL_LED_TRG_ASSOC)
priv->allow_blinking = 1;
if (led->led_on) if (led->led_on)
led->led_on(priv, IWL_LED_LINK); led->led_on(priv, IWL_LED_LINK);
break; break;
case LED_OFF: case LED_OFF:
if (led->type == IWL_LED_TRG_ASSOC)
priv->allow_blinking = 0;
if (led->led_off) if (led->led_off)
led->led_off(priv, IWL_LED_LINK); led->led_off(priv, IWL_LED_LINK);
break; break;
@ -228,12 +242,12 @@ static void iwl_led_brightness_set(struct led_classdev *led_cdev,
*/ */
static int iwl_leds_register_led(struct iwl_priv *priv, struct iwl_led *led, static int iwl_leds_register_led(struct iwl_priv *priv, struct iwl_led *led,
enum led_type type, u8 set_led, enum led_type type, u8 set_led,
const char *name, char *trigger) char *trigger)
{ {
struct device *device = wiphy_dev(priv->hw->wiphy); struct device *device = wiphy_dev(priv->hw->wiphy);
int ret; int ret;
led->led_dev.name = name; led->led_dev.name = led->name;
led->led_dev.brightness_set = iwl_led_brightness_set; led->led_dev.brightness_set = iwl_led_brightness_set;
led->led_dev.default_trigger = trigger; led->led_dev.default_trigger = trigger;
@ -284,12 +298,6 @@ static int iwl_get_blink_rate(struct iwl_priv *priv)
return i; return i;
} }
static inline int is_rf_kill(struct iwl_priv *priv)
{
return test_bit(STATUS_RF_KILL_HW, &priv->status) ||
test_bit(STATUS_RF_KILL_SW, &priv->status);
}
/* /*
* this function called from handler. Since setting Led command can * this function called from handler. Since setting Led command can
* happen very frequent we postpone led command to be called from * happen very frequent we postpone led command to be called from
@ -303,7 +311,7 @@ void iwl_leds_background(struct iwl_priv *priv)
priv->last_blink_time = 0; priv->last_blink_time = 0;
return; return;
} }
if (is_rf_kill(priv)) { if (iwl_is_rfkill(priv)) {
priv->last_blink_time = 0; priv->last_blink_time = 0;
return; return;
} }
@ -337,7 +345,6 @@ EXPORT_SYMBOL(iwl_leds_background);
int iwl_leds_register(struct iwl_priv *priv) int iwl_leds_register(struct iwl_priv *priv)
{ {
char *trigger; char *trigger;
char name[32];
int ret; int ret;
priv->last_blink_rate = 0; priv->last_blink_rate = 0;
@ -346,7 +353,8 @@ int iwl_leds_register(struct iwl_priv *priv)
priv->allow_blinking = 0; priv->allow_blinking = 0;
trigger = ieee80211_get_radio_led_name(priv->hw); trigger = ieee80211_get_radio_led_name(priv->hw);
snprintf(name, sizeof(name), "iwl-%s:radio", snprintf(priv->led[IWL_LED_TRG_RADIO].name,
sizeof(priv->led[IWL_LED_TRG_RADIO].name), "iwl-%s:radio",
wiphy_name(priv->hw->wiphy)); wiphy_name(priv->hw->wiphy));
priv->led[IWL_LED_TRG_RADIO].led_on = iwl4965_led_on_reg; priv->led[IWL_LED_TRG_RADIO].led_on = iwl4965_led_on_reg;
@ -354,31 +362,33 @@ int iwl_leds_register(struct iwl_priv *priv)
priv->led[IWL_LED_TRG_RADIO].led_pattern = NULL; priv->led[IWL_LED_TRG_RADIO].led_pattern = NULL;
ret = iwl_leds_register_led(priv, &priv->led[IWL_LED_TRG_RADIO], ret = iwl_leds_register_led(priv, &priv->led[IWL_LED_TRG_RADIO],
IWL_LED_TRG_RADIO, 1, name, trigger); IWL_LED_TRG_RADIO, 1, trigger);
if (ret) if (ret)
goto exit_fail; goto exit_fail;
trigger = ieee80211_get_assoc_led_name(priv->hw); trigger = ieee80211_get_assoc_led_name(priv->hw);
snprintf(name, sizeof(name), "iwl-%s:assoc", snprintf(priv->led[IWL_LED_TRG_ASSOC].name,
sizeof(priv->led[IWL_LED_TRG_ASSOC].name), "iwl-%s:assoc",
wiphy_name(priv->hw->wiphy)); wiphy_name(priv->hw->wiphy));
ret = iwl_leds_register_led(priv, &priv->led[IWL_LED_TRG_ASSOC], ret = iwl_leds_register_led(priv, &priv->led[IWL_LED_TRG_ASSOC],
IWL_LED_TRG_ASSOC, 0, name, trigger); IWL_LED_TRG_ASSOC, 0, trigger);
/* for assoc always turn led on */ /* for assoc always turn led on */
priv->led[IWL_LED_TRG_ASSOC].led_on = iwl4965_led_on_reg; priv->led[IWL_LED_TRG_ASSOC].led_on = iwl_led_associate;
priv->led[IWL_LED_TRG_ASSOC].led_off = iwl4965_led_on_reg; priv->led[IWL_LED_TRG_ASSOC].led_off = iwl_led_disassociate;
priv->led[IWL_LED_TRG_ASSOC].led_pattern = NULL; priv->led[IWL_LED_TRG_ASSOC].led_pattern = NULL;
if (ret) if (ret)
goto exit_fail; goto exit_fail;
trigger = ieee80211_get_rx_led_name(priv->hw); trigger = ieee80211_get_rx_led_name(priv->hw);
snprintf(name, sizeof(name), "iwl-%s:RX", wiphy_name(priv->hw->wiphy)); snprintf(priv->led[IWL_LED_TRG_RX].name,
sizeof(priv->led[IWL_LED_TRG_RX].name), "iwl-%s:RX",
wiphy_name(priv->hw->wiphy));
ret = iwl_leds_register_led(priv, &priv->led[IWL_LED_TRG_RX], ret = iwl_leds_register_led(priv, &priv->led[IWL_LED_TRG_RX],
IWL_LED_TRG_RX, 0, name, trigger); IWL_LED_TRG_RX, 0, trigger);
priv->led[IWL_LED_TRG_RX].led_on = iwl_led_associated; priv->led[IWL_LED_TRG_RX].led_on = iwl_led_associated;
priv->led[IWL_LED_TRG_RX].led_off = iwl_led_associated; priv->led[IWL_LED_TRG_RX].led_off = iwl_led_associated;
@ -388,9 +398,12 @@ int iwl_leds_register(struct iwl_priv *priv)
goto exit_fail; goto exit_fail;
trigger = ieee80211_get_tx_led_name(priv->hw); trigger = ieee80211_get_tx_led_name(priv->hw);
snprintf(name, sizeof(name), "iwl-%s:TX", wiphy_name(priv->hw->wiphy)); snprintf(priv->led[IWL_LED_TRG_TX].name,
sizeof(priv->led[IWL_LED_TRG_TX].name), "iwl-%s:TX",
wiphy_name(priv->hw->wiphy));
ret = iwl_leds_register_led(priv, &priv->led[IWL_LED_TRG_TX], ret = iwl_leds_register_led(priv, &priv->led[IWL_LED_TRG_TX],
IWL_LED_TRG_TX, 0, name, trigger); IWL_LED_TRG_TX, 0, trigger);
priv->led[IWL_LED_TRG_TX].led_on = iwl_led_associated; priv->led[IWL_LED_TRG_TX].led_on = iwl_led_associated;
priv->led[IWL_LED_TRG_TX].led_off = iwl_led_associated; priv->led[IWL_LED_TRG_TX].led_off = iwl_led_associated;

View File

@ -52,6 +52,7 @@ enum led_type {
struct iwl_led { struct iwl_led {
struct iwl_priv *priv; struct iwl_priv *priv;
struct led_classdev led_dev; struct led_classdev led_dev;
char name[32];
int (*led_on) (struct iwl_priv *priv, int led_id); int (*led_on) (struct iwl_priv *priv, int led_id);
int (*led_off) (struct iwl_priv *priv, int led_id); int (*led_off) (struct iwl_priv *priv, int led_id);

View File

@ -82,7 +82,7 @@
/* default power management (not Tx power) table values */ /* default power management (not Tx power) table values */
/* for tim 0-10 */ /* for tim 0-10 */
static struct iwl_power_vec_entry range_0[IWL_POWER_AC] = { static struct iwl_power_vec_entry range_0[IWL_POWER_MAX] = {
{{NOSLP, SLP_TOUT(0), SLP_TOUT(0), SLP_VEC(0, 0, 0, 0, 0)}, 0}, {{NOSLP, SLP_TOUT(0), SLP_TOUT(0), SLP_VEC(0, 0, 0, 0, 0)}, 0},
{{SLP, SLP_TOUT(200), SLP_TOUT(500), SLP_VEC(1, 2, 2, 2, 0xFF)}, 0}, {{SLP, SLP_TOUT(200), SLP_TOUT(500), SLP_VEC(1, 2, 2, 2, 0xFF)}, 0},
{{SLP, SLP_TOUT(200), SLP_TOUT(300), SLP_VEC(1, 2, 2, 2, 0xFF)}, 0}, {{SLP, SLP_TOUT(200), SLP_TOUT(300), SLP_VEC(1, 2, 2, 2, 0xFF)}, 0},
@ -93,7 +93,7 @@ static struct iwl_power_vec_entry range_0[IWL_POWER_AC] = {
/* for tim = 3-10 */ /* for tim = 3-10 */
static struct iwl_power_vec_entry range_1[IWL_POWER_AC] = { static struct iwl_power_vec_entry range_1[IWL_POWER_MAX] = {
{{NOSLP, SLP_TOUT(0), SLP_TOUT(0), SLP_VEC(0, 0, 0, 0, 0)}, 0}, {{NOSLP, SLP_TOUT(0), SLP_TOUT(0), SLP_VEC(0, 0, 0, 0, 0)}, 0},
{{SLP, SLP_TOUT(200), SLP_TOUT(500), SLP_VEC(1, 2, 3, 4, 4)}, 0}, {{SLP, SLP_TOUT(200), SLP_TOUT(500), SLP_VEC(1, 2, 3, 4, 4)}, 0},
{{SLP, SLP_TOUT(200), SLP_TOUT(300), SLP_VEC(1, 2, 3, 4, 7)}, 0}, {{SLP, SLP_TOUT(200), SLP_TOUT(300), SLP_VEC(1, 2, 3, 4, 7)}, 0},
@ -103,7 +103,7 @@ static struct iwl_power_vec_entry range_1[IWL_POWER_AC] = {
}; };
/* for tim > 11 */ /* for tim > 11 */
static struct iwl_power_vec_entry range_2[IWL_POWER_AC] = { static struct iwl_power_vec_entry range_2[IWL_POWER_MAX] = {
{{NOSLP, SLP_TOUT(0), SLP_TOUT(0), SLP_VEC(0, 0, 0, 0, 0)}, 0}, {{NOSLP, SLP_TOUT(0), SLP_TOUT(0), SLP_VEC(0, 0, 0, 0, 0)}, 0},
{{SLP, SLP_TOUT(200), SLP_TOUT(500), SLP_VEC(1, 2, 3, 4, 0xFF)}, 0}, {{SLP, SLP_TOUT(200), SLP_TOUT(500), SLP_VEC(1, 2, 3, 4, 0xFF)}, 0},
{{SLP, SLP_TOUT(200), SLP_TOUT(300), SLP_VEC(2, 4, 6, 7, 0xFF)}, 0}, {{SLP, SLP_TOUT(200), SLP_TOUT(300), SLP_VEC(2, 4, 6, 7, 0xFF)}, 0},
@ -112,12 +112,19 @@ static struct iwl_power_vec_entry range_2[IWL_POWER_AC] = {
{{SLP, SLP_TOUT(25), SLP_TOUT(25), SLP_VEC(4, 7, 10, 10, 0xFF)}, 0} {{SLP, SLP_TOUT(25), SLP_TOUT(25), SLP_VEC(4, 7, 10, 10, 0xFF)}, 0}
}; };
/* set card power command */
static int iwl_set_power(struct iwl_priv *priv, void *cmd)
{
return iwl_send_cmd_pdu_async(priv, POWER_TABLE_CMD,
sizeof(struct iwl_powertable_cmd),
cmd, NULL);
}
/* decide the right power level according to association status /* decide the right power level according to association status
* and battery status * and battery status
*/ */
static u16 iwl_get_auto_power_mode(struct iwl_priv *priv) static u16 iwl_get_auto_power_mode(struct iwl_priv *priv)
{ {
u16 mode = priv->power_data.user_power_setting; u16 mode;
switch (priv->power_data.user_power_setting) { switch (priv->power_data.user_power_setting) {
case IWL_POWER_AUTO: case IWL_POWER_AUTO:
@ -129,12 +136,16 @@ static u16 iwl_get_auto_power_mode(struct iwl_priv *priv)
else else
mode = IWL_POWER_ON_AC_DISASSOC; mode = IWL_POWER_ON_AC_DISASSOC;
break; break;
/* FIXME: remove battery and ac from here */
case IWL_POWER_BATTERY: case IWL_POWER_BATTERY:
mode = IWL_POWER_INDEX_3; mode = IWL_POWER_INDEX_3;
break; break;
case IWL_POWER_AC: case IWL_POWER_AC:
mode = IWL_POWER_MODE_CAM; mode = IWL_POWER_MODE_CAM;
break; break;
default:
mode = priv->power_data.user_power_setting;
break;
} }
return mode; return mode;
} }
@ -144,7 +155,7 @@ static int iwl_power_init_handle(struct iwl_priv *priv)
{ {
int ret = 0, i; int ret = 0, i;
struct iwl_power_mgr *pow_data; struct iwl_power_mgr *pow_data;
int size = sizeof(struct iwl_power_vec_entry) * IWL_POWER_AC; int size = sizeof(struct iwl_power_vec_entry) * IWL_POWER_MAX;
u16 pci_pm; u16 pci_pm;
IWL_DEBUG_POWER("Initialize power \n"); IWL_DEBUG_POWER("Initialize power \n");
@ -162,11 +173,11 @@ static int iwl_power_init_handle(struct iwl_priv *priv)
if (ret != 0) if (ret != 0)
return 0; return 0;
else { else {
struct iwl4965_powertable_cmd *cmd; struct iwl_powertable_cmd *cmd;
IWL_DEBUG_POWER("adjust power command flags\n"); IWL_DEBUG_POWER("adjust power command flags\n");
for (i = 0; i < IWL_POWER_AC; i++) { for (i = 0; i < IWL_POWER_MAX; i++) {
cmd = &pow_data->pwr_range_0[i].cmd; cmd = &pow_data->pwr_range_0[i].cmd;
if (pci_pm & 0x1) if (pci_pm & 0x1)
@ -180,7 +191,7 @@ static int iwl_power_init_handle(struct iwl_priv *priv)
/* adjust power command according to dtim period and power level*/ /* adjust power command according to dtim period and power level*/
static int iwl_update_power_command(struct iwl_priv *priv, static int iwl_update_power_command(struct iwl_priv *priv,
struct iwl4965_powertable_cmd *cmd, struct iwl_powertable_cmd *cmd,
u16 mode) u16 mode)
{ {
int ret = 0, i; int ret = 0, i;
@ -204,7 +215,7 @@ static int iwl_update_power_command(struct iwl_priv *priv,
range = &pow_data->pwr_range_2[0]; range = &pow_data->pwr_range_2[0];
period = pow_data->dtim_period; period = pow_data->dtim_period;
memcpy(cmd, &range[mode].cmd, sizeof(struct iwl4965_powertable_cmd)); memcpy(cmd, &range[mode].cmd, sizeof(struct iwl_powertable_cmd));
if (period == 0) { if (period == 0) {
period = 1; period = 1;
@ -258,17 +269,18 @@ int iwl_power_update_mode(struct iwl_priv *priv, u8 refresh)
* else user level */ * else user level */
switch (setting->system_power_setting) { switch (setting->system_power_setting) {
case IWL_POWER_AUTO: case IWL_POWER_SYS_AUTO:
final_mode = iwl_get_auto_power_mode(priv); final_mode = iwl_get_auto_power_mode(priv);
break; break;
case IWL_POWER_BATTERY: case IWL_POWER_SYS_BATTERY:
final_mode = IWL_POWER_INDEX_3; final_mode = IWL_POWER_INDEX_3;
break; break;
case IWL_POWER_AC: case IWL_POWER_SYS_AC:
final_mode = IWL_POWER_MODE_CAM; final_mode = IWL_POWER_MODE_CAM;
break; break;
default: default:
final_mode = setting->system_power_setting; final_mode = IWL_POWER_INDEX_3;
WARN_ON(1);
} }
if (setting->critical_power_setting > final_mode) if (setting->critical_power_setting > final_mode)
@ -280,7 +292,7 @@ int iwl_power_update_mode(struct iwl_priv *priv, u8 refresh)
if (!iwl_is_rfkill(priv) && !setting->power_disabled && if (!iwl_is_rfkill(priv) && !setting->power_disabled &&
((setting->power_mode != final_mode) || refresh)) { ((setting->power_mode != final_mode) || refresh)) {
struct iwl4965_powertable_cmd cmd; struct iwl_powertable_cmd cmd;
if (final_mode != IWL_POWER_MODE_CAM) if (final_mode != IWL_POWER_MODE_CAM)
set_bit(STATUS_POWER_PMI, &priv->status); set_bit(STATUS_POWER_PMI, &priv->status);
@ -291,8 +303,7 @@ int iwl_power_update_mode(struct iwl_priv *priv, u8 refresh)
if (final_mode == IWL_POWER_INDEX_5) if (final_mode == IWL_POWER_INDEX_5)
cmd.flags |= IWL_POWER_FAST_PD; cmd.flags |= IWL_POWER_FAST_PD;
if (priv->cfg->ops->lib->set_power) ret = iwl_set_power(priv, &cmd);
ret = priv->cfg->ops->lib->set_power(priv, &cmd);
if (final_mode == IWL_POWER_MODE_CAM) if (final_mode == IWL_POWER_MODE_CAM)
clear_bit(STATUS_POWER_PMI, &priv->status); clear_bit(STATUS_POWER_PMI, &priv->status);
@ -388,7 +399,7 @@ void iwl_power_initialize(struct iwl_priv *priv)
iwl_power_init_handle(priv); iwl_power_init_handle(priv);
priv->power_data.user_power_setting = IWL_POWER_AUTO; priv->power_data.user_power_setting = IWL_POWER_AUTO;
priv->power_data.power_disabled = 0; priv->power_data.power_disabled = 0;
priv->power_data.system_power_setting = IWL_POWER_AUTO; priv->power_data.system_power_setting = IWL_POWER_SYS_AUTO;
priv->power_data.is_battery_active = 0; priv->power_data.is_battery_active = 0;
priv->power_data.power_disabled = 0; priv->power_data.power_disabled = 0;
priv->power_data.critical_power_setting = 0; priv->power_data.critical_power_setting = 0;

View File

@ -33,12 +33,25 @@
struct iwl_priv; struct iwl_priv;
#define IWL_POWER_MODE_CAM 0x00 /* Continuously Aware Mode, always on */ enum {
#define IWL_POWER_INDEX_3 0x03 IWL_POWER_MODE_CAM, /* Continuously Aware Mode, always on */
#define IWL_POWER_INDEX_5 0x05 IWL_POWER_INDEX_1,
#define IWL_POWER_AC 0x06 IWL_POWER_INDEX_2,
#define IWL_POWER_BATTERY 0x07 IWL_POWER_INDEX_3,
#define IWL_POWER_AUTO 0x08 IWL_POWER_INDEX_4,
IWL_POWER_INDEX_5,
IWL_POWER_AUTO,
IWL_POWER_MAX = IWL_POWER_AUTO,
IWL_POWER_AC,
IWL_POWER_BATTERY,
};
enum {
IWL_POWER_SYS_AUTO,
IWL_POWER_SYS_AC,
IWL_POWER_SYS_BATTERY,
};
#define IWL_POWER_LIMIT 0x08 #define IWL_POWER_LIMIT 0x08
#define IWL_POWER_MASK 0x0F #define IWL_POWER_MASK 0x0F
#define IWL_POWER_ENABLED 0x10 #define IWL_POWER_ENABLED 0x10
@ -46,15 +59,15 @@ struct iwl_priv;
/* Power management (not Tx power) structures */ /* Power management (not Tx power) structures */
struct iwl_power_vec_entry { struct iwl_power_vec_entry {
struct iwl4965_powertable_cmd cmd; struct iwl_powertable_cmd cmd;
u8 no_dtim; u8 no_dtim;
}; };
struct iwl_power_mgr { struct iwl_power_mgr {
spinlock_t lock; spinlock_t lock;
struct iwl_power_vec_entry pwr_range_0[IWL_POWER_AC]; struct iwl_power_vec_entry pwr_range_0[IWL_POWER_MAX];
struct iwl_power_vec_entry pwr_range_1[IWL_POWER_AC]; struct iwl_power_vec_entry pwr_range_1[IWL_POWER_MAX];
struct iwl_power_vec_entry pwr_range_2[IWL_POWER_AC]; struct iwl_power_vec_entry pwr_range_2[IWL_POWER_MAX];
u32 dtim_period; u32 dtim_period;
/* final power level that used to calculate final power command */ /* final power level that used to calculate final power command */
u8 power_mode; u8 power_mode;

View File

@ -84,14 +84,16 @@
#define APMG_CLK_VAL_DMA_CLK_RQT (0x00000200) #define APMG_CLK_VAL_DMA_CLK_RQT (0x00000200)
#define APMG_CLK_VAL_BSM_CLK_RQT (0x00000800) #define APMG_CLK_VAL_BSM_CLK_RQT (0x00000800)
#define APMG_PS_CTRL_VAL_RESET_REQ (0x04000000)
#define APMG_PCIDEV_STT_VAL_L1_ACT_DIS (0x00000800) #define APMG_PS_CTRL_EARLY_PWR_OFF_RESET_DIS (0x00400000)
#define APMG_PS_CTRL_VAL_RESET_REQ (0x04000000)
#define APMG_PS_CTRL_MSK_PWR_SRC (0x03000000)
#define APMG_PS_CTRL_VAL_PWR_SRC_VMAIN (0x00000000)
#define APMG_PS_CTRL_VAL_PWR_SRC_MAX (0x01000000) /* 3945 only */
#define APMG_PS_CTRL_VAL_PWR_SRC_VAUX (0x02000000)
#define APMG_PS_CTRL_MSK_PWR_SRC (0x03000000)
#define APMG_PS_CTRL_VAL_PWR_SRC_VMAIN (0x00000000)
#define APMG_PS_CTRL_VAL_PWR_SRC_VAUX (0x01000000)
#define APMG_PCIDEV_STT_VAL_L1_ACT_DIS (0x00000800)
/** /**
* BSM (Bootstrap State Machine) * BSM (Bootstrap State Machine)

View File

@ -791,7 +791,7 @@ static inline void iwl_dbg_report_frame(struct iwl_priv *priv,
static void iwl_add_radiotap(struct iwl_priv *priv, static void iwl_add_radiotap(struct iwl_priv *priv,
struct sk_buff *skb, struct sk_buff *skb,
struct iwl4965_rx_phy_res *rx_start, struct iwl_rx_phy_res *rx_start,
struct ieee80211_rx_status *stats, struct ieee80211_rx_status *stats,
u32 ampdu_status) u32 ampdu_status)
{ {
@ -1010,8 +1010,8 @@ static void iwl_pass_packet_to_mac80211(struct iwl_priv *priv,
struct ieee80211_rx_status *stats) struct ieee80211_rx_status *stats)
{ {
struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data; struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
struct iwl4965_rx_phy_res *rx_start = (include_phy) ? struct iwl_rx_phy_res *rx_start = (include_phy) ?
(struct iwl4965_rx_phy_res *)&(pkt->u.raw[0]) : NULL; (struct iwl_rx_phy_res *)&(pkt->u.raw[0]) : NULL;
struct ieee80211_hdr *hdr; struct ieee80211_hdr *hdr;
u16 len; u16 len;
__le32 *rx_end; __le32 *rx_end;
@ -1020,7 +1020,7 @@ static void iwl_pass_packet_to_mac80211(struct iwl_priv *priv,
u32 ampdu_status_legacy; u32 ampdu_status_legacy;
if (!include_phy && priv->last_phy_res[0]) if (!include_phy && priv->last_phy_res[0])
rx_start = (struct iwl4965_rx_phy_res *)&priv->last_phy_res[1]; rx_start = (struct iwl_rx_phy_res *)&priv->last_phy_res[1];
if (!rx_start) { if (!rx_start) {
IWL_ERROR("MPDU frame without a PHY data\n"); IWL_ERROR("MPDU frame without a PHY data\n");
@ -1032,8 +1032,8 @@ static void iwl_pass_packet_to_mac80211(struct iwl_priv *priv,
len = le16_to_cpu(rx_start->byte_count); len = le16_to_cpu(rx_start->byte_count);
rx_end = (__le32 *) ((u8 *) &pkt->u.raw[0] + rx_end = (__le32 *)((u8 *) &pkt->u.raw[0] +
sizeof(struct iwl4965_rx_phy_res) + sizeof(struct iwl_rx_phy_res) +
rx_start->cfg_phy_cnt + len); rx_start->cfg_phy_cnt + len);
} else { } else {
@ -1084,40 +1084,13 @@ static void iwl_pass_packet_to_mac80211(struct iwl_priv *priv,
} }
/* Calc max signal level (dBm) among 3 possible receivers */ /* Calc max signal level (dBm) among 3 possible receivers */
static int iwl_calc_rssi(struct iwl_priv *priv, static inline int iwl_calc_rssi(struct iwl_priv *priv,
struct iwl4965_rx_phy_res *rx_resp) struct iwl_rx_phy_res *rx_resp)
{ {
/* data from PHY/DSP regarding signal strength, etc., return priv->cfg->ops->utils->calc_rssi(priv, rx_resp);
* contents are always there, not configurable by host. */
struct iwl4965_rx_non_cfg_phy *ncphy =
(struct iwl4965_rx_non_cfg_phy *)rx_resp->non_cfg_phy;
u32 agc = (le16_to_cpu(ncphy->agc_info) & IWL_AGC_DB_MASK)
>> IWL_AGC_DB_POS;
u32 valid_antennae =
(le16_to_cpu(rx_resp->phy_flags) & RX_PHY_FLAGS_ANTENNAE_MASK)
>> RX_PHY_FLAGS_ANTENNAE_OFFSET;
u8 max_rssi = 0;
u32 i;
/* Find max rssi among 3 possible receivers.
* These values are measured by the digital signal processor (DSP).
* They should stay fairly constant even as the signal strength varies,
* if the radio's automatic gain control (AGC) is working right.
* AGC value (see below) will provide the "interesting" info. */
for (i = 0; i < 3; i++)
if (valid_antennae & (1 << i))
max_rssi = max(ncphy->rssi_info[i << 1], max_rssi);
IWL_DEBUG_STATS("Rssi In A %d B %d C %d Max %d AGC dB %d\n",
ncphy->rssi_info[0], ncphy->rssi_info[2], ncphy->rssi_info[4],
max_rssi, agc);
/* dBm = max_rssi dB - agc dB - constant.
* Higher AGC (higher radio gain) means lower signal. */
return max_rssi - agc - IWL_RSSI_OFFSET;
} }
static void iwl_sta_modify_ps_wake(struct iwl_priv *priv, int sta_id) static void iwl_sta_modify_ps_wake(struct iwl_priv *priv, int sta_id)
{ {
unsigned long flags; unsigned long flags;
@ -1180,9 +1153,9 @@ void iwl_rx_reply_rx(struct iwl_priv *priv,
* this rx packet for legacy frames, * this rx packet for legacy frames,
* or phy data cached from REPLY_RX_PHY_CMD for HT frames. */ * or phy data cached from REPLY_RX_PHY_CMD for HT frames. */
int include_phy = (pkt->hdr.cmd == REPLY_RX); int include_phy = (pkt->hdr.cmd == REPLY_RX);
struct iwl4965_rx_phy_res *rx_start = (include_phy) ? struct iwl_rx_phy_res *rx_start = (include_phy) ?
(struct iwl4965_rx_phy_res *)&(pkt->u.raw[0]) : (struct iwl_rx_phy_res *)&(pkt->u.raw[0]) :
(struct iwl4965_rx_phy_res *)&priv->last_phy_res[1]; (struct iwl_rx_phy_res *)&priv->last_phy_res[1];
__le32 *rx_end; __le32 *rx_end;
unsigned int len = 0; unsigned int len = 0;
u16 fc; u16 fc;
@ -1210,7 +1183,7 @@ void iwl_rx_reply_rx(struct iwl_priv *priv,
if (!include_phy) { if (!include_phy) {
if (priv->last_phy_res[0]) if (priv->last_phy_res[0])
rx_start = (struct iwl4965_rx_phy_res *) rx_start = (struct iwl_rx_phy_res *)
&priv->last_phy_res[1]; &priv->last_phy_res[1];
else else
rx_start = NULL; rx_start = NULL;
@ -1227,7 +1200,7 @@ void iwl_rx_reply_rx(struct iwl_priv *priv,
len = le16_to_cpu(rx_start->byte_count); len = le16_to_cpu(rx_start->byte_count);
rx_end = (__le32 *)(pkt->u.raw + rx_start->cfg_phy_cnt + rx_end = (__le32 *)(pkt->u.raw + rx_start->cfg_phy_cnt +
sizeof(struct iwl4965_rx_phy_res) + len); sizeof(struct iwl_rx_phy_res) + len);
} else { } else {
struct iwl4965_rx_mpdu_res_start *amsdu = struct iwl4965_rx_mpdu_res_start *amsdu =
(struct iwl4965_rx_mpdu_res_start *)pkt->u.raw; (struct iwl4965_rx_mpdu_res_start *)pkt->u.raw;
@ -1316,6 +1289,6 @@ void iwl_rx_reply_rx_phy(struct iwl_priv *priv,
struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data; struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
priv->last_phy_res[0] = 1; priv->last_phy_res[0] = 1;
memcpy(&priv->last_phy_res[1], &(pkt->u.raw[0]), memcpy(&priv->last_phy_res[1], &(pkt->u.raw[0]),
sizeof(struct iwl4965_rx_phy_res)); sizeof(struct iwl_rx_phy_res));
} }
EXPORT_SYMBOL(iwl_rx_reply_rx_phy); EXPORT_SYMBOL(iwl_rx_reply_rx_phy);

View File

@ -202,6 +202,7 @@ static int iwl_send_scan_abort(struct iwl_priv *priv)
clear_bit(STATUS_SCAN_HW, &priv->status); clear_bit(STATUS_SCAN_HW, &priv->status);
} }
priv->alloc_rxb_skb--;
dev_kfree_skb_any(cmd.meta.u.skb); dev_kfree_skb_any(cmd.meta.u.skb);
return ret; return ret;

View File

@ -823,7 +823,7 @@ int iwl_send_lq_cmd(struct iwl_priv *priv,
if (lq->sta_id == 0xFF) if (lq->sta_id == 0xFF)
lq->sta_id = IWL_AP_ID; lq->sta_id = IWL_AP_ID;
iwl_dump_lq_cmd(priv,lq); iwl_dump_lq_cmd(priv, lq);
if (iwl_is_associated(priv) && priv->assoc_station_added) if (iwl_is_associated(priv) && priv->assoc_station_added)
return iwl_send_cmd(priv, &cmd); return iwl_send_cmd(priv, &cmd);
@ -839,7 +839,7 @@ EXPORT_SYMBOL(iwl_send_lq_cmd);
* for automatic fallback during transmission. * for automatic fallback during transmission.
* *
* NOTE: This sets up a default set of values. These will be replaced later * NOTE: This sets up a default set of values. These will be replaced later
* if the driver's iwl-4965-rs rate scaling algorithm is used, instead of * if the driver's iwl-agn-rs rate scaling algorithm is used, instead of
* rc80211_simple. * rc80211_simple.
* *
* NOTE: Run REPLY_ADD_STA command to set up station table entry, before * NOTE: Run REPLY_ADD_STA command to set up station table entry, before

View File

@ -208,11 +208,12 @@ EXPORT_SYMBOL(iwl_txq_update_write_ptr);
* Free all buffers. * Free all buffers.
* 0-fill, but do not free "txq" descriptor structure. * 0-fill, but do not free "txq" descriptor structure.
*/ */
static void iwl_tx_queue_free(struct iwl_priv *priv, struct iwl_tx_queue *txq) static void iwl_tx_queue_free(struct iwl_priv *priv, int txq_id)
{ {
struct iwl_tx_queue *txq = &priv->txq[txq_id];
struct iwl_queue *q = &txq->q; struct iwl_queue *q = &txq->q;
struct pci_dev *dev = priv->pci_dev; struct pci_dev *dev = priv->pci_dev;
int len; int i, slots_num, len;
if (q->n_bd == 0) if (q->n_bd == 0)
return; return;
@ -227,7 +228,12 @@ static void iwl_tx_queue_free(struct iwl_priv *priv, struct iwl_tx_queue *txq)
len += IWL_MAX_SCAN_SIZE; len += IWL_MAX_SCAN_SIZE;
/* De-alloc array of command/tx buffers */ /* De-alloc array of command/tx buffers */
pci_free_consistent(dev, len, txq->cmd, txq->dma_addr_cmd); slots_num = (txq_id == IWL_CMD_QUEUE_NUM) ?
TFD_CMD_SLOTS : TFD_TX_CMD_SLOTS;
for (i = 0; i < slots_num; i++)
kfree(txq->cmd[i]);
if (txq_id == IWL_CMD_QUEUE_NUM)
kfree(txq->cmd[slots_num]);
/* De-alloc circular buffer of TFDs */ /* De-alloc circular buffer of TFDs */
if (txq->q.n_bd) if (txq->q.n_bd)
@ -400,8 +406,7 @@ static int iwl_tx_queue_init(struct iwl_priv *priv,
struct iwl_tx_queue *txq, struct iwl_tx_queue *txq,
int slots_num, u32 txq_id) int slots_num, u32 txq_id)
{ {
struct pci_dev *dev = priv->pci_dev; int i, len;
int len;
int rc = 0; int rc = 0;
/* /*
@ -412,17 +417,25 @@ static int iwl_tx_queue_init(struct iwl_priv *priv,
* For normal Tx queues (all other queues), no super-size command * For normal Tx queues (all other queues), no super-size command
* space is needed. * space is needed.
*/ */
len = sizeof(struct iwl_cmd) * slots_num; len = sizeof(struct iwl_cmd);
if (txq_id == IWL_CMD_QUEUE_NUM) for (i = 0; i <= slots_num; i++) {
len += IWL_MAX_SCAN_SIZE; if (i == slots_num) {
txq->cmd = pci_alloc_consistent(dev, len, &txq->dma_addr_cmd); if (txq_id == IWL_CMD_QUEUE_NUM)
if (!txq->cmd) len += IWL_MAX_SCAN_SIZE;
return -ENOMEM; else
continue;
}
txq->cmd[i] = kmalloc(len, GFP_KERNEL | GFP_DMA);
if (!txq->cmd[i])
return -ENOMEM;
}
/* Alloc driver data array and TFD circular buffer */ /* Alloc driver data array and TFD circular buffer */
rc = iwl_tx_queue_alloc(priv, txq, txq_id); rc = iwl_tx_queue_alloc(priv, txq, txq_id);
if (rc) { if (rc) {
pci_free_consistent(dev, len, txq->cmd, txq->dma_addr_cmd); for (i = 0; i < slots_num; i++)
kfree(txq->cmd[i]);
return -ENOMEM; return -ENOMEM;
} }
@ -451,7 +464,7 @@ void iwl_hw_txq_ctx_free(struct iwl_priv *priv)
/* Tx queues */ /* Tx queues */
for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; txq_id++) for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; txq_id++)
iwl_tx_queue_free(priv, &priv->txq[txq_id]); iwl_tx_queue_free(priv, txq_id);
/* Keep-warm buffer */ /* Keep-warm buffer */
iwl_kw_free(priv); iwl_kw_free(priv);
@ -859,7 +872,7 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
txq->txb[q->write_ptr].skb[0] = skb; txq->txb[q->write_ptr].skb[0] = skb;
/* Set up first empty entry in queue's array of Tx/cmd buffers */ /* Set up first empty entry in queue's array of Tx/cmd buffers */
out_cmd = &txq->cmd[idx]; out_cmd = txq->cmd[idx];
tx_cmd = &out_cmd->cmd.tx; tx_cmd = &out_cmd->cmd.tx;
memset(&out_cmd->hdr, 0, sizeof(out_cmd->hdr)); memset(&out_cmd->hdr, 0, sizeof(out_cmd->hdr));
memset(tx_cmd, 0, sizeof(struct iwl_tx_cmd)); memset(tx_cmd, 0, sizeof(struct iwl_tx_cmd));
@ -899,8 +912,9 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
/* Physical address of this Tx command's header (not MAC header!), /* Physical address of this Tx command's header (not MAC header!),
* within command buffer array. */ * within command buffer array. */
txcmd_phys = txq->dma_addr_cmd + sizeof(struct iwl_cmd) * idx + txcmd_phys = pci_map_single(priv->pci_dev, out_cmd,
offsetof(struct iwl_cmd, hdr); sizeof(struct iwl_cmd), PCI_DMA_TODEVICE);
txcmd_phys += offsetof(struct iwl_cmd, hdr);
/* Add buffer containing Tx command and MAC(!) header to TFD's /* Add buffer containing Tx command and MAC(!) header to TFD's
* first entry */ * first entry */
@ -1004,7 +1018,7 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
u32 idx; u32 idx;
u16 fix_size; u16 fix_size;
dma_addr_t phys_addr; dma_addr_t phys_addr;
int ret; int len, ret;
unsigned long flags; unsigned long flags;
cmd->len = priv->cfg->ops->utils->get_hcmd_size(cmd->id, cmd->len); cmd->len = priv->cfg->ops->utils->get_hcmd_size(cmd->id, cmd->len);
@ -1034,7 +1048,7 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
control_flags = (u32 *) tfd; control_flags = (u32 *) tfd;
idx = get_cmd_index(q, q->write_ptr, cmd->meta.flags & CMD_SIZE_HUGE); idx = get_cmd_index(q, q->write_ptr, cmd->meta.flags & CMD_SIZE_HUGE);
out_cmd = &txq->cmd[idx]; out_cmd = txq->cmd[idx];
out_cmd->hdr.cmd = cmd->id; out_cmd->hdr.cmd = cmd->id;
memcpy(&out_cmd->meta, &cmd->meta, sizeof(cmd->meta)); memcpy(&out_cmd->meta, &cmd->meta, sizeof(cmd->meta));
@ -1048,9 +1062,11 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
INDEX_TO_SEQ(q->write_ptr)); INDEX_TO_SEQ(q->write_ptr));
if (out_cmd->meta.flags & CMD_SIZE_HUGE) if (out_cmd->meta.flags & CMD_SIZE_HUGE)
out_cmd->hdr.sequence |= cpu_to_le16(SEQ_HUGE_FRAME); out_cmd->hdr.sequence |= cpu_to_le16(SEQ_HUGE_FRAME);
len = (idx == TFD_CMD_SLOTS) ?
phys_addr = txq->dma_addr_cmd + sizeof(txq->cmd[0]) * idx + IWL_MAX_SCAN_SIZE : sizeof(struct iwl_cmd);
offsetof(struct iwl_cmd, hdr); phys_addr = pci_map_single(priv->pci_dev, out_cmd, len,
PCI_DMA_TODEVICE);
phys_addr += offsetof(struct iwl_cmd, hdr);
iwl_hw_txq_attach_buf_to_tfd(priv, tfd, phys_addr, fix_size); iwl_hw_txq_attach_buf_to_tfd(priv, tfd, phys_addr, fix_size);
IWL_DEBUG_HC("Sending command %s (#%x), seq: 0x%04X, " IWL_DEBUG_HC("Sending command %s (#%x), seq: 0x%04X, "
@ -1115,6 +1131,9 @@ static void iwl_hcmd_queue_reclaim(struct iwl_priv *priv, int txq_id, int index)
{ {
struct iwl_tx_queue *txq = &priv->txq[txq_id]; struct iwl_tx_queue *txq = &priv->txq[txq_id];
struct iwl_queue *q = &txq->q; struct iwl_queue *q = &txq->q;
struct iwl_tfd_frame *bd = &txq->bd[index];
dma_addr_t dma_addr;
int is_odd, buf_len;
int nfreed = 0; int nfreed = 0;
if ((index >= q->n_bd) || (iwl_queue_used(q, index) == 0)) { if ((index >= q->n_bd) || (iwl_queue_used(q, index) == 0)) {
@ -1132,6 +1151,19 @@ static void iwl_hcmd_queue_reclaim(struct iwl_priv *priv, int txq_id, int index)
q->write_ptr, q->read_ptr); q->write_ptr, q->read_ptr);
queue_work(priv->workqueue, &priv->restart); queue_work(priv->workqueue, &priv->restart);
} }
is_odd = (index/2) & 0x1;
if (is_odd) {
dma_addr = IWL_GET_BITS(bd->pa[index], tb2_addr_lo16) |
(IWL_GET_BITS(bd->pa[index],
tb2_addr_hi20) << 16);
buf_len = IWL_GET_BITS(bd->pa[index], tb2_len);
} else {
dma_addr = le32_to_cpu(bd->pa[index].tb1_addr);
buf_len = IWL_GET_BITS(bd->pa[index], tb1_len);
}
pci_unmap_single(priv->pci_dev, dma_addr, buf_len,
PCI_DMA_TODEVICE);
nfreed++; nfreed++;
} }
} }
@ -1163,7 +1195,7 @@ void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
BUG_ON(txq_id != IWL_CMD_QUEUE_NUM); BUG_ON(txq_id != IWL_CMD_QUEUE_NUM);
cmd_index = get_cmd_index(&priv->txq[IWL_CMD_QUEUE_NUM].q, index, huge); cmd_index = get_cmd_index(&priv->txq[IWL_CMD_QUEUE_NUM].q, index, huge);
cmd = &priv->txq[IWL_CMD_QUEUE_NUM].cmd[cmd_index]; cmd = priv->txq[IWL_CMD_QUEUE_NUM].cmd[cmd_index];
/* Input error checking is done when commands are added to queue. */ /* Input error checking is done when commands are added to queue. */
if (cmd->meta.flags & CMD_WANT_SKB) { if (cmd->meta.flags & CMD_WANT_SKB) {
@ -1391,7 +1423,7 @@ static int iwl_tx_status_reply_compressed_ba(struct iwl_priv *priv,
/* For each frame attempted in aggregation, /* For each frame attempted in aggregation,
* update driver's record of tx frame's status. */ * update driver's record of tx frame's status. */
for (i = 0; i < agg->frame_count ; i++) { for (i = 0; i < agg->frame_count ; i++) {
ack = bitmap & (1 << i); ack = bitmap & (1ULL << i);
successes += !!ack; successes += !!ack;
IWL_DEBUG_TX_REPLY("%s ON i=%d idx=%d raw=%d\n", IWL_DEBUG_TX_REPLY("%s ON i=%d idx=%d raw=%d\n",
ack? "ACK":"NACK", i, (agg->start_idx + i) & 0xff, ack? "ACK":"NACK", i, (agg->start_idx + i) & 0xff,

View File

@ -275,10 +275,8 @@ static int iwl3945_tx_queue_alloc(struct iwl3945_priv *priv,
return 0; return 0;
error: error:
if (txq->txb) { kfree(txq->txb);
kfree(txq->txb); txq->txb = NULL;
txq->txb = NULL;
}
return -ENOMEM; return -ENOMEM;
} }
@ -365,10 +363,8 @@ void iwl3945_tx_queue_free(struct iwl3945_priv *priv, struct iwl3945_tx_queue *t
txq->q.n_bd, txq->bd, txq->q.dma_addr); txq->q.n_bd, txq->bd, txq->q.dma_addr);
/* De-alloc array of per-TFD driver data */ /* De-alloc array of per-TFD driver data */
if (txq->txb) { kfree(txq->txb);
kfree(txq->txb); txq->txb = NULL;
txq->txb = NULL;
}
/* 0-fill queue descriptor structure */ /* 0-fill queue descriptor structure */
memset(txq, 0, sizeof(*txq)); memset(txq, 0, sizeof(*txq));
@ -2703,9 +2699,8 @@ static int iwl3945_tx_skb(struct iwl3945_priv *priv, struct sk_buff *skb)
if (!ieee80211_has_morefrags(hdr->frame_control)) { if (!ieee80211_has_morefrags(hdr->frame_control)) {
txq->need_update = 1; txq->need_update = 1;
if (qc) { if (qc)
priv->stations[sta_id].tid[tid].seq_number = seq_number; priv->stations[sta_id].tid[tid].seq_number = seq_number;
}
} else { } else {
wait_write_ptr = 1; wait_write_ptr = 1;
txq->need_update = 0; txq->need_update = 0;
@ -3813,7 +3808,7 @@ int iwl3945_calc_db_from_ratio(int sig_ratio)
/* 100:1 or higher, divide by 10 and use table, /* 100:1 or higher, divide by 10 and use table,
* add 20 dB to make up for divide by 10 */ * add 20 dB to make up for divide by 10 */
if (sig_ratio >= 100) if (sig_ratio >= 100)
return (20 + (int)ratio2dB[sig_ratio/10]); return 20 + (int)ratio2dB[sig_ratio/10];
/* We shouldn't see this */ /* We shouldn't see this */
if (sig_ratio < 1) if (sig_ratio < 1)
@ -5088,7 +5083,7 @@ static void iwl3945_dealloc_ucode_pci(struct iwl3945_priv *priv)
* iwl3945_verify_inst_full - verify runtime uCode image in card vs. host, * iwl3945_verify_inst_full - verify runtime uCode image in card vs. host,
* looking at all data. * looking at all data.
*/ */
static int iwl3945_verify_inst_full(struct iwl3945_priv *priv, __le32 * image, u32 len) static int iwl3945_verify_inst_full(struct iwl3945_priv *priv, __le32 *image, u32 len)
{ {
u32 val; u32 val;
u32 save_len = len; u32 save_len = len;
@ -5237,7 +5232,7 @@ static int iwl3945_verify_bsm(struct iwl3945_priv *priv)
val = iwl3945_read_prph(priv, BSM_WR_DWCOUNT_REG); val = iwl3945_read_prph(priv, BSM_WR_DWCOUNT_REG);
for (reg = BSM_SRAM_LOWER_BOUND; for (reg = BSM_SRAM_LOWER_BOUND;
reg < BSM_SRAM_LOWER_BOUND + len; reg < BSM_SRAM_LOWER_BOUND + len;
reg += sizeof(u32), image ++) { reg += sizeof(u32), image++) {
val = iwl3945_read_prph(priv, reg); val = iwl3945_read_prph(priv, reg);
if (val != le32_to_cpu(*image)) { if (val != le32_to_cpu(*image)) {
IWL_ERROR("BSM uCode verification failed at " IWL_ERROR("BSM uCode verification failed at "
@ -6336,7 +6331,7 @@ static void iwl3945_bg_post_associate(struct work_struct *data)
DECLARE_MAC_BUF(mac); DECLARE_MAC_BUF(mac);
if (priv->iw_mode == IEEE80211_IF_TYPE_AP) { if (priv->iw_mode == IEEE80211_IF_TYPE_AP) {
IWL_ERROR("%s Should not be called in AP mode\n", __FUNCTION__); IWL_ERROR("%s Should not be called in AP mode\n", __func__);
return; return;
} }
@ -6417,7 +6412,7 @@ static void iwl3945_bg_post_associate(struct work_struct *data)
default: default:
IWL_ERROR("%s Should not be called in %d mode\n", IWL_ERROR("%s Should not be called in %d mode\n",
__FUNCTION__, priv->iw_mode); __func__, priv->iw_mode);
break; break;
} }
@ -6594,12 +6589,6 @@ static int iwl3945_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
IWL_DEBUG_MAC80211("enter\n"); IWL_DEBUG_MAC80211("enter\n");
if (priv->iw_mode == IEEE80211_IF_TYPE_MNTR) {
IWL_DEBUG_MAC80211("leave - monitor\n");
dev_kfree_skb_any(skb);
return 0;
}
IWL_DEBUG_TX("dev->xmit(%d bytes) at rate 0x%02x\n", skb->len, IWL_DEBUG_TX("dev->xmit(%d bytes) at rate 0x%02x\n", skb->len,
ieee80211_get_tx_rate(hw, IEEE80211_SKB_CB(skb))->bitrate); ieee80211_get_tx_rate(hw, IEEE80211_SKB_CB(skb))->bitrate);
@ -7456,7 +7445,7 @@ static ssize_t show_measurement(struct device *d,
struct iwl3945_priv *priv = dev_get_drvdata(d); struct iwl3945_priv *priv = dev_get_drvdata(d);
struct iwl3945_spectrum_notification measure_report; struct iwl3945_spectrum_notification measure_report;
u32 size = sizeof(measure_report), len = 0, ofs = 0; u32 size = sizeof(measure_report), len = 0, ofs = 0;
u8 *data = (u8 *) & measure_report; u8 *data = (u8 *)&measure_report;
unsigned long flags; unsigned long flags;
spin_lock_irqsave(&priv->lock, flags); spin_lock_irqsave(&priv->lock, flags);
@ -7627,7 +7616,7 @@ static ssize_t show_power_level(struct device *d,
else else
p += sprintf(p, " \n"); p += sprintf(p, " \n");
return (p - buf + 1); return p - buf + 1;
} }
@ -7649,7 +7638,7 @@ static ssize_t show_statistics(struct device *d,
struct iwl3945_priv *priv = dev_get_drvdata(d); struct iwl3945_priv *priv = dev_get_drvdata(d);
u32 size = sizeof(struct iwl3945_notif_statistics); u32 size = sizeof(struct iwl3945_notif_statistics);
u32 len = 0, ofs = 0; u32 len = 0, ofs = 0;
u8 *data = (u8 *) & priv->statistics; u8 *data = (u8 *)&priv->statistics;
int rc = 0; int rc = 0;
if (!iwl3945_is_alive(priv)) if (!iwl3945_is_alive(priv))
@ -8003,16 +7992,16 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
/* nic init */ /* nic init */
iwl3945_set_bit(priv, CSR_GIO_CHICKEN_BITS, iwl3945_set_bit(priv, CSR_GIO_CHICKEN_BITS,
CSR_GIO_CHICKEN_BITS_REG_BIT_DIS_L0S_EXIT_TIMER); CSR_GIO_CHICKEN_BITS_REG_BIT_DIS_L0S_EXIT_TIMER);
iwl3945_set_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE); iwl3945_set_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
err = iwl3945_poll_bit(priv, CSR_GP_CNTRL, err = iwl3945_poll_bit(priv, CSR_GP_CNTRL,
CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY,
CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000); CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000);
if (err < 0) { if (err < 0) {
IWL_DEBUG_INFO("Failed to init the card\n"); IWL_DEBUG_INFO("Failed to init the card\n");
goto out_remove_sysfs; goto out_remove_sysfs;
} }
/* Read the EEPROM */ /* Read the EEPROM */
err = iwl3945_eeprom_init(priv); err = iwl3945_eeprom_init(priv);
if (err) { if (err) {
@ -8114,9 +8103,8 @@ static void __devexit iwl3945_pci_remove(struct pci_dev *pdev)
iwl3945_unset_hw_setting(priv); iwl3945_unset_hw_setting(priv);
iwl3945_clear_stations_table(priv); iwl3945_clear_stations_table(priv);
if (priv->mac80211_registered) { if (priv->mac80211_registered)
ieee80211_unregister_hw(priv->hw); ieee80211_unregister_hw(priv->hw);
}
/*netif_stop_queue(dev); */ /*netif_stop_queue(dev); */
flush_workqueue(priv->workqueue); flush_workqueue(priv->workqueue);

View File

@ -52,6 +52,7 @@ struct p54_common {
int (*open)(struct ieee80211_hw *dev); int (*open)(struct ieee80211_hw *dev);
void (*stop)(struct ieee80211_hw *dev); void (*stop)(struct ieee80211_hw *dev);
int mode; int mode;
struct mutex conf_mutex;
u8 mac_addr[ETH_ALEN]; u8 mac_addr[ETH_ALEN];
u8 bssid[ETH_ALEN]; u8 bssid[ETH_ALEN];
struct pda_iq_autocal_entry *iq_autocal; struct pda_iq_autocal_entry *iq_autocal;

View File

@ -886,9 +886,12 @@ static void p54_remove_interface(struct ieee80211_hw *dev,
static int p54_config(struct ieee80211_hw *dev, struct ieee80211_conf *conf) static int p54_config(struct ieee80211_hw *dev, struct ieee80211_conf *conf)
{ {
int ret; int ret;
struct p54_common *priv = dev->priv;
mutex_lock(&priv->conf_mutex);
ret = p54_set_freq(dev, cpu_to_le16(conf->channel->center_freq)); ret = p54_set_freq(dev, cpu_to_le16(conf->channel->center_freq));
p54_set_vdcf(dev); p54_set_vdcf(dev);
mutex_unlock(&priv->conf_mutex);
return ret; return ret;
} }
@ -898,10 +901,12 @@ static int p54_config_interface(struct ieee80211_hw *dev,
{ {
struct p54_common *priv = dev->priv; struct p54_common *priv = dev->priv;
mutex_lock(&priv->conf_mutex);
p54_set_filter(dev, 0, priv->mac_addr, conf->bssid, 0, 1, 0, 0xF642); p54_set_filter(dev, 0, priv->mac_addr, conf->bssid, 0, 1, 0, 0xF642);
p54_set_filter(dev, 0, priv->mac_addr, conf->bssid, 2, 0, 0, 0); p54_set_filter(dev, 0, priv->mac_addr, conf->bssid, 2, 0, 0, 0);
p54_set_leds(dev, 1, !is_multicast_ether_addr(conf->bssid), 0); p54_set_leds(dev, 1, !is_multicast_ether_addr(conf->bssid), 0);
memcpy(priv->bssid, conf->bssid, ETH_ALEN); memcpy(priv->bssid, conf->bssid, ETH_ALEN);
mutex_unlock(&priv->conf_mutex);
return 0; return 0;
} }
@ -1009,6 +1014,7 @@ struct ieee80211_hw *p54_init_common(size_t priv_data_len)
} }
p54_init_vdcf(dev); p54_init_vdcf(dev);
mutex_init(&priv->conf_mutex);
return dev; return dev;
} }

View File

@ -633,6 +633,16 @@ static void rt2500usb_reset_tuner(struct rt2x00_dev *rt2x00dev)
rt2x00dev->link.vgc_level = value; rt2x00dev->link.vgc_level = value;
} }
/*
* NOTE: This function is directly ported from legacy driver, but
* despite it being declared it was never called. Although link tuning
* sounds like a good idea, and usually works well for the other drivers,
* it does _not_ work with rt2500usb. Enabling this function will result
* in TX capabilities only until association kicks in. Immediately
* after the successful association all TX frames will be kept in the
* hardware queue and never transmitted.
*/
#if 0
static void rt2500usb_link_tuner(struct rt2x00_dev *rt2x00dev) static void rt2500usb_link_tuner(struct rt2x00_dev *rt2x00dev)
{ {
int rssi = rt2x00_get_link_rssi(&rt2x00dev->link); int rssi = rt2x00_get_link_rssi(&rt2x00dev->link);
@ -752,6 +762,9 @@ static void rt2500usb_link_tuner(struct rt2x00_dev *rt2x00dev)
rt2x00dev->link.vgc_level = r17; rt2x00dev->link.vgc_level = r17;
} }
} }
#else
#define rt2500usb_link_tuner NULL
#endif
/* /*
* Initialization functions. * Initialization functions.
@ -1737,6 +1750,7 @@ static int rt2500usb_probe_hw(struct rt2x00_dev *rt2x00dev)
__set_bit(DRIVER_REQUIRE_ATIM_QUEUE, &rt2x00dev->flags); __set_bit(DRIVER_REQUIRE_ATIM_QUEUE, &rt2x00dev->flags);
__set_bit(DRIVER_REQUIRE_BEACON_GUARD, &rt2x00dev->flags); __set_bit(DRIVER_REQUIRE_BEACON_GUARD, &rt2x00dev->flags);
__set_bit(DRIVER_REQUIRE_SCHEDULED, &rt2x00dev->flags); __set_bit(DRIVER_REQUIRE_SCHEDULED, &rt2x00dev->flags);
__set_bit(CONFIG_DISABLE_LINK_TUNING, &rt2x00dev->flags);
/* /*
* Set the rssi offset. * Set the rssi offset.

View File

@ -506,6 +506,19 @@ struct ieee80211_channel_sw_ie {
u8 count; u8 count;
} __attribute__ ((packed)); } __attribute__ ((packed));
/**
* struct ieee80211_tim
*
* This structure refers to "Traffic Indication Map information element"
*/
struct ieee80211_tim_ie {
u8 dtim_count;
u8 dtim_period;
u8 bitmap_ctrl;
/* variable size: 1 - 251 bytes */
u8 virtual_map[0];
} __attribute__ ((packed));
struct ieee80211_mgmt { struct ieee80211_mgmt {
__le16 frame_control; __le16 frame_control;
__le16 duration; __le16 duration;

View File

@ -177,9 +177,10 @@ enum ieee80211_bss_change {
* @aid: association ID number, valid only when @assoc is true * @aid: association ID number, valid only when @assoc is true
* @use_cts_prot: use CTS protection * @use_cts_prot: use CTS protection
* @use_short_preamble: use 802.11b short preamble * @use_short_preamble: use 802.11b short preamble
* @dtim_period: num of beacons before the next DTIM, for PSM
* @timestamp: beacon timestamp * @timestamp: beacon timestamp
* @beacon_int: beacon interval * @beacon_int: beacon interval
* @assoc_capability: capabbilities taken from assoc resp * @assoc_capability: capabilities taken from assoc resp
* @assoc_ht: association in HT mode * @assoc_ht: association in HT mode
* @ht_conf: ht capabilities * @ht_conf: ht capabilities
* @ht_bss_conf: ht extended capabilities * @ht_bss_conf: ht extended capabilities
@ -191,6 +192,7 @@ struct ieee80211_bss_conf {
/* erp related data */ /* erp related data */
bool use_cts_prot; bool use_cts_prot;
bool use_short_preamble; bool use_short_preamble;
u8 dtim_period;
u16 beacon_int; u16 beacon_int;
u16 assoc_capability; u16 assoc_capability;
u64 timestamp; u64 timestamp;
@ -430,6 +432,7 @@ enum ieee80211_conf_flags {
* @radio_enabled: when zero, driver is required to switch off the radio. * @radio_enabled: when zero, driver is required to switch off the radio.
* TODO make a flag * TODO make a flag
* @beacon_int: beacon interval (TODO make interface config) * @beacon_int: beacon interval (TODO make interface config)
* @listen_interval: listen interval in units of beacon interval
* @flags: configuration flags defined above * @flags: configuration flags defined above
* @power_level: requested transmit power (in dBm) * @power_level: requested transmit power (in dBm)
* @max_antenna_gain: maximum antenna gain (in dBi) * @max_antenna_gain: maximum antenna gain (in dBi)
@ -444,6 +447,7 @@ struct ieee80211_conf {
int radio_enabled; int radio_enabled;
int beacon_int; int beacon_int;
u16 listen_interval;
u32 flags; u32 flags;
int power_level; int power_level;
int max_antenna_gain; int max_antenna_gain;
@ -785,6 +789,9 @@ enum ieee80211_hw_flags {
* @max_signal: Maximum value for signal (rssi) in RX information, used * @max_signal: Maximum value for signal (rssi) in RX information, used
* only when @IEEE80211_HW_SIGNAL_UNSPEC or @IEEE80211_HW_SIGNAL_DB * only when @IEEE80211_HW_SIGNAL_UNSPEC or @IEEE80211_HW_SIGNAL_DB
* *
* @max_listen_interval: max listen interval in units of beacon interval
* that HW supports
*
* @queues: number of available hardware transmit queues for * @queues: number of available hardware transmit queues for
* data packets. WMM/QoS requires at least four, these * data packets. WMM/QoS requires at least four, these
* queues need to have configurable access parameters. * queues need to have configurable access parameters.
@ -812,7 +819,9 @@ struct ieee80211_hw {
unsigned int extra_tx_headroom; unsigned int extra_tx_headroom;
int channel_change_time; int channel_change_time;
int vif_data_size; int vif_data_size;
u16 queues, ampdu_queues; u16 queues;
u16 ampdu_queues;
u16 max_listen_interval;
s8 max_signal; s8 max_signal;
}; };

View File

@ -82,6 +82,7 @@ struct ieee80211_sta_bss {
u8 bssid[ETH_ALEN]; u8 bssid[ETH_ALEN];
u8 ssid[IEEE80211_MAX_SSID_LEN]; u8 ssid[IEEE80211_MAX_SSID_LEN];
u8 dtim_period;
u16 capability; /* host byte order */ u16 capability; /* host byte order */
enum ieee80211_band band; enum ieee80211_band band;
int freq; int freq;

View File

@ -1689,6 +1689,11 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
if (local->hw.conf.beacon_int < 10) if (local->hw.conf.beacon_int < 10)
local->hw.conf.beacon_int = 100; local->hw.conf.beacon_int = 100;
if (local->hw.max_listen_interval == 0)
local->hw.max_listen_interval = 1;
local->hw.conf.listen_interval = local->hw.max_listen_interval;
local->wstats_flags |= local->hw.flags & (IEEE80211_HW_SIGNAL_UNSPEC | local->wstats_flags |= local->hw.flags & (IEEE80211_HW_SIGNAL_UNSPEC |
IEEE80211_HW_SIGNAL_DB | IEEE80211_HW_SIGNAL_DB |
IEEE80211_HW_SIGNAL_DBM) ? IEEE80211_HW_SIGNAL_DBM) ?

View File

@ -551,6 +551,7 @@ static void ieee80211_set_associated(struct net_device *dev,
/* set timing information */ /* set timing information */
sdata->bss_conf.beacon_int = bss->beacon_int; sdata->bss_conf.beacon_int = bss->beacon_int;
sdata->bss_conf.timestamp = bss->timestamp; sdata->bss_conf.timestamp = bss->timestamp;
sdata->bss_conf.dtim_period = bss->dtim_period;
changed |= ieee80211_handle_bss_capability(sdata, bss); changed |= ieee80211_handle_bss_capability(sdata, bss);
@ -773,7 +774,8 @@ static void ieee80211_send_assoc(struct net_device *dev,
mgmt->frame_control = IEEE80211_FC(IEEE80211_FTYPE_MGMT, mgmt->frame_control = IEEE80211_FC(IEEE80211_FTYPE_MGMT,
IEEE80211_STYPE_REASSOC_REQ); IEEE80211_STYPE_REASSOC_REQ);
mgmt->u.reassoc_req.capab_info = cpu_to_le16(capab); mgmt->u.reassoc_req.capab_info = cpu_to_le16(capab);
mgmt->u.reassoc_req.listen_interval = cpu_to_le16(1); mgmt->u.reassoc_req.listen_interval =
cpu_to_le16(local->hw.conf.listen_interval);
memcpy(mgmt->u.reassoc_req.current_ap, ifsta->prev_bssid, memcpy(mgmt->u.reassoc_req.current_ap, ifsta->prev_bssid,
ETH_ALEN); ETH_ALEN);
} else { } else {
@ -781,7 +783,8 @@ static void ieee80211_send_assoc(struct net_device *dev,
mgmt->frame_control = IEEE80211_FC(IEEE80211_FTYPE_MGMT, mgmt->frame_control = IEEE80211_FC(IEEE80211_FTYPE_MGMT,
IEEE80211_STYPE_ASSOC_REQ); IEEE80211_STYPE_ASSOC_REQ);
mgmt->u.assoc_req.capab_info = cpu_to_le16(capab); mgmt->u.assoc_req.capab_info = cpu_to_le16(capab);
mgmt->u.assoc_req.listen_interval = cpu_to_le16(1); mgmt->u.reassoc_req.listen_interval =
cpu_to_le16(local->hw.conf.listen_interval);
} }
/* SSID */ /* SSID */
@ -2688,6 +2691,16 @@ static void ieee80211_rx_bss_info(struct net_device *dev,
bss->beacon_int = le16_to_cpu(mgmt->u.beacon.beacon_int); bss->beacon_int = le16_to_cpu(mgmt->u.beacon.beacon_int);
bss->capability = le16_to_cpu(mgmt->u.beacon.capab_info); bss->capability = le16_to_cpu(mgmt->u.beacon.capab_info);
if (elems->tim) {
struct ieee80211_tim_ie *tim_ie =
(struct ieee80211_tim_ie *)elems->tim;
bss->dtim_period = tim_ie->dtim_period;
}
/* set default value for buggy APs */
if (!elems->tim || bss->dtim_period == 0)
bss->dtim_period = 1;
bss->supp_rates_len = 0; bss->supp_rates_len = 0;
if (elems->supp_rates) { if (elems->supp_rates) {
clen = IEEE80211_MAX_SUPP_RATES - bss->supp_rates_len; clen = IEEE80211_MAX_SUPP_RATES - bss->supp_rates_len;
@ -3650,11 +3663,21 @@ static int ieee80211_sta_find_ibss(struct net_device *dev,
"%s\n", print_mac(mac, bssid), "%s\n", print_mac(mac, bssid),
print_mac(mac2, ifsta->bssid)); print_mac(mac2, ifsta->bssid));
#endif /* CONFIG_MAC80211_IBSS_DEBUG */ #endif /* CONFIG_MAC80211_IBSS_DEBUG */
if (found && memcmp(ifsta->bssid, bssid, ETH_ALEN) != 0 &&
(bss = ieee80211_rx_bss_get(dev, bssid, if (found && memcmp(ifsta->bssid, bssid, ETH_ALEN) != 0) {
local->hw.conf.channel->center_freq,
ifsta->ssid, ifsta->ssid_len))) {
int ret; int ret;
int search_freq;
if (ifsta->flags & IEEE80211_STA_AUTO_CHANNEL_SEL)
search_freq = bss->freq;
else
search_freq = local->hw.conf.channel->center_freq;
bss = ieee80211_rx_bss_get(dev, bssid, search_freq,
ifsta->ssid, ifsta->ssid_len);
if (!bss)
goto dont_join;
printk(KERN_DEBUG "%s: Selected IBSS BSSID %s" printk(KERN_DEBUG "%s: Selected IBSS BSSID %s"
" based on configured SSID\n", " based on configured SSID\n",
dev->name, print_mac(mac, bssid)); dev->name, print_mac(mac, bssid));
@ -3662,6 +3685,8 @@ static int ieee80211_sta_find_ibss(struct net_device *dev,
ieee80211_rx_bss_put(local, bss); ieee80211_rx_bss_put(local, bss);
return ret; return ret;
} }
dont_join:
#ifdef CONFIG_MAC80211_IBSS_DEBUG #ifdef CONFIG_MAC80211_IBSS_DEBUG
printk(KERN_DEBUG " did not try to join ibss\n"); printk(KERN_DEBUG " did not try to join ibss\n");
#endif /* CONFIG_MAC80211_IBSS_DEBUG */ #endif /* CONFIG_MAC80211_IBSS_DEBUG */
@ -3895,7 +3920,7 @@ void ieee80211_scan_completed(struct ieee80211_hw *hw)
if (sdata->vif.type == IEEE80211_IF_TYPE_IBSS) { if (sdata->vif.type == IEEE80211_IF_TYPE_IBSS) {
struct ieee80211_if_sta *ifsta = &sdata->u.sta; struct ieee80211_if_sta *ifsta = &sdata->u.sta;
if (!(ifsta->flags & IEEE80211_STA_BSSID_SET) || if (!(ifsta->flags & IEEE80211_STA_BSSID_SET) ||
(!ifsta->state == IEEE80211_IBSS_JOINED && (!(ifsta->state == IEEE80211_IBSS_JOINED) &&
!ieee80211_sta_active_ibss(dev))) !ieee80211_sta_active_ibss(dev)))
ieee80211_sta_find_ibss(dev, ifsta); ieee80211_sta_find_ibss(dev, ifsta);
} }