mirror of https://gitee.com/openkylin/linux.git
Merge branch 'no-ath9k' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-2.6
This commit is contained in:
commit
33e334950a
|
@ -14,18 +14,49 @@ config IWLWIFI_LEDS
|
|||
default n
|
||||
|
||||
config IWLWIFI_RFKILL
|
||||
boolean "IWLWIFI RF kill support"
|
||||
boolean "Iwlwifi RF kill support"
|
||||
depends on IWLCORE
|
||||
|
||||
config IWL4965
|
||||
tristate "Intel Wireless WiFi 4965AGN"
|
||||
config IWLWIFI_DEBUG
|
||||
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
|
||||
select FW_LOADER
|
||||
select IWLCORE
|
||||
---help---
|
||||
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.
|
||||
|
||||
|
@ -42,60 +73,33 @@ config IWL4965
|
|||
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),
|
||||
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
|
||||
bool "Enable LEDS features in iwl4965 driver"
|
||||
depends on IWL4965
|
||||
config IWLAGN_SPECTRUM_MEASUREMENT
|
||||
bool "Enable Spectrum Measurement in iwlagn driver"
|
||||
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
|
||||
---help---
|
||||
This option enables LEDS for the iwlwifi drivers
|
||||
This option enables LEDS for the iwlagn drivers
|
||||
|
||||
|
||||
config IWL4965_SPECTRUM_MEASUREMENT
|
||||
bool "Enable Spectrum Measurement in iwl4965 driver"
|
||||
depends on IWL4965
|
||||
config IWL4965
|
||||
bool "Intel Wireless WiFi 4965AGN"
|
||||
depends on IWLAGN
|
||||
---help---
|
||||
This option will enable spectrum measurement for the iwl4965 driver.
|
||||
|
||||
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.
|
||||
This option enables support for Intel Wireless WiFi Link 4965AGN
|
||||
|
||||
config IWL5000
|
||||
bool "Intel Wireless WiFi 5000AGN"
|
||||
depends on IWL4965
|
||||
depends on IWLAGN
|
||||
---help---
|
||||
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
|
||||
tristate "Intel PRO/Wireless 3945ABG/BG Network Connection"
|
||||
|
|
|
@ -6,15 +6,14 @@ iwlcore-$(CONFIG_IWLWIFI_DEBUGFS) += iwl-debugfs.o
|
|||
iwlcore-$(CONFIG_IWLWIFI_LEDS) += iwl-led.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
|
||||
iwl3945-objs := iwl3945-base.o iwl-3945.o iwl-3945-rs.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
|
||||
|
||||
|
||||
|
|
|
@ -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,
|
||||
struct iwl3945_led *led,
|
||||
enum led_type type, u8 set_led,
|
||||
const char *name, char *trigger)
|
||||
char *trigger)
|
||||
{
|
||||
struct device *device = wiphy_dev(priv->hw->wiphy);
|
||||
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.default_trigger = trigger;
|
||||
|
||||
|
@ -308,7 +308,6 @@ void iwl3945_led_background(struct iwl3945_priv *priv)
|
|||
int iwl3945_led_register(struct iwl3945_priv *priv)
|
||||
{
|
||||
char *trigger;
|
||||
char name[32];
|
||||
int ret;
|
||||
|
||||
priv->last_blink_rate = 0;
|
||||
|
@ -318,7 +317,8 @@ int iwl3945_led_register(struct iwl3945_priv *priv)
|
|||
priv->allow_blinking = 0;
|
||||
|
||||
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));
|
||||
|
||||
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,
|
||||
&priv->led[IWL_LED_TRG_RADIO],
|
||||
IWL_LED_TRG_RADIO, 1,
|
||||
name, trigger);
|
||||
IWL_LED_TRG_RADIO, 1, trigger);
|
||||
|
||||
if (ret)
|
||||
goto exit_fail;
|
||||
|
||||
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));
|
||||
|
||||
ret = iwl3945_led_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 */
|
||||
priv->led[IWL_LED_TRG_ASSOC].led_on = 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;
|
||||
|
||||
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));
|
||||
|
||||
|
||||
ret = iwl3945_led_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 = 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;
|
||||
|
||||
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));
|
||||
|
||||
ret = iwl3945_led_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 = 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;
|
||||
|
|
|
@ -50,6 +50,7 @@ enum led_type {
|
|||
struct iwl3945_led {
|
||||
struct iwl3945_priv *priv;
|
||||
struct led_classdev led_dev;
|
||||
char name[32];
|
||||
|
||||
int (*led_on) (struct iwl3945_priv *priv, int led_id);
|
||||
int (*led_off) (struct iwl3945_priv *priv, int led_id);
|
||||
|
|
|
@ -795,8 +795,7 @@ static void iwl3945_rx_reply_rx(struct iwl3945_priv *priv,
|
|||
struct ieee80211_mgmt *mgmt =
|
||||
(struct ieee80211_mgmt *)header;
|
||||
__le32 *pos;
|
||||
pos =
|
||||
(__le32 *) & mgmt->u.beacon.
|
||||
pos = (__le32 *)&mgmt->u.beacon.
|
||||
timestamp;
|
||||
priv->timestamp0 = le32_to_cpu(pos[0]);
|
||||
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)
|
||||
{
|
||||
return (((temperature < -260) || (temperature > 25)) ? 1 : 0);
|
||||
return ((temperature < -260) || (temperature > 25)) ? 1 : 0;
|
||||
}
|
||||
|
||||
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] =
|
||||
(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)
|
||||
|
|
|
@ -341,39 +341,6 @@ static int iwl4965_eeprom_check_version(struct iwl_priv *priv)
|
|||
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
|
||||
|
@ -875,18 +842,6 @@ static int iwl4965_hw_set_hw_params(struct iwl_priv *priv)
|
|||
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)
|
||||
{
|
||||
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,
|
||||
tx_power.s.radio_tx_gain[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);
|
||||
|
||||
}/* for each rate */
|
||||
} /* for each rate */
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
|
@ -2240,9 +2130,9 @@ static int iwl4965_tx_status_reply_tx(struct iwl_priv *priv,
|
|||
bitmap = bitmap << sh;
|
||||
sh = 0;
|
||||
}
|
||||
bitmap |= (1 << sh);
|
||||
IWL_DEBUG_TX_REPLY("start=%d bitmap=0x%x\n",
|
||||
start, (u32)(bitmap & 0xFFFFFFFF));
|
||||
bitmap |= 1ULL << sh;
|
||||
IWL_DEBUG_TX_REPLY("start=%d bitmap=0x%llx\n",
|
||||
start, (unsigned long long)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");
|
||||
}
|
||||
|
||||
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 */
|
||||
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,
|
||||
.gain_computation = iwl4965_gain_computation,
|
||||
.rts_tx_cmd_flag = iwl4965_rts_tx_cmd_flag,
|
||||
.calc_rssi = iwl4965_calc_rssi,
|
||||
};
|
||||
|
||||
static struct iwl_lib_ops iwl4965_lib = {
|
||||
|
@ -2440,7 +2365,6 @@ static struct iwl_lib_ops iwl4965_lib = {
|
|||
.check_version = iwl4965_eeprom_check_version,
|
||||
.query_addr = iwlcore_eeprom_query_addr,
|
||||
},
|
||||
.set_power = iwl4965_set_power,
|
||||
.send_tx_power = iwl4965_send_tx_power,
|
||||
.update_chain_flags = iwl4965_update_chain_flags,
|
||||
.temperature = iwl4965_temperature_calib,
|
||||
|
|
|
@ -93,6 +93,13 @@ static int iwl5000_apm_init(struct iwl_priv *priv)
|
|||
iwl_set_bit(priv, CSR_GIO_CHICKEN_BITS,
|
||||
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);
|
||||
|
||||
/* 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_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);
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
||||
if (txq_id != IWL_CMD_QUEUE_NUM) {
|
||||
sta = txq->cmd[txq->q.write_ptr].cmd.tx.sta_id;
|
||||
sec_ctl = txq->cmd[txq->q.write_ptr].cmd.tx.sec_ctl;
|
||||
sta = txq->cmd[txq->q.write_ptr]->cmd.tx.sta_id;
|
||||
sec_ctl = txq->cmd[txq->q.write_ptr]->cmd.tx.sec_ctl;
|
||||
|
||||
switch (sec_ctl & TX_CMD_SEC_MSK) {
|
||||
case TX_CMD_SEC_CCM:
|
||||
|
@ -964,7 +981,7 @@ static void iwl5000_txq_inval_byte_cnt_tbl(struct iwl_priv *priv,
|
|||
u8 sta = 0;
|
||||
|
||||
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].
|
||||
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)
|
||||
{
|
||||
return le32_to_cpup((__le32*)&tx_resp->status +
|
||||
return le32_to_cpup((__le32 *)&tx_resp->status +
|
||||
tx_resp->frame_count) & MAX_SN;
|
||||
}
|
||||
|
||||
|
@ -1228,9 +1245,9 @@ static int iwl5000_tx_status_reply_tx(struct iwl_priv *priv,
|
|||
bitmap = bitmap << sh;
|
||||
sh = 0;
|
||||
}
|
||||
bitmap |= (1 << sh);
|
||||
IWL_DEBUG_TX_REPLY("start=%d bitmap=0x%x\n",
|
||||
start, (u32)(bitmap & 0xFFFFFFFF));
|
||||
bitmap |= 1ULL << sh;
|
||||
IWL_DEBUG_TX_REPLY("start=%d bitmap=0x%llx\n",
|
||||
start, (unsigned long long)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);
|
||||
}
|
||||
|
||||
/* 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 = {
|
||||
.rxon_assoc = iwl5000_send_rxon_assoc,
|
||||
};
|
||||
|
@ -1454,6 +1509,7 @@ static struct iwl_hcmd_utils_ops iwl5000_hcmd_utils = {
|
|||
.gain_computation = iwl5000_gain_computation,
|
||||
.chain_noise_reset = iwl5000_chain_noise_reset,
|
||||
.rts_tx_cmd_flag = iwl5000_rts_tx_cmd_flag,
|
||||
.calc_rssi = iwl5000_calc_rssi,
|
||||
};
|
||||
|
||||
static struct iwl_lib_ops iwl5000_lib = {
|
||||
|
@ -1474,6 +1530,7 @@ static struct iwl_lib_ops iwl5000_lib = {
|
|||
.alive_notify = iwl5000_alive_notify,
|
||||
.send_tx_power = iwl5000_send_tx_power,
|
||||
.temperature = iwl5000_temperature,
|
||||
.update_chain_flags = iwl4965_update_chain_flags,
|
||||
.apm_ops = {
|
||||
.init = iwl5000_apm_init,
|
||||
.reset = iwl5000_apm_reset,
|
||||
|
|
|
@ -42,7 +42,7 @@
|
|||
#include "iwl-core.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 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 */
|
||||
s32 success_counter; /* number of frames successful */
|
||||
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".
|
||||
*/
|
||||
struct iwl4965_scale_tbl_info {
|
||||
struct iwl_scale_tbl_info {
|
||||
enum iwl_table_type lq_type;
|
||||
u8 ant_type;
|
||||
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_* */
|
||||
s32 *expected_tpt; /* throughput metrics; expected_tpt_G, etc. */
|
||||
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 */
|
||||
u32 packet_count[TID_QUEUE_MAX_SIZE]; /* packet count in this time
|
||||
* 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.
|
||||
*/
|
||||
struct iwl4965_lq_sta {
|
||||
struct iwl_lq_sta {
|
||||
u8 active_tbl; /* index of active table, range 0-1 */
|
||||
u8 enable_counter; /* indicates HT 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;
|
||||
|
||||
struct iwl_link_quality_cmd lq;
|
||||
struct iwl4965_scale_tbl_info lq_info[LQ_SIZE]; /* "active", "search" */
|
||||
struct iwl4965_traffic_load load[TID_MAX_LOAD_COUNT];
|
||||
struct iwl_scale_tbl_info lq_info[LQ_SIZE]; /* "active", "search" */
|
||||
struct iwl_traffic_load load[TID_MAX_LOAD_COUNT];
|
||||
u8 tx_agg_tid_en;
|
||||
#ifdef CONFIG_MAC80211_DEBUGFS
|
||||
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 sta_info *sta);
|
||||
static void rs_fill_link_cmd(const struct iwl_priv *priv,
|
||||
struct iwl4965_lq_sta *lq_sta,
|
||||
u32 rate_n_flags);
|
||||
struct iwl_lq_sta *lq_sta, u32 rate_n_flags);
|
||||
|
||||
|
||||
#ifdef CONFIG_MAC80211_DEBUGFS
|
||||
static void rs_dbgfs_set_mcs(struct iwl4965_lq_sta *lq_sta,
|
||||
u32 *rate_n_flags, int index);
|
||||
static void rs_dbgfs_set_mcs(struct iwl_lq_sta *lq_sta,
|
||||
u32 *rate_n_flags, int index);
|
||||
#else
|
||||
static void rs_dbgfs_set_mcs(struct iwl4965_lq_sta *lq_sta,
|
||||
u32 *rate_n_flags, int index)
|
||||
static void rs_dbgfs_set_mcs(struct iwl_lq_sta *lq_sta,
|
||||
u32 *rate_n_flags, int index)
|
||||
{}
|
||||
#endif
|
||||
|
||||
|
@ -234,7 +233,7 @@ static inline u8 rs_extract_rate(u32 rate_n_flags)
|
|||
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->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)
|
||||
{
|
||||
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
|
||||
* 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 */
|
||||
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
|
||||
* 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)
|
||||
{
|
||||
u32 curr_time = jiffies_to_msecs(jiffies);
|
||||
u32 time_diff;
|
||||
s32 index;
|
||||
struct iwl4965_traffic_load *tl = NULL;
|
||||
struct iwl_traffic_load *tl = NULL;
|
||||
__le16 fc = hdr->frame_control;
|
||||
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
|
||||
*/
|
||||
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 time_diff;
|
||||
s32 index;
|
||||
struct iwl4965_traffic_load *tl = NULL;
|
||||
struct iwl_traffic_load *tl = NULL;
|
||||
|
||||
if (tid >= TID_MAX_LOAD_COUNT)
|
||||
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,
|
||||
struct iwl4965_lq_sta *lq_data, u8 tid,
|
||||
struct sta_info *sta)
|
||||
struct iwl_lq_sta *lq_data, u8 tid,
|
||||
struct sta_info *sta)
|
||||
{
|
||||
unsigned long state;
|
||||
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,
|
||||
struct iwl4965_lq_sta *lq_data,
|
||||
struct sta_info *sta)
|
||||
struct iwl_lq_sta *lq_data,
|
||||
struct sta_info *sta)
|
||||
{
|
||||
if ((tid < TID_MAX_LOAD_COUNT))
|
||||
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)
|
||||
{
|
||||
return (!!(rate_n_flags & RATE_MCS_ANT_A_MSK) +
|
||||
!!(rate_n_flags & RATE_MCS_ANT_B_MSK) +
|
||||
!!(rate_n_flags & RATE_MCS_ANT_C_MSK));
|
||||
return !!(rate_n_flags & RATE_MCS_ANT_A_MSK) +
|
||||
!!(rate_n_flags & RATE_MCS_ANT_B_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
|
||||
* 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 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));
|
||||
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.
|
||||
*/
|
||||
/* 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)
|
||||
{
|
||||
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,
|
||||
enum ieee80211_band band,
|
||||
struct iwl4965_scale_tbl_info *tbl,
|
||||
struct iwl_scale_tbl_info *tbl,
|
||||
int *rate_idx)
|
||||
{
|
||||
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 */
|
||||
/* if no other valid antenna found, return 0 */
|
||||
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;
|
||||
|
||||
|
@ -621,9 +620,9 @@ static int rs_toggle_antenna(u32 valid_ant, u32 *rate_n_flags,
|
|||
#if 0
|
||||
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.non_GF_STA_present);
|
||||
!priv->current_ht_config.non_GF_STA_present;
|
||||
}
|
||||
#endif
|
||||
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.
|
||||
*
|
||||
*/
|
||||
static u16 rs_get_supported_rates(struct iwl4965_lq_sta *lq_sta,
|
||||
struct ieee80211_hdr *hdr,
|
||||
enum iwl_table_type rate_type)
|
||||
static u16 rs_get_supported_rates(struct iwl_lq_sta *lq_sta,
|
||||
struct ieee80211_hdr *hdr,
|
||||
enum iwl_table_type rate_type)
|
||||
{
|
||||
if (hdr && is_multicast_ether_addr(hdr->addr1) &&
|
||||
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;
|
||||
}
|
||||
|
||||
static u32 rs_get_lower_rate(struct iwl4965_lq_sta *lq_sta,
|
||||
struct iwl4965_scale_tbl_info *tbl, u8 scale_index,
|
||||
u8 ht_possible)
|
||||
static u32 rs_get_lower_rate(struct iwl_lq_sta *lq_sta,
|
||||
struct iwl_scale_tbl_info *tbl,
|
||||
u8 scale_index, u8 ht_possible)
|
||||
{
|
||||
s32 low;
|
||||
u16 rate_mask;
|
||||
|
@ -780,7 +779,7 @@ static void rs_tx_status(void *priv_rate, struct net_device *dev,
|
|||
int status;
|
||||
u8 retries;
|
||||
int rs_index, index = 0;
|
||||
struct iwl4965_lq_sta *lq_sta;
|
||||
struct iwl_lq_sta *lq_sta;
|
||||
struct iwl_link_quality_cmd *table;
|
||||
struct sta_info *sta;
|
||||
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_hw *hw = local_to_hw(local);
|
||||
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
|
||||
struct iwl4965_rate_scale_data *window = NULL;
|
||||
struct iwl4965_rate_scale_data *search_win = NULL;
|
||||
struct iwl_rate_scale_data *window = NULL;
|
||||
struct iwl_rate_scale_data *search_win = NULL;
|
||||
u32 tx_rate;
|
||||
struct iwl4965_scale_tbl_info tbl_type;
|
||||
struct iwl4965_scale_tbl_info *curr_tbl, *search_tbl;
|
||||
struct iwl_scale_tbl_info tbl_type;
|
||||
struct iwl_scale_tbl_info *curr_tbl, *search_tbl;
|
||||
u8 active_index = 0;
|
||||
__le16 fc = hdr->frame_control;
|
||||
s32 tpt = 0;
|
||||
|
@ -820,7 +819,7 @@ static void rs_tx_status(void *priv_rate, struct net_device *dev,
|
|||
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) &&
|
||||
!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]);
|
||||
search_tbl = &(lq_sta->lq_info[(1 - active_index)]);
|
||||
window = (struct iwl4965_rate_scale_data *)
|
||||
&(curr_tbl->win[0]);
|
||||
search_win = (struct iwl4965_rate_scale_data *)
|
||||
&(search_tbl->win[0]);
|
||||
window = (struct iwl_rate_scale_data *)&(curr_tbl->win[0]);
|
||||
search_win = (struct iwl_rate_scale_data *)&(search_tbl->win[0]);
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
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");
|
||||
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
|
||||
*/
|
||||
static void rs_set_expected_tpt_table(struct iwl4965_lq_sta *lq_sta,
|
||||
struct iwl4965_scale_tbl_info *tbl)
|
||||
static void rs_set_expected_tpt_table(struct iwl_lq_sta *lq_sta,
|
||||
struct iwl_scale_tbl_info *tbl)
|
||||
{
|
||||
if (is_legacy(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.
|
||||
*/
|
||||
static s32 rs_get_best_rate(struct iwl_priv *priv,
|
||||
struct iwl4965_lq_sta *lq_sta,
|
||||
struct iwl4965_scale_tbl_info *tbl, /* "search" */
|
||||
struct iwl_lq_sta *lq_sta,
|
||||
struct iwl_scale_tbl_info *tbl, /* "search" */
|
||||
u16 rate_mask, s8 index)
|
||||
{
|
||||
/* "active" values */
|
||||
struct iwl4965_scale_tbl_info *active_tbl =
|
||||
struct iwl_scale_tbl_info *active_tbl =
|
||||
&(lq_sta->lq_info[lq_sta->active_tbl]);
|
||||
s32 active_sr = active_tbl->win[index].success_ratio;
|
||||
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
|
||||
*/
|
||||
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 sta_info *sta,
|
||||
struct iwl4965_scale_tbl_info *tbl, int index)
|
||||
struct iwl_scale_tbl_info *tbl, int index)
|
||||
{
|
||||
u16 rate_mask;
|
||||
s32 rate;
|
||||
|
@ -1210,10 +1207,10 @@ static int rs_switch_to_mimo2(struct iwl_priv *priv,
|
|||
* Set up search table for SISO
|
||||
*/
|
||||
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 sta_info *sta,
|
||||
struct iwl4965_scale_tbl_info *tbl, int index)
|
||||
struct iwl_scale_tbl_info *tbl, int index)
|
||||
{
|
||||
u16 rate_mask;
|
||||
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
|
||||
*/
|
||||
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 sta_info *sta,
|
||||
int index)
|
||||
{
|
||||
struct iwl4965_scale_tbl_info *tbl =
|
||||
&(lq_sta->lq_info[lq_sta->active_tbl]);
|
||||
struct iwl4965_scale_tbl_info *search_tbl =
|
||||
&(lq_sta->lq_info[(1 - lq_sta->active_tbl)]);
|
||||
struct iwl4965_rate_scale_data *window = &(tbl->win[index]);
|
||||
u32 sz = (sizeof(struct iwl4965_scale_tbl_info) -
|
||||
(sizeof(struct iwl4965_rate_scale_data) * IWL_RATE_COUNT));
|
||||
struct iwl_scale_tbl_info *tbl = &(lq_sta->lq_info[lq_sta->active_tbl]);
|
||||
struct iwl_scale_tbl_info *search_tbl =
|
||||
&(lq_sta->lq_info[(1 - lq_sta->active_tbl)]);
|
||||
struct iwl_rate_scale_data *window = &(tbl->win[index]);
|
||||
u32 sz = (sizeof(struct iwl_scale_tbl_info) -
|
||||
(sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT));
|
||||
u8 start_action = tbl->action;
|
||||
u8 valid_tx_ant = priv->hw_params.valid_tx_ant;
|
||||
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
|
||||
*/
|
||||
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 sta_info *sta,
|
||||
int index)
|
||||
struct sta_info *sta, int index)
|
||||
{
|
||||
u8 is_green = lq_sta->is_green;
|
||||
struct iwl4965_scale_tbl_info *tbl =
|
||||
&(lq_sta->lq_info[lq_sta->active_tbl]);
|
||||
struct iwl4965_scale_tbl_info *search_tbl =
|
||||
&(lq_sta->lq_info[(1 - lq_sta->active_tbl)]);
|
||||
struct iwl4965_rate_scale_data *window = &(tbl->win[index]);
|
||||
u32 sz = (sizeof(struct iwl4965_scale_tbl_info) -
|
||||
(sizeof(struct iwl4965_rate_scale_data) * IWL_RATE_COUNT));
|
||||
struct iwl_scale_tbl_info *tbl = &(lq_sta->lq_info[lq_sta->active_tbl]);
|
||||
struct iwl_scale_tbl_info *search_tbl =
|
||||
&(lq_sta->lq_info[(1 - lq_sta->active_tbl)]);
|
||||
struct iwl_rate_scale_data *window = &(tbl->win[index]);
|
||||
u32 sz = (sizeof(struct iwl_scale_tbl_info) -
|
||||
(sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT));
|
||||
u8 start_action = tbl->action;
|
||||
u8 valid_tx_ant = priv->hw_params.valid_tx_ant;
|
||||
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
|
||||
*/
|
||||
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 sta_info *sta,
|
||||
int index)
|
||||
struct sta_info *sta, int index)
|
||||
{
|
||||
s8 is_green = lq_sta->is_green;
|
||||
struct iwl4965_scale_tbl_info *tbl =
|
||||
&(lq_sta->lq_info[lq_sta->active_tbl]);
|
||||
struct iwl4965_scale_tbl_info *search_tbl =
|
||||
&(lq_sta->lq_info[(1 - lq_sta->active_tbl)]);
|
||||
u32 sz = (sizeof(struct iwl4965_scale_tbl_info) -
|
||||
(sizeof(struct iwl4965_rate_scale_data) * IWL_RATE_COUNT));
|
||||
struct iwl_scale_tbl_info *tbl = &(lq_sta->lq_info[lq_sta->active_tbl]);
|
||||
struct iwl_scale_tbl_info *search_tbl =
|
||||
&(lq_sta->lq_info[(1 - lq_sta->active_tbl)]);
|
||||
u32 sz = (sizeof(struct iwl_scale_tbl_info) -
|
||||
(sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT));
|
||||
u8 start_action = tbl->action;
|
||||
/*u8 valid_tx_ant = priv->hw_params.valid_tx_ant;*/
|
||||
int ret;
|
||||
|
@ -1552,9 +1544,9 @@ static int rs_move_mimo_to_other(struct iwl_priv *priv,
|
|||
* 2) # times calling this function
|
||||
* 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 active_tbl;
|
||||
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 index;
|
||||
int i;
|
||||
struct iwl4965_rate_scale_data *window = NULL;
|
||||
struct iwl_rate_scale_data *window = NULL;
|
||||
int current_tpt = IWL_INVALID_VALUE;
|
||||
int low_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;
|
||||
u16 rate_mask;
|
||||
u8 update_lq = 0;
|
||||
struct iwl4965_lq_sta *lq_sta;
|
||||
struct iwl4965_scale_tbl_info *tbl, *tbl1;
|
||||
struct iwl_lq_sta *lq_sta;
|
||||
struct iwl_scale_tbl_info *tbl, *tbl1;
|
||||
u16 rate_scale_index_msk = 0;
|
||||
u32 rate;
|
||||
u8 is_green = 0;
|
||||
|
@ -1675,7 +1667,7 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
|
|||
if (!sta || !sta->rate_ctrl_priv)
|
||||
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);
|
||||
|
||||
|
@ -2030,8 +2022,8 @@ static void rs_initialize_lq(struct iwl_priv *priv,
|
|||
struct ieee80211_conf *conf,
|
||||
struct sta_info *sta)
|
||||
{
|
||||
struct iwl4965_lq_sta *lq_sta;
|
||||
struct iwl4965_scale_tbl_info *tbl;
|
||||
struct iwl_lq_sta *lq_sta;
|
||||
struct iwl_scale_tbl_info *tbl;
|
||||
int rate_idx;
|
||||
int i;
|
||||
u32 rate;
|
||||
|
@ -2042,7 +2034,7 @@ static void rs_initialize_lq(struct iwl_priv *priv,
|
|||
if (!sta || !sta->rate_ctrl_priv)
|
||||
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;
|
||||
|
||||
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;
|
||||
__le16 fc;
|
||||
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");
|
||||
|
||||
|
@ -2113,7 +2105,7 @@ static void rs_get_rate(void *priv_rate, struct net_device *dev,
|
|||
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;
|
||||
|
||||
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)
|
||||
{
|
||||
struct iwl4965_lq_sta *lq_sta;
|
||||
struct iwl_lq_sta *lq_sta;
|
||||
struct iwl_priv *priv;
|
||||
int i, j;
|
||||
|
||||
priv = (struct iwl_priv *)priv_rate;
|
||||
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)
|
||||
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 (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;
|
||||
}
|
||||
|
@ -2178,7 +2170,7 @@ static void rs_rate_init(void *priv_rate, void *priv_sta,
|
|||
struct ieee80211_conf *conf = &local->hw.conf;
|
||||
struct ieee80211_supported_band *sband;
|
||||
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];
|
||||
|
||||
|
@ -2187,7 +2179,7 @@ static void rs_rate_init(void *priv_rate, void *priv_sta,
|
|||
sta->txrate_idx = 3;
|
||||
for (j = 0; j < LQ_SIZE; j++)
|
||||
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");
|
||||
/* 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,
|
||||
struct iwl4965_lq_sta *lq_sta,
|
||||
u32 new_rate)
|
||||
struct iwl_lq_sta *lq_sta, u32 new_rate)
|
||||
{
|
||||
struct iwl4965_scale_tbl_info tbl_type;
|
||||
struct iwl_scale_tbl_info tbl_type;
|
||||
int index = 0;
|
||||
int rate_idx;
|
||||
int repeat_rate = 0;
|
||||
|
@ -2402,6 +2393,7 @@ static void rs_free(void *priv_rate)
|
|||
|
||||
static void rs_clear(void *priv_rate)
|
||||
{
|
||||
#ifdef CONFIG_IWLWIFI_DEBUG
|
||||
struct iwl_priv *priv = (struct iwl_priv *) priv_rate;
|
||||
|
||||
IWL_DEBUG_RATE("enter\n");
|
||||
|
@ -2409,11 +2401,12 @@ static void rs_clear(void *priv_rate)
|
|||
/* TODO - add rate scale state reset */
|
||||
|
||||
IWL_DEBUG_RATE("leave\n");
|
||||
#endif /* CONFIG_IWLWIFI_DEBUG */
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
return 0;
|
||||
}
|
||||
static void rs_dbgfs_set_mcs(struct iwl4965_lq_sta *lq_sta,
|
||||
u32 *rate_n_flags, int index)
|
||||
static void rs_dbgfs_set_mcs(struct iwl_lq_sta *lq_sta,
|
||||
u32 *rate_n_flags, int index)
|
||||
{
|
||||
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,
|
||||
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;
|
||||
char buf[64];
|
||||
int buf_size;
|
||||
|
@ -2493,7 +2486,7 @@ static ssize_t rs_sta_dbgfs_scale_table_read(struct file *file,
|
|||
int desc = 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, "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 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++) {
|
||||
desc += sprintf(buff+desc, "%s type=%d SGI=%d FAT=%d DUP=%d\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,
|
||||
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 =
|
||||
debugfs_create_file("rate_scale_table", 0600, dir,
|
||||
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)
|
||||
{
|
||||
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_stats_table_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
|
||||
};
|
||||
|
||||
int iwl4965_fill_rs_info(struct ieee80211_hw *hw, char *buf, u8 sta_id)
|
||||
{
|
||||
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)
|
||||
int iwlagn_rate_control_register(void)
|
||||
{
|
||||
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);
|
||||
}
|
|
@ -24,8 +24,8 @@
|
|||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef __iwl_4965_rs_h__
|
||||
#define __iwl_4965_rs_h__
|
||||
#ifndef __iwl_agn_rs_h__
|
||||
#define __iwl_agn_rs_h__
|
||||
|
||||
#include "iwl-dev.h"
|
||||
|
||||
|
@ -88,7 +88,7 @@ enum {
|
|||
#define IWL_RATE_5M_MASK (1 << IWL_RATE_5M_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 {
|
||||
IWL_RATE_6M_PLCP = 13,
|
||||
IWL_RATE_9M_PLCP = 15,
|
||||
|
@ -107,7 +107,7 @@ enum {
|
|||
/*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 {
|
||||
IWL_RATE_SISO_6M_PLCP = 0,
|
||||
IWL_RATE_SISO_12M_PLCP = 1,
|
||||
|
@ -286,15 +286,6 @@ static inline u8 iwl4965_get_prev_ieee_rate(u8 rate_index)
|
|||
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
|
||||
*
|
||||
|
@ -305,7 +296,7 @@ extern int iwl4965_fill_rs_info(struct ieee80211_hw *, char *buf, u8 sta_id);
|
|||
* 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
|
||||
|
@ -313,6 +304,6 @@ extern int iwl4965_rate_control_register(void);
|
|||
* This should be called after calling ieee80211_unregister_hw, but before
|
||||
* the driver is unloaded.
|
||||
*/
|
||||
extern void iwl4965_rate_control_unregister(void);
|
||||
extern void iwlagn_rate_control_unregister(void);
|
||||
|
||||
#endif
|
||||
#endif /* __iwl_agn__rs__ */
|
|
@ -65,7 +65,7 @@
|
|||
* 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
|
||||
#define VD "d"
|
||||
|
@ -73,7 +73,7 @@
|
|||
#define VD
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_IWL4965_SPECTRUM_MEASUREMENT
|
||||
#ifdef CONFIG_IWLAGN_SPECTRUM_MEASUREMENT
|
||||
#define VS "s"
|
||||
#else
|
||||
#define VS
|
||||
|
@ -86,6 +86,7 @@ MODULE_DESCRIPTION(DRV_DESCRIPTION);
|
|||
MODULE_VERSION(DRV_VERSION);
|
||||
MODULE_AUTHOR(DRV_COPYRIGHT);
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_ALIAS("iwl4965");
|
||||
|
||||
/*************** STATION TABLE MANAGEMENT ****
|
||||
* 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);
|
||||
}
|
||||
|
||||
unsigned int iwl4965_fill_beacon_frame(struct iwl_priv *priv,
|
||||
struct ieee80211_hdr *hdr,
|
||||
const u8 *dest, int left)
|
||||
static unsigned int iwl_fill_beacon_frame(struct iwl_priv *priv,
|
||||
struct ieee80211_hdr *hdr,
|
||||
const u8 *dest, int left)
|
||||
{
|
||||
|
||||
if (!iwl_is_associated(priv) || !priv->ibss_beacon ||
|
||||
((priv->iw_mode != IEEE80211_IF_TYPE_IBSS) &&
|
||||
(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;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
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 INTEL_CONN_LISTEN_INTERVAL __constant_cpu_to_le16(0xA)
|
||||
|
||||
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] =
|
||||
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;
|
||||
|
||||
|
@ -853,7 +884,7 @@ static void iwl4965_set_rate(struct iwl_priv *priv)
|
|||
(IWL_OFDM_BASIC_RATES_MASK >> IWL_FIRST_OFDM_RATE) & 0xFF;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_IWL4965_SPECTRUM_MEASUREMENT
|
||||
#ifdef CONFIG_IWLAGN_SPECTRUM_MEASUREMENT
|
||||
|
||||
#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,
|
||||
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 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);
|
||||
}
|
||||
|
||||
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
|
||||
*
|
||||
|
@ -2170,17 +2232,16 @@ static int __iwl4965_up(struct iwl_priv *priv)
|
|||
}
|
||||
|
||||
/* If platform's RF_KILL switch is NOT set to KILL */
|
||||
if (iwl_read32(priv, CSR_GP_CNTRL) &
|
||||
CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW)
|
||||
if (iwl_read32(priv, CSR_GP_CNTRL) & CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW)
|
||||
clear_bit(STATUS_RF_KILL_HW, &priv->status);
|
||||
else
|
||||
set_bit(STATUS_RF_KILL_HW, &priv->status);
|
||||
|
||||
if (!test_bit(STATUS_IN_SUSPEND, &priv->status) &&
|
||||
iwl_is_rfkill(priv)) {
|
||||
if (iwl_is_rfkill(priv)) {
|
||||
iwl4965_enable_interrupts(priv);
|
||||
IWL_WARNING("Radio disabled by %s RF Kill switch\n",
|
||||
test_bit(STATUS_RF_KILL_HW, &priv->status) ? "HW" : "SW");
|
||||
return -ENODEV;
|
||||
return 0;
|
||||
}
|
||||
|
||||
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,
|
||||
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++) {
|
||||
|
||||
iwl_clear_stations_table(priv);
|
||||
|
@ -2415,7 +2471,7 @@ static void iwl4965_post_associate(struct iwl_priv *priv)
|
|||
unsigned long flags;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -2491,7 +2547,7 @@ static void iwl4965_post_associate(struct iwl_priv *priv)
|
|||
|
||||
default:
|
||||
IWL_ERROR("%s Should not be called in %d mode\n",
|
||||
__FUNCTION__, priv->iw_mode);
|
||||
__func__, priv->iw_mode);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -2589,6 +2645,9 @@ static int iwl4965_mac_start(struct ieee80211_hw *hw)
|
|||
if (ret)
|
||||
goto out_release_irq;
|
||||
|
||||
if (iwl_is_rfkill(priv))
|
||||
goto out;
|
||||
|
||||
IWL_DEBUG_INFO("Start UP work done.\n");
|
||||
|
||||
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;
|
||||
IWL_DEBUG_MAC80211("leave\n");
|
||||
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);
|
||||
|
||||
|
||||
/* if we are switching from ht to 2.4 clear flags
|
||||
* from any ht related info since 2.4 does not
|
||||
* support ht */
|
||||
|
@ -3102,6 +3163,7 @@ static void iwl4965_bss_info_changed(struct ieee80211_hw *hw,
|
|||
if (bss_conf->assoc) {
|
||||
priv->assoc_id = bss_conf->aid;
|
||||
priv->beacon_int = bss_conf->beacon_int;
|
||||
priv->power_data.dtim_period = bss_conf->dtim_period;
|
||||
priv->timestamp = bss_conf->timestamp;
|
||||
priv->assoc_capability = bss_conf->assoc_capability;
|
||||
priv->next_scan_jiffies = jiffies +
|
||||
|
@ -3345,6 +3407,39 @@ static int iwl4965_mac_conf_tx(struct ieee80211_hw *hw, u16 queue,
|
|||
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,
|
||||
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 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,
|
||||
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,
|
||||
store_filter_flags);
|
||||
|
||||
#ifdef CONFIG_IWL4965_SPECTRUM_MEASUREMENT
|
||||
#ifdef CONFIG_IWLAGN_SPECTRUM_MEASUREMENT
|
||||
|
||||
static ssize_t show_measurement(struct device *d,
|
||||
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 iwl4965_spectrum_notification measure_report;
|
||||
u32 size = sizeof(measure_report), len = 0, ofs = 0;
|
||||
u8 *data = (u8 *) & measure_report;
|
||||
u8 *data = (u8 *)&measure_report;
|
||||
unsigned long 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,
|
||||
show_measurement, store_measurement);
|
||||
#endif /* CONFIG_IWL4965_SPECTRUM_MEASUREMENT */
|
||||
#endif /* CONFIG_IWLAGN_SPECTRUM_MEASUREMENT */
|
||||
|
||||
static ssize_t store_retry_rate(struct device *d,
|
||||
struct device_attribute *attr,
|
||||
|
@ -3800,77 +3886,54 @@ static ssize_t store_power_level(struct device *d,
|
|||
const char *buf, size_t count)
|
||||
{
|
||||
struct iwl_priv *priv = dev_get_drvdata(d);
|
||||
int rc;
|
||||
int ret;
|
||||
int mode;
|
||||
|
||||
mode = simple_strtoul(buf, NULL, 0);
|
||||
mutex_lock(&priv->mutex);
|
||||
|
||||
if (!iwl_is_ready(priv)) {
|
||||
rc = -EAGAIN;
|
||||
ret = -EAGAIN;
|
||||
goto out;
|
||||
}
|
||||
|
||||
rc = iwl_power_set_user_mode(priv, mode);
|
||||
if (rc) {
|
||||
ret = iwl_power_set_user_mode(priv, mode);
|
||||
if (ret) {
|
||||
IWL_DEBUG_MAC80211("failed setting power mode.\n");
|
||||
goto out;
|
||||
}
|
||||
rc = count;
|
||||
ret = count;
|
||||
|
||||
out:
|
||||
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,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
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;
|
||||
char *p = buf;
|
||||
|
||||
p += sprintf(p, "%d ", level);
|
||||
switch (level) {
|
||||
case IWL_POWER_MODE_CAM:
|
||||
case IWL_POWER_AC:
|
||||
p += sprintf(p, "(AC)");
|
||||
switch (system) {
|
||||
case IWL_POWER_SYS_AUTO:
|
||||
p += sprintf(p, "SYSTEM:auto");
|
||||
break;
|
||||
case IWL_POWER_BATTERY:
|
||||
p += sprintf(p, "(BATTERY)");
|
||||
case IWL_POWER_SYS_AC:
|
||||
p += sprintf(p, "SYSTEM:ac");
|
||||
break;
|
||||
case IWL_POWER_SYS_BATTERY:
|
||||
p += sprintf(p, "SYSTEM:battery");
|
||||
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, " OFF\n");
|
||||
else
|
||||
p += sprintf(p, " \n");
|
||||
*/
|
||||
p += sprintf(p, " \n");
|
||||
return (p - buf + 1);
|
||||
|
||||
p += sprintf(p, "\tMODE:%s", (mode < IWL_POWER_AUTO)?"fixed":"auto");
|
||||
p += sprintf(p, "\tINDEX:%d", level);
|
||||
p += sprintf(p, "\n");
|
||||
return p - buf + 1;
|
||||
}
|
||||
|
||||
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);
|
||||
u32 size = sizeof(struct iwl_notif_statistics);
|
||||
u32 len = 0, ofs = 0;
|
||||
u8 *data = (u8 *) & priv->statistics;
|
||||
u8 *data = (u8 *)&priv->statistics;
|
||||
int rc = 0;
|
||||
|
||||
if (!iwl_is_alive(priv))
|
||||
|
@ -4041,12 +4104,11 @@ static struct attribute *iwl4965_sysfs_entries[] = {
|
|||
&dev_attr_channels.attr,
|
||||
&dev_attr_flags.attr,
|
||||
&dev_attr_filter_flags.attr,
|
||||
#ifdef CONFIG_IWL4965_SPECTRUM_MEASUREMENT
|
||||
#ifdef CONFIG_IWLAGN_SPECTRUM_MEASUREMENT
|
||||
&dev_attr_measurement.attr,
|
||||
#endif
|
||||
&dev_attr_power_level.attr,
|
||||
&dev_attr_retry_rate.attr,
|
||||
&dev_attr_rs_window.attr,
|
||||
&dev_attr_statistics.attr,
|
||||
&dev_attr_status.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 */
|
||||
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(0x4230, PCI_ANY_ID, iwl4965_agn_cfg)},
|
||||
#endif /* CONFIG_IWL4965 */
|
||||
#ifdef CONFIG_IWL5000
|
||||
{IWL_PCI_DEVICE(0x4232, 0x1205, 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_COPYRIGHT "\n");
|
||||
|
||||
ret = iwl4965_rate_control_register();
|
||||
ret = iwlagn_rate_control_register();
|
||||
if (ret) {
|
||||
IWL_ERROR("Unable to register rate control algorithm: %d\n", ret);
|
||||
return ret;
|
||||
|
@ -4446,14 +4510,14 @@ static int __init iwl4965_init(void)
|
|||
return ret;
|
||||
|
||||
error_register:
|
||||
iwl4965_rate_control_unregister();
|
||||
iwlagn_rate_control_unregister();
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void __exit iwl4965_exit(void)
|
||||
{
|
||||
pci_unregister_driver(&iwl_driver);
|
||||
iwl4965_rate_control_unregister();
|
||||
iwlagn_rate_control_unregister();
|
||||
}
|
||||
|
||||
module_exit(iwl4965_exit);
|
|
@ -666,8 +666,7 @@ struct iwl4965_rxon_assoc_cmd {
|
|||
__le16 reserved;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
|
||||
|
||||
#define IWL_CONN_MAX_LISTEN_INTERVAL 10
|
||||
|
||||
/*
|
||||
* REPLY_RXON_TIMING = 0x14 (command, has simple generic response)
|
||||
|
@ -1076,10 +1075,12 @@ struct iwl4965_rx_frame {
|
|||
} __attribute__ ((packed));
|
||||
|
||||
/* Fixed (non-configurable) rx data from phy */
|
||||
#define RX_PHY_FLAGS_ANTENNAE_OFFSET (4)
|
||||
#define RX_PHY_FLAGS_ANTENNAE_MASK (0x70)
|
||||
#define IWL_AGC_DB_MASK (0x3f80) /* MASK(7,13) */
|
||||
#define IWL_AGC_DB_POS (7)
|
||||
|
||||
#define IWL49_RX_RES_PHY_CNT 14
|
||||
#define IWL49_RX_PHY_FLAGS_ANTENNAE_OFFSET (4)
|
||||
#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 {
|
||||
__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 */
|
||||
|
@ -1087,12 +1088,30 @@ struct iwl4965_rx_non_cfg_phy {
|
|||
u8 pad[0];
|
||||
} __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)
|
||||
* Used only for legacy (non 11n) frames.
|
||||
*/
|
||||
#define RX_RES_PHY_CNT 14
|
||||
struct iwl4965_rx_phy_res {
|
||||
struct iwl_rx_phy_res {
|
||||
u8 non_cfg_phy_cnt; /* non 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 */
|
||||
|
@ -1101,8 +1120,7 @@ struct iwl4965_rx_phy_res {
|
|||
__le32 beacon_time_stamp; /* beacon at on-air rise */
|
||||
__le16 phy_flags; /* general phy flags: band, modulation, ... */
|
||||
__le16 channel; /* channel number */
|
||||
__le16 non_cfg_phy[RX_RES_PHY_CNT]; /* upto 14 phy entries */
|
||||
__le32 reserved2;
|
||||
u8 non_cfg_phy_buf[32]; /* for various implementations of non_cfg_phy */
|
||||
__le32 rate_n_flags; /* RATE_MCS_* */
|
||||
__le16 byte_count; /* frame's byte-count */
|
||||
__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:
|
||||
*
|
||||
* 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_FAST_PD __constant_cpu_to_le16(1 << 4)
|
||||
|
||||
struct iwl4965_powertable_cmd {
|
||||
struct iwl_powertable_cmd {
|
||||
__le16 flags;
|
||||
u8 keep_alive_seconds;
|
||||
u8 debug_flags;
|
||||
|
@ -2324,7 +2342,7 @@ struct iwl4965_beacon_notif {
|
|||
/*
|
||||
* REPLY_TX_BEACON = 0x91 (command, has simple generic response)
|
||||
*/
|
||||
struct iwl4965_tx_beacon_cmd {
|
||||
struct iwl_tx_beacon_cmd {
|
||||
struct iwl_tx_cmd tx;
|
||||
__le16 tim_idx;
|
||||
u8 tim_size;
|
||||
|
|
|
@ -383,8 +383,8 @@ void iwl_reset_qos(struct iwl_priv *priv)
|
|||
}
|
||||
EXPORT_SYMBOL(iwl_reset_qos);
|
||||
|
||||
#define MAX_BIT_RATE_40_MHZ 0x96; /* 150 Mbps */
|
||||
#define MAX_BIT_RATE_20_MHZ 0x48; /* 72 Mbps */
|
||||
#define MAX_BIT_RATE_40_MHZ 0x96 /* 150 Mbps */
|
||||
#define MAX_BIT_RATE_20_MHZ 0x48 /* 72 Mbps */
|
||||
static void iwlcore_init_ht_hw_capab(const struct iwl_priv *priv,
|
||||
struct ieee80211_ht_info *ht_info,
|
||||
enum ieee80211_band band)
|
||||
|
@ -815,7 +815,7 @@ int iwl_setup_mac(struct iwl_priv *priv)
|
|||
{
|
||||
int ret;
|
||||
struct ieee80211_hw *hw = priv->hw;
|
||||
hw->rate_control_algorithm = "iwl-4965-rs";
|
||||
hw->rate_control_algorithm = "iwl-agn-rs";
|
||||
|
||||
/* Tell mac80211 our characteristics */
|
||||
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->conf.beacon_int = 100;
|
||||
hw->max_listen_interval = IWL_CONN_MAX_LISTEN_INTERVAL;
|
||||
|
||||
if (priv->bands[IEEE80211_BAND_2GHZ].n_channels)
|
||||
priv->hw->wiphy->bands[IEEE80211_BAND_2GHZ] =
|
||||
|
|
|
@ -95,6 +95,8 @@ struct iwl_hcmd_utils_ops {
|
|||
void (*chain_noise_reset)(struct iwl_priv *priv);
|
||||
void (*rts_tx_cmd_flag)(struct ieee80211_tx_info *info,
|
||||
__le32 *tx_flags);
|
||||
int (*calc_rssi)(struct iwl_priv *priv,
|
||||
struct iwl_rx_phy_res *rx_resp);
|
||||
};
|
||||
|
||||
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);
|
||||
} apm_ops;
|
||||
/* power */
|
||||
int (*set_power)(struct iwl_priv *priv, void *cmd);
|
||||
int (*send_tx_power) (struct iwl_priv *priv);
|
||||
void (*update_chain_flags)(struct iwl_priv *priv);
|
||||
void (*temperature) (struct iwl_priv *priv);
|
||||
|
|
|
@ -104,6 +104,7 @@
|
|||
* 3-2: 0 = A, 1 = B, 2 = C, 3 = D step
|
||||
*/
|
||||
#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 */
|
||||
#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_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),
|
||||
* acknowledged (reset) by host writing "1" to flagged bits. */
|
||||
|
@ -236,6 +242,8 @@
|
|||
#define CSR39_ANA_PLL_CFG_VAL (0x01000000)
|
||||
#define CSR50_ANA_PLL_CFG_VAL (0x00880300)
|
||||
|
||||
/* HPET MEM debug */
|
||||
#define CSR_DBG_HPET_MEM_REG_VAL (0xFFFF0000)
|
||||
/*=== HBUS (Host-side Bus) ===*/
|
||||
#define HBUS_BASE (0x400)
|
||||
/*
|
||||
|
|
|
@ -33,12 +33,12 @@
|
|||
#define IWL_DEBUG(level, fmt, args...) \
|
||||
do { if (priv->debug_level & (level)) \
|
||||
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...) \
|
||||
do { if ((priv->debug_level & (level)) && net_ratelimit()) \
|
||||
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
|
||||
struct iwl_debugfs {
|
||||
|
|
|
@ -231,7 +231,7 @@ static ssize_t iwl_dbgfs_stations_read(struct file *file, char __user *user_buf,
|
|||
DECLARE_MAC_BUF(mac);
|
||||
|
||||
buf = kmalloc(bufsz, GFP_KERNEL);
|
||||
if(!buf)
|
||||
if (!buf)
|
||||
return -ENOMEM;
|
||||
|
||||
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 dentry *phyd = priv->hw->wiphy->debugfsdir;
|
||||
int ret = 0;
|
||||
|
||||
dbgfs = kzalloc(sizeof(struct iwl_debugfs), GFP_KERNEL);
|
||||
if (!dbgfs) {
|
||||
ret = -ENOMEM;
|
||||
goto err;
|
||||
}
|
||||
|
||||
priv->dbgfs = dbgfs;
|
||||
dbgfs->name = name;
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -394,7 +397,7 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name)
|
|||
err:
|
||||
IWL_ERROR("Can't open the debugfs directory\n");
|
||||
iwl_dbgfs_unregister(priv);
|
||||
return -ENOENT;
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(iwl_dbgfs_register);
|
||||
|
||||
|
@ -404,7 +407,7 @@ EXPORT_SYMBOL(iwl_dbgfs_register);
|
|||
*/
|
||||
void iwl_dbgfs_unregister(struct iwl_priv *priv)
|
||||
{
|
||||
if (!(priv->dbgfs))
|
||||
if (!priv->dbgfs)
|
||||
return;
|
||||
|
||||
DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_eeprom);
|
||||
|
|
|
@ -36,7 +36,7 @@
|
|||
#include <linux/kernel.h>
|
||||
#include <net/ieee80211_radiotap.h>
|
||||
|
||||
#define DRV_NAME "iwl4965"
|
||||
#define DRV_NAME "iwlagn"
|
||||
#include "iwl-rfkill.h"
|
||||
#include "iwl-eeprom.h"
|
||||
#include "iwl-4965-hw.h"
|
||||
|
@ -45,6 +45,7 @@
|
|||
#include "iwl-debug.h"
|
||||
#include "iwl-led.h"
|
||||
#include "iwl-power.h"
|
||||
#include "iwl-agn-rs.h"
|
||||
|
||||
/* configuration for the iwl4965 */
|
||||
extern struct iwl_cfg iwl4965_agn_cfg;
|
||||
|
@ -134,8 +135,7 @@ struct iwl_tx_info {
|
|||
struct iwl_tx_queue {
|
||||
struct iwl_queue q;
|
||||
struct iwl_tfd_frame *bd;
|
||||
struct iwl_cmd *cmd;
|
||||
dma_addr_t dma_addr_cmd;
|
||||
struct iwl_cmd *cmd[TFD_TX_CMD_SLOTS];
|
||||
struct iwl_tx_info *txb;
|
||||
int need_update;
|
||||
int sched_retry;
|
||||
|
@ -191,7 +191,6 @@ struct iwl4965_clip_group {
|
|||
const s8 clip_powers[IWL_MAX_RATES];
|
||||
};
|
||||
|
||||
#include "iwl-4965-rs.h"
|
||||
|
||||
#define IWL_TX_FIFO_AC0 0
|
||||
#define IWL_TX_FIFO_AC1 1
|
||||
|
@ -219,7 +218,7 @@ enum iwl_pwr_src {
|
|||
struct iwl_frame {
|
||||
union {
|
||||
struct ieee80211_hdr frame;
|
||||
struct iwl4965_tx_beacon_cmd beacon;
|
||||
struct iwl_tx_beacon_cmd beacon;
|
||||
u8 raw[IEEE80211_FRAME_LEN];
|
||||
u8 cmd[360];
|
||||
} u;
|
||||
|
@ -283,10 +282,9 @@ struct iwl_cmd {
|
|||
u32 val32;
|
||||
struct iwl4965_bt_cmd bt;
|
||||
struct iwl4965_rxon_time_cmd rxon_time;
|
||||
struct iwl4965_powertable_cmd powertable;
|
||||
struct iwl_powertable_cmd powertable;
|
||||
struct iwl_qosparam_cmd qosparam;
|
||||
struct iwl_tx_cmd tx;
|
||||
struct iwl4965_tx_beacon_cmd tx_beacon;
|
||||
struct iwl4965_rxon_assoc_cmd rxon_assoc;
|
||||
struct iwl_rem_sta_cmd rm_sta;
|
||||
u8 *indirect;
|
||||
|
@ -590,6 +588,7 @@ extern unsigned int iwl4965_fill_beacon_frame(struct iwl_priv *priv,
|
|||
const u8 *dest, int left);
|
||||
extern void iwl4965_update_chain_flags(struct iwl_priv *priv);
|
||||
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];
|
||||
|
||||
|
@ -642,10 +641,6 @@ struct iwl_priv;
|
|||
* Forward declare iwl-4965.c functions for iwl-base.c
|
||||
*/
|
||||
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,
|
||||
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) */
|
||||
|
||||
|
||||
#ifdef CONFIG_IWL4965_SPECTRUM_MEASUREMENT
|
||||
|
||||
enum {
|
||||
MEASUREMENT_READY = (1 << 0),
|
||||
MEASUREMENT_ACTIVE = (1 << 1),
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
#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];
|
||||
|
||||
#ifdef CONFIG_IWL4965_SPECTRUM_MEASUREMENT
|
||||
#ifdef CONFIG_IWLAGN_SPECTRUM_MEASUREMENT
|
||||
/* spectrum measurement report caching */
|
||||
struct iwl4965_spectrum_notification measure_report;
|
||||
u8 measurement_status;
|
||||
|
|
|
@ -273,8 +273,7 @@ EXPORT_SYMBOL(iwl_eeprom_init);
|
|||
|
||||
void iwl_eeprom_free(struct iwl_priv *priv)
|
||||
{
|
||||
if(priv->eeprom)
|
||||
kfree(priv->eeprom);
|
||||
kfree(priv->eeprom);
|
||||
priv->eeprom = NULL;
|
||||
}
|
||||
EXPORT_SYMBOL(iwl_eeprom_free);
|
||||
|
|
|
@ -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
|
||||
* in later, it will possibly set an invalid
|
||||
* 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;
|
||||
}
|
||||
fail:
|
||||
|
|
|
@ -161,11 +161,31 @@ int iwl4965_led_off(struct iwl_priv *priv, int led_id)
|
|||
/* Set led register off */
|
||||
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);
|
||||
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
|
||||
*/
|
||||
|
@ -199,16 +219,10 @@ static void iwl_led_brightness_set(struct led_classdev *led_cdev,
|
|||
led_type_str[led->type], brightness);
|
||||
switch (brightness) {
|
||||
case LED_FULL:
|
||||
if (led->type == IWL_LED_TRG_ASSOC)
|
||||
priv->allow_blinking = 1;
|
||||
|
||||
if (led->led_on)
|
||||
led->led_on(priv, IWL_LED_LINK);
|
||||
break;
|
||||
case LED_OFF:
|
||||
if (led->type == IWL_LED_TRG_ASSOC)
|
||||
priv->allow_blinking = 0;
|
||||
|
||||
if (led->led_off)
|
||||
led->led_off(priv, IWL_LED_LINK);
|
||||
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,
|
||||
enum led_type type, u8 set_led,
|
||||
const char *name, char *trigger)
|
||||
char *trigger)
|
||||
{
|
||||
struct device *device = wiphy_dev(priv->hw->wiphy);
|
||||
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.default_trigger = trigger;
|
||||
|
||||
|
@ -284,12 +298,6 @@ static int iwl_get_blink_rate(struct iwl_priv *priv)
|
|||
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
|
||||
* 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;
|
||||
return;
|
||||
}
|
||||
if (is_rf_kill(priv)) {
|
||||
if (iwl_is_rfkill(priv)) {
|
||||
priv->last_blink_time = 0;
|
||||
return;
|
||||
}
|
||||
|
@ -337,7 +345,6 @@ EXPORT_SYMBOL(iwl_leds_background);
|
|||
int iwl_leds_register(struct iwl_priv *priv)
|
||||
{
|
||||
char *trigger;
|
||||
char name[32];
|
||||
int ret;
|
||||
|
||||
priv->last_blink_rate = 0;
|
||||
|
@ -346,7 +353,8 @@ int iwl_leds_register(struct iwl_priv *priv)
|
|||
priv->allow_blinking = 0;
|
||||
|
||||
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));
|
||||
|
||||
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;
|
||||
|
||||
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)
|
||||
goto exit_fail;
|
||||
|
||||
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));
|
||||
|
||||
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 */
|
||||
priv->led[IWL_LED_TRG_ASSOC].led_on = iwl4965_led_on_reg;
|
||||
priv->led[IWL_LED_TRG_ASSOC].led_off = iwl4965_led_on_reg;
|
||||
priv->led[IWL_LED_TRG_ASSOC].led_on = iwl_led_associate;
|
||||
priv->led[IWL_LED_TRG_ASSOC].led_off = iwl_led_disassociate;
|
||||
priv->led[IWL_LED_TRG_ASSOC].led_pattern = NULL;
|
||||
|
||||
if (ret)
|
||||
goto exit_fail;
|
||||
|
||||
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],
|
||||
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_off = iwl_led_associated;
|
||||
|
@ -388,9 +398,12 @@ int iwl_leds_register(struct iwl_priv *priv)
|
|||
goto exit_fail;
|
||||
|
||||
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],
|
||||
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_off = iwl_led_associated;
|
||||
|
|
|
@ -52,6 +52,7 @@ enum led_type {
|
|||
struct iwl_led {
|
||||
struct iwl_priv *priv;
|
||||
struct led_classdev led_dev;
|
||||
char name[32];
|
||||
|
||||
int (*led_on) (struct iwl_priv *priv, int led_id);
|
||||
int (*led_off) (struct iwl_priv *priv, int led_id);
|
||||
|
|
|
@ -82,7 +82,7 @@
|
|||
|
||||
/* default power management (not Tx power) table values */
|
||||
/* 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},
|
||||
{{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},
|
||||
|
@ -93,7 +93,7 @@ static struct iwl_power_vec_entry range_0[IWL_POWER_AC] = {
|
|||
|
||||
|
||||
/* 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},
|
||||
{{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},
|
||||
|
@ -103,7 +103,7 @@ static struct iwl_power_vec_entry range_1[IWL_POWER_AC] = {
|
|||
};
|
||||
|
||||
/* 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},
|
||||
{{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},
|
||||
|
@ -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}
|
||||
};
|
||||
|
||||
/* 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
|
||||
* and battery status
|
||||
*/
|
||||
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) {
|
||||
case IWL_POWER_AUTO:
|
||||
|
@ -129,12 +136,16 @@ static u16 iwl_get_auto_power_mode(struct iwl_priv *priv)
|
|||
else
|
||||
mode = IWL_POWER_ON_AC_DISASSOC;
|
||||
break;
|
||||
/* FIXME: remove battery and ac from here */
|
||||
case IWL_POWER_BATTERY:
|
||||
mode = IWL_POWER_INDEX_3;
|
||||
break;
|
||||
case IWL_POWER_AC:
|
||||
mode = IWL_POWER_MODE_CAM;
|
||||
break;
|
||||
default:
|
||||
mode = priv->power_data.user_power_setting;
|
||||
break;
|
||||
}
|
||||
return mode;
|
||||
}
|
||||
|
@ -144,7 +155,7 @@ static int iwl_power_init_handle(struct iwl_priv *priv)
|
|||
{
|
||||
int ret = 0, i;
|
||||
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;
|
||||
|
||||
IWL_DEBUG_POWER("Initialize power \n");
|
||||
|
@ -162,11 +173,11 @@ static int iwl_power_init_handle(struct iwl_priv *priv)
|
|||
if (ret != 0)
|
||||
return 0;
|
||||
else {
|
||||
struct iwl4965_powertable_cmd *cmd;
|
||||
struct iwl_powertable_cmd *cmd;
|
||||
|
||||
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;
|
||||
|
||||
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*/
|
||||
static int iwl_update_power_command(struct iwl_priv *priv,
|
||||
struct iwl4965_powertable_cmd *cmd,
|
||||
struct iwl_powertable_cmd *cmd,
|
||||
u16 mode)
|
||||
{
|
||||
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];
|
||||
|
||||
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) {
|
||||
period = 1;
|
||||
|
@ -258,17 +269,18 @@ int iwl_power_update_mode(struct iwl_priv *priv, u8 refresh)
|
|||
* else user level */
|
||||
|
||||
switch (setting->system_power_setting) {
|
||||
case IWL_POWER_AUTO:
|
||||
case IWL_POWER_SYS_AUTO:
|
||||
final_mode = iwl_get_auto_power_mode(priv);
|
||||
break;
|
||||
case IWL_POWER_BATTERY:
|
||||
case IWL_POWER_SYS_BATTERY:
|
||||
final_mode = IWL_POWER_INDEX_3;
|
||||
break;
|
||||
case IWL_POWER_AC:
|
||||
case IWL_POWER_SYS_AC:
|
||||
final_mode = IWL_POWER_MODE_CAM;
|
||||
break;
|
||||
default:
|
||||
final_mode = setting->system_power_setting;
|
||||
final_mode = IWL_POWER_INDEX_3;
|
||||
WARN_ON(1);
|
||||
}
|
||||
|
||||
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 &&
|
||||
((setting->power_mode != final_mode) || refresh)) {
|
||||
struct iwl4965_powertable_cmd cmd;
|
||||
struct iwl_powertable_cmd cmd;
|
||||
|
||||
if (final_mode != IWL_POWER_MODE_CAM)
|
||||
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)
|
||||
cmd.flags |= IWL_POWER_FAST_PD;
|
||||
|
||||
if (priv->cfg->ops->lib->set_power)
|
||||
ret = priv->cfg->ops->lib->set_power(priv, &cmd);
|
||||
ret = iwl_set_power(priv, &cmd);
|
||||
|
||||
if (final_mode == IWL_POWER_MODE_CAM)
|
||||
clear_bit(STATUS_POWER_PMI, &priv->status);
|
||||
|
@ -388,7 +399,7 @@ void iwl_power_initialize(struct iwl_priv *priv)
|
|||
iwl_power_init_handle(priv);
|
||||
priv->power_data.user_power_setting = IWL_POWER_AUTO;
|
||||
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.power_disabled = 0;
|
||||
priv->power_data.critical_power_setting = 0;
|
||||
|
|
|
@ -33,12 +33,25 @@
|
|||
|
||||
struct iwl_priv;
|
||||
|
||||
#define IWL_POWER_MODE_CAM 0x00 /* Continuously Aware Mode, always on */
|
||||
#define IWL_POWER_INDEX_3 0x03
|
||||
#define IWL_POWER_INDEX_5 0x05
|
||||
#define IWL_POWER_AC 0x06
|
||||
#define IWL_POWER_BATTERY 0x07
|
||||
#define IWL_POWER_AUTO 0x08
|
||||
enum {
|
||||
IWL_POWER_MODE_CAM, /* Continuously Aware Mode, always on */
|
||||
IWL_POWER_INDEX_1,
|
||||
IWL_POWER_INDEX_2,
|
||||
IWL_POWER_INDEX_3,
|
||||
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_MASK 0x0F
|
||||
#define IWL_POWER_ENABLED 0x10
|
||||
|
@ -46,15 +59,15 @@ struct iwl_priv;
|
|||
/* Power management (not Tx power) structures */
|
||||
|
||||
struct iwl_power_vec_entry {
|
||||
struct iwl4965_powertable_cmd cmd;
|
||||
struct iwl_powertable_cmd cmd;
|
||||
u8 no_dtim;
|
||||
};
|
||||
|
||||
struct iwl_power_mgr {
|
||||
spinlock_t lock;
|
||||
struct iwl_power_vec_entry pwr_range_0[IWL_POWER_AC];
|
||||
struct iwl_power_vec_entry pwr_range_1[IWL_POWER_AC];
|
||||
struct iwl_power_vec_entry pwr_range_2[IWL_POWER_AC];
|
||||
struct iwl_power_vec_entry pwr_range_0[IWL_POWER_MAX];
|
||||
struct iwl_power_vec_entry pwr_range_1[IWL_POWER_MAX];
|
||||
struct iwl_power_vec_entry pwr_range_2[IWL_POWER_MAX];
|
||||
u32 dtim_period;
|
||||
/* final power level that used to calculate final power command */
|
||||
u8 power_mode;
|
||||
|
|
|
@ -84,14 +84,16 @@
|
|||
#define APMG_CLK_VAL_DMA_CLK_RQT (0x00000200)
|
||||
#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)
|
||||
|
|
|
@ -791,7 +791,7 @@ static inline void iwl_dbg_report_frame(struct iwl_priv *priv,
|
|||
|
||||
static void iwl_add_radiotap(struct iwl_priv *priv,
|
||||
struct sk_buff *skb,
|
||||
struct iwl4965_rx_phy_res *rx_start,
|
||||
struct iwl_rx_phy_res *rx_start,
|
||||
struct ieee80211_rx_status *stats,
|
||||
u32 ampdu_status)
|
||||
{
|
||||
|
@ -1010,8 +1010,8 @@ static void iwl_pass_packet_to_mac80211(struct iwl_priv *priv,
|
|||
struct ieee80211_rx_status *stats)
|
||||
{
|
||||
struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
|
||||
struct iwl4965_rx_phy_res *rx_start = (include_phy) ?
|
||||
(struct iwl4965_rx_phy_res *)&(pkt->u.raw[0]) : NULL;
|
||||
struct iwl_rx_phy_res *rx_start = (include_phy) ?
|
||||
(struct iwl_rx_phy_res *)&(pkt->u.raw[0]) : NULL;
|
||||
struct ieee80211_hdr *hdr;
|
||||
u16 len;
|
||||
__le32 *rx_end;
|
||||
|
@ -1020,7 +1020,7 @@ static void iwl_pass_packet_to_mac80211(struct iwl_priv *priv,
|
|||
u32 ampdu_status_legacy;
|
||||
|
||||
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) {
|
||||
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);
|
||||
|
||||
rx_end = (__le32 *) ((u8 *) &pkt->u.raw[0] +
|
||||
sizeof(struct iwl4965_rx_phy_res) +
|
||||
rx_end = (__le32 *)((u8 *) &pkt->u.raw[0] +
|
||||
sizeof(struct iwl_rx_phy_res) +
|
||||
rx_start->cfg_phy_cnt + len);
|
||||
|
||||
} 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 */
|
||||
static int iwl_calc_rssi(struct iwl_priv *priv,
|
||||
struct iwl4965_rx_phy_res *rx_resp)
|
||||
static inline int iwl_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;
|
||||
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;
|
||||
return priv->cfg->ops->utils->calc_rssi(priv, rx_resp);
|
||||
}
|
||||
|
||||
|
||||
static void iwl_sta_modify_ps_wake(struct iwl_priv *priv, int sta_id)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
@ -1180,9 +1153,9 @@ void iwl_rx_reply_rx(struct iwl_priv *priv,
|
|||
* this rx packet for legacy frames,
|
||||
* or phy data cached from REPLY_RX_PHY_CMD for HT frames. */
|
||||
int include_phy = (pkt->hdr.cmd == REPLY_RX);
|
||||
struct iwl4965_rx_phy_res *rx_start = (include_phy) ?
|
||||
(struct iwl4965_rx_phy_res *)&(pkt->u.raw[0]) :
|
||||
(struct iwl4965_rx_phy_res *)&priv->last_phy_res[1];
|
||||
struct iwl_rx_phy_res *rx_start = (include_phy) ?
|
||||
(struct iwl_rx_phy_res *)&(pkt->u.raw[0]) :
|
||||
(struct iwl_rx_phy_res *)&priv->last_phy_res[1];
|
||||
__le32 *rx_end;
|
||||
unsigned int len = 0;
|
||||
u16 fc;
|
||||
|
@ -1210,7 +1183,7 @@ void iwl_rx_reply_rx(struct iwl_priv *priv,
|
|||
|
||||
if (!include_phy) {
|
||||
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];
|
||||
else
|
||||
rx_start = NULL;
|
||||
|
@ -1227,7 +1200,7 @@ void iwl_rx_reply_rx(struct iwl_priv *priv,
|
|||
|
||||
len = le16_to_cpu(rx_start->byte_count);
|
||||
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 {
|
||||
struct iwl4965_rx_mpdu_res_start *amsdu =
|
||||
(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;
|
||||
priv->last_phy_res[0] = 1;
|
||||
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);
|
||||
|
|
|
@ -202,6 +202,7 @@ static int iwl_send_scan_abort(struct iwl_priv *priv)
|
|||
clear_bit(STATUS_SCAN_HW, &priv->status);
|
||||
}
|
||||
|
||||
priv->alloc_rxb_skb--;
|
||||
dev_kfree_skb_any(cmd.meta.u.skb);
|
||||
|
||||
return ret;
|
||||
|
|
|
@ -823,7 +823,7 @@ int iwl_send_lq_cmd(struct iwl_priv *priv,
|
|||
if (lq->sta_id == 0xFF)
|
||||
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)
|
||||
return iwl_send_cmd(priv, &cmd);
|
||||
|
@ -839,7 +839,7 @@ EXPORT_SYMBOL(iwl_send_lq_cmd);
|
|||
* for automatic fallback during transmission.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* NOTE: Run REPLY_ADD_STA command to set up station table entry, before
|
||||
|
|
|
@ -208,11 +208,12 @@ EXPORT_SYMBOL(iwl_txq_update_write_ptr);
|
|||
* Free all buffers.
|
||||
* 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 pci_dev *dev = priv->pci_dev;
|
||||
int len;
|
||||
int i, slots_num, len;
|
||||
|
||||
if (q->n_bd == 0)
|
||||
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;
|
||||
|
||||
/* 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 */
|
||||
if (txq->q.n_bd)
|
||||
|
@ -400,8 +406,7 @@ static int iwl_tx_queue_init(struct iwl_priv *priv,
|
|||
struct iwl_tx_queue *txq,
|
||||
int slots_num, u32 txq_id)
|
||||
{
|
||||
struct pci_dev *dev = priv->pci_dev;
|
||||
int len;
|
||||
int i, len;
|
||||
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
|
||||
* space is needed.
|
||||
*/
|
||||
len = sizeof(struct iwl_cmd) * slots_num;
|
||||
if (txq_id == IWL_CMD_QUEUE_NUM)
|
||||
len += IWL_MAX_SCAN_SIZE;
|
||||
txq->cmd = pci_alloc_consistent(dev, len, &txq->dma_addr_cmd);
|
||||
if (!txq->cmd)
|
||||
return -ENOMEM;
|
||||
len = sizeof(struct iwl_cmd);
|
||||
for (i = 0; i <= slots_num; i++) {
|
||||
if (i == slots_num) {
|
||||
if (txq_id == IWL_CMD_QUEUE_NUM)
|
||||
len += IWL_MAX_SCAN_SIZE;
|
||||
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 */
|
||||
rc = iwl_tx_queue_alloc(priv, txq, txq_id);
|
||||
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;
|
||||
}
|
||||
|
@ -451,7 +464,7 @@ void iwl_hw_txq_ctx_free(struct iwl_priv *priv)
|
|||
|
||||
/* Tx queues */
|
||||
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 */
|
||||
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;
|
||||
|
||||
/* 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;
|
||||
memset(&out_cmd->hdr, 0, sizeof(out_cmd->hdr));
|
||||
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!),
|
||||
* within command buffer array. */
|
||||
txcmd_phys = txq->dma_addr_cmd + sizeof(struct iwl_cmd) * idx +
|
||||
offsetof(struct iwl_cmd, hdr);
|
||||
txcmd_phys = pci_map_single(priv->pci_dev, out_cmd,
|
||||
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
|
||||
* first entry */
|
||||
|
@ -1004,7 +1018,7 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
|
|||
u32 idx;
|
||||
u16 fix_size;
|
||||
dma_addr_t phys_addr;
|
||||
int ret;
|
||||
int len, ret;
|
||||
unsigned long flags;
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
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));
|
||||
if (out_cmd->meta.flags & CMD_SIZE_HUGE)
|
||||
out_cmd->hdr.sequence |= cpu_to_le16(SEQ_HUGE_FRAME);
|
||||
|
||||
phys_addr = txq->dma_addr_cmd + sizeof(txq->cmd[0]) * idx +
|
||||
offsetof(struct iwl_cmd, hdr);
|
||||
len = (idx == TFD_CMD_SLOTS) ?
|
||||
IWL_MAX_SCAN_SIZE : sizeof(struct iwl_cmd);
|
||||
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_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_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;
|
||||
|
||||
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);
|
||||
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++;
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
||||
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. */
|
||||
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,
|
||||
* update driver's record of tx frame's status. */
|
||||
for (i = 0; i < agg->frame_count ; i++) {
|
||||
ack = bitmap & (1 << i);
|
||||
ack = bitmap & (1ULL << i);
|
||||
successes += !!ack;
|
||||
IWL_DEBUG_TX_REPLY("%s ON i=%d idx=%d raw=%d\n",
|
||||
ack? "ACK":"NACK", i, (agg->start_idx + i) & 0xff,
|
||||
|
|
|
@ -275,10 +275,8 @@ static int iwl3945_tx_queue_alloc(struct iwl3945_priv *priv,
|
|||
return 0;
|
||||
|
||||
error:
|
||||
if (txq->txb) {
|
||||
kfree(txq->txb);
|
||||
txq->txb = NULL;
|
||||
}
|
||||
kfree(txq->txb);
|
||||
txq->txb = NULL;
|
||||
|
||||
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);
|
||||
|
||||
/* De-alloc array of per-TFD driver data */
|
||||
if (txq->txb) {
|
||||
kfree(txq->txb);
|
||||
txq->txb = NULL;
|
||||
}
|
||||
kfree(txq->txb);
|
||||
txq->txb = NULL;
|
||||
|
||||
/* 0-fill queue descriptor structure */
|
||||
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)) {
|
||||
txq->need_update = 1;
|
||||
if (qc) {
|
||||
if (qc)
|
||||
priv->stations[sta_id].tid[tid].seq_number = seq_number;
|
||||
}
|
||||
} else {
|
||||
wait_write_ptr = 1;
|
||||
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,
|
||||
* add 20 dB to make up for divide by 10 */
|
||||
if (sig_ratio >= 100)
|
||||
return (20 + (int)ratio2dB[sig_ratio/10]);
|
||||
return 20 + (int)ratio2dB[sig_ratio/10];
|
||||
|
||||
/* We shouldn't see this */
|
||||
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,
|
||||
* 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 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);
|
||||
for (reg = BSM_SRAM_LOWER_BOUND;
|
||||
reg < BSM_SRAM_LOWER_BOUND + len;
|
||||
reg += sizeof(u32), image ++) {
|
||||
reg += sizeof(u32), image++) {
|
||||
val = iwl3945_read_prph(priv, reg);
|
||||
if (val != le32_to_cpu(*image)) {
|
||||
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);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -6417,7 +6412,7 @@ static void iwl3945_bg_post_associate(struct work_struct *data)
|
|||
|
||||
default:
|
||||
IWL_ERROR("%s Should not be called in %d mode\n",
|
||||
__FUNCTION__, priv->iw_mode);
|
||||
__func__, priv->iw_mode);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -6594,12 +6589,6 @@ static int iwl3945_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
|
|||
|
||||
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,
|
||||
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_spectrum_notification measure_report;
|
||||
u32 size = sizeof(measure_report), len = 0, ofs = 0;
|
||||
u8 *data = (u8 *) & measure_report;
|
||||
u8 *data = (u8 *)&measure_report;
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&priv->lock, flags);
|
||||
|
@ -7627,7 +7616,7 @@ static ssize_t show_power_level(struct device *d,
|
|||
else
|
||||
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);
|
||||
u32 size = sizeof(struct iwl3945_notif_statistics);
|
||||
u32 len = 0, ofs = 0;
|
||||
u8 *data = (u8 *) & priv->statistics;
|
||||
u8 *data = (u8 *)&priv->statistics;
|
||||
int rc = 0;
|
||||
|
||||
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 */
|
||||
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);
|
||||
err = iwl3945_poll_bit(priv, CSR_GP_CNTRL,
|
||||
CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY,
|
||||
CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000);
|
||||
if (err < 0) {
|
||||
IWL_DEBUG_INFO("Failed to init the card\n");
|
||||
iwl3945_set_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
|
||||
err = iwl3945_poll_bit(priv, CSR_GP_CNTRL,
|
||||
CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY,
|
||||
CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000);
|
||||
if (err < 0) {
|
||||
IWL_DEBUG_INFO("Failed to init the card\n");
|
||||
goto out_remove_sysfs;
|
||||
}
|
||||
}
|
||||
/* Read the EEPROM */
|
||||
err = iwl3945_eeprom_init(priv);
|
||||
if (err) {
|
||||
|
@ -8114,9 +8103,8 @@ static void __devexit iwl3945_pci_remove(struct pci_dev *pdev)
|
|||
iwl3945_unset_hw_setting(priv);
|
||||
iwl3945_clear_stations_table(priv);
|
||||
|
||||
if (priv->mac80211_registered) {
|
||||
if (priv->mac80211_registered)
|
||||
ieee80211_unregister_hw(priv->hw);
|
||||
}
|
||||
|
||||
/*netif_stop_queue(dev); */
|
||||
flush_workqueue(priv->workqueue);
|
||||
|
|
|
@ -52,6 +52,7 @@ struct p54_common {
|
|||
int (*open)(struct ieee80211_hw *dev);
|
||||
void (*stop)(struct ieee80211_hw *dev);
|
||||
int mode;
|
||||
struct mutex conf_mutex;
|
||||
u8 mac_addr[ETH_ALEN];
|
||||
u8 bssid[ETH_ALEN];
|
||||
struct pda_iq_autocal_entry *iq_autocal;
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
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));
|
||||
p54_set_vdcf(dev);
|
||||
mutex_unlock(&priv->conf_mutex);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -898,10 +901,12 @@ static int p54_config_interface(struct ieee80211_hw *dev,
|
|||
{
|
||||
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, 2, 0, 0, 0);
|
||||
p54_set_leds(dev, 1, !is_multicast_ether_addr(conf->bssid), 0);
|
||||
memcpy(priv->bssid, conf->bssid, ETH_ALEN);
|
||||
mutex_unlock(&priv->conf_mutex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1009,6 +1014,7 @@ struct ieee80211_hw *p54_init_common(size_t priv_data_len)
|
|||
}
|
||||
|
||||
p54_init_vdcf(dev);
|
||||
mutex_init(&priv->conf_mutex);
|
||||
|
||||
return dev;
|
||||
}
|
||||
|
|
|
@ -633,6 +633,16 @@ static void rt2500usb_reset_tuner(struct rt2x00_dev *rt2x00dev)
|
|||
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)
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
#else
|
||||
#define rt2500usb_link_tuner NULL
|
||||
#endif
|
||||
|
||||
/*
|
||||
* 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_BEACON_GUARD, &rt2x00dev->flags);
|
||||
__set_bit(DRIVER_REQUIRE_SCHEDULED, &rt2x00dev->flags);
|
||||
__set_bit(CONFIG_DISABLE_LINK_TUNING, &rt2x00dev->flags);
|
||||
|
||||
/*
|
||||
* Set the rssi offset.
|
||||
|
|
|
@ -506,6 +506,19 @@ struct ieee80211_channel_sw_ie {
|
|||
u8 count;
|
||||
} __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 {
|
||||
__le16 frame_control;
|
||||
__le16 duration;
|
||||
|
|
|
@ -177,9 +177,10 @@ enum ieee80211_bss_change {
|
|||
* @aid: association ID number, valid only when @assoc is true
|
||||
* @use_cts_prot: use CTS protection
|
||||
* @use_short_preamble: use 802.11b short preamble
|
||||
* @dtim_period: num of beacons before the next DTIM, for PSM
|
||||
* @timestamp: beacon timestamp
|
||||
* @beacon_int: beacon interval
|
||||
* @assoc_capability: capabbilities taken from assoc resp
|
||||
* @assoc_capability: capabilities taken from assoc resp
|
||||
* @assoc_ht: association in HT mode
|
||||
* @ht_conf: ht capabilities
|
||||
* @ht_bss_conf: ht extended capabilities
|
||||
|
@ -191,6 +192,7 @@ struct ieee80211_bss_conf {
|
|||
/* erp related data */
|
||||
bool use_cts_prot;
|
||||
bool use_short_preamble;
|
||||
u8 dtim_period;
|
||||
u16 beacon_int;
|
||||
u16 assoc_capability;
|
||||
u64 timestamp;
|
||||
|
@ -430,6 +432,7 @@ enum ieee80211_conf_flags {
|
|||
* @radio_enabled: when zero, driver is required to switch off the radio.
|
||||
* TODO make a flag
|
||||
* @beacon_int: beacon interval (TODO make interface config)
|
||||
* @listen_interval: listen interval in units of beacon interval
|
||||
* @flags: configuration flags defined above
|
||||
* @power_level: requested transmit power (in dBm)
|
||||
* @max_antenna_gain: maximum antenna gain (in dBi)
|
||||
|
@ -444,6 +447,7 @@ struct ieee80211_conf {
|
|||
int radio_enabled;
|
||||
|
||||
int beacon_int;
|
||||
u16 listen_interval;
|
||||
u32 flags;
|
||||
int power_level;
|
||||
int max_antenna_gain;
|
||||
|
@ -785,6 +789,9 @@ enum ieee80211_hw_flags {
|
|||
* @max_signal: Maximum value for signal (rssi) in RX information, used
|
||||
* 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
|
||||
* data packets. WMM/QoS requires at least four, these
|
||||
* queues need to have configurable access parameters.
|
||||
|
@ -812,7 +819,9 @@ struct ieee80211_hw {
|
|||
unsigned int extra_tx_headroom;
|
||||
int channel_change_time;
|
||||
int vif_data_size;
|
||||
u16 queues, ampdu_queues;
|
||||
u16 queues;
|
||||
u16 ampdu_queues;
|
||||
u16 max_listen_interval;
|
||||
s8 max_signal;
|
||||
};
|
||||
|
||||
|
|
|
@ -82,6 +82,7 @@ struct ieee80211_sta_bss {
|
|||
|
||||
u8 bssid[ETH_ALEN];
|
||||
u8 ssid[IEEE80211_MAX_SSID_LEN];
|
||||
u8 dtim_period;
|
||||
u16 capability; /* host byte order */
|
||||
enum ieee80211_band band;
|
||||
int freq;
|
||||
|
|
|
@ -1689,6 +1689,11 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
|
|||
if (local->hw.conf.beacon_int < 10)
|
||||
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 |
|
||||
IEEE80211_HW_SIGNAL_DB |
|
||||
IEEE80211_HW_SIGNAL_DBM) ?
|
||||
|
|
|
@ -551,6 +551,7 @@ static void ieee80211_set_associated(struct net_device *dev,
|
|||
/* set timing information */
|
||||
sdata->bss_conf.beacon_int = bss->beacon_int;
|
||||
sdata->bss_conf.timestamp = bss->timestamp;
|
||||
sdata->bss_conf.dtim_period = bss->dtim_period;
|
||||
|
||||
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,
|
||||
IEEE80211_STYPE_REASSOC_REQ);
|
||||
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,
|
||||
ETH_ALEN);
|
||||
} else {
|
||||
|
@ -781,7 +783,8 @@ static void ieee80211_send_assoc(struct net_device *dev,
|
|||
mgmt->frame_control = IEEE80211_FC(IEEE80211_FTYPE_MGMT,
|
||||
IEEE80211_STYPE_ASSOC_REQ);
|
||||
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 */
|
||||
|
@ -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->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;
|
||||
if (elems->supp_rates) {
|
||||
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),
|
||||
print_mac(mac2, ifsta->bssid));
|
||||
#endif /* CONFIG_MAC80211_IBSS_DEBUG */
|
||||
if (found && memcmp(ifsta->bssid, bssid, ETH_ALEN) != 0 &&
|
||||
(bss = ieee80211_rx_bss_get(dev, bssid,
|
||||
local->hw.conf.channel->center_freq,
|
||||
ifsta->ssid, ifsta->ssid_len))) {
|
||||
|
||||
if (found && memcmp(ifsta->bssid, bssid, ETH_ALEN) != 0) {
|
||||
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"
|
||||
" based on configured SSID\n",
|
||||
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);
|
||||
return ret;
|
||||
}
|
||||
|
||||
dont_join:
|
||||
#ifdef CONFIG_MAC80211_IBSS_DEBUG
|
||||
printk(KERN_DEBUG " did not try to join ibss\n");
|
||||
#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) {
|
||||
struct ieee80211_if_sta *ifsta = &sdata->u.sta;
|
||||
if (!(ifsta->flags & IEEE80211_STA_BSSID_SET) ||
|
||||
(!ifsta->state == IEEE80211_IBSS_JOINED &&
|
||||
(!(ifsta->state == IEEE80211_IBSS_JOINED) &&
|
||||
!ieee80211_sta_active_ibss(dev)))
|
||||
ieee80211_sta_find_ibss(dev, ifsta);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue