aboutsummaryrefslogtreecommitdiff
path: root/drivers/net/wireless/iwlwifi/iwl-agn.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl-agn.c')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.c791
1 files changed, 57 insertions, 734 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index 1ef4192207a..277dfc57fde 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -102,7 +102,7 @@ MODULE_ALIAS("iwl4965");
* function correctly transitions out of the RXON_ASSOC_MSK state if
* a HW tune is required based on the RXON structure changes.
*/
-static int iwl_commit_rxon(struct iwl_priv *priv)
+int iwl_commit_rxon(struct iwl_priv *priv)
{
/* cast away the const for active_rxon in this function */
struct iwl_rxon_cmd *active_rxon = (void *)&priv->active_rxon;
@@ -188,7 +188,7 @@ static int iwl_commit_rxon(struct iwl_priv *priv)
memcpy(active_rxon, &priv->staging_rxon, sizeof(*active_rxon));
}
- iwl_clear_stations_table(priv);
+ priv->cfg->ops->smgmt->clear_station_table(priv);
if (!priv->error_recovering)
priv->start_calib = 0;
@@ -246,8 +246,9 @@ static int iwl_commit_rxon(struct iwl_priv *priv)
void iwl_update_chain_flags(struct iwl_priv *priv)
{
- iwl_set_rxon_chain(priv);
- iwl_commit_rxon(priv);
+ if (priv->cfg->ops->hcmd->set_rxon_chain)
+ priv->cfg->ops->hcmd->set_rxon_chain(priv);
+ iwlcore_commit_rxon(priv);
}
static void iwl_clear_free_frames(struct iwl_priv *priv)
@@ -531,76 +532,6 @@ int iwl_hw_tx_queue_init(struct iwl_priv *priv,
*
******************************************************************************/
-static void iwl_ht_conf(struct iwl_priv *priv,
- struct ieee80211_bss_conf *bss_conf)
-{
- struct ieee80211_sta_ht_cap *ht_conf;
- struct iwl_ht_info *iwl_conf = &priv->current_ht_config;
- struct ieee80211_sta *sta;
-
- IWL_DEBUG_MAC80211(priv, "enter: \n");
-
- if (!iwl_conf->is_ht)
- return;
-
-
- /*
- * It is totally wrong to base global information on something
- * that is valid only when associated, alas, this driver works
- * that way and I don't know how to fix it.
- */
-
- rcu_read_lock();
- sta = ieee80211_find_sta(priv->hw, priv->bssid);
- if (!sta) {
- rcu_read_unlock();
- return;
- }
- ht_conf = &sta->ht_cap;
-
- if (ht_conf->cap & IEEE80211_HT_CAP_SGI_20)
- iwl_conf->sgf |= HT_SHORT_GI_20MHZ;
- if (ht_conf->cap & IEEE80211_HT_CAP_SGI_40)
- iwl_conf->sgf |= HT_SHORT_GI_40MHZ;
-
- iwl_conf->is_green_field = !!(ht_conf->cap & IEEE80211_HT_CAP_GRN_FLD);
- iwl_conf->max_amsdu_size =
- !!(ht_conf->cap & IEEE80211_HT_CAP_MAX_AMSDU);
-
- iwl_conf->supported_chan_width =
- !!(ht_conf->cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40);
-
- /*
- * XXX: The HT configuration needs to be moved into iwl_mac_config()
- * to be done there correctly.
- */
-
- iwl_conf->extension_chan_offset = IEEE80211_HT_PARAM_CHA_SEC_NONE;
- if (conf_is_ht40_minus(&priv->hw->conf))
- iwl_conf->extension_chan_offset = IEEE80211_HT_PARAM_CHA_SEC_BELOW;
- else if (conf_is_ht40_plus(&priv->hw->conf))
- iwl_conf->extension_chan_offset = IEEE80211_HT_PARAM_CHA_SEC_ABOVE;
-
- /* If no above or below channel supplied disable FAT channel */
- if (iwl_conf->extension_chan_offset != IEEE80211_HT_PARAM_CHA_SEC_ABOVE &&
- iwl_conf->extension_chan_offset != IEEE80211_HT_PARAM_CHA_SEC_BELOW)
- iwl_conf->supported_chan_width = 0;
-
- iwl_conf->sm_ps = (u8)((ht_conf->cap & IEEE80211_HT_CAP_SM_PS) >> 2);
-
- memcpy(&iwl_conf->mcs, &ht_conf->mcs, 16);
-
- iwl_conf->tx_chan_width = iwl_conf->supported_chan_width != 0;
- iwl_conf->ht_protection =
- bss_conf->ht.operation_mode & IEEE80211_HT_OP_MODE_PROTECTION;
- iwl_conf->non_GF_STA_present =
- !!(bss_conf->ht.operation_mode & IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT);
-
- rcu_read_unlock();
-
- IWL_DEBUG_MAC80211(priv, "leave\n");
-}
-
#define MAX_UCODE_BEACON_INTERVAL 4096
static u16 iwl_adjust_beacon_interval(u16 beacon_val)
@@ -657,30 +588,6 @@ static void iwl_setup_rxon_timing(struct iwl_priv *priv)
le16_to_cpu(priv->rxon_timing.atim_window));
}
-static int iwl_set_mode(struct iwl_priv *priv, int mode)
-{
- iwl_connection_init_rx_config(priv, mode);
- iwl_set_rxon_chain(priv);
- memcpy(priv->staging_rxon.node_addr, priv->mac_addr, ETH_ALEN);
-
- iwl_clear_stations_table(priv);
-
- /* dont commit rxon if rf-kill is on*/
- if (!iwl_is_ready_rf(priv))
- return -EAGAIN;
-
- cancel_delayed_work(&priv->scan_check);
- if (iwl_scan_cancel_timeout(priv, 100)) {
- IWL_WARN(priv, "Aborted scan still in progress after 100ms\n");
- IWL_DEBUG_MAC80211(priv, "leaving - scan abort failed.\n");
- return -EAGAIN;
- }
-
- iwl_commit_rxon(priv);
-
- return 0;
-}
-
/******************************************************************************
*
* Generic RX handler implementations
@@ -1002,6 +909,7 @@ void iwl_rx_handle(struct iwl_priv *priv)
IWL_DEBUG_RX(priv, "r = %d, i = %d, %s, 0x%02x\n", r,
i, get_cmd_string(pkt->hdr.cmd), pkt->hdr.cmd);
priv->rx_handlers[pkt->hdr.cmd] (priv, rxb);
+ priv->isr_stats.rx_handlers[pkt->hdr.cmd]++;
} else {
/* No handling needed */
IWL_DEBUG_RX(priv,
@@ -1065,7 +973,7 @@ static void iwl_error_recovery(struct iwl_priv *priv)
memcpy(&priv->staging_rxon, &priv->recovery_rxon,
sizeof(priv->staging_rxon));
priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
- iwl_commit_rxon(priv);
+ iwlcore_commit_rxon(priv);
iwl_rxon_add_station(priv, priv->bssid, 1);
@@ -1123,6 +1031,7 @@ static void iwl_irq_tasklet(struct iwl_priv *priv)
/* Tell the device to stop sending interrupts */
iwl_disable_interrupts(priv);
+ priv->isr_stats.hw++;
iwl_irq_handle_error(priv);
handled |= CSR_INT_BIT_HW_ERR;
@@ -1135,13 +1044,17 @@ static void iwl_irq_tasklet(struct iwl_priv *priv)
#ifdef CONFIG_IWLWIFI_DEBUG
if (priv->debug_level & (IWL_DL_ISR)) {
/* NIC fires this, but we don't use it, redundant with WAKEUP */
- if (inta & CSR_INT_BIT_SCD)
+ if (inta & CSR_INT_BIT_SCD) {
IWL_DEBUG_ISR(priv, "Scheduler finished to transmit "
"the frame/frames.\n");
+ priv->isr_stats.sch++;
+ }
/* Alive notification via Rx interrupt will do the real work */
- if (inta & CSR_INT_BIT_ALIVE)
+ if (inta & CSR_INT_BIT_ALIVE) {
IWL_DEBUG_ISR(priv, "Alive interrupt\n");
+ priv->isr_stats.alive++;
+ }
}
#endif
/* Safely ignore these bits for debug checks below */
@@ -1157,6 +1070,8 @@ static void iwl_irq_tasklet(struct iwl_priv *priv)
IWL_DEBUG_RF_KILL(priv, "RF_KILL bit toggled to %s.\n",
hw_rf_kill ? "disable radio" : "enable radio");
+ priv->isr_stats.rfkill++;
+
/* driver only loads ucode once setting the interface up.
* the driver allows loading the ucode even if the radio
* is killed. Hence update the killswitch state here. The
@@ -1176,6 +1091,7 @@ static void iwl_irq_tasklet(struct iwl_priv *priv)
/* Chip got too hot and stopped itself */
if (inta & CSR_INT_BIT_CT_KILL) {
IWL_ERR(priv, "Microcode CT kill error detected.\n");
+ priv->isr_stats.ctkill++;
handled |= CSR_INT_BIT_CT_KILL;
}
@@ -1183,6 +1099,8 @@ static void iwl_irq_tasklet(struct iwl_priv *priv)
if (inta & CSR_INT_BIT_SW_ERR) {
IWL_ERR(priv, "Microcode SW error detected. "
" Restarting 0x%X.\n", inta);
+ priv->isr_stats.sw++;
+ priv->isr_stats.sw_err = inta;
iwl_irq_handle_error(priv);
handled |= CSR_INT_BIT_SW_ERR;
}
@@ -1198,6 +1116,8 @@ static void iwl_irq_tasklet(struct iwl_priv *priv)
iwl_txq_update_write_ptr(priv, &priv->txq[4]);
iwl_txq_update_write_ptr(priv, &priv->txq[5]);
+ priv->isr_stats.wakeup++;
+
handled |= CSR_INT_BIT_WAKEUP;
}
@@ -1206,19 +1126,23 @@ static void iwl_irq_tasklet(struct iwl_priv *priv)
* notifications from uCode come through here*/
if (inta & (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX)) {
iwl_rx_handle(priv);
+ priv->isr_stats.rx++;
handled |= (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX);
}
if (inta & CSR_INT_BIT_FH_TX) {
IWL_DEBUG_ISR(priv, "Tx interrupt\n");
+ priv->isr_stats.tx++;
handled |= CSR_INT_BIT_FH_TX;
/* FH finished to write, send event */
priv->ucode_write_complete = 1;
wake_up_interruptible(&priv->wait_command_queue);
}
- if (inta & ~handled)
+ if (inta & ~handled) {
IWL_ERR(priv, "Unhandled INTA bits 0x%08x\n", inta & ~handled);
+ priv->isr_stats.unhandled++;
+ }
if (inta & ~CSR_INI_SET_MASK) {
IWL_WARN(priv, "Disabled INTA bits 0x%08x were pending\n",
@@ -1243,6 +1167,7 @@ static void iwl_irq_tasklet(struct iwl_priv *priv)
spin_unlock_irqrestore(&priv->lock, flags);
}
+
/******************************************************************************
*
* uCode download functions
@@ -1508,10 +1433,6 @@ static int iwl_read_ucode(struct iwl_priv *priv)
return ret;
}
-/* temporary */
-static int iwl_mac_beacon_update(struct ieee80211_hw *hw,
- struct sk_buff *skb);
-
/**
* iwl_alive_start - called after REPLY_ALIVE notification received
* from protocol/runtime uCode (initialization uCode's
@@ -1540,7 +1461,7 @@ static void iwl_alive_start(struct iwl_priv *priv)
goto restart;
}
- iwl_clear_stations_table(priv);
+ priv->cfg->ops->smgmt->clear_station_table(priv);
ret = priv->cfg->ops->lib->alive_notify(priv);
if (ret) {
IWL_WARN(priv,
@@ -1568,7 +1489,10 @@ static void iwl_alive_start(struct iwl_priv *priv)
} else {
/* Initialize our rx_config data */
iwl_connection_init_rx_config(priv, priv->iw_mode);
- iwl_set_rxon_chain(priv);
+
+ if (priv->cfg->ops->hcmd->set_rxon_chain)
+ priv->cfg->ops->hcmd->set_rxon_chain(priv);
+
memcpy(priv->staging_rxon.node_addr, priv->mac_addr, ETH_ALEN);
}
@@ -1578,7 +1502,7 @@ static void iwl_alive_start(struct iwl_priv *priv)
iwl_reset_run_time_calib(priv);
/* Configure the adapter for unassociated operation */
- iwl_commit_rxon(priv);
+ iwlcore_commit_rxon(priv);
/* At this point, the NIC is initialized and operational */
iwl_rf_kill_ct_config(priv);
@@ -1626,7 +1550,7 @@ static void __iwl_down(struct iwl_priv *priv)
iwl_leds_unregister(priv);
- iwl_clear_stations_table(priv);
+ priv->cfg->ops->smgmt->clear_station_table(priv);
/* Unblock any waiting calls */
wake_up_interruptible_all(&priv->wait_command_queue);
@@ -1649,7 +1573,7 @@ static void __iwl_down(struct iwl_priv *priv)
ieee80211_stop_queues(priv->hw);
/* If we have not previously called iwl_init() then
- * clear all bits but the RF Kill and SUSPEND bits and return */
+ * clear all bits but the RF Kill bits and return */
if (!iwl_is_init(priv)) {
priv->status = test_bit(STATUS_RF_KILL_HW, &priv->status) <<
STATUS_RF_KILL_HW |
@@ -1657,23 +1581,19 @@ static void __iwl_down(struct iwl_priv *priv)
STATUS_RF_KILL_SW |
test_bit(STATUS_GEO_CONFIGURED, &priv->status) <<
STATUS_GEO_CONFIGURED |
- test_bit(STATUS_IN_SUSPEND, &priv->status) <<
- STATUS_IN_SUSPEND |
test_bit(STATUS_EXIT_PENDING, &priv->status) <<
STATUS_EXIT_PENDING;
goto exit;
}
- /* ...otherwise clear out all the status bits but the RF Kill and
- * SUSPEND bits and continue taking the NIC down. */
+ /* ...otherwise clear out all the status bits but the RF Kill
+ * bits and continue taking the NIC down. */
priv->status &= test_bit(STATUS_RF_KILL_HW, &priv->status) <<
STATUS_RF_KILL_HW |
test_bit(STATUS_RF_KILL_SW, &priv->status) <<
STATUS_RF_KILL_SW |
test_bit(STATUS_GEO_CONFIGURED, &priv->status) <<
STATUS_GEO_CONFIGURED |
- test_bit(STATUS_IN_SUSPEND, &priv->status) <<
- STATUS_IN_SUSPEND |
test_bit(STATUS_FW_ERROR, &priv->status) <<
STATUS_FW_ERROR |
test_bit(STATUS_EXIT_PENDING, &priv->status) <<
@@ -1698,7 +1618,7 @@ static void __iwl_down(struct iwl_priv *priv)
udelay(5);
/* FIXME: apm_ops.suspend(priv) */
- if (exit_pending || test_bit(STATUS_IN_SUSPEND, &priv->status))
+ if (exit_pending)
priv->cfg->ops->lib->apm_ops.stop(priv);
else
priv->cfg->ops->lib->apm_ops.reset(priv);
@@ -1781,7 +1701,7 @@ static int __iwl_up(struct iwl_priv *priv)
for (i = 0; i < MAX_HW_RESTARTS; i++) {
- iwl_clear_stations_table(priv);
+ priv->cfg->ops->smgmt->clear_station_table(priv);
/* load bootstrap state machine,
* load bootstrap program into processor's memory,
@@ -1910,7 +1830,7 @@ static void iwl_bg_rx_replenish(struct work_struct *data)
#define IWL_DELAY_NEXT_SCAN (HZ*2)
-static void iwl_post_associate(struct iwl_priv *priv)
+void iwl_post_associate(struct iwl_priv *priv)
{
struct ieee80211_conf *conf = NULL;
int ret = 0;
@@ -1938,7 +1858,7 @@ static void iwl_post_associate(struct iwl_priv *priv)
conf = ieee80211_get_hw_conf(priv->hw);
priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
- iwl_commit_rxon(priv);
+ iwlcore_commit_rxon(priv);
iwl_setup_rxon_timing(priv);
ret = iwl_send_cmd_pdu(priv, REPLY_RXON_TIMING,
@@ -1951,7 +1871,9 @@ static void iwl_post_associate(struct iwl_priv *priv)
iwl_set_rxon_ht(priv, &priv->current_ht_config);
- iwl_set_rxon_chain(priv);
+ if (priv->cfg->ops->hcmd->set_rxon_chain)
+ priv->cfg->ops->hcmd->set_rxon_chain(priv);
+
priv->staging_rxon.assoc_id = cpu_to_le16(priv->assoc_id);
IWL_DEBUG_ASSOC(priv, "assoc id %d beacon interval %d\n",
@@ -1973,7 +1895,7 @@ static void iwl_post_associate(struct iwl_priv *priv)
}
- iwl_commit_rxon(priv);
+ iwlcore_commit_rxon(priv);
switch (priv->iw_mode) {
case NL80211_IFTYPE_STATION:
@@ -2059,9 +1981,6 @@ static int iwl_mac_start(struct ieee80211_hw *hw)
IWL_DEBUG_INFO(priv, "Start UP work done.\n");
- if (test_bit(STATUS_IN_SUSPEND, &priv->status))
- return 0;
-
/* Wait for START_ALIVE from Run Time ucode. Otherwise callbacks from
* mac80211 will not be run successfully. */
ret = wait_event_interruptible_timeout(priv->wait_command_queue,
@@ -2130,175 +2049,7 @@ static int iwl_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
return NETDEV_TX_OK;
}
-static int iwl_mac_add_interface(struct ieee80211_hw *hw,
- struct ieee80211_if_init_conf *conf)
-{
- struct iwl_priv *priv = hw->priv;
- unsigned long flags;
-
- IWL_DEBUG_MAC80211(priv, "enter: type %d\n", conf->type);
-
- if (priv->vif) {
- IWL_DEBUG_MAC80211(priv, "leave - vif != NULL\n");
- return -EOPNOTSUPP;
- }
-
- spin_lock_irqsave(&priv->lock, flags);
- priv->vif = conf->vif;
- priv->iw_mode = conf->type;
-
- spin_unlock_irqrestore(&priv->lock, flags);
-
- mutex_lock(&priv->mutex);
-
- if (conf->mac_addr) {
- IWL_DEBUG_MAC80211(priv, "Set %pM\n", conf->mac_addr);
- memcpy(priv->mac_addr, conf->mac_addr, ETH_ALEN);
- }
-
- if (iwl_set_mode(priv, conf->type) == -EAGAIN)
- /* we are not ready, will run again when ready */
- set_bit(STATUS_MODE_PENDING, &priv->status);
-
- mutex_unlock(&priv->mutex);
-
- IWL_DEBUG_MAC80211(priv, "leave\n");
- return 0;
-}
-
-/**
- * iwl_mac_config - mac80211 config callback
- *
- * We ignore conf->flags & IEEE80211_CONF_SHORT_SLOT_TIME since it seems to
- * be set inappropriately and the driver currently sets the hardware up to
- * use it whenever needed.
- */
-static int iwl_mac_config(struct ieee80211_hw *hw, u32 changed)
-{
- struct iwl_priv *priv = hw->priv;
- const struct iwl_channel_info *ch_info;
- struct ieee80211_conf *conf = &hw->conf;
- unsigned long flags = 0;
- int ret = 0;
- u16 ch;
- int scan_active = 0;
-
- mutex_lock(&priv->mutex);
- IWL_DEBUG_MAC80211(priv, "enter to channel %d changed 0x%X\n",
- conf->channel->hw_value, changed);
-
- if (unlikely(!priv->cfg->mod_params->disable_hw_scan &&
- test_bit(STATUS_SCANNING, &priv->status))) {
- scan_active = 1;
- IWL_DEBUG_MAC80211(priv, "leave - scanning\n");
- }
-
-
- /* during scanning mac80211 will delay channel setting until
- * scan finish with changed = 0
- */
- if (!changed || (changed & IEEE80211_CONF_CHANGE_CHANNEL)) {
- if (scan_active)
- goto set_ch_out;
-
- ch = ieee80211_frequency_to_channel(conf->channel->center_freq);
- ch_info = iwl_get_channel_info(priv, conf->channel->band, ch);
- if (!is_channel_valid(ch_info)) {
- IWL_DEBUG_MAC80211(priv, "leave - invalid channel\n");
- ret = -EINVAL;
- goto set_ch_out;
- }
-
- if (priv->iw_mode == NL80211_IFTYPE_ADHOC &&
- !is_channel_ibss(ch_info)) {
- IWL_ERR(priv, "channel %d in band %d not "
- "IBSS channel\n",
- conf->channel->hw_value, conf->channel->band);
- ret = -EINVAL;
- goto set_ch_out;
- }
-
- priv->current_ht_config.is_ht = conf_is_ht(conf);
-
- 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 */
- if ((le16_to_cpu(priv->staging_rxon.channel) != ch))
- priv->staging_rxon.flags = 0;
-
- iwl_set_rxon_channel(priv, conf->channel);
-
- iwl_set_flags_for_band(priv, conf->channel->band);
- spin_unlock_irqrestore(&priv->lock, flags);
- set_ch_out:
- /* The list of supported rates and rate mask can be different
- * for each band; since the band may have changed, reset
- * the rate mask to what mac80211 lists */
- iwl_set_rate(priv);
- }
-
- if (changed & IEEE80211_CONF_CHANGE_PS) {
- if (conf->flags & IEEE80211_CONF_PS)
- ret = iwl_power_set_user_mode(priv, IWL_POWER_INDEX_3);
- else
- ret = iwl_power_set_user_mode(priv, IWL_POWER_MODE_CAM);
- if (ret)
- IWL_DEBUG_MAC80211(priv, "Error setting power level\n");
-
- }
-
- if (changed & IEEE80211_CONF_CHANGE_POWER) {
- IWL_DEBUG_MAC80211(priv, "TX Power old=%d new=%d\n",
- priv->tx_power_user_lmt, conf->power_level);
-
- iwl_set_tx_power(priv, conf->power_level, false);
- }
-
- /* call to ensure that 4965 rx_chain is set properly in monitor mode */
- iwl_set_rxon_chain(priv);
-
- if (changed & IEEE80211_CONF_CHANGE_RADIO_ENABLED) {
- if (conf->radio_enabled &&
- iwl_radio_kill_sw_enable_radio(priv)) {
- IWL_DEBUG_MAC80211(priv, "leave - RF-KILL - "
- "waiting for uCode\n");
- goto out;
- }
-
- if (!conf->radio_enabled)
- iwl_radio_kill_sw_disable_radio(priv);
- }
-
- if (!conf->radio_enabled) {
- IWL_DEBUG_MAC80211(priv, "leave - radio disabled\n");
- goto out;
- }
-
- if (!iwl_is_ready(priv)) {
- IWL_DEBUG_MAC80211(priv, "leave - not ready\n");
- goto out;
- }
-
- if (scan_active)
- goto out;
-
- if (memcmp(&priv->active_rxon,
- &priv->staging_rxon, sizeof(priv->staging_rxon)))
- iwl_commit_rxon(priv);
- else
- IWL_DEBUG_INFO(priv, "No re-sending same RXON configuration.\n");
-
-
-out:
- IWL_DEBUG_MAC80211(priv, "leave\n");
- mutex_unlock(&priv->mutex);
- return ret;
-}
-
-static void iwl_config_ap(struct iwl_priv *priv)
+void iwl_config_ap(struct iwl_priv *priv)
{
int ret = 0;
unsigned long flags;
@@ -2311,7 +2062,7 @@ static void iwl_config_ap(struct iwl_priv *priv)
/* RXON - unassoc (to set timing command) */
priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
- iwl_commit_rxon(priv);
+ iwlcore_commit_rxon(priv);
/* RXON Timing */
iwl_setup_rxon_timing(priv);
@@ -2321,7 +2072,8 @@ static void iwl_config_ap(struct iwl_priv *priv)
IWL_WARN(priv, "REPLY_RXON_TIMING failed - "
"Attempting to continue.\n");
- iwl_set_rxon_chain(priv);
+ if (priv->cfg->ops->hcmd->set_rxon_chain)
+ priv->cfg->ops->hcmd->set_rxon_chain(priv);
/* FIXME: what should be the assoc_id for AP? */
priv->staging_rxon.assoc_id = cpu_to_le16(priv->assoc_id);
@@ -2347,7 +2099,7 @@ static void iwl_config_ap(struct iwl_priv *priv)
}
/* restore RXON assoc */
priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK;
- iwl_commit_rxon(priv);
+ iwlcore_commit_rxon(priv);
spin_lock_irqsave(&priv->lock, flags);
iwl_activate_qos(priv, 1);
spin_unlock_irqrestore(&priv->lock, flags);
@@ -2360,194 +2112,6 @@ static void iwl_config_ap(struct iwl_priv *priv)
* clear sta table, add BCAST sta... */
}
-
-static int iwl_mac_config_interface(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif,
- struct ieee80211_if_conf *conf)
-{
- struct iwl_priv *priv = hw->priv;
- int rc;
-
- if (conf == NULL)
- return -EIO;
-
- if (priv->vif != vif) {
- IWL_DEBUG_MAC80211(priv, "leave - priv->vif != vif\n");
- return 0;
- }
-
- if (priv->iw_mode == NL80211_IFTYPE_ADHOC &&
- conf->changed & IEEE80211_IFCC_BEACON) {
- struct sk_buff *beacon = ieee80211_beacon_get(hw, vif);
- if (!beacon)
- return -ENOMEM;
- mutex_lock(&priv->mutex);
- rc = iwl_mac_beacon_update(hw, beacon);
- mutex_unlock(&priv->mutex);
- if (rc)
- return rc;
- }
-
- if (!iwl_is_alive(priv))
- return -EAGAIN;
-
- mutex_lock(&priv->mutex);
-
- if (conf->bssid)
- IWL_DEBUG_MAC80211(priv, "bssid: %pM\n", conf->bssid);
-
-/*
- * very dubious code was here; the probe filtering flag is never set:
- *
- if (unlikely(test_bit(STATUS_SCANNING, &priv->status)) &&
- !(priv->hw->flags & IEEE80211_HW_NO_PROBE_FILTERING)) {
- */
-
- if (priv->iw_mode == NL80211_IFTYPE_AP) {
- if (!conf->bssid) {
- conf->bssid = priv->mac_addr;
- memcpy(priv->bssid, priv->mac_addr, ETH_ALEN);
- IWL_DEBUG_MAC80211(priv, "bssid was set to: %pM\n",
- conf->bssid);
- }
- if (priv->ibss_beacon)
- dev_kfree_skb(priv->ibss_beacon);
-
- priv->ibss_beacon = ieee80211_beacon_get(hw, vif);
- }
-
- if (iwl_is_rfkill(priv))
- goto done;
-
- if (conf->bssid && !is_zero_ether_addr(conf->bssid) &&
- !is_multicast_ether_addr(conf->bssid)) {
- /* If there is currently a HW scan going on in the background
- * then we need to cancel it else the RXON below will fail. */
- if (iwl_scan_cancel_timeout(priv, 100)) {
- IWL_WARN(priv, "Aborted scan still in progress "
- "after 100ms\n");
- IWL_DEBUG_MAC80211(priv, "leaving - scan abort failed.\n");
- mutex_unlock(&priv->mutex);
- return -EAGAIN;
- }
- memcpy(priv->staging_rxon.bssid_addr, conf->bssid, ETH_ALEN);
-
- /* TODO: Audit driver for usage of these members and see
- * if mac80211 deprecates them (priv->bssid looks like it
- * shouldn't be there, but I haven't scanned the IBSS code
- * to verify) - jpk */
- memcpy(priv->bssid, conf->bssid, ETH_ALEN);
-
- if (priv->iw_mode == NL80211_IFTYPE_AP)
- iwl_config_ap(priv);
- else {
- rc = iwl_commit_rxon(priv);
- if ((priv->iw_mode == NL80211_IFTYPE_STATION) && rc)
- iwl_rxon_add_station(
- priv, priv->active_rxon.bssid_addr, 1);
- }
-
- } else {
- iwl_scan_cancel_timeout(priv, 100);
- priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
- iwl_commit_rxon(priv);
- }
-
- done:
- IWL_DEBUG_MAC80211(priv, "leave\n");
- mutex_unlock(&priv->mutex);
-
- return 0;
-}
-
-static void iwl_mac_remove_interface(struct ieee80211_hw *hw,
- struct ieee80211_if_init_conf *conf)
-{
- struct iwl_priv *priv = hw->priv;
-
- IWL_DEBUG_MAC80211(priv, "enter\n");
-
- mutex_lock(&priv->mutex);
-
- if (iwl_is_ready_rf(priv)) {
- iwl_scan_cancel_timeout(priv, 100);
- priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
- iwl_commit_rxon(priv);
- }
- if (priv->vif == conf->vif) {
- priv->vif = NULL;
- memset(priv->bssid, 0, ETH_ALEN);
- }
- mutex_unlock(&priv->mutex);
-
- IWL_DEBUG_MAC80211(priv, "leave\n");
-
-}
-
-#define IWL_DELAY_NEXT_SCAN_AFTER_ASSOC (HZ*6)
-static void iwl_bss_info_changed(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif,
- struct ieee80211_bss_conf *bss_conf,
- u32 changes)
-{
- struct iwl_priv *priv = hw->priv;
-
- IWL_DEBUG_MAC80211(priv, "changes = 0x%X\n", changes);
-
- if (changes & BSS_CHANGED_ERP_PREAMBLE) {
- IWL_DEBUG_MAC80211(priv, "ERP_PREAMBLE %d\n",
- bss_conf->use_short_preamble);
- if (bss_conf->use_short_preamble)
- priv->staging_rxon.flags |= RXON_FLG_SHORT_PREAMBLE_MSK;
- else
- priv->staging_rxon.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK;
- }
-
- if (changes & BSS_CHANGED_ERP_CTS_PROT) {
- IWL_DEBUG_MAC80211(priv, "ERP_CTS %d\n", bss_conf->use_cts_prot);
- if (bss_conf->use_cts_prot && (priv->band != IEEE80211_BAND_5GHZ))
- priv->staging_rxon.flags |= RXON_FLG_TGG_PROTECT_MSK;
- else
- priv->staging_rxon.flags &= ~RXON_FLG_TGG_PROTECT_MSK;
- }
-
- if (changes & BSS_CHANGED_HT) {
- iwl_ht_conf(priv, bss_conf);
- iwl_set_rxon_chain(priv);
- }
-
- if (changes & BSS_CHANGED_ASSOC) {
- IWL_DEBUG_MAC80211(priv, "ASSOC %d\n", bss_conf->assoc);
- /* This should never happen as this function should
- * never be called from interrupt context. */
- if (WARN_ON_ONCE(in_interrupt()))
- return;
- 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;
-
- /* we have just associated, don't start scan too early
- * leave time for EAPOL exchange to complete
- */
- priv->next_scan_jiffies = jiffies +
- IWL_DELAY_NEXT_SCAN_AFTER_ASSOC;
- mutex_lock(&priv->mutex);
- iwl_post_associate(priv);
- mutex_unlock(&priv->mutex);
- } else {
- priv->assoc_id = 0;
- IWL_DEBUG_MAC80211(priv, "DISASSOC %d\n", bss_conf->assoc);
- }
- } else if (changes && iwl_is_associated(priv) && priv->assoc_id) {
- IWL_DEBUG_MAC80211(priv, "Associated Changes %d\n", changes);
- iwl_send_rxon_assoc(priv);
- }
-
-}
-
static void iwl_mac_update_tkip_key(struct ieee80211_hw *hw,
struct ieee80211_key_conf *keyconf, const u8 *addr,
u32 iv32, u16 *phase1key)
@@ -2579,7 +2143,7 @@ static int iwl_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
return -EOPNOTSUPP;
}
addr = sta ? sta->addr : iwl_bcast_addr;
- sta_id = iwl_find_station(priv, addr);
+ sta_id = priv->cfg->ops->smgmt->find_station(priv, addr);
if (sta_id == IWL_INVALID_STATION) {
IWL_DEBUG_MAC80211(priv, "leave - %pM not in station map.\n",
addr);
@@ -2630,49 +2194,6 @@ static int iwl_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
return ret;
}
-static int iwl_mac_conf_tx(struct ieee80211_hw *hw, u16 queue,
- const struct ieee80211_tx_queue_params *params)
-{
- struct iwl_priv *priv = hw->priv;
- unsigned long flags;
- int q;
-
- IWL_DEBUG_MAC80211(priv, "enter\n");
-
- if (!iwl_is_ready_rf(priv)) {
- IWL_DEBUG_MAC80211(priv, "leave - RF not ready\n");
- return -EIO;
- }
-
- if (queue >= AC_NUM) {
- IWL_DEBUG_MAC80211(priv, "leave - queue >= AC_NUM %d\n", queue);
- return 0;
- }
-
- q = AC_NUM - 1 - queue;
-
- spin_lock_irqsave(&priv->lock, flags);
-
- priv->qos_data.def_qos_parm.ac[q].cw_min = cpu_to_le16(params->cw_min);
- priv->qos_data.def_qos_parm.ac[q].cw_max = cpu_to_le16(params->cw_max);
- priv->qos_data.def_qos_parm.ac[q].aifsn = params->aifs;
- priv->qos_data.def_qos_parm.ac[q].edca_txop =
- cpu_to_le16((params->txop * 32));
-
- priv->qos_data.def_qos_parm.ac[q].reserved1 = 0;
- priv->qos_data.qos_active = 1;
-
- if (priv->iw_mode == NL80211_IFTYPE_AP)
- iwl_activate_qos(priv, 1);
- else if (priv->assoc_id && iwl_is_associated(priv))
- iwl_activate_qos(priv, 0);
-
- spin_unlock_irqrestore(&priv->lock, flags);
-
- IWL_DEBUG_MAC80211(priv, "leave\n");
- return 0;
-}
-
static int iwl_mac_ampdu_action(struct ieee80211_hw *hw,
enum ieee80211_ampdu_mlme_action action,
struct ieee80211_sta *sta, u16 tid, u16 *ssn)
@@ -2715,41 +2236,6 @@ static int iwl_mac_ampdu_action(struct ieee80211_hw *hw,
return 0;
}
-static int iwl_mac_get_tx_stats(struct ieee80211_hw *hw,
- struct ieee80211_tx_queue_stats *stats)
-{
- struct iwl_priv *priv = hw->priv;
- int i, avail;
- struct iwl_tx_queue *txq;
- struct iwl_queue *q;
- unsigned long flags;
-
- IWL_DEBUG_MAC80211(priv, "enter\n");
-
- if (!iwl_is_ready_rf(priv)) {
- IWL_DEBUG_MAC80211(priv, "leave - RF not ready\n");
- return -EIO;
- }
-
- spin_lock_irqsave(&priv->lock, flags);
-
- for (i = 0; i < AC_NUM; i++) {
- txq = &priv->txq[i];
- q = &txq->q;
- avail = iwl_queue_space(q);
-
- stats[i].len = q->n_window - avail;
- stats[i].limit = q->n_window - q->high_mark;
- stats[i].count = q->n_window;
-
- }
- spin_unlock_irqrestore(&priv->lock, flags);
-
- IWL_DEBUG_MAC80211(priv, "leave\n");
-
- return 0;
-}
-
static int iwl_mac_get_stats(struct ieee80211_hw *hw,
struct ieee80211_low_level_stats *stats)
{
@@ -2762,120 +2248,6 @@ static int iwl_mac_get_stats(struct ieee80211_hw *hw,
return 0;
}
-static void iwl_mac_reset_tsf(struct ieee80211_hw *hw)
-{
- struct iwl_priv *priv = hw->priv;
- unsigned long flags;
-
- mutex_lock(&priv->mutex);
- IWL_DEBUG_MAC80211(priv, "enter\n");
-
- spin_lock_irqsave(&priv->lock, flags);
- memset(&priv->current_ht_config, 0, sizeof(struct iwl_ht_info));
- spin_unlock_irqrestore(&priv->lock, flags);
-
- iwl_reset_qos(priv);
-
- spin_lock_irqsave(&priv->lock, flags);
- priv->assoc_id = 0;
- priv->assoc_capability = 0;
- priv->assoc_station_added = 0;
-
- /* new association get rid of ibss beacon skb */
- if (priv->ibss_beacon)
- dev_kfree_skb(priv->ibss_beacon);
-
- priv->ibss_beacon = NULL;
-
- priv->beacon_int = priv->hw->conf.beacon_int;
- priv->timestamp = 0;
- if ((priv->iw_mode == NL80211_IFTYPE_STATION))
- priv->beacon_int = 0;
-
- spin_unlock_irqrestore(&priv->lock, flags);
-
- if (!iwl_is_ready_rf(priv)) {
- IWL_DEBUG_MAC80211(priv, "leave - not ready\n");
- mutex_unlock(&priv->mutex);
- return;
- }
-
- /* we are restarting association process
- * clear RXON_FILTER_ASSOC_MSK bit
- */
- if (priv->iw_mode != NL80211_IFTYPE_AP) {
- iwl_scan_cancel_timeout(priv, 100);
- priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
- iwl_commit_rxon(priv);
- }
-
- iwl_power_update_mode(priv, 0);
-
- /* Per mac80211.h: This is only used in IBSS mode... */
- if (priv->iw_mode != NL80211_IFTYPE_ADHOC) {
-
- /* switch to CAM during association period.
- * the ucode will block any association/authentication
- * frome during assiciation period if it can not hear
- * the AP because of PM. the timer enable PM back is
- * association do not complete
- */
- if (priv->hw->conf.channel->flags & (IEEE80211_CHAN_PASSIVE_SCAN |
- IEEE80211_CHAN_RADAR))
- iwl_power_disable_management(priv, 3000);
-
- IWL_DEBUG_MAC80211(priv, "leave - not in IBSS\n");
- mutex_unlock(&priv->mutex);
- return;
- }
-
- iwl_set_rate(priv);
-
- mutex_unlock(&priv->mutex);
-
- IWL_DEBUG_MAC80211(priv, "leave\n");
-}
-
-static int iwl_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb)
-{
- struct iwl_priv *priv = hw->priv;
- unsigned long flags;
- __le64 timestamp;
-
- IWL_DEBUG_MAC80211(priv, "enter\n");
-
- if (!iwl_is_ready_rf(priv)) {
- IWL_DEBUG_MAC80211(priv, "leave - RF not ready\n");
- return -EIO;
- }
-
- if (priv->iw_mode != NL80211_IFTYPE_ADHOC) {
- IWL_DEBUG_MAC80211(priv, "leave - not IBSS\n");
- return -EIO;
- }
-
- spin_lock_irqsave(&priv->lock, flags);
-
- if (priv->ibss_beacon)
- dev_kfree_skb(priv->ibss_beacon);
-
- priv->ibss_beacon = skb;
-
- priv->assoc_id = 0;
- timestamp = ((struct ieee80211_mgmt *)skb->data)->u.beacon.timestamp;
- priv->timestamp = le64_to_cpu(timestamp);
-
- IWL_DEBUG_MAC80211(priv, "leave\n");
- spin_unlock_irqrestore(&priv->lock, flags);
-
- iwl_reset_qos(priv);
-
- iwl_post_associate(priv);
-
-
- return 0;
-}
-
/*****************************************************************************
*
* sysfs attributes
@@ -3025,7 +2397,7 @@ static ssize_t store_flags(struct device *d,
else {
IWL_DEBUG_INFO(priv, "Commit rxon.flags = 0x%04X\n", flags);
priv->staging_rxon.flags = cpu_to_le32(flags);
- iwl_commit_rxon(priv);
+ iwlcore_commit_rxon(priv);
}
}
mutex_unlock(&priv->mutex);
@@ -3066,7 +2438,7 @@ static ssize_t store_filter_flags(struct device *d,
"0x%04X\n", filter_flags);
priv->staging_rxon.filter_flags =
cpu_to_le32(filter_flags);
- iwl_commit_rxon(priv);
+ iwlcore_commit_rxon(priv);
}
}
mutex_unlock(&priv->mutex);
@@ -3397,18 +2769,8 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
goto out_free_eeprom;
/* At this point both hw and priv are initialized. */
- /**********************************
- * 7. Initialize module parameters
- **********************************/
-
- /* Disable radio (SW RF KILL) via parameter when loading driver */
- if (priv->cfg->mod_params->disable) {
- set_bit(STATUS_RF_KILL_SW, &priv->status);
- IWL_DEBUG_INFO(priv, "Radio disabled.\n");
- }
-
/********************
- * 8. Setup services
+ * 7. Setup services
********************/
spin_lock_irqsave(&priv->lock, flags);
iwl_disable_interrupts(priv);
@@ -3432,7 +2794,7 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
iwl_setup_rx_handlers(priv);
/**********************************
- * 9. Setup and register mac80211
+ * 8. Setup and register mac80211
**********************************/
/* enable interrupts if needed: hw bug w/a */
@@ -3450,7 +2812,7 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
err = iwl_dbgfs_register(priv, DRV_NAME);
if (err)
- IWL_ERR(priv, "failed to create debugfs files\n");
+ IWL_ERR(priv, "failed to create debugfs files. Ignoring error: %d\n", err);
/* 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)
@@ -3533,7 +2895,7 @@ static void __devexit iwl_pci_remove(struct pci_dev *pdev)
iwl_rx_queue_free(priv, &priv->rxq);
iwl_hw_txq_ctx_free(priv);
- iwl_clear_stations_table(priv);
+ priv->cfg->ops->smgmt->clear_station_table(priv);
iwl_eeprom_free(priv);
@@ -3561,45 +2923,6 @@ static void __devexit iwl_pci_remove(struct pci_dev *pdev)
ieee80211_free_hw(priv->hw);
}
-#ifdef CONFIG_PM
-
-static int iwl_pci_suspend(struct pci_dev *pdev, pm_message_t state)
-{
- struct iwl_priv *priv = pci_get_drvdata(pdev);
-
- if (priv->is_open) {
- set_bit(STATUS_IN_SUSPEND, &priv->status);
- iwl_mac_stop(priv->hw);
- priv->is_open = 1;
- }
-
- pci_save_state(pdev);
- pci_disable_device(pdev);
- pci_set_power_state(pdev, PCI_D3hot);
-
- return 0;
-}
-
-static int iwl_pci_resume(struct pci_dev *pdev)
-{
- struct iwl_priv *priv = pci_get_drvdata(pdev);
- int ret;
-
- pci_set_power_state(pdev, PCI_D0);
- ret = pci_enable_device(pdev);
- if (ret)
- return ret;
- pci_restore_state(pdev);
- iwl_enable_interrupts(priv);
-
- if (priv->is_open)
- iwl_mac_start(priv->hw);
-
- clear_bit(STATUS_IN_SUSPEND, &priv->status);
- return 0;
-}
-
-#endif /* CONFIG_PM */
/*****************************************************************************
*