|
@@ -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 */
|
|
|
|
|
|
/*****************************************************************************
|
|
|
*
|