Commit 33e33495 authored by David S. Miller's avatar David S. Miller
Browse files
parents ad619800 3e2236c1
...@@ -14,18 +14,49 @@ config IWLWIFI_LEDS ...@@ -14,18 +14,49 @@ config IWLWIFI_LEDS
default n default n
config IWLWIFI_RFKILL config IWLWIFI_RFKILL
boolean "IWLWIFI RF kill support" boolean "Iwlwifi RF kill support"
depends on IWLCORE depends on IWLCORE
config IWL4965 config IWLWIFI_DEBUG
tristate "Intel Wireless WiFi 4965AGN" bool "Enable full debugging output in iwlagn driver"
depends on IWLCORE
---help---
This option will enable debug tracing output for the iwlwifi drivers
This will result in the kernel module being ~100k larger. You can
control which debug output is sent to the kernel log by setting the
value in
/sys/class/net/wlan0/device/debug_level
This entry will only exist if this option is enabled.
To set a value, simply echo an 8-byte hex value to the same file:
% echo 0x43fff > /sys/class/net/wlan0/device/debug_level
You can find the list of debug mask values in:
drivers/net/wireless/iwlwifi/iwl-debug.h
If this is your first time using this driver, you should say Y here
as the debug information can assist others in helping you resolve
any problems you may encounter.
config IWLWIFI_DEBUGFS
bool "Iwlwifi debugfs support"
depends on IWLCORE && IWLWIFI_DEBUG && MAC80211_DEBUGFS
---help---
Enable creation of debugfs files for the iwlwifi drivers.
config IWLAGN
tristate "Intel Wireless WiFi Next Gen AGN"
depends on PCI && MAC80211 && WLAN_80211 && EXPERIMENTAL depends on PCI && MAC80211 && WLAN_80211 && EXPERIMENTAL
select FW_LOADER select FW_LOADER
select IWLCORE select IWLCORE
---help--- ---help---
Select to build the driver supporting the: Select to build the driver supporting the:
Intel Wireless WiFi Link 4965AGN Intel Wireless WiFi Link Next-Gen AGN
This driver uses the kernel's mac80211 subsystem. This driver uses the kernel's mac80211 subsystem.
...@@ -42,60 +73,33 @@ config IWL4965 ...@@ -42,60 +73,33 @@ config IWL4965
If you want to compile the driver as a module ( = code which can be If you want to compile the driver as a module ( = code which can be
inserted in and removed from the running kernel whenever you want), inserted in and removed from the running kernel whenever you want),
say M here and read <file:Documentation/kbuild/modules.txt>. The say M here and read <file:Documentation/kbuild/modules.txt>. The
module will be called iwl4965.ko. module will be called iwlagn.ko.
config IWL4965_LEDS
bool "Enable LEDS features in iwl4965 driver"
depends on IWL4965
select IWLWIFI_LEDS
---help---
This option enables LEDS for the iwlwifi drivers
config IWLAGN_SPECTRUM_MEASUREMENT
config IWL4965_SPECTRUM_MEASUREMENT bool "Enable Spectrum Measurement in iwlagn driver"
bool "Enable Spectrum Measurement in iwl4965 driver" depends on IWLAGN
depends on IWL4965
---help--- ---help---
This option will enable spectrum measurement for the iwl4965 driver. This option will enable spectrum measurement for the iwlagn driver.
config IWLWIFI_DEBUG config IWLAGN_LEDS
bool "Enable full debugging output in iwl4965 driver" bool "Enable LEDS features in iwlagn driver"
depends on IWL4965 depends on IWLAGN
select IWLWIFI_LEDS
---help--- ---help---
This option will enable debug tracing output for the iwl4965 This option enables LEDS for the iwlagn drivers
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 config IWL4965
as the debug information can assist others in helping you resolve bool "Intel Wireless WiFi 4965AGN"
any problems you may encounter. depends on IWLAGN
---help---
This option enables support for Intel Wireless WiFi Link 4965AGN
config IWL5000 config IWL5000
bool "Intel Wireless WiFi 5000AGN" bool "Intel Wireless WiFi 5000AGN"
depends on IWL4965 depends on IWLAGN
---help--- ---help---
This option enables support for Intel Wireless WiFi Link 5000AGN Family This option enables support for Intel Wireless WiFi Link 5000AGN Family
Dependency on 4965 is temporary
config IWLWIFI_DEBUGFS
bool "Iwlwifi debugfs support"
depends on IWLCORE && IWLWIFI_DEBUG && MAC80211_DEBUGFS
---help---
Enable creation of debugfs files for the iwlwifi drivers.
config IWL3945 config IWL3945
tristate "Intel PRO/Wireless 3945ABG/BG Network Connection" tristate "Intel PRO/Wireless 3945ABG/BG Network Connection"
......
...@@ -6,15 +6,14 @@ iwlcore-$(CONFIG_IWLWIFI_DEBUGFS) += iwl-debugfs.o ...@@ -6,15 +6,14 @@ iwlcore-$(CONFIG_IWLWIFI_DEBUGFS) += iwl-debugfs.o
iwlcore-$(CONFIG_IWLWIFI_LEDS) += iwl-led.o iwlcore-$(CONFIG_IWLWIFI_LEDS) += iwl-led.o
iwlcore-$(CONFIG_IWLWIFI_RFKILL) += iwl-rfkill.o iwlcore-$(CONFIG_IWLWIFI_RFKILL) += iwl-rfkill.o
obj-$(CONFIG_IWLAGN) += iwlagn.o
iwlagn-objs := iwl-agn.o iwl-agn-rs.o
iwlagn-$(CONFIG_IWL4965) += iwl-4965.o
iwlagn-$(CONFIG_IWL5000) += iwl-5000.o
obj-$(CONFIG_IWL3945) += iwl3945.o obj-$(CONFIG_IWL3945) += iwl3945.o
iwl3945-objs := iwl3945-base.o iwl-3945.o iwl-3945-rs.o iwl3945-objs := iwl3945-base.o iwl-3945.o iwl-3945-rs.o
iwl3945-$(CONFIG_IWL3945_LEDS) += iwl-3945-led.o iwl3945-$(CONFIG_IWL3945_LEDS) += iwl-3945-led.o
obj-$(CONFIG_IWL4965) += iwl4965.o
iwl4965-objs := iwl4965-base.o iwl-4965.o iwl-4965-rs.o
ifeq ($(CONFIG_IWL5000),y)
iwl4965-objs += iwl-5000.o
endif
...@@ -206,12 +206,12 @@ static void iwl3945_led_brightness_set(struct led_classdev *led_cdev, ...@@ -206,12 +206,12 @@ static void iwl3945_led_brightness_set(struct led_classdev *led_cdev,
static int iwl3945_led_register_led(struct iwl3945_priv *priv, static int iwl3945_led_register_led(struct iwl3945_priv *priv,
struct iwl3945_led *led, struct iwl3945_led *led,
enum led_type type, u8 set_led, enum led_type type, u8 set_led,
const char *name, char *trigger) char *trigger)
{ {
struct device *device = wiphy_dev(priv->hw->wiphy); struct device *device = wiphy_dev(priv->hw->wiphy);
int ret; int ret;
led->led_dev.name = name; led->led_dev.name = led->name;
led->led_dev.brightness_set = iwl3945_led_brightness_set; led->led_dev.brightness_set = iwl3945_led_brightness_set;
led->led_dev.default_trigger = trigger; led->led_dev.default_trigger = trigger;
...@@ -308,7 +308,6 @@ void iwl3945_led_background(struct iwl3945_priv *priv) ...@@ -308,7 +308,6 @@ void iwl3945_led_background(struct iwl3945_priv *priv)
int iwl3945_led_register(struct iwl3945_priv *priv) int iwl3945_led_register(struct iwl3945_priv *priv)
{ {
char *trigger; char *trigger;
char name[32];
int ret; int ret;
priv->last_blink_rate = 0; priv->last_blink_rate = 0;
...@@ -318,7 +317,8 @@ int iwl3945_led_register(struct iwl3945_priv *priv) ...@@ -318,7 +317,8 @@ int iwl3945_led_register(struct iwl3945_priv *priv)
priv->allow_blinking = 0; priv->allow_blinking = 0;
trigger = ieee80211_get_radio_led_name(priv->hw); trigger = ieee80211_get_radio_led_name(priv->hw);
snprintf(name, sizeof(name), "iwl-%s:radio", snprintf(priv->led[IWL_LED_TRG_RADIO].name,
sizeof(priv->led[IWL_LED_TRG_RADIO].name), "iwl-%s:radio",
wiphy_name(priv->hw->wiphy)); wiphy_name(priv->hw->wiphy));
priv->led[IWL_LED_TRG_RADIO].led_on = iwl3945_led_on; priv->led[IWL_LED_TRG_RADIO].led_on = iwl3945_led_on;
...@@ -327,19 +327,20 @@ int iwl3945_led_register(struct iwl3945_priv *priv) ...@@ -327,19 +327,20 @@ int iwl3945_led_register(struct iwl3945_priv *priv)
ret = iwl3945_led_register_led(priv, ret = iwl3945_led_register_led(priv,
&priv->led[IWL_LED_TRG_RADIO], &priv->led[IWL_LED_TRG_RADIO],
IWL_LED_TRG_RADIO, 1, IWL_LED_TRG_RADIO, 1, trigger);
name, trigger);
if (ret) if (ret)
goto exit_fail; goto exit_fail;
trigger = ieee80211_get_assoc_led_name(priv->hw); trigger = ieee80211_get_assoc_led_name(priv->hw);
snprintf(name, sizeof(name), "iwl-%s:assoc", snprintf(priv->led[IWL_LED_TRG_ASSOC].name,
sizeof(priv->led[IWL_LED_TRG_ASSOC].name), "iwl-%s:assoc",
wiphy_name(priv->hw->wiphy)); wiphy_name(priv->hw->wiphy));
ret = iwl3945_led_register_led(priv, ret = iwl3945_led_register_led(priv,
&priv->led[IWL_LED_TRG_ASSOC], &priv->led[IWL_LED_TRG_ASSOC],
IWL_LED_TRG_ASSOC, 0, IWL_LED_TRG_ASSOC, 0, trigger);
name, trigger);
/* for assoc always turn led on */ /* for assoc always turn led on */
priv->led[IWL_LED_TRG_ASSOC].led_on = iwl3945_led_on; priv->led[IWL_LED_TRG_ASSOC].led_on = iwl3945_led_on;
priv->led[IWL_LED_TRG_ASSOC].led_off = iwl3945_led_on; priv->led[IWL_LED_TRG_ASSOC].led_off = iwl3945_led_on;
...@@ -349,14 +350,13 @@ int iwl3945_led_register(struct iwl3945_priv *priv) ...@@ -349,14 +350,13 @@ int iwl3945_led_register(struct iwl3945_priv *priv)
goto exit_fail; goto exit_fail;
trigger = ieee80211_get_rx_led_name(priv->hw); trigger = ieee80211_get_rx_led_name(priv->hw);
snprintf(name, sizeof(name), "iwl-%s:RX", snprintf(priv->led[IWL_LED_TRG_RX].name,
sizeof(priv->led[IWL_LED_TRG_RX].name), "iwl-%s:RX",
wiphy_name(priv->hw->wiphy)); wiphy_name(priv->hw->wiphy));
ret = iwl3945_led_register_led(priv, ret = iwl3945_led_register_led(priv,
&priv->led[IWL_LED_TRG_RX], &priv->led[IWL_LED_TRG_RX],
IWL_LED_TRG_RX, 0, IWL_LED_TRG_RX, 0, trigger);
name, trigger);
priv->led[IWL_LED_TRG_RX].led_on = iwl3945_led_associated; priv->led[IWL_LED_TRG_RX].led_on = iwl3945_led_associated;
priv->led[IWL_LED_TRG_RX].led_off = iwl3945_led_associated; priv->led[IWL_LED_TRG_RX].led_off = iwl3945_led_associated;
...@@ -366,13 +366,14 @@ int iwl3945_led_register(struct iwl3945_priv *priv) ...@@ -366,13 +366,14 @@ int iwl3945_led_register(struct iwl3945_priv *priv)
goto exit_fail; goto exit_fail;
trigger = ieee80211_get_tx_led_name(priv->hw); trigger = ieee80211_get_tx_led_name(priv->hw);
snprintf(name, sizeof(name), "iwl-%s:TX", snprintf(priv->led[IWL_LED_TRG_TX].name,
sizeof(priv->led[IWL_LED_TRG_TX].name), "iwl-%s:TX",
wiphy_name(priv->hw->wiphy)); wiphy_name(priv->hw->wiphy));
ret = iwl3945_led_register_led(priv, ret = iwl3945_led_register_led(priv,
&priv->led[IWL_LED_TRG_TX], &priv->led[IWL_LED_TRG_TX],
IWL_LED_TRG_TX, 0, IWL_LED_TRG_TX, 0, trigger);
name, trigger);
priv->led[IWL_LED_TRG_TX].led_on = iwl3945_led_associated; priv->led[IWL_LED_TRG_TX].led_on = iwl3945_led_associated;
priv->led[IWL_LED_TRG_TX].led_off = iwl3945_led_associated; priv->led[IWL_LED_TRG_TX].led_off = iwl3945_led_associated;
priv->led[IWL_LED_TRG_TX].led_pattern = iwl3945_led_pattern; priv->led[IWL_LED_TRG_TX].led_pattern = iwl3945_led_pattern;
......
...@@ -50,6 +50,7 @@ enum led_type { ...@@ -50,6 +50,7 @@ enum led_type {
struct iwl3945_led { struct iwl3945_led {
struct iwl3945_priv *priv; struct iwl3945_priv *priv;
struct led_classdev led_dev; struct led_classdev led_dev;
char name[32];
int (*led_on) (struct iwl3945_priv *priv, int led_id); int (*led_on) (struct iwl3945_priv *priv, int led_id);
int (*led_off) (struct iwl3945_priv *priv, int led_id); int (*led_off) (struct iwl3945_priv *priv, int led_id);
......
...@@ -795,8 +795,7 @@ static void iwl3945_rx_reply_rx(struct iwl3945_priv *priv, ...@@ -795,8 +795,7 @@ static void iwl3945_rx_reply_rx(struct iwl3945_priv *priv,
struct ieee80211_mgmt *mgmt = struct ieee80211_mgmt *mgmt =
(struct ieee80211_mgmt *)header; (struct ieee80211_mgmt *)header;
__le32 *pos; __le32 *pos;
pos = pos = (__le32 *)&mgmt->u.beacon.
(__le32 *) & mgmt->u.beacon.
timestamp; timestamp;
priv->timestamp0 = le32_to_cpu(pos[0]); priv->timestamp0 = le32_to_cpu(pos[0]);
priv->timestamp1 = le32_to_cpu(pos[1]); priv->timestamp1 = le32_to_cpu(pos[1]);
...@@ -1509,7 +1508,7 @@ static int iwl3945_hw_reg_adjust_power_by_temp(int new_reading, int old_reading) ...@@ -1509,7 +1508,7 @@ static int iwl3945_hw_reg_adjust_power_by_temp(int new_reading, int old_reading)
*/ */
static inline int iwl3945_hw_reg_temp_out_of_range(int temperature) static inline int iwl3945_hw_reg_temp_out_of_range(int temperature)
{ {
return (((temperature < -260) || (temperature > 25)) ? 1 : 0); return ((temperature < -260) || (temperature > 25)) ? 1 : 0;
} }
int iwl3945_hw_get_temperature(struct iwl3945_priv *priv) int iwl3945_hw_get_temperature(struct iwl3945_priv *priv)
...@@ -2630,7 +2629,7 @@ unsigned int iwl3945_hw_get_beacon_cmd(struct iwl3945_priv *priv, ...@@ -2630,7 +2629,7 @@ unsigned int iwl3945_hw_get_beacon_cmd(struct iwl3945_priv *priv,
tx_beacon_cmd->tx.supp_rates[1] = tx_beacon_cmd->tx.supp_rates[1] =
(IWL_CCK_BASIC_RATES_MASK & 0xF); (IWL_CCK_BASIC_RATES_MASK & 0xF);
return (sizeof(struct iwl3945_tx_beacon_cmd) + frame_size); return sizeof(struct iwl3945_tx_beacon_cmd) + frame_size;
} }
void iwl3945_hw_rx_handler_setup(struct iwl3945_priv *priv) void iwl3945_hw_rx_handler_setup(struct iwl3945_priv *priv)
......
...@@ -341,39 +341,6 @@ static int iwl4965_eeprom_check_version(struct iwl_priv *priv) ...@@ -341,39 +341,6 @@ static int iwl4965_eeprom_check_version(struct iwl_priv *priv)
return -EINVAL; return -EINVAL;
} }
int iwl4965_set_pwr_src(struct iwl_priv *priv, enum iwl_pwr_src src)
{
int ret;
unsigned long flags;
spin_lock_irqsave(&priv->lock, flags);
ret = iwl_grab_nic_access(priv);
if (ret) {
spin_unlock_irqrestore(&priv->lock, flags);
return ret;
}
if (src == IWL_PWR_SRC_VAUX) {
u32 val;
ret = pci_read_config_dword(priv->pci_dev, PCI_POWER_SOURCE,
&val);
if (val & PCI_CFG_PMC_PME_FROM_D3COLD_SUPPORT) {
iwl_set_bits_mask_prph(priv, APMG_PS_CTRL_REG,
APMG_PS_CTRL_VAL_PWR_SRC_VAUX,
~APMG_PS_CTRL_MSK_PWR_SRC);
}
} else {
iwl_set_bits_mask_prph(priv, APMG_PS_CTRL_REG,
APMG_PS_CTRL_VAL_PWR_SRC_VMAIN,
~APMG_PS_CTRL_MSK_PWR_SRC);
}
iwl_release_nic_access(priv);
spin_unlock_irqrestore(&priv->lock, flags);
return ret;
}
/* /*
* Activate/Deactivat Tx DMA/FIFO channels according tx fifos mask * Activate/Deactivat Tx DMA/FIFO channels according tx fifos mask
...@@ -875,18 +842,6 @@ static int iwl4965_hw_set_hw_params(struct iwl_priv *priv) ...@@ -875,18 +842,6 @@ static int iwl4965_hw_set_hw_params(struct iwl_priv *priv)
return 0; return 0;
} }
/* set card power command */
static int iwl4965_set_power(struct iwl_priv *priv,
void *cmd)
{
int ret = 0;
ret = iwl_send_cmd_pdu_async(priv, POWER_TABLE_CMD,
sizeof(struct iwl4965_powertable_cmd),
cmd, NULL);
return ret;
}
static s32 iwl4965_math_div_round(s32 num, s32 denom, s32 *res) static s32 iwl4965_math_div_round(s32 num, s32 denom, s32 *res)
{ {
s32 sign = 1; s32 sign = 1;
...@@ -1560,11 +1515,11 @@ static int iwl4965_fill_txpower_tbl(struct iwl_priv *priv, u8 band, u16 channel, ...@@ -1560,11 +1515,11 @@ static int iwl4965_fill_txpower_tbl(struct iwl_priv *priv, u8 band, u16 channel,
c, atten_value, power_index, c, atten_value, power_index,
tx_power.s.radio_tx_gain[c], tx_power.s.radio_tx_gain[c],
tx_power.s.dsp_predis_atten[c]); tx_power.s.dsp_predis_atten[c]);
}/* for each chain */ } /* for each chain */
tx_power_tbl->power_tbl[i].dw = cpu_to_le32(tx_power.dw); tx_power_tbl->power_tbl[i].dw = cpu_to_le32(tx_power.dw);
}/* for each rate */ } /* for each rate */
return 0; return 0;
} }
...@@ -1701,38 +1656,6 @@ static int iwl4965_shared_mem_rx_idx(struct iwl_priv *priv) ...@@ -1701,38 +1656,6 @@ static int iwl4965_shared_mem_rx_idx(struct iwl_priv *priv)
return le32_to_cpu(s->rb_closed) & 0xFFF; return le32_to_cpu(s->rb_closed) & 0xFFF;
} }
unsigned int iwl4965_hw_get_beacon_cmd(struct iwl_priv *priv,
struct iwl_frame *frame, u8 rate)
{
struct iwl4965_tx_beacon_cmd *tx_beacon_cmd;
unsigned int frame_size;
tx_beacon_cmd = &frame->u.beacon;
memset(tx_beacon_cmd, 0, sizeof(*tx_beacon_cmd));
tx_beacon_cmd->tx.sta_id = priv->hw_params.bcast_sta_id;
tx_beacon_cmd->tx.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE;
frame_size = iwl4965_fill_beacon_frame(priv,
tx_beacon_cmd->frame,
iwl_bcast_addr,
sizeof(frame->u) - sizeof(*tx_beacon_cmd));
BUG_ON(frame_size > MAX_MPDU_SIZE);
tx_beacon_cmd->tx.len = cpu_to_le16((u16)frame_size);
if ((rate == IWL_RATE_1M_PLCP) || (rate >= IWL_RATE_2M_PLCP))
tx_beacon_cmd->tx.rate_n_flags =
iwl_hw_set_rate_n_flags(rate, RATE_MCS_CCK_MSK);
else
tx_beacon_cmd->tx.rate_n_flags =
iwl_hw_set_rate_n_flags(rate, 0);
tx_beacon_cmd->tx.tx_flags = (TX_CMD_FLG_SEQ_CTL_MSK |
TX_CMD_FLG_TSF_MSK | TX_CMD_FLG_STA_RATE_MSK);
return (sizeof(*tx_beacon_cmd) + frame_size);
}
static int iwl4965_alloc_shared_mem(struct iwl_priv *priv) static int iwl4965_alloc_shared_mem(struct iwl_priv *priv)
{ {
priv->shared_virt = pci_alloc_consistent(priv->pci_dev, priv->shared_virt = pci_alloc_consistent(priv->pci_dev,
...@@ -2079,39 +2002,6 @@ static int iwl4965_txq_agg_enable(struct iwl_priv *priv, int txq_id, ...@@ -2079,39 +2002,6 @@ static int iwl4965_txq_agg_enable(struct iwl_priv *priv, int txq_id,
return 0; return 0;
} }
int iwl4965_mac_ampdu_action(struct ieee80211_hw *hw,
enum ieee80211_ampdu_mlme_action action,
const u8 *addr, u16 tid, u16 *ssn)
{
struct iwl_priv *priv = hw->priv;
DECLARE_MAC_BUF(mac);
IWL_DEBUG_HT("A-MPDU action on addr %s tid %d\n",
print_mac(mac, addr), tid);
if (!(priv->cfg->sku & IWL_SKU_N))
return -EACCES;
switch (action) {
case IEEE80211_AMPDU_RX_START:
IWL_DEBUG_HT("start Rx\n");
return iwl_rx_agg_start(priv, addr, tid, *ssn);
case IEEE80211_AMPDU_RX_STOP:
IWL_DEBUG_HT("stop Rx\n");
return iwl_rx_agg_stop(priv, addr, tid);
case IEEE80211_AMPDU_TX_START:
IWL_DEBUG_HT("start Tx\n");
return iwl_tx_agg_start(priv, addr, tid, ssn);
case IEEE80211_AMPDU_TX_STOP:
IWL_DEBUG_HT("stop Tx\n");
return iwl_tx_agg_stop(priv, addr, tid);
default:
IWL_DEBUG_HT("unknown\n");
return -EINVAL;
break;
}
return 0;
}
static u16 iwl4965_get_hcmd_size(u8 cmd_id, u16 len) static u16 iwl4965_get_hcmd_size(u8 cmd_id, u16 len)
{ {
...@@ -2240,9 +2130,9 @@ static int iwl4965_tx_status_reply_tx(struct iwl_priv *priv, ...@@ -2240,9 +2130,9 @@ static int iwl4965_tx_status_reply_tx(struct iwl_priv *priv,
bitmap = bitmap << sh; bitmap = bitmap << sh;
sh = 0; sh = 0;
} }
bitmap |= (1 << sh); bitmap |= 1ULL << sh;
IWL_DEBUG_TX_REPLY("start=%d bitmap=0x%x\n", IWL_DEBUG_TX_REPLY("start=%d bitmap=0x%llx\n",
start, (u32)(bitmap & 0xFFFFFFFF)); start, (unsigned long long)bitmap);
} }
agg->bitmap = bitmap; agg->bitmap = bitmap;
...@@ -2368,6 +2258,40 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv, ...@@ -2368,6 +2258,40 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv,
IWL_ERROR("TODO: Implement Tx ABORT REQUIRED!!!\n"); IWL_ERROR("TODO: Implement Tx ABORT REQUIRED!!!\n");
} }
static int iwl4965_calc_rssi(struct iwl_priv *priv,
struct iwl_rx_phy_res *rx_resp)
{
/* data from PHY/DSP regarding signal strength, etc.,
* contents are always there, not configurable by host. */
struct iwl4965_rx_non_cfg_phy *ncphy =
(struct iwl4965_rx_non_cfg_phy *)rx_resp->non_cfg_phy_buf;
u32 agc = (le16_to_cpu(ncphy->agc_info) & IWL49_AGC_DB_MASK)
>> IWL49_AGC_DB_POS;
u32 valid_antennae =
(le16_to_cpu(rx_resp->phy_flags) & IWL49_RX_PHY_FLAGS_ANTENNAE_MASK)
>> IWL49_RX_PHY_FLAGS_ANTENNAE_OFFSET;
u8 max_rssi = 0;
u32 i;
/* Find max rssi among 3 possible receivers.
* These values are measured by the digital signal processor (DSP).
* They should stay fairly constant even as the signal strength varies,
* if the radio's automatic gain control (AGC) is working right.
* AGC value (see below) will provide the "interesting" info. */
for (i = 0; i < 3; i++)
if (valid_antennae & (1 << i))
max_rssi = max(ncphy->rssi_info[i << 1], max_rssi);
IWL_DEBUG_STATS("Rssi In A %d B %d C %d Max %d AGC dB %d\n",
ncphy->rssi_info[0], ncphy->rssi_info[2], ncphy->rssi_info[4],
max_rssi, agc);
/* dBm = max_rssi dB - agc dB - constant.
* Higher AGC (higher radio gain) means lower signal. */
return max_rssi - agc - IWL_RSSI_OFFSET;
}
/* Set up 4965-specific Rx frame reply handlers */ /* Set up 4965-specific Rx frame reply handlers */
static void iwl4965_rx_handler_setup(struct iwl_priv *priv) static void iwl4965_rx_handler_setup(struct iwl_priv *priv)
...@@ -2399,6 +2323,7 @@ static struct iwl_hcmd_utils_ops iwl4965_hcmd_utils = { ...@@ -2399,6 +2323,7 @@ static struct iwl_hcmd_utils_ops iwl4965_hcmd_utils = {
.chain_noise_reset = iwl4965_chain_noise_reset, .chain_noise_reset = iwl4965_chain_noise_reset,
.gain_computation = iwl4965_gain_computation, .gain_computation = iwl4965_gain_computation,
.rts_tx_cmd_flag = iwl4965_rts_tx_cmd_flag, .rts_tx_cmd_flag = iwl4965_rts_tx_cmd_flag,
.calc_rssi = iwl4965_calc_rssi,
}; };
static struct iwl_lib_ops iwl4965_lib = { static struct iwl_lib_ops iwl4965_lib = {
...@@ -2440,7 +2365,6 @@ static struct iwl_lib_ops iwl4965_lib = { ...@@ -2440,7 +2365,6 @@ static struct iwl_lib_ops iwl4965_lib = {
.check_version = iwl4965_eeprom_check_version, .check_version = iwl4965_eeprom_check_version,
.query_addr = iwlcore_eeprom_query_addr, .query_addr = iwlcore_eeprom_query_addr,
}, },
.set_power = iwl4965_set_power,
.send_tx_power = iwl4965_send_tx_power, .send_tx_power = iwl4965_send_tx_power,
.update_chain_flags = iwl4965_update_chain_flags, .update_chain_flags = iwl4965_update_chain_flags,
.temperature = iwl4965_temperature_calib, .temperature = iwl4965_temperature_calib,
......
...@@ -93,6 +93,13 @@ static int iwl5000_apm_init(struct iwl_priv *priv) ...@@ -93,6 +93,13 @@ static int iwl5000_apm_init(struct iwl_priv *priv)
iwl_set_bit(priv, CSR_GIO_CHICKEN_BITS, iwl_set_bit(priv, CSR_GIO_CHICKEN_BITS,
CSR_GIO_CHICKEN_BITS_REG_BIT_L1A_NO_L0S_RX); CSR_GIO_CHICKEN_BITS_REG_BIT_L1A_NO_L0S_RX);
/* Set FH wait treshold to maximum (HW error during stress W/A) */
iwl_set_bit(priv, CSR_DBG_HPET_MEM_REG, CSR_DBG_HPET_MEM_REG_VAL);
/* enable HAP INTA to move device L1a -> L0s */
iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG,
CSR_HW_IF_CONFIG_REG_BIT_HAP_WAKE_L1A);
iwl_set_bit(priv, CSR_ANA_PLL_CFG, CSR50_ANA_PLL_CFG_VAL); iwl_set_bit(priv, CSR_ANA_PLL_CFG, CSR50_ANA_PLL_CFG_VAL);
/* set "initialization complete" bit to move adapter /* set "initialization complete" bit to move adapter
...@@ -230,6 +237,16 @@ static void iwl5000_nic_config(struct iwl_priv *priv) ...@@ -230,6 +237,16 @@ static void iwl5000_nic_config(struct iwl_priv *priv)
CSR_HW_IF_CONFIG_REG_BIT_RADIO_SI | CSR_HW_IF_CONFIG_REG_BIT_RADIO_SI |
CSR_HW_IF_CONFIG_REG_BIT_MAC_SI); CSR_HW_IF_CONFIG_REG_BIT_MAC_SI);
/* W/A : NIC is stuck in a reset state after Early PCIe power off
* (PCIe power is lost before PERST# is asserted),
* causing ME FW to lose ownership and not being able to obtain it back.
*/
iwl_grab_nic_access(priv);
iwl_set_bits_mask_prph(priv, APMG_PS_CTRL_REG,
APMG_PS_CTRL_EARLY_PWR_OFF_RESET_DIS,
~APMG_PS_CTRL_EARLY_PWR_OFF_RESET_DIS);
iwl_release_nic_access(priv);
spin_unlock_irqrestore(&priv->lock, flags); spin_unlock_irqrestore(&priv->lock, flags);
} }
...@@ -924,8 +941,8 @@ static void iwl5000_txq_update_byte_cnt_tbl(struct iwl_priv *priv, ...@@ -924,8 +941,8 @@ static void iwl5000_txq_update_byte_cnt_tbl(struct iwl_priv *priv,
len = byte_cnt + IWL_TX_CRC_SIZE + IWL_TX_DELIMITER_SIZE; len = byte_cnt + IWL_TX_CRC_SIZE + IWL_TX_DELIMITER_SIZE;
if (txq_id != IWL_CMD_QUEUE_NUM) { if (txq_id != IWL_CMD_QUEUE_NUM) {
sta = txq->cmd[txq->q.write_ptr].cmd.tx.sta_id; sta = txq->cmd[txq->q.write_ptr]->cmd.tx.sta_id;
sec_ctl = txq->cmd[txq->q.write_ptr].cmd.tx.sec_ctl; sec_ctl = txq->cmd[txq->q.write_ptr]->cmd.tx.sec_ctl;
switch (sec_ctl & TX_CMD_SEC_MSK) { switch (sec_ctl & TX_CMD_SEC_MSK) {
case TX_CMD_SEC_CCM: case TX_CMD_SEC_CCM:
...@@ -964,7 +981,7 @@ static void iwl5000_txq_inval_byte_cnt_tbl(struct iwl_priv *priv, ...@@ -964,7 +981,7 @@ static void iwl5000_txq_inval_byte_cnt_tbl(struct iwl_priv *priv,
u8 sta = 0; u8 sta = 0;
if (txq_id != IWL_CMD_QUEUE_NUM) if (txq_id != IWL_CMD_QUEUE_NUM)
sta = txq->cmd[txq->q.read_ptr].cmd.tx.sta_id; sta = txq->cmd[txq->q.read_ptr]->cmd.tx.sta_id;
shared_data->queues_byte_cnt_tbls[txq_id].tfd_offset[txq->q.read_ptr]. shared_data->queues_byte_cnt_tbls[txq_id].tfd_offset[txq->q.read_ptr].
val = cpu_to_le16(1 | (sta << 12)); val = cpu_to_le16(1 | (sta << 12));
...@@ -1131,7 +1148,7 @@ static void iwl5000_txq_set_sched(struct iwl_priv *priv, u32 mask) ...@@ -1131,7 +1148,7 @@ static void iwl5000_txq_set_sched(struct iwl_priv *priv, u32 mask)
static inline u32 iwl5000_get_scd_ssn(struct iwl5000_tx_resp *tx_resp) static inline u32 iwl5000_get_scd_ssn(struct iwl5000_tx_resp *tx_resp)
{ {
return le32_to_cpup((__le32*)&tx_resp->status + return le32_to_cpup((__le32 *)&tx_resp->status +
tx_resp->frame_count) & MAX_SN; tx_resp->frame_count) & MAX_SN;
} }
...@@ -1228,9 +1245,9 @@ static int iwl5000_tx_status_reply_tx(struct iwl_priv *priv, ...@@ -1228,9 +1245,9 @@ static int iwl5000_tx_status_reply_tx(struct iwl_priv *priv,
bitmap = bitmap << sh; bitmap = bitmap << sh;
sh = 0; sh = 0;
} }
bitmap |= (1 << sh); bitmap |= 1ULL << sh;
IWL_DEBUG_TX_REPLY("start=%d bitmap=0x%x\n", IWL_DEBUG_TX_REPLY("start=%d bitmap=0x%llx\n",
start, (u32)(bitmap & 0xFFFFFFFF)); start, (unsigned long long)bitmap);
} }
agg->bitmap = bitmap; agg->bitmap = bitmap;
...@@ -1444,6 +1461,44 @@ static void iwl5000_temperature(struct iwl_priv *priv) ...@@ -1444,6 +1461,44 @@ static void iwl5000_temperature(struct iwl_priv *priv)
priv->temperature = le32_to_cpu(priv->statistics.general.temperature); priv->temperature = le32_to_cpu(priv->statistics.general.temperature);
} }
/* Calc max signal level (dBm) among 3 possible receivers */
static int iwl5000_calc_rssi(struct iwl_priv *priv,
struct iwl_rx_phy_res *rx_resp)
{
/* data from PHY/DSP regarding signal strength, etc.,
* contents are always there, not configurable by host
*/
struct iwl5000_non_cfg_phy *ncphy =
(struct iwl5000_non_cfg_phy *)rx_resp->non_cfg_phy_buf;
u32 val, rssi_a, rssi_b, rssi_c, max_rssi;
u8 agc;
val = le32_to_cpu(ncphy->non_cfg_phy[IWL50_RX_RES_AGC_IDX]);
agc = (val & IWL50_OFDM_AGC_MSK) >> IWL50_OFDM_AGC_BIT_POS;
/* Find max rssi among 3 possible receivers.
* These values are measured by the digital signal processor (DSP).
* They should stay fairly constant even as the signal strength varies,
* if the radio's automatic gain control (AGC) is working right.
* AGC value (see below) will provide the "interesting" info.
*/
val = le32_to_cpu(ncphy->non_cfg_phy[IWL50_RX_RES_RSSI_AB_IDX]);
rssi_a = (val & IWL50_OFDM_RSSI_A_MSK) >> IWL50_OFDM_RSSI_A_BIT_POS;
rssi_b = (val & IWL50_OFDM_RSSI_B_MSK) >> IWL50_OFDM_RSSI_B_BIT_POS;
val = le32_to_cpu(ncphy->non_cfg_phy[IWL50_RX_RES_RSSI_C_IDX]);
rssi_c = (val & IWL50_OFDM_RSSI_C_MSK) >> IWL50_OFDM_RSSI_C_BIT_POS;
max_rssi = max_t(u32, rssi_a, rssi_b);
max_rssi = max_t(u32, max_rssi, rssi_c);
IWL_DEBUG_STATS("Rssi In A %d B %d C %d Max %d AGC dB %d\n",
rssi_a, rssi_b, rssi_c, max_rssi, agc);
/* dBm = max_rssi dB - agc dB - constant.
* Higher AGC (higher radio gain) means lower signal. */
return max_rssi - agc - IWL_RSSI_OFFSET;
}
static struct iwl_hcmd_ops iwl5000_hcmd = { static struct iwl_hcmd_ops iwl5000_hcmd = {
.rxon_assoc = iwl5000_send_rxon_assoc, .rxon_assoc = iwl5000_send_rxon_assoc,
}; };
...@@ -1454,6 +1509,7 @@ static struct iwl_hcmd_utils_ops iwl5000_hcmd_utils = { ...@@ -1454,6 +1509,7 @@ static struct iwl_hcmd_utils_ops iwl5000_hcmd_utils = {
.gain_computation = iwl5000_gain_computation, .gain_computation = iwl5000_gain_computation,
.chain_noise_reset = iwl5000_chain_noise_reset, .chain_noise_reset = iwl5000_chain_noise_reset,
.rts_tx_cmd_flag = iwl5000_rts_tx_cmd_flag, .rts_tx_cmd_flag = iwl5000_rts_tx_cmd_flag,
.calc_rssi = iwl5000_calc_rssi,
}; };
static struct iwl_lib_ops iwl5000_lib = { static struct iwl_lib_ops iwl5000_lib = {
...@@ -1474,6 +1530,7 @@ static struct iwl_lib_ops iwl5000_lib = { ...@@ -1474,6 +1530,7 @@ static struct iwl_lib_ops iwl5000_lib = {
.alive_notify = iwl5000_alive_notify, .alive_notify = iwl5000_alive_notify,
.send_tx_power = iwl5000_send_tx_power, .send_tx_power = iwl5000_send_tx_power,
.temperature = iwl5000_temperature, .temperature = iwl5000_temperature,
.update_chain_flags = iwl4965_update_chain_flags,
.apm_ops = { .apm_ops = {
.init = iwl5000_apm_init, .init = iwl5000_apm_init,
.reset = iwl5000_apm_reset, .reset = iwl5000_apm_reset,
......
...@@ -24,8 +24,8 @@ ...@@ -24,8 +24,8 @@
* *
*****************************************************************************/ *****************************************************************************/
#ifndef __iwl_4965_rs_h__ #ifndef __iwl_agn_rs_h__
#define __iwl_4965_rs_h__ #define __iwl_agn_rs_h__
#include "iwl-dev.h" #include "iwl-dev.h"
...@@ -88,7 +88,7 @@ enum { ...@@ -88,7 +88,7 @@ enum {
#define IWL_RATE_5M_MASK (1 << IWL_RATE_5M_INDEX) #define IWL_RATE_5M_MASK (1 << IWL_RATE_5M_INDEX)
#define IWL_RATE_11M_MASK (1 << IWL_RATE_11M_INDEX) #define IWL_RATE_11M_MASK (1 << IWL_RATE_11M_INDEX)
/* 4965 uCode API values for legacy bit rates, both OFDM and CCK */ /* uCode API values for legacy bit rates, both OFDM and CCK */
enum { enum {
IWL_RATE_6M_PLCP = 13, IWL_RATE_6M_PLCP = 13,
IWL_RATE_9M_PLCP = 15, IWL_RATE_9M_PLCP = 15,
...@@ -107,7 +107,7 @@ enum { ...@@ -107,7 +107,7 @@ enum {
/*FIXME:RS:add IWL_RATE_LEGACY_INVM_PLCP = 0,*/ /*FIXME:RS:add IWL_RATE_LEGACY_INVM_PLCP = 0,*/
}; };
/* 4965 uCode API values for OFDM high-throughput (HT) bit rates */ /* uCode API values for OFDM high-throughput (HT) bit rates */
enum { enum {
IWL_RATE_SISO_6M_PLCP = 0, IWL_RATE_SISO_6M_PLCP = 0,
IWL_RATE_SISO_12M_PLCP = 1, IWL_RATE_SISO_12M_PLCP = 1,
...@@ -286,15 +286,6 @@ static inline u8 iwl4965_get_prev_ieee_rate(u8 rate_index) ...@@ -286,15 +286,6 @@ static inline u8 iwl4965_get_prev_ieee_rate(u8 rate_index)
return rate; return rate;
} }
/**
* iwl4965_fill_rs_info - Fill an output text buffer with the rate representation
*
* NOTE: This is provided as a quick mechanism for a user to visualize
* the performance of the rate control algorithm and is not meant to be
* parsed software.
*/
extern int iwl4965_fill_rs_info(struct ieee80211_hw *, char *buf, u8 sta_id);
/** /**
* iwl4965_rate_control_register - Register the rate control algorithm callbacks * iwl4965_rate_control_register - Register the rate control algorithm callbacks
* *
...@@ -305,7 +296,7 @@ extern int iwl4965_fill_rs_info(struct ieee80211_hw *, char *buf, u8 sta_id); ...@@ -305,7 +296,7 @@ extern int iwl4965_fill_rs_info(struct ieee80211_hw *, char *buf, u8 sta_id);
* ieee80211_register_hw * ieee80211_register_hw
* *
*/ */
extern int iwl4965_rate_control_register(void); extern int iwlagn_rate_control_register(void);
/** /**
* iwl4965_rate_control_unregister - Unregister the rate control callbacks * iwl4965_rate_control_unregister - Unregister the rate control callbacks
...@@ -313,6 +304,6 @@ extern int iwl4965_rate_control_register(void); ...@@ -313,6 +304,6 @@ extern int iwl4965_rate_control_register(void);
* This should be called after calling ieee80211_unregister_hw, but before * This should be called after calling ieee80211_unregister_hw, but before
* the driver is unloaded. * the driver is unloaded.
*/ */
extern void iwl4965_rate_control_unregister(void); extern void iwlagn_rate_control_unregister(void);
#endif #endif /* __iwl_agn__rs__ */
...@@ -65,7 +65,7 @@ ...@@ -65,7 +65,7 @@
* NOTE: DRV_NAME is defined in iwlwifi.h for use by iwl-debug.h and printk * NOTE: DRV_NAME is defined in iwlwifi.h for use by iwl-debug.h and printk
*/ */
#define DRV_DESCRIPTION "Intel(R) Wireless WiFi Link 4965AGN driver for Linux" #define DRV_DESCRIPTION "Intel(R) Wireless WiFi Link AGN driver for Linux"
#ifdef CONFIG_IWLWIFI_DEBUG #ifdef CONFIG_IWLWIFI_DEBUG
#define VD "d" #define VD "d"
...@@ -73,7 +73,7 @@ ...@@ -73,7 +73,7 @@
#define VD #define VD
#endif #endif
#ifdef CONFIG_IWL4965_SPECTRUM_MEASUREMENT #ifdef CONFIG_IWLAGN_SPECTRUM_MEASUREMENT
#define VS "s" #define VS "s"
#else #else
#define VS #define VS
...@@ -86,6 +86,7 @@ MODULE_DESCRIPTION(DRV_DESCRIPTION); ...@@ -86,6 +86,7 @@ MODULE_DESCRIPTION(DRV_DESCRIPTION);
MODULE_VERSION(DRV_VERSION); MODULE_VERSION(DRV_VERSION);
MODULE_AUTHOR(DRV_COPYRIGHT); MODULE_AUTHOR(DRV_COPYRIGHT);
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
MODULE_ALIAS("iwl4965");
/*************** STATION TABLE MANAGEMENT **** /*************** STATION TABLE MANAGEMENT ****
* mac80211 should be examined to determine if sta_info is duplicating * mac80211 should be examined to determine if sta_info is duplicating
...@@ -444,11 +445,10 @@ static void iwl_free_frame(struct iwl_priv *priv, struct iwl_frame *frame) ...@@ -444,11 +445,10 @@ static void iwl_free_frame(struct iwl_priv *priv, struct iwl_frame *frame)
list_add(&frame->list, &priv->free_frames); list_add(&frame->list, &priv->free_frames);
} }
unsigned int iwl4965_fill_beacon_frame(struct iwl_priv *priv, static unsigned int iwl_fill_beacon_frame(struct iwl_priv *priv,
struct ieee80211_hdr *hdr, struct ieee80211_hdr *hdr,
const u8 *dest, int left) const u8 *dest, int left)
{ {
if (!iwl_is_associated(priv) || !priv->ibss_beacon || if (!iwl_is_associated(priv) || !priv->ibss_beacon ||
((priv->iw_mode != IEEE80211_IF_TYPE_IBSS) && ((priv->iw_mode != IEEE80211_IF_TYPE_IBSS) &&
(priv->iw_mode != IEEE80211_IF_TYPE_AP))) (priv->iw_mode != IEEE80211_IF_TYPE_AP)))
...@@ -487,6 +487,38 @@ static u8 iwl4965_rate_get_lowest_plcp(struct iwl_priv *priv) ...@@ -487,6 +487,38 @@ static u8 iwl4965_rate_get_lowest_plcp(struct iwl_priv *priv)
return IWL_RATE_6M_PLCP; return IWL_RATE_6M_PLCP;
} }
unsigned int iwl4965_hw_get_beacon_cmd(struct iwl_priv *priv,
struct iwl_frame *frame, u8 rate)
{
struct iwl_tx_beacon_cmd *tx_beacon_cmd;
unsigned int frame_size;
tx_beacon_cmd = &frame->u.beacon;
memset(tx_beacon_cmd, 0, sizeof(*tx_beacon_cmd));
tx_beacon_cmd->tx.sta_id = priv->hw_params.bcast_sta_id;
tx_beacon_cmd->tx.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE;
frame_size = iwl_fill_beacon_frame(priv, tx_beacon_cmd->frame,
iwl_bcast_addr,
sizeof(frame->u) - sizeof(*tx_beacon_cmd));
BUG_ON(frame_size > MAX_MPDU_SIZE);
tx_beacon_cmd->tx.len = cpu_to_le16((u16)frame_size);
if ((rate == IWL_RATE_1M_PLCP) || (rate >= IWL_RATE_2M_PLCP))
tx_beacon_cmd->tx.rate_n_flags =
iwl_hw_set_rate_n_flags(rate, RATE_MCS_CCK_MSK);
else
tx_beacon_cmd->tx.rate_n_flags =
iwl_hw_set_rate_n_flags(rate, 0);
tx_beacon_cmd->tx.tx_flags = TX_CMD_FLG_SEQ_CTL_MSK |
TX_CMD_FLG_TSF_MSK |
TX_CMD_FLG_STA_RATE_MSK;
return sizeof(*tx_beacon_cmd) + frame_size;
}
static int iwl4965_send_beacon_cmd(struct iwl_priv *priv) static int iwl4965_send_beacon_cmd(struct iwl_priv *priv)
{ {
struct iwl_frame *frame; struct iwl_frame *frame;
...@@ -608,7 +640,6 @@ static void iwl_activate_qos(struct iwl_priv *priv, u8 force) ...@@ -608,7 +640,6 @@ static void iwl_activate_qos(struct iwl_priv *priv, u8 force)
} }
#define MAX_UCODE_BEACON_INTERVAL 4096 #define MAX_UCODE_BEACON_INTERVAL 4096
#define INTEL_CONN_LISTEN_INTERVAL __constant_cpu_to_le16(0xA)
static __le16 iwl4965_adjust_beacon_interval(u16 beacon_val) static __le16 iwl4965_adjust_beacon_interval(u16 beacon_val)
{ {
...@@ -638,7 +669,7 @@ static void iwl4965_setup_rxon_timing(struct iwl_priv *priv) ...@@ -638,7 +669,7 @@ static void iwl4965_setup_rxon_timing(struct iwl_priv *priv)
priv->rxon_timing.timestamp.dw[0] = priv->rxon_timing.timestamp.dw[0] =
cpu_to_le32(priv->timestamp & 0xFFFFFFFF); cpu_to_le32(priv->timestamp & 0xFFFFFFFF);
priv->rxon_timing.listen_interval = INTEL_CONN_LISTEN_INTERVAL; priv->rxon_timing.listen_interval = cpu_to_le16(conf->listen_interval);
tsf = priv->timestamp; tsf = priv->timestamp;
...@@ -853,7 +884,7 @@ static void iwl4965_set_rate(struct iwl_priv *priv) ...@@ -853,7 +884,7 @@ static void iwl4965_set_rate(struct iwl_priv *priv)
(IWL_OFDM_BASIC_RATES_MASK >> IWL_FIRST_OFDM_RATE) & 0xFF; (IWL_OFDM_BASIC_RATES_MASK >> IWL_FIRST_OFDM_RATE) & 0xFF;
} }
#ifdef CONFIG_IWL4965_SPECTRUM_MEASUREMENT #ifdef CONFIG_IWLAGN_SPECTRUM_MEASUREMENT
#include "iwl-spectrum.h" #include "iwl-spectrum.h"
...@@ -1057,7 +1088,7 @@ static void iwl4965_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) ...@@ -1057,7 +1088,7 @@ static void iwl4965_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
static void iwl4965_rx_spectrum_measure_notif(struct iwl_priv *priv, static void iwl4965_rx_spectrum_measure_notif(struct iwl_priv *priv,
struct iwl_rx_mem_buffer *rxb) struct iwl_rx_mem_buffer *rxb)
{ {
#ifdef CONFIG_IWL4965_SPECTRUM_MEASUREMENT #ifdef CONFIG_IWLAGN_SPECTRUM_MEASUREMENT
struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data; struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
struct iwl4965_spectrum_notification *report = &(pkt->u.spectrum_notif); struct iwl4965_spectrum_notification *report = &(pkt->u.spectrum_notif);
...@@ -1231,6 +1262,37 @@ static void iwl4965_rx_card_state_notif(struct iwl_priv *priv, ...@@ -1231,6 +1262,37 @@ static void iwl4965_rx_card_state_notif(struct iwl_priv *priv,
wake_up_interruptible(&priv->wait_command_queue); wake_up_interruptible(&priv->wait_command_queue);
} }
int iwl4965_set_pwr_src(struct iwl_priv *priv, enum iwl_pwr_src src)
{
int ret;
unsigned long flags;
spin_lock_irqsave(&priv->lock, flags);
ret = iwl_grab_nic_access(priv);
if (ret)
goto err;
if (src == IWL_PWR_SRC_VAUX) {
u32 val;
ret = pci_read_config_dword(priv->pci_dev, PCI_POWER_SOURCE,
&val);
if (val & PCI_CFG_PMC_PME_FROM_D3COLD_SUPPORT)
iwl_set_bits_mask_prph(priv, APMG_PS_CTRL_REG,
APMG_PS_CTRL_VAL_PWR_SRC_VAUX,
~APMG_PS_CTRL_MSK_PWR_SRC);
} else {
iwl_set_bits_mask_prph(priv, APMG_PS_CTRL_REG,
APMG_PS_CTRL_VAL_PWR_SRC_VMAIN,
~APMG_PS_CTRL_MSK_PWR_SRC);
}
iwl_release_nic_access(priv);
err:
spin_unlock_irqrestore(&priv->lock, flags);
return ret;
}
/** /**
* iwl4965_setup_rx_handlers - Initialize Rx handler callbacks * iwl4965_setup_rx_handlers - Initialize Rx handler callbacks
* *
...@@ -2170,17 +2232,16 @@ static int __iwl4965_up(struct iwl_priv *priv) ...@@ -2170,17 +2232,16 @@ static int __iwl4965_up(struct iwl_priv *priv)
} }
/* If platform's RF_KILL switch is NOT set to KILL */ /* If platform's RF_KILL switch is NOT set to KILL */
if (iwl_read32(priv, CSR_GP_CNTRL) & if (iwl_read32(priv, CSR_GP_CNTRL) & CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW)
CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW)
clear_bit(STATUS_RF_KILL_HW, &priv->status); clear_bit(STATUS_RF_KILL_HW, &priv->status);
else else
set_bit(STATUS_RF_KILL_HW, &priv->status); set_bit(STATUS_RF_KILL_HW, &priv->status);
if (!test_bit(STATUS_IN_SUSPEND, &priv->status) && if (iwl_is_rfkill(priv)) {
iwl_is_rfkill(priv)) { iwl4965_enable_interrupts(priv);
IWL_WARNING("Radio disabled by %s RF Kill switch\n", IWL_WARNING("Radio disabled by %s RF Kill switch\n",
test_bit(STATUS_RF_KILL_HW, &priv->status) ? "HW" : "SW"); test_bit(STATUS_RF_KILL_HW, &priv->status) ? "HW" : "SW");
return -ENODEV; return 0;
} }
iwl_write32(priv, CSR_INT, 0xFFFFFFFF); iwl_write32(priv, CSR_INT, 0xFFFFFFFF);
...@@ -2216,11 +2277,6 @@ static int __iwl4965_up(struct iwl_priv *priv) ...@@ -2216,11 +2277,6 @@ static int __iwl4965_up(struct iwl_priv *priv)
memcpy(priv->ucode_data_backup.v_addr, priv->ucode_data.v_addr, memcpy(priv->ucode_data_backup.v_addr, priv->ucode_data.v_addr,
priv->ucode_data.len); priv->ucode_data.len);
/* We return success when we resume from suspend and rf_kill is on. */
if (test_bit(STATUS_RF_KILL_HW, &priv->status) ||
test_bit(STATUS_RF_KILL_SW, &priv->status))
return 0;
for (i = 0; i < MAX_HW_RESTARTS; i++) { for (i = 0; i < MAX_HW_RESTARTS; i++) {
iwl_clear_stations_table(priv); iwl_clear_stations_table(priv);
...@@ -2415,7 +2471,7 @@ static void iwl4965_post_associate(struct iwl_priv *priv) ...@@ -2415,7 +2471,7 @@ static void iwl4965_post_associate(struct iwl_priv *priv)
unsigned long flags; unsigned long flags;
if (priv->iw_mode == IEEE80211_IF_TYPE_AP) { if (priv->iw_mode == IEEE80211_IF_TYPE_AP) {
IWL_ERROR("%s Should not be called in AP mode\n", __FUNCTION__); IWL_ERROR("%s Should not be called in AP mode\n", __func__);
return; return;
} }
...@@ -2491,7 +2547,7 @@ static void iwl4965_post_associate(struct iwl_priv *priv) ...@@ -2491,7 +2547,7 @@ static void iwl4965_post_associate(struct iwl_priv *priv)
default: default:
IWL_ERROR("%s Should not be called in %d mode\n", IWL_ERROR("%s Should not be called in %d mode\n",
__FUNCTION__, priv->iw_mode); __func__, priv->iw_mode);
break; break;
} }
...@@ -2589,6 +2645,9 @@ static int iwl4965_mac_start(struct ieee80211_hw *hw) ...@@ -2589,6 +2645,9 @@ static int iwl4965_mac_start(struct ieee80211_hw *hw)
if (ret) if (ret)
goto out_release_irq; goto out_release_irq;
if (iwl_is_rfkill(priv))
goto out;
IWL_DEBUG_INFO("Start UP work done.\n"); IWL_DEBUG_INFO("Start UP work done.\n");
if (test_bit(STATUS_IN_SUSPEND, &priv->status)) if (test_bit(STATUS_IN_SUSPEND, &priv->status))
...@@ -2608,6 +2667,7 @@ static int iwl4965_mac_start(struct ieee80211_hw *hw) ...@@ -2608,6 +2667,7 @@ static int iwl4965_mac_start(struct ieee80211_hw *hw)
} }
} }
out:
priv->is_open = 1; priv->is_open = 1;
IWL_DEBUG_MAC80211("leave\n"); IWL_DEBUG_MAC80211("leave\n");
return 0; return 0;
...@@ -2773,6 +2833,7 @@ static int iwl4965_mac_config(struct ieee80211_hw *hw, struct ieee80211_conf *co ...@@ -2773,6 +2833,7 @@ static int iwl4965_mac_config(struct ieee80211_hw *hw, struct ieee80211_conf *co
spin_lock_irqsave(&priv->lock, flags); spin_lock_irqsave(&priv->lock, flags);
/* if we are switching from ht to 2.4 clear flags /* if we are switching from ht to 2.4 clear flags
* from any ht related info since 2.4 does not * from any ht related info since 2.4 does not
* support ht */ * support ht */
...@@ -3102,6 +3163,7 @@ static void iwl4965_bss_info_changed(struct ieee80211_hw *hw, ...@@ -3102,6 +3163,7 @@ static void iwl4965_bss_info_changed(struct ieee80211_hw *hw,
if (bss_conf->assoc) { if (bss_conf->assoc) {
priv->assoc_id = bss_conf->aid; priv->assoc_id = bss_conf->aid;
priv->beacon_int = bss_conf->beacon_int; priv->beacon_int = bss_conf->beacon_int;
priv->power_data.dtim_period = bss_conf->dtim_period;
priv->timestamp = bss_conf->timestamp; priv->timestamp = bss_conf->timestamp;
priv->assoc_capability = bss_conf->assoc_capability; priv->assoc_capability = bss_conf->assoc_capability;
priv->next_scan_jiffies = jiffies + priv->next_scan_jiffies = jiffies +
...@@ -3345,6 +3407,39 @@ static int iwl4965_mac_conf_tx(struct ieee80211_hw *hw, u16 queue, ...@@ -3345,6 +3407,39 @@ static int iwl4965_mac_conf_tx(struct ieee80211_hw *hw, u16 queue,
return 0; return 0;
} }
static int iwl4965_mac_ampdu_action(struct ieee80211_hw *hw,
enum ieee80211_ampdu_mlme_action action,
const u8 *addr, u16 tid, u16 *ssn)
{
struct iwl_priv *priv = hw->priv;
DECLARE_MAC_BUF(mac);
IWL_DEBUG_HT("A-MPDU action on addr %s tid %d\n",
print_mac(mac, addr), tid);
if (!(priv->cfg->sku & IWL_SKU_N))
return -EACCES;
switch (action) {
case IEEE80211_AMPDU_RX_START:
IWL_DEBUG_HT("start Rx\n");
return iwl_rx_agg_start(priv, addr, tid, *ssn);
case IEEE80211_AMPDU_RX_STOP:
IWL_DEBUG_HT("stop Rx\n");
return iwl_rx_agg_stop(priv, addr, tid);
case IEEE80211_AMPDU_TX_START:
IWL_DEBUG_HT("start Tx\n");
return iwl_tx_agg_start(priv, addr, tid, ssn);
case IEEE80211_AMPDU_TX_STOP:
IWL_DEBUG_HT("stop Tx\n");
return iwl_tx_agg_stop(priv, addr, tid);
default:
IWL_DEBUG_HT("unknown\n");
return -EINVAL;
break;
}
return 0;
}
static int iwl4965_mac_get_tx_stats(struct ieee80211_hw *hw, static int iwl4965_mac_get_tx_stats(struct ieee80211_hw *hw,
struct ieee80211_tx_queue_stats *stats) struct ieee80211_tx_queue_stats *stats)
{ {
...@@ -3592,15 +3687,6 @@ static ssize_t show_temperature(struct device *d, ...@@ -3592,15 +3687,6 @@ static ssize_t show_temperature(struct device *d,
static DEVICE_ATTR(temperature, S_IRUGO, show_temperature, NULL); static DEVICE_ATTR(temperature, S_IRUGO, show_temperature, NULL);
static ssize_t show_rs_window(struct device *d,
struct device_attribute *attr,
char *buf)
{
struct iwl_priv *priv = d->driver_data;
return iwl4965_fill_rs_info(priv->hw, buf, IWL_AP_ID);
}
static DEVICE_ATTR(rs_window, S_IRUGO, show_rs_window, NULL);
static ssize_t show_tx_power(struct device *d, static ssize_t show_tx_power(struct device *d,
struct device_attribute *attr, char *buf) struct device_attribute *attr, char *buf)
{ {
...@@ -3699,7 +3785,7 @@ static ssize_t store_filter_flags(struct device *d, ...@@ -3699,7 +3785,7 @@ static ssize_t store_filter_flags(struct device *d,
static DEVICE_ATTR(filter_flags, S_IWUSR | S_IRUGO, show_filter_flags, static DEVICE_ATTR(filter_flags, S_IWUSR | S_IRUGO, show_filter_flags,
store_filter_flags); store_filter_flags);
#ifdef CONFIG_IWL4965_SPECTRUM_MEASUREMENT #ifdef CONFIG_IWLAGN_SPECTRUM_MEASUREMENT
static ssize_t show_measurement(struct device *d, static ssize_t show_measurement(struct device *d,
struct device_attribute *attr, char *buf) struct device_attribute *attr, char *buf)
...@@ -3707,7 +3793,7 @@ static ssize_t show_measurement(struct device *d, ...@@ -3707,7 +3793,7 @@ static ssize_t show_measurement(struct device *d,
struct iwl_priv *priv = dev_get_drvdata(d); struct iwl_priv *priv = dev_get_drvdata(d);
struct iwl4965_spectrum_notification measure_report; struct iwl4965_spectrum_notification measure_report;
u32 size = sizeof(measure_report), len = 0, ofs = 0; u32 size = sizeof(measure_report), len = 0, ofs = 0;
u8 *data = (u8 *) & measure_report; u8 *data = (u8 *)&measure_report;
unsigned long flags; unsigned long flags;
spin_lock_irqsave(&priv->lock, flags); spin_lock_irqsave(&priv->lock, flags);
...@@ -3770,7 +3856,7 @@ static ssize_t store_measurement(struct device *d, ...@@ -3770,7 +3856,7 @@ static ssize_t store_measurement(struct device *d,
static DEVICE_ATTR(measurement, S_IRUSR | S_IWUSR, static DEVICE_ATTR(measurement, S_IRUSR | S_IWUSR,
show_measurement, store_measurement); show_measurement, store_measurement);
#endif /* CONFIG_IWL4965_SPECTRUM_MEASUREMENT */ #endif /* CONFIG_IWLAGN_SPECTRUM_MEASUREMENT */
static ssize_t store_retry_rate(struct device *d, static ssize_t store_retry_rate(struct device *d,
struct device_attribute *attr, struct device_attribute *attr,
...@@ -3800,77 +3886,54 @@ static ssize_t store_power_level(struct device *d, ...@@ -3800,77 +3886,54 @@ static ssize_t store_power_level(struct device *d,
const char *buf, size_t count) const char *buf, size_t count)
{ {
struct iwl_priv *priv = dev_get_drvdata(d); struct iwl_priv *priv = dev_get_drvdata(d);
int rc; int ret;
int mode; int mode;
mode = simple_strtoul(buf, NULL, 0); mode = simple_strtoul(buf, NULL, 0);
mutex_lock(&priv->mutex); mutex_lock(&priv->mutex);
if (!iwl_is_ready(priv)) { if (!iwl_is_ready(priv)) {
rc = -EAGAIN; ret = -EAGAIN;
goto out; goto out;
} }
rc = iwl_power_set_user_mode(priv, mode); ret = iwl_power_set_user_mode(priv, mode);
if (rc) { if (ret) {
IWL_DEBUG_MAC80211("failed setting power mode.\n"); IWL_DEBUG_MAC80211("failed setting power mode.\n");
goto out; goto out;
} }
rc = count; ret = count;
out: out:
mutex_unlock(&priv->mutex); mutex_unlock(&priv->mutex);
return rc; return ret;
} }
#define MAX_WX_STRING 80
/* Values are in microsecond */
static const s32 timeout_duration[] = {
350000,
250000,
75000,
37000,
25000,
};
static const s32 period_duration[] = {
400000,
700000,
1000000,
1000000,
1000000
};
static ssize_t show_power_level(struct device *d, static ssize_t show_power_level(struct device *d,
struct device_attribute *attr, char *buf) struct device_attribute *attr, char *buf)
{ {
struct iwl_priv *priv = dev_get_drvdata(d); struct iwl_priv *priv = dev_get_drvdata(d);
int mode = priv->power_data.user_power_setting;
int system = priv->power_data.system_power_setting;
int level = priv->power_data.power_mode; int level = priv->power_data.power_mode;
char *p = buf; char *p = buf;
p += sprintf(p, "%d ", level); switch (system) {
switch (level) { case IWL_POWER_SYS_AUTO:
case IWL_POWER_MODE_CAM: p += sprintf(p, "SYSTEM:auto");
case IWL_POWER_AC:
p += sprintf(p, "(AC)");
break; break;
case IWL_POWER_BATTERY: case IWL_POWER_SYS_AC:
p += sprintf(p, "(BATTERY)"); p += sprintf(p, "SYSTEM:ac");
break;
case IWL_POWER_SYS_BATTERY:
p += sprintf(p, "SYSTEM:battery");
break; break;
default:
p += sprintf(p,
"(Timeout %dms, Period %dms)",
timeout_duration[level - 1] / 1000,
period_duration[level - 1] / 1000);
} }
/*
if (!(priv->power_mode & IWL_POWER_ENABLED)) p += sprintf(p, "\tMODE:%s", (mode < IWL_POWER_AUTO)?"fixed":"auto");
p += sprintf(p, " OFF\n"); p += sprintf(p, "\tINDEX:%d", level);
else p += sprintf(p, "\n");
p += sprintf(p, " \n"); return p - buf + 1;
*/
p += sprintf(p, " \n");
return (p - buf + 1);
} }
static DEVICE_ATTR(power_level, S_IWUSR | S_IRUSR, show_power_level, static DEVICE_ATTR(power_level, S_IWUSR | S_IRUSR, show_power_level,
...@@ -3945,7 +4008,7 @@ static ssize_t show_statistics(struct device *d, ...@@ -3945,7 +4008,7 @@ static ssize_t show_statistics(struct device *d,
struct iwl_priv *priv = dev_get_drvdata(d); struct iwl_priv *priv = dev_get_drvdata(d);
u32 size = sizeof(struct iwl_notif_statistics); u32 size = sizeof(struct iwl_notif_statistics);
u32 len = 0, ofs = 0; u32 len = 0, ofs = 0;
u8 *data = (u8 *) & priv->statistics; u8 *data = (u8 *)&priv->statistics;
int rc = 0; int rc = 0;
if (!iwl_is_alive(priv)) if (!iwl_is_alive(priv))
...@@ -4041,12 +4104,11 @@ static struct attribute *iwl4965_sysfs_entries[] = { ...@@ -4041,12 +4104,11 @@ static struct attribute *iwl4965_sysfs_entries[] = {
&dev_attr_channels.attr, &dev_attr_channels.attr,
&dev_attr_flags.attr, &dev_attr_flags.attr,
&dev_attr_filter_flags.attr, &dev_attr_filter_flags.attr,
#ifdef CONFIG_IWL4965_SPECTRUM_MEASUREMENT #ifdef CONFIG_IWLAGN_SPECTRUM_MEASUREMENT
&dev_attr_measurement.attr, &dev_attr_measurement.attr,
#endif #endif
&dev_attr_power_level.attr, &dev_attr_power_level.attr,
&dev_attr_retry_rate.attr, &dev_attr_retry_rate.attr,
&dev_attr_rs_window.attr,
&dev_attr_statistics.attr, &dev_attr_statistics.attr,
&dev_attr_status.attr, &dev_attr_status.attr,
&dev_attr_temperature.attr, &dev_attr_temperature.attr,
...@@ -4394,8 +4456,10 @@ static int iwl4965_pci_resume(struct pci_dev *pdev) ...@@ -4394,8 +4456,10 @@ static int iwl4965_pci_resume(struct pci_dev *pdev)
/* Hardware specific file defines the PCI IDs table for that hardware module */ /* Hardware specific file defines the PCI IDs table for that hardware module */
static struct pci_device_id iwl_hw_card_ids[] = { static struct pci_device_id iwl_hw_card_ids[] = {
#ifdef CONFIG_IWL4965
{IWL_PCI_DEVICE(0x4229, PCI_ANY_ID, iwl4965_agn_cfg)}, {IWL_PCI_DEVICE(0x4229, PCI_ANY_ID, iwl4965_agn_cfg)},
{IWL_PCI_DEVICE(0x4230, PCI_ANY_ID, iwl4965_agn_cfg)}, {IWL_PCI_DEVICE(0x4230, PCI_ANY_ID, iwl4965_agn_cfg)},
#endif /* CONFIG_IWL4965 */
#ifdef CONFIG_IWL5000 #ifdef CONFIG_IWL5000
{IWL_PCI_DEVICE(0x4232, 0x1205, iwl5100_bg_cfg)}, {IWL_PCI_DEVICE(0x4232, 0x1205, iwl5100_bg_cfg)},
{IWL_PCI_DEVICE(0x4232, 0x1305, iwl5100_bg_cfg)}, {IWL_PCI_DEVICE(0x4232, 0x1305, iwl5100_bg_cfg)},
...@@ -4431,7 +4495,7 @@ static int __init iwl4965_init(void) ...@@ -4431,7 +4495,7 @@ static int __init iwl4965_init(void)
printk(KERN_INFO DRV_NAME ": " DRV_DESCRIPTION ", " DRV_VERSION "\n"); printk(KERN_INFO DRV_NAME ": " DRV_DESCRIPTION ", " DRV_VERSION "\n");
printk(KERN_INFO DRV_NAME ": " DRV_COPYRIGHT "\n"); printk(KERN_INFO DRV_NAME ": " DRV_COPYRIGHT "\n");
ret = iwl4965_rate_control_register(); ret = iwlagn_rate_control_register();
if (ret) { if (ret) {
IWL_ERROR("Unable to register rate control algorithm: %d\n", ret); IWL_ERROR("Unable to register rate control algorithm: %d\n", ret);
return ret; return ret;
...@@ -4446,14 +4510,14 @@ static int __init iwl4965_init(void) ...@@ -4446,14 +4510,14 @@ static int __init iwl4965_init(void)
return ret; return ret;
error_register: error_register:
iwl4965_rate_control_unregister(); iwlagn_rate_control_unregister();
return ret; return ret;
} }
static void __exit iwl4965_exit(void) static void __exit iwl4965_exit(void)
{ {
pci_unregister_driver(&iwl_driver); pci_unregister_driver(&iwl_driver);
iwl4965_rate_control_unregister(); iwlagn_rate_control_unregister();
} }
module_exit(iwl4965_exit); module_exit(iwl4965_exit);
......
...@@ -666,8 +666,7 @@ struct iwl4965_rxon_assoc_cmd { ...@@ -666,8 +666,7 @@ struct iwl4965_rxon_assoc_cmd {
__le16 reserved; __le16 reserved;
} __attribute__ ((packed)); } __attribute__ ((packed));
#define IWL_CONN_MAX_LISTEN_INTERVAL 10
/* /*
* REPLY_RXON_TIMING = 0x14 (command, has simple generic response) * REPLY_RXON_TIMING = 0x14 (command, has simple generic response)
...@@ -1076,10 +1075,12 @@ struct iwl4965_rx_frame { ...@@ -1076,10 +1075,12 @@ struct iwl4965_rx_frame {
} __attribute__ ((packed)); } __attribute__ ((packed));
/* Fixed (non-configurable) rx data from phy */ /* Fixed (non-configurable) rx data from phy */
#define RX_PHY_FLAGS_ANTENNAE_OFFSET (4)
#define RX_PHY_FLAGS_ANTENNAE_MASK (0x70) #define IWL49_RX_RES_PHY_CNT 14
#define IWL_AGC_DB_MASK (0x3f80) /* MASK(7,13) */ #define IWL49_RX_PHY_FLAGS_ANTENNAE_OFFSET (4)
#define IWL_AGC_DB_POS (7) #define IWL49_RX_PHY_FLAGS_ANTENNAE_MASK (0x70)
#define IWL49_AGC_DB_MASK (0x3f80) /* MASK(7,13) */
#define IWL49_AGC_DB_POS (7)
struct iwl4965_rx_non_cfg_phy { struct iwl4965_rx_non_cfg_phy {
__le16 ant_selection; /* ant A bit 4, ant B bit 5, ant C bit 6 */ __le16 ant_selection; /* ant A bit 4, ant B bit 5, ant C bit 6 */
__le16 agc_info; /* agc code 0:6, agc dB 7:13, reserved 14:15 */ __le16 agc_info; /* agc code 0:6, agc dB 7:13, reserved 14:15 */
...@@ -1087,12 +1088,30 @@ struct iwl4965_rx_non_cfg_phy { ...@@ -1087,12 +1088,30 @@ struct iwl4965_rx_non_cfg_phy {
u8 pad[0]; u8 pad[0];
} __attribute__ ((packed)); } __attribute__ ((packed));
#define IWL50_RX_RES_PHY_CNT 8
#define IWL50_RX_RES_AGC_IDX 1
#define IWL50_RX_RES_RSSI_AB_IDX 2
#define IWL50_RX_RES_RSSI_C_IDX 3
#define IWL50_OFDM_AGC_MSK 0xfe00
#define IWL50_OFDM_AGC_BIT_POS 9
#define IWL50_OFDM_RSSI_A_MSK 0x00ff
#define IWL50_OFDM_RSSI_A_BIT_POS 0
#define IWL50_OFDM_RSSI_B_MSK 0xff0000
#define IWL50_OFDM_RSSI_B_BIT_POS 16
#define IWL50_OFDM_RSSI_C_MSK 0x00ff
#define IWL50_OFDM_RSSI_C_BIT_POS 0
struct iwl5000_non_cfg_phy {
__le32 non_cfg_phy[IWL50_RX_RES_PHY_CNT]; /* upto 8 phy entries */
} __attribute__ ((packed));
/* /*
* REPLY_RX = 0xc3 (response only, not a command) * REPLY_RX = 0xc3 (response only, not a command)
* Used only for legacy (non 11n) frames. * Used only for legacy (non 11n) frames.
*/ */
#define RX_RES_PHY_CNT 14 struct iwl_rx_phy_res {
struct iwl4965_rx_phy_res {
u8 non_cfg_phy_cnt; /* non configurable DSP phy data byte count */ u8 non_cfg_phy_cnt; /* non configurable DSP phy data byte count */
u8 cfg_phy_cnt; /* configurable DSP phy data byte count */ u8 cfg_phy_cnt; /* configurable DSP phy data byte count */
u8 stat_id; /* configurable DSP phy data set ID */ u8 stat_id; /* configurable DSP phy data set ID */
...@@ -1101,8 +1120,7 @@ struct iwl4965_rx_phy_res { ...@@ -1101,8 +1120,7 @@ struct iwl4965_rx_phy_res {
__le32 beacon_time_stamp; /* beacon at on-air rise */ __le32 beacon_time_stamp; /* beacon at on-air rise */
__le16 phy_flags; /* general phy flags: band, modulation, ... */ __le16 phy_flags; /* general phy flags: band, modulation, ... */
__le16 channel; /* channel number */ __le16 channel; /* channel number */
__le16 non_cfg_phy[RX_RES_PHY_CNT]; /* upto 14 phy entries */ u8 non_cfg_phy_buf[32]; /* for various implementations of non_cfg_phy */
__le32 reserved2;
__le32 rate_n_flags; /* RATE_MCS_* */ __le32 rate_n_flags; /* RATE_MCS_* */
__le16 byte_count; /* frame's byte-count */ __le16 byte_count; /* frame's byte-count */
__le16 reserved3; __le16 reserved3;
...@@ -1993,7 +2011,7 @@ struct iwl4965_spectrum_notification { ...@@ -1993,7 +2011,7 @@ struct iwl4965_spectrum_notification {
*****************************************************************************/ *****************************************************************************/
/** /**
* struct iwl4965_powertable_cmd - Power Table Command * struct iwl_powertable_cmd - Power Table Command
* @flags: See below: * @flags: See below:
* *
* POWER_TABLE_CMD = 0x77 (command, has simple generic response) * POWER_TABLE_CMD = 0x77 (command, has simple generic response)
...@@ -2027,7 +2045,7 @@ struct iwl4965_spectrum_notification { ...@@ -2027,7 +2045,7 @@ struct iwl4965_spectrum_notification {
#define IWL_POWER_PCI_PM_MSK __constant_cpu_to_le16(1 << 3) #define IWL_POWER_PCI_PM_MSK __constant_cpu_to_le16(1 << 3)
#define IWL_POWER_FAST_PD __constant_cpu_to_le16(1 << 4) #define IWL_POWER_FAST_PD __constant_cpu_to_le16(1 << 4)
struct iwl4965_powertable_cmd { struct iwl_powertable_cmd {
__le16 flags; __le16 flags;
u8 keep_alive_seconds; u8 keep_alive_seconds;
u8 debug_flags; u8 debug_flags;
...@@ -2324,7 +2342,7 @@ struct iwl4965_beacon_notif { ...@@ -2324,7 +2342,7 @@ struct iwl4965_beacon_notif {
/* /*
* REPLY_TX_BEACON = 0x91 (command, has simple generic response) * REPLY_TX_BEACON = 0x91 (command, has simple generic response)
*/ */
struct iwl4965_tx_beacon_cmd { struct iwl_tx_beacon_cmd {
struct iwl_tx_cmd tx; struct iwl_tx_cmd tx;
__le16 tim_idx; __le16 tim_idx;
u8 tim_size; u8 tim_size;
......
...@@ -383,8 +383,8 @@ void iwl_reset_qos(struct iwl_priv *priv) ...@@ -383,8 +383,8 @@ void iwl_reset_qos(struct iwl_priv *priv)
} }
EXPORT_SYMBOL(iwl_reset_qos); EXPORT_SYMBOL(iwl_reset_qos);
#define MAX_BIT_RATE_40_MHZ 0x96; /* 150 Mbps */ #define MAX_BIT_RATE_40_MHZ 0x96 /* 150 Mbps */
#define MAX_BIT_RATE_20_MHZ 0x48; /* 72 Mbps */ #define MAX_BIT_RATE_20_MHZ 0x48 /* 72 Mbps */
static void iwlcore_init_ht_hw_capab(const struct iwl_priv *priv, static void iwlcore_init_ht_hw_capab(const struct iwl_priv *priv,
struct ieee80211_ht_info *ht_info, struct ieee80211_ht_info *ht_info,
enum ieee80211_band band) enum ieee80211_band band)
...@@ -815,7 +815,7 @@ int iwl_setup_mac(struct iwl_priv *priv) ...@@ -815,7 +815,7 @@ int iwl_setup_mac(struct iwl_priv *priv)
{ {
int ret; int ret;
struct ieee80211_hw *hw = priv->hw; struct ieee80211_hw *hw = priv->hw;
hw->rate_control_algorithm = "iwl-4965-rs"; hw->rate_control_algorithm = "iwl-agn-rs";
/* Tell mac80211 our characteristics */ /* Tell mac80211 our characteristics */
hw->flags = IEEE80211_HW_SIGNAL_DBM | hw->flags = IEEE80211_HW_SIGNAL_DBM |
...@@ -827,6 +827,7 @@ int iwl_setup_mac(struct iwl_priv *priv) ...@@ -827,6 +827,7 @@ int iwl_setup_mac(struct iwl_priv *priv)
hw->ampdu_queues = priv->cfg->mod_params->num_of_ampdu_queues; hw->ampdu_queues = priv->cfg->mod_params->num_of_ampdu_queues;
hw->conf.beacon_int = 100; hw->conf.beacon_int = 100;
hw->max_listen_interval = IWL_CONN_MAX_LISTEN_INTERVAL;
if (priv->bands[IEEE80211_BAND_2GHZ].n_channels) if (priv->bands[IEEE80211_BAND_2GHZ].n_channels)
priv->hw->wiphy->bands[IEEE80211_BAND_2GHZ] = priv->hw->wiphy->bands[IEEE80211_BAND_2GHZ] =
......
...@@ -95,6 +95,8 @@ struct iwl_hcmd_utils_ops { ...@@ -95,6 +95,8 @@ struct iwl_hcmd_utils_ops {
void (*chain_noise_reset)(struct iwl_priv *priv); void (*chain_noise_reset)(struct iwl_priv *priv);
void (*rts_tx_cmd_flag)(struct ieee80211_tx_info *info, void (*rts_tx_cmd_flag)(struct ieee80211_tx_info *info,
__le32 *tx_flags); __le32 *tx_flags);
int (*calc_rssi)(struct iwl_priv *priv,
struct iwl_rx_phy_res *rx_resp);
}; };
struct iwl_lib_ops { struct iwl_lib_ops {
...@@ -139,7 +141,6 @@ struct iwl_lib_ops { ...@@ -139,7 +141,6 @@ struct iwl_lib_ops {
int (*set_pwr_src)(struct iwl_priv *priv, enum iwl_pwr_src src); int (*set_pwr_src)(struct iwl_priv *priv, enum iwl_pwr_src src);
} apm_ops; } apm_ops;
/* power */ /* power */
int (*set_power)(struct iwl_priv *priv, void *cmd);
int (*send_tx_power) (struct iwl_priv *priv); int (*send_tx_power) (struct iwl_priv *priv);
void (*update_chain_flags)(struct iwl_priv *priv); void (*update_chain_flags)(struct iwl_priv *priv);
void (*temperature) (struct iwl_priv *priv); void (*temperature) (struct iwl_priv *priv);
......
...@@ -104,6 +104,7 @@ ...@@ -104,6 +104,7 @@
* 3-2: 0 = A, 1 = B, 2 = C, 3 = D step * 3-2: 0 = A, 1 = B, 2 = C, 3 = D step
*/ */
#define CSR_HW_REV_WA_REG (CSR_BASE+0x22C) #define CSR_HW_REV_WA_REG (CSR_BASE+0x22C)
#define CSR_DBG_HPET_MEM_REG (CSR_BASE+0x240)
/* Bits for CSR_HW_IF_CONFIG_REG */ /* Bits for CSR_HW_IF_CONFIG_REG */
#define CSR49_HW_IF_CONFIG_REG_BIT_4965_R (0x00000010) #define CSR49_HW_IF_CONFIG_REG_BIT_4965_R (0x00000010)
...@@ -118,7 +119,12 @@ ...@@ -118,7 +119,12 @@
#define CSR39_HW_IF_CONFIG_REG_BITS_SILICON_TYPE_A (0x00000000) #define CSR39_HW_IF_CONFIG_REG_BITS_SILICON_TYPE_A (0x00000000)
#define CSR39_HW_IF_CONFIG_REG_BITS_SILICON_TYPE_B (0x00001000) #define CSR39_HW_IF_CONFIG_REG_BITS_SILICON_TYPE_B (0x00001000)
#define CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM (0x00200000) #define CSR_HW_IF_CONFIG_REG_BIT_HAP_WAKE_L1A (0x00080000)
#define CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM (0x00200000)
#define CSR_HW_IF_CONFIG_REG_BIT_PCI_OWN_SEM (0x00400000)
#define CSR_HW_IF_CONFIG_REG_BIT_ME_OWN (0x02000000)
#define CSR_HW_IF_CONFIG_REG_BIT_WAKE_ME (0x08000000)
/* interrupt flags in INTA, set by uCode or hardware (e.g. dma), /* interrupt flags in INTA, set by uCode or hardware (e.g. dma),
* acknowledged (reset) by host writing "1" to flagged bits. */ * acknowledged (reset) by host writing "1" to flagged bits. */
...@@ -236,6 +242,8 @@ ...@@ -236,6 +242,8 @@
#define CSR39_ANA_PLL_CFG_VAL (0x01000000) #define CSR39_ANA_PLL_CFG_VAL (0x01000000)
#define CSR50_ANA_PLL_CFG_VAL (0x00880300) #define CSR50_ANA_PLL_CFG_VAL (0x00880300)
/* HPET MEM debug */
#define CSR_DBG_HPET_MEM_REG_VAL (0xFFFF0000)
/*=== HBUS (Host-side Bus) ===*/ /*=== HBUS (Host-side Bus) ===*/
#define HBUS_BASE (0x400) #define HBUS_BASE (0x400)
/* /*
......
...@@ -33,12 +33,12 @@ ...@@ -33,12 +33,12 @@
#define IWL_DEBUG(level, fmt, args...) \ #define IWL_DEBUG(level, fmt, args...) \
do { if (priv->debug_level & (level)) \ do { if (priv->debug_level & (level)) \
dev_printk(KERN_ERR, &(priv->hw->wiphy->dev), "%c %s " fmt, \ dev_printk(KERN_ERR, &(priv->hw->wiphy->dev), "%c %s " fmt, \
in_interrupt() ? 'I' : 'U', __FUNCTION__ , ## args); } while (0) in_interrupt() ? 'I' : 'U', __func__ , ## args); } while (0)
#define IWL_DEBUG_LIMIT(level, fmt, args...) \ #define IWL_DEBUG_LIMIT(level, fmt, args...) \
do { if ((priv->debug_level & (level)) && net_ratelimit()) \ do { if ((priv->debug_level & (level)) && net_ratelimit()) \
dev_printk(KERN_ERR, &(priv->hw->wiphy->dev), "%c %s " fmt, \ dev_printk(KERN_ERR, &(priv->hw->wiphy->dev), "%c %s " fmt, \
in_interrupt() ? 'I' : 'U', __FUNCTION__ , ## args); } while (0) in_interrupt() ? 'I' : 'U', __func__ , ## args); } while (0)
#ifdef CONFIG_IWLWIFI_DEBUGFS #ifdef CONFIG_IWLWIFI_DEBUGFS
struct iwl_debugfs { struct iwl_debugfs {
......
...@@ -231,7 +231,7 @@ static ssize_t iwl_dbgfs_stations_read(struct file *file, char __user *user_buf, ...@@ -231,7 +231,7 @@ static ssize_t iwl_dbgfs_stations_read(struct file *file, char __user *user_buf,
DECLARE_MAC_BUF(mac); DECLARE_MAC_BUF(mac);
buf = kmalloc(bufsz, GFP_KERNEL); buf = kmalloc(bufsz, GFP_KERNEL);
if(!buf) if (!buf)
return -ENOMEM; return -ENOMEM;
pos += scnprintf(buf + pos, bufsz - pos, "num of stations: %d\n\n", pos += scnprintf(buf + pos, bufsz - pos, "num of stations: %d\n\n",
...@@ -364,16 +364,19 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name) ...@@ -364,16 +364,19 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name)
{ {
struct iwl_debugfs *dbgfs; struct iwl_debugfs *dbgfs;
struct dentry *phyd = priv->hw->wiphy->debugfsdir; struct dentry *phyd = priv->hw->wiphy->debugfsdir;
int ret = 0;
dbgfs = kzalloc(sizeof(struct iwl_debugfs), GFP_KERNEL); dbgfs = kzalloc(sizeof(struct iwl_debugfs), GFP_KERNEL);
if (!dbgfs) { if (!dbgfs) {
ret = -ENOMEM;
goto err; goto err;
} }
priv->dbgfs = dbgfs; priv->dbgfs = dbgfs;
dbgfs->name = name; dbgfs->name = name;
dbgfs->dir_drv = debugfs_create_dir(name, phyd); dbgfs->dir_drv = debugfs_create_dir(name, phyd);
if (!dbgfs->dir_drv || IS_ERR(dbgfs->dir_drv)){ if (!dbgfs->dir_drv || IS_ERR(dbgfs->dir_drv)) {
ret = -ENOENT;
goto err; goto err;
} }
...@@ -394,7 +397,7 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name) ...@@ -394,7 +397,7 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name)
err: err:
IWL_ERROR("Can't open the debugfs directory\n"); IWL_ERROR("Can't open the debugfs directory\n");
iwl_dbgfs_unregister(priv); iwl_dbgfs_unregister(priv);
return -ENOENT; return ret;
} }
EXPORT_SYMBOL(iwl_dbgfs_register); EXPORT_SYMBOL(iwl_dbgfs_register);
...@@ -404,7 +407,7 @@ EXPORT_SYMBOL(iwl_dbgfs_register); ...@@ -404,7 +407,7 @@ EXPORT_SYMBOL(iwl_dbgfs_register);
*/ */
void iwl_dbgfs_unregister(struct iwl_priv *priv) void iwl_dbgfs_unregister(struct iwl_priv *priv)
{ {
if (!(priv->dbgfs)) if (!priv->dbgfs)
return; return;
DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_eeprom); DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_eeprom);
......
...@@ -36,7 +36,7 @@ ...@@ -36,7 +36,7 @@
#include <linux/kernel.h> #include <linux/kernel.h>
#include <net/ieee80211_radiotap.h> #include <net/ieee80211_radiotap.h>
#define DRV_NAME "iwl4965" #define DRV_NAME "iwlagn"
#include "iwl-rfkill.h" #include "iwl-rfkill.h"
#include "iwl-eeprom.h" #include "iwl-eeprom.h"
#include "iwl-4965-hw.h" #include "iwl-4965-hw.h"
...@@ -45,6 +45,7 @@ ...@@ -45,6 +45,7 @@
#include "iwl-debug.h" #include "iwl-debug.h"
#include "iwl-led.h" #include "iwl-led.h"
#include "iwl-power.h" #include "iwl-power.h"
#include "iwl-agn-rs.h"
/* configuration for the iwl4965 */ /* configuration for the iwl4965 */
extern struct iwl_cfg iwl4965_agn_cfg; extern struct iwl_cfg iwl4965_agn_cfg;
...@@ -134,8 +135,7 @@ struct iwl_tx_info { ...@@ -134,8 +135,7 @@ struct iwl_tx_info {
struct iwl_tx_queue { struct iwl_tx_queue {
struct iwl_queue q; struct iwl_queue q;
struct iwl_tfd_frame *bd; struct iwl_tfd_frame *bd;
struct iwl_cmd *cmd; struct iwl_cmd *cmd[TFD_TX_CMD_SLOTS];
dma_addr_t dma_addr_cmd;
struct iwl_tx_info *txb; struct iwl_tx_info *txb;
int need_update; int need_update;
int sched_retry; int sched_retry;
...@@ -191,7 +191,6 @@ struct iwl4965_clip_group { ...@@ -191,7 +191,6 @@ struct iwl4965_clip_group {
const s8 clip_powers[IWL_MAX_RATES]; const s8 clip_powers[IWL_MAX_RATES];
}; };
#include "iwl-4965-rs.h"
#define IWL_TX_FIFO_AC0 0 #define IWL_TX_FIFO_AC0 0
#define IWL_TX_FIFO_AC1 1 #define IWL_TX_FIFO_AC1 1
...@@ -219,7 +218,7 @@ enum iwl_pwr_src { ...@@ -219,7 +218,7 @@ enum iwl_pwr_src {
struct iwl_frame { struct iwl_frame {
union { union {
struct ieee80211_hdr frame; struct ieee80211_hdr frame;
struct iwl4965_tx_beacon_cmd beacon; struct iwl_tx_beacon_cmd beacon;
u8 raw[IEEE80211_FRAME_LEN]; u8 raw[IEEE80211_FRAME_LEN];
u8 cmd[360]; u8 cmd[360];
} u; } u;
...@@ -283,10 +282,9 @@ struct iwl_cmd { ...@@ -283,10 +282,9 @@ struct iwl_cmd {
u32 val32; u32 val32;
struct iwl4965_bt_cmd bt; struct iwl4965_bt_cmd bt;
struct iwl4965_rxon_time_cmd rxon_time; struct iwl4965_rxon_time_cmd rxon_time;
struct iwl4965_powertable_cmd powertable; struct iwl_powertable_cmd powertable;
struct iwl_qosparam_cmd qosparam; struct iwl_qosparam_cmd qosparam;
struct iwl_tx_cmd tx; struct iwl_tx_cmd tx;
struct iwl4965_tx_beacon_cmd tx_beacon;
struct iwl4965_rxon_assoc_cmd rxon_assoc; struct iwl4965_rxon_assoc_cmd rxon_assoc;
struct iwl_rem_sta_cmd rm_sta; struct iwl_rem_sta_cmd rm_sta;
u8 *indirect; u8 *indirect;
...@@ -590,6 +588,7 @@ extern unsigned int iwl4965_fill_beacon_frame(struct iwl_priv *priv, ...@@ -590,6 +588,7 @@ extern unsigned int iwl4965_fill_beacon_frame(struct iwl_priv *priv,
const u8 *dest, int left); const u8 *dest, int left);
extern void iwl4965_update_chain_flags(struct iwl_priv *priv); extern void iwl4965_update_chain_flags(struct iwl_priv *priv);
int iwl4965_set_pwr_src(struct iwl_priv *priv, enum iwl_pwr_src src); int iwl4965_set_pwr_src(struct iwl_priv *priv, enum iwl_pwr_src src);
extern int iwl4965_set_power(struct iwl_priv *priv, void *cmd);
extern const u8 iwl_bcast_addr[ETH_ALEN]; extern const u8 iwl_bcast_addr[ETH_ALEN];
...@@ -642,10 +641,6 @@ struct iwl_priv; ...@@ -642,10 +641,6 @@ struct iwl_priv;
* Forward declare iwl-4965.c functions for iwl-base.c * Forward declare iwl-4965.c functions for iwl-base.c
*/ */
extern void iwl4965_rf_kill_ct_config(struct iwl_priv *priv); extern void iwl4965_rf_kill_ct_config(struct iwl_priv *priv);
int iwl4965_mac_ampdu_action(struct ieee80211_hw *hw,
enum ieee80211_ampdu_mlme_action action,
const u8 *addr, u16 tid, u16 *ssn);
int iwl4965_check_empty_hw_queue(struct iwl_priv *priv, int sta_id, int iwl4965_check_empty_hw_queue(struct iwl_priv *priv, int sta_id,
u8 tid, int txq_id); u8 tid, int txq_id);
...@@ -812,14 +807,11 @@ struct iwl_chain_noise_data { ...@@ -812,14 +807,11 @@ struct iwl_chain_noise_data {
#define EEPROM_SEM_RETRY_LIMIT 1000 /* number of attempts (not time) */ #define EEPROM_SEM_RETRY_LIMIT 1000 /* number of attempts (not time) */
#ifdef CONFIG_IWL4965_SPECTRUM_MEASUREMENT
enum { enum {
MEASUREMENT_READY = (1 << 0), MEASUREMENT_READY = (1 << 0),
MEASUREMENT_ACTIVE = (1 << 1), MEASUREMENT_ACTIVE = (1 << 1),
}; };
#endif
#define IWL_MAX_NUM_QUEUES 20 /* FIXME: do dynamic allocation */ #define IWL_MAX_NUM_QUEUES 20 /* FIXME: do dynamic allocation */
...@@ -844,7 +836,7 @@ struct iwl_priv { ...@@ -844,7 +836,7 @@ struct iwl_priv {
struct ieee80211_supported_band bands[IEEE80211_NUM_BANDS]; struct ieee80211_supported_band bands[IEEE80211_NUM_BANDS];
#ifdef CONFIG_IWL4965_SPECTRUM_MEASUREMENT #ifdef CONFIG_IWLAGN_SPECTRUM_MEASUREMENT
/* spectrum measurement report caching */ /* spectrum measurement report caching */
struct iwl4965_spectrum_notification measure_report; struct iwl4965_spectrum_notification measure_report;
u8 measurement_status; u8 measurement_status;
......
...@@ -273,8 +273,7 @@ EXPORT_SYMBOL(iwl_eeprom_init); ...@@ -273,8 +273,7 @@ EXPORT_SYMBOL(iwl_eeprom_init);
void iwl_eeprom_free(struct iwl_priv *priv) void iwl_eeprom_free(struct iwl_priv *priv)
{ {
if(priv->eeprom) kfree(priv->eeprom);
kfree(priv->eeprom);
priv->eeprom = NULL; priv->eeprom = NULL;
} }
EXPORT_SYMBOL(iwl_eeprom_free); EXPORT_SYMBOL(iwl_eeprom_free);
......
...@@ -228,7 +228,7 @@ int iwl_send_cmd_sync(struct iwl_priv *priv, struct iwl_host_cmd *cmd) ...@@ -228,7 +228,7 @@ int iwl_send_cmd_sync(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
* TX cmd queue. Otherwise in case the cmd comes * TX cmd queue. Otherwise in case the cmd comes
* in later, it will possibly set an invalid * in later, it will possibly set an invalid
* address (cmd->meta.source). */ * address (cmd->meta.source). */
qcmd = &priv->txq[IWL_CMD_QUEUE_NUM].cmd[cmd_idx]; qcmd = priv->txq[IWL_CMD_QUEUE_NUM].cmd[cmd_idx];
qcmd->meta.flags &= ~CMD_WANT_SKB; qcmd->meta.flags &= ~CMD_WANT_SKB;
} }
fail: fail:
......
...@@ -161,11 +161,31 @@ int iwl4965_led_off(struct iwl_priv *priv, int led_id) ...@@ -161,11 +161,31 @@ int iwl4965_led_off(struct iwl_priv *priv, int led_id)
/* Set led register off */ /* Set led register off */
static int iwl4965_led_off_reg(struct iwl_priv *priv, int led_id) static int iwl4965_led_off_reg(struct iwl_priv *priv, int led_id)
{ {
IWL_DEBUG_LED("radio off\n"); IWL_DEBUG_LED("LED Reg off\n");
iwl_write32(priv, CSR_LED_REG, CSR_LED_REG_TRUN_OFF); iwl_write32(priv, CSR_LED_REG, CSR_LED_REG_TRUN_OFF);
return 0; return 0;
} }
/*
* Set led register in case of disassociation according to rfkill state
*/
static int iwl_led_associate(struct iwl_priv *priv, int led_id)
{
IWL_DEBUG_LED("Associated\n");
priv->allow_blinking = 1;
return iwl4965_led_on_reg(priv, led_id);
}
static int iwl_led_disassociate(struct iwl_priv *priv, int led_id)
{
priv->allow_blinking = 0;
if (iwl_is_rfkill(priv))
iwl4965_led_off_reg(priv, led_id);
else
iwl4965_led_on_reg(priv, led_id);
return 0;
}
/* /*
* brightness call back function for Tx/Rx LED * brightness call back function for Tx/Rx LED
*/ */
...@@ -199,16 +219,10 @@ static void iwl_led_brightness_set(struct led_classdev *led_cdev, ...@@ -199,16 +219,10 @@ static void iwl_led_brightness_set(struct led_classdev *led_cdev,
led_type_str[led->type], brightness); led_type_str[led->type], brightness);
switch (brightness) { switch (brightness) {
case LED_FULL: case LED_FULL:
if (led->type == IWL_LED_TRG_ASSOC)
priv->allow_blinking = 1;
if (led->led_on) if (led->led_on)
led->led_on(priv, IWL_LED_LINK); led->led_on(priv, IWL_LED_LINK);
break; break;
case LED_OFF: case LED_OFF:
if (led->type == IWL_LED_TRG_ASSOC)
priv->allow_blinking = 0;
if (led->led_off) if (led->led_off)
led->led_off(priv, IWL_LED_LINK); led->led_off(priv, IWL_LED_LINK);
break; break;
...@@ -228,12 +242,12 @@ static void iwl_led_brightness_set(struct led_classdev *led_cdev, ...@@ -228,12 +242,12 @@ static void iwl_led_brightness_set(struct led_classdev *led_cdev,
*/ */
static int iwl_leds_register_led(struct iwl_priv *priv, struct iwl_led *led, static int iwl_leds_register_led(struct iwl_priv *priv, struct iwl_led *led,
enum led_type type, u8 set_led, enum led_type type, u8 set_led,
const char *name, char *trigger) char *trigger)
{ {
struct device *device = wiphy_dev(priv->hw->wiphy); struct device *device = wiphy_dev(priv->hw->wiphy);
int ret; int ret;
led->led_dev.name = name; led->led_dev.name = led->name;
led->led_dev.brightness_set = iwl_led_brightness_set; led->led_dev.brightness_set = iwl_led_brightness_set;
led->led_dev.default_trigger = trigger; led->led_dev.default_trigger = trigger;
...@@ -284,12 +298,6 @@ static int iwl_get_blink_rate(struct iwl_priv *priv) ...@@ -284,12 +298,6 @@ static int iwl_get_blink_rate(struct iwl_priv *priv)
return i; return i;
} }
static inline int is_rf_kill(struct iwl_priv *priv)
{
return test_bit(STATUS_RF_KILL_HW, &priv->status) ||
test_bit(STATUS_RF_KILL_SW, &priv->status);
}
/* /*
* this function called from handler. Since setting Led command can * this function called from handler. Since setting Led command can
* happen very frequent we postpone led command to be called from * happen very frequent we postpone led command to be called from
...@@ -303,7 +311,7 @@ void iwl_leds_background(struct iwl_priv *priv) ...@@ -303,7 +311,7 @@ void iwl_leds_background(struct iwl_priv *priv)
priv->last_blink_time = 0; priv->last_blink_time = 0;
return; return;
} }
if (is_rf_kill(priv)) { if (iwl_is_rfkill(priv)) {
priv->last_blink_time = 0; priv->last_blink_time = 0;
return; return;
} }
...@@ -337,7 +345,6 @@ EXPORT_SYMBOL(iwl_leds_background); ...@@ -337,7 +345,6 @@ EXPORT_SYMBOL(iwl_leds_background);
int iwl_leds_register(struct iwl_priv *priv) int iwl_leds_register(struct iwl_priv *priv)
{ {
char *trigger; char *trigger;
char name[32];
int ret; int ret;
priv->last_blink_rate = 0; priv->last_blink_rate = 0;
...@@ -346,7 +353,8 @@ int iwl_leds_register(struct iwl_priv *priv) ...@@ -346,7 +353,8 @@ int iwl_leds_register(struct iwl_priv *priv)
priv->allow_blinking = 0; priv->allow_blinking = 0;
trigger = ieee80211_get_radio_led_name(priv->hw); trigger = ieee80211_get_radio_led_name(priv->hw);
snprintf(name, sizeof(name), "iwl-%s:radio", snprintf(priv->led[IWL_LED_TRG_RADIO].name,
sizeof(priv->led[IWL_LED_TRG_RADIO].name), "iwl-%s:radio",
wiphy_name(priv->hw->wiphy)); wiphy_name(priv->hw->wiphy));
priv->led[IWL_LED_TRG_RADIO].led_on = iwl4965_led_on_reg; priv->led[IWL_LED_TRG_RADIO].led_on = iwl4965_led_on_reg;
...@@ -354,31 +362,33 @@ int iwl_leds_register(struct iwl_priv *priv) ...@@ -354,31 +362,33 @@ int iwl_leds_register(struct iwl_priv *priv)
priv->led[IWL_LED_TRG_RADIO].led_pattern = NULL; priv->led[IWL_LED_TRG_RADIO].led_pattern = NULL;
ret = iwl_leds_register_led(priv, &priv->led[IWL_LED_TRG_RADIO], ret = iwl_leds_register_led(priv, &priv->led[IWL_LED_TRG_RADIO],
IWL_LED_TRG_RADIO, 1, name, trigger); IWL_LED_TRG_RADIO, 1, trigger);
if (ret) if (ret)
goto exit_fail; goto exit_fail;
trigger = ieee80211_get_assoc_led_name(priv->hw); trigger = ieee80211_get_assoc_led_name(priv->hw);
snprintf(name, sizeof(name), "iwl-%s:assoc", snprintf(priv->led[IWL_LED_TRG_ASSOC].name,
sizeof(priv->led[IWL_LED_TRG_ASSOC].name), "iwl-%s:assoc",
wiphy_name(priv->hw->wiphy)); wiphy_name(priv->hw->wiphy));
ret = iwl_leds_register_led(priv, &priv->led[IWL_LED_TRG_ASSOC], ret = iwl_leds_register_led(priv, &priv->led[IWL_LED_TRG_ASSOC],
IWL_LED_TRG_ASSOC, 0, name, trigger); IWL_LED_TRG_ASSOC, 0, trigger);
/* for assoc always turn led on */ /* for assoc always turn led on */
priv->led[IWL_LED_TRG_ASSOC].led_on = iwl4965_led_on_reg; priv->led[IWL_LED_TRG_ASSOC].led_on = iwl_led_associate;
priv->led[IWL_LED_TRG_ASSOC].led_off = iwl4965_led_on_reg; priv->led[IWL_LED_TRG_ASSOC].led_off = iwl_led_disassociate;
priv->led[IWL_LED_TRG_ASSOC].led_pattern = NULL; priv->led[IWL_LED_TRG_ASSOC].led_pattern = NULL;
if (ret) if (ret)
goto exit_fail; goto exit_fail;
trigger = ieee80211_get_rx_led_name(priv->hw); trigger = ieee80211_get_rx_led_name(priv->hw);
snprintf(name, sizeof(name), "iwl-%s:RX", wiphy_name(priv->hw->wiphy)); snprintf(priv->led[IWL_LED_TRG_RX].name,
sizeof(priv->led[IWL_LED_TRG_RX].name), "iwl-%s:RX",
wiphy_name(priv->hw->wiphy));
ret = iwl_leds_register_led(priv, &priv->led[IWL_LED_TRG_RX], ret = iwl_leds_register_led(priv, &priv->led[IWL_LED_TRG_RX],
IWL_LED_TRG_RX, 0, name, trigger); IWL_LED_TRG_RX, 0, trigger);
priv->led[IWL_LED_TRG_RX].led_on = iwl_led_associated; priv->led[IWL_LED_TRG_RX].led_on = iwl_led_associated;
priv->led[IWL_LED_TRG_RX].led_off = iwl_led_associated; priv->led[IWL_LED_TRG_RX].led_off = iwl_led_associated;
...@@ -388,9 +398,12 @@ int iwl_leds_register(struct iwl_priv *priv) ...@@ -388,9 +398,12 @@ int iwl_leds_register(struct iwl_priv *priv)
goto exit_fail; goto exit_fail;
trigger = ieee80211_get_tx_led_name(priv->hw); trigger = ieee80211_get_tx_led_name(priv->hw);
snprintf(name, sizeof(name), "iwl-%s:TX", wiphy_name(priv->hw->wiphy)); snprintf(priv->led[IWL_LED_TRG_TX].name,
sizeof(priv->led[IWL_LED_TRG_TX].name), "iwl-%s:TX",
wiphy_name(priv->hw->wiphy));
ret = iwl_leds_register_led(priv, &priv->led[IWL_LED_TRG_TX], ret = iwl_leds_register_led(priv, &priv->led[IWL_LED_TRG_TX],
IWL_LED_TRG_TX, 0, name, trigger); IWL_LED_TRG_TX, 0, trigger);
priv->led[IWL_LED_TRG_TX].led_on = iwl_led_associated; priv->led[IWL_LED_TRG_TX].led_on = iwl_led_associated;
priv->led[IWL_LED_TRG_TX].led_off = iwl_led_associated; priv->led[IWL_LED_TRG_TX].led_off = iwl_led_associated;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment