diff options
author | David S. Miller <davem@davemloft.net> | 2009-04-25 19:36:46 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-04-25 19:36:46 -0400 |
commit | 495a1b4eff1a216a3ea171ac137f1807e6555f52 (patch) | |
tree | 72d059d6d66fac6a74df33bac2eb40dcd0ea0732 /drivers/net/wireless/iwlwifi/iwl-agn.c | |
parent | ad8affd972a705a38e769859c50ee8e749b631da (diff) | |
parent | d3feaf5ad12259927039a675cfb25dc342b403ab (diff) |
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next-2.6
Conflicts:
net/mac80211/pm.c
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl-agn.c')
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-agn.c | 791 |
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 1ef4192207a5..277dfc57fde9 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c | |||
@@ -102,7 +102,7 @@ MODULE_ALIAS("iwl4965"); | |||
102 | * function correctly transitions out of the RXON_ASSOC_MSK state if | 102 | * function correctly transitions out of the RXON_ASSOC_MSK state if |
103 | * a HW tune is required based on the RXON structure changes. | 103 | * a HW tune is required based on the RXON structure changes. |
104 | */ | 104 | */ |
105 | static int iwl_commit_rxon(struct iwl_priv *priv) | 105 | int iwl_commit_rxon(struct iwl_priv *priv) |
106 | { | 106 | { |
107 | /* cast away the const for active_rxon in this function */ | 107 | /* cast away the const for active_rxon in this function */ |
108 | struct iwl_rxon_cmd *active_rxon = (void *)&priv->active_rxon; | 108 | struct iwl_rxon_cmd *active_rxon = (void *)&priv->active_rxon; |
@@ -188,7 +188,7 @@ static int iwl_commit_rxon(struct iwl_priv *priv) | |||
188 | memcpy(active_rxon, &priv->staging_rxon, sizeof(*active_rxon)); | 188 | memcpy(active_rxon, &priv->staging_rxon, sizeof(*active_rxon)); |
189 | } | 189 | } |
190 | 190 | ||
191 | iwl_clear_stations_table(priv); | 191 | priv->cfg->ops->smgmt->clear_station_table(priv); |
192 | 192 | ||
193 | if (!priv->error_recovering) | 193 | if (!priv->error_recovering) |
194 | priv->start_calib = 0; | 194 | priv->start_calib = 0; |
@@ -246,8 +246,9 @@ static int iwl_commit_rxon(struct iwl_priv *priv) | |||
246 | void iwl_update_chain_flags(struct iwl_priv *priv) | 246 | void iwl_update_chain_flags(struct iwl_priv *priv) |
247 | { | 247 | { |
248 | 248 | ||
249 | iwl_set_rxon_chain(priv); | 249 | if (priv->cfg->ops->hcmd->set_rxon_chain) |
250 | iwl_commit_rxon(priv); | 250 | priv->cfg->ops->hcmd->set_rxon_chain(priv); |
251 | iwlcore_commit_rxon(priv); | ||
251 | } | 252 | } |
252 | 253 | ||
253 | static void iwl_clear_free_frames(struct iwl_priv *priv) | 254 | static void iwl_clear_free_frames(struct iwl_priv *priv) |
@@ -531,76 +532,6 @@ int iwl_hw_tx_queue_init(struct iwl_priv *priv, | |||
531 | * | 532 | * |
532 | ******************************************************************************/ | 533 | ******************************************************************************/ |
533 | 534 | ||
534 | static void iwl_ht_conf(struct iwl_priv *priv, | ||
535 | struct ieee80211_bss_conf *bss_conf) | ||
536 | { | ||
537 | struct ieee80211_sta_ht_cap *ht_conf; | ||
538 | struct iwl_ht_info *iwl_conf = &priv->current_ht_config; | ||
539 | struct ieee80211_sta *sta; | ||
540 | |||
541 | IWL_DEBUG_MAC80211(priv, "enter: \n"); | ||
542 | |||
543 | if (!iwl_conf->is_ht) | ||
544 | return; | ||
545 | |||
546 | |||
547 | /* | ||
548 | * It is totally wrong to base global information on something | ||
549 | * that is valid only when associated, alas, this driver works | ||
550 | * that way and I don't know how to fix it. | ||
551 | */ | ||
552 | |||
553 | rcu_read_lock(); | ||
554 | sta = ieee80211_find_sta(priv->hw, priv->bssid); | ||
555 | if (!sta) { | ||
556 | rcu_read_unlock(); | ||
557 | return; | ||
558 | } | ||
559 | ht_conf = &sta->ht_cap; | ||
560 | |||
561 | if (ht_conf->cap & IEEE80211_HT_CAP_SGI_20) | ||
562 | iwl_conf->sgf |= HT_SHORT_GI_20MHZ; | ||
563 | if (ht_conf->cap & IEEE80211_HT_CAP_SGI_40) | ||
564 | iwl_conf->sgf |= HT_SHORT_GI_40MHZ; | ||
565 | |||
566 | iwl_conf->is_green_field = !!(ht_conf->cap & IEEE80211_HT_CAP_GRN_FLD); | ||
567 | iwl_conf->max_amsdu_size = | ||
568 | !!(ht_conf->cap & IEEE80211_HT_CAP_MAX_AMSDU); | ||
569 | |||
570 | iwl_conf->supported_chan_width = | ||
571 | !!(ht_conf->cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40); | ||
572 | |||
573 | /* | ||
574 | * XXX: The HT configuration needs to be moved into iwl_mac_config() | ||
575 | * to be done there correctly. | ||
576 | */ | ||
577 | |||
578 | iwl_conf->extension_chan_offset = IEEE80211_HT_PARAM_CHA_SEC_NONE; | ||
579 | if (conf_is_ht40_minus(&priv->hw->conf)) | ||
580 | iwl_conf->extension_chan_offset = IEEE80211_HT_PARAM_CHA_SEC_BELOW; | ||
581 | else if (conf_is_ht40_plus(&priv->hw->conf)) | ||
582 | iwl_conf->extension_chan_offset = IEEE80211_HT_PARAM_CHA_SEC_ABOVE; | ||
583 | |||
584 | /* If no above or below channel supplied disable FAT channel */ | ||
585 | if (iwl_conf->extension_chan_offset != IEEE80211_HT_PARAM_CHA_SEC_ABOVE && | ||
586 | iwl_conf->extension_chan_offset != IEEE80211_HT_PARAM_CHA_SEC_BELOW) | ||
587 | iwl_conf->supported_chan_width = 0; | ||
588 | |||
589 | iwl_conf->sm_ps = (u8)((ht_conf->cap & IEEE80211_HT_CAP_SM_PS) >> 2); | ||
590 | |||
591 | memcpy(&iwl_conf->mcs, &ht_conf->mcs, 16); | ||
592 | |||
593 | iwl_conf->tx_chan_width = iwl_conf->supported_chan_width != 0; | ||
594 | iwl_conf->ht_protection = | ||
595 | bss_conf->ht.operation_mode & IEEE80211_HT_OP_MODE_PROTECTION; | ||
596 | iwl_conf->non_GF_STA_present = | ||
597 | !!(bss_conf->ht.operation_mode & IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT); | ||
598 | |||
599 | rcu_read_unlock(); | ||
600 | |||
601 | IWL_DEBUG_MAC80211(priv, "leave\n"); | ||
602 | } | ||
603 | |||
604 | #define MAX_UCODE_BEACON_INTERVAL 4096 | 535 | #define MAX_UCODE_BEACON_INTERVAL 4096 |
605 | 536 | ||
606 | static u16 iwl_adjust_beacon_interval(u16 beacon_val) | 537 | static u16 iwl_adjust_beacon_interval(u16 beacon_val) |
@@ -657,30 +588,6 @@ static void iwl_setup_rxon_timing(struct iwl_priv *priv) | |||
657 | le16_to_cpu(priv->rxon_timing.atim_window)); | 588 | le16_to_cpu(priv->rxon_timing.atim_window)); |
658 | } | 589 | } |
659 | 590 | ||
660 | static int iwl_set_mode(struct iwl_priv *priv, int mode) | ||
661 | { | ||
662 | iwl_connection_init_rx_config(priv, mode); | ||
663 | iwl_set_rxon_chain(priv); | ||
664 | memcpy(priv->staging_rxon.node_addr, priv->mac_addr, ETH_ALEN); | ||
665 | |||
666 | iwl_clear_stations_table(priv); | ||
667 | |||
668 | /* dont commit rxon if rf-kill is on*/ | ||
669 | if (!iwl_is_ready_rf(priv)) | ||
670 | return -EAGAIN; | ||
671 | |||
672 | cancel_delayed_work(&priv->scan_check); | ||
673 | if (iwl_scan_cancel_timeout(priv, 100)) { | ||
674 | IWL_WARN(priv, "Aborted scan still in progress after 100ms\n"); | ||
675 | IWL_DEBUG_MAC80211(priv, "leaving - scan abort failed.\n"); | ||
676 | return -EAGAIN; | ||
677 | } | ||
678 | |||
679 | iwl_commit_rxon(priv); | ||
680 | |||
681 | return 0; | ||
682 | } | ||
683 | |||
684 | /****************************************************************************** | 591 | /****************************************************************************** |
685 | * | 592 | * |
686 | * Generic RX handler implementations | 593 | * Generic RX handler implementations |
@@ -1002,6 +909,7 @@ void iwl_rx_handle(struct iwl_priv *priv) | |||
1002 | IWL_DEBUG_RX(priv, "r = %d, i = %d, %s, 0x%02x\n", r, | 909 | IWL_DEBUG_RX(priv, "r = %d, i = %d, %s, 0x%02x\n", r, |
1003 | i, get_cmd_string(pkt->hdr.cmd), pkt->hdr.cmd); | 910 | i, get_cmd_string(pkt->hdr.cmd), pkt->hdr.cmd); |
1004 | priv->rx_handlers[pkt->hdr.cmd] (priv, rxb); | 911 | priv->rx_handlers[pkt->hdr.cmd] (priv, rxb); |
912 | priv->isr_stats.rx_handlers[pkt->hdr.cmd]++; | ||
1005 | } else { | 913 | } else { |
1006 | /* No handling needed */ | 914 | /* No handling needed */ |
1007 | IWL_DEBUG_RX(priv, | 915 | IWL_DEBUG_RX(priv, |
@@ -1065,7 +973,7 @@ static void iwl_error_recovery(struct iwl_priv *priv) | |||
1065 | memcpy(&priv->staging_rxon, &priv->recovery_rxon, | 973 | memcpy(&priv->staging_rxon, &priv->recovery_rxon, |
1066 | sizeof(priv->staging_rxon)); | 974 | sizeof(priv->staging_rxon)); |
1067 | priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; | 975 | priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; |
1068 | iwl_commit_rxon(priv); | 976 | iwlcore_commit_rxon(priv); |
1069 | 977 | ||
1070 | iwl_rxon_add_station(priv, priv->bssid, 1); | 978 | iwl_rxon_add_station(priv, priv->bssid, 1); |
1071 | 979 | ||
@@ -1123,6 +1031,7 @@ static void iwl_irq_tasklet(struct iwl_priv *priv) | |||
1123 | /* Tell the device to stop sending interrupts */ | 1031 | /* Tell the device to stop sending interrupts */ |
1124 | iwl_disable_interrupts(priv); | 1032 | iwl_disable_interrupts(priv); |
1125 | 1033 | ||
1034 | priv->isr_stats.hw++; | ||
1126 | iwl_irq_handle_error(priv); | 1035 | iwl_irq_handle_error(priv); |
1127 | 1036 | ||
1128 | handled |= CSR_INT_BIT_HW_ERR; | 1037 | handled |= CSR_INT_BIT_HW_ERR; |
@@ -1135,13 +1044,17 @@ static void iwl_irq_tasklet(struct iwl_priv *priv) | |||
1135 | #ifdef CONFIG_IWLWIFI_DEBUG | 1044 | #ifdef CONFIG_IWLWIFI_DEBUG |
1136 | if (priv->debug_level & (IWL_DL_ISR)) { | 1045 | if (priv->debug_level & (IWL_DL_ISR)) { |
1137 | /* NIC fires this, but we don't use it, redundant with WAKEUP */ | 1046 | /* NIC fires this, but we don't use it, redundant with WAKEUP */ |
1138 | if (inta & CSR_INT_BIT_SCD) | 1047 | if (inta & CSR_INT_BIT_SCD) { |
1139 | IWL_DEBUG_ISR(priv, "Scheduler finished to transmit " | 1048 | IWL_DEBUG_ISR(priv, "Scheduler finished to transmit " |
1140 | "the frame/frames.\n"); | 1049 | "the frame/frames.\n"); |
1050 | priv->isr_stats.sch++; | ||
1051 | } | ||
1141 | 1052 | ||
1142 | /* Alive notification via Rx interrupt will do the real work */ | 1053 | /* Alive notification via Rx interrupt will do the real work */ |
1143 | if (inta & CSR_INT_BIT_ALIVE) | 1054 | if (inta & CSR_INT_BIT_ALIVE) { |
1144 | IWL_DEBUG_ISR(priv, "Alive interrupt\n"); | 1055 | IWL_DEBUG_ISR(priv, "Alive interrupt\n"); |
1056 | priv->isr_stats.alive++; | ||
1057 | } | ||
1145 | } | 1058 | } |
1146 | #endif | 1059 | #endif |
1147 | /* Safely ignore these bits for debug checks below */ | 1060 | /* Safely ignore these bits for debug checks below */ |
@@ -1157,6 +1070,8 @@ static void iwl_irq_tasklet(struct iwl_priv *priv) | |||
1157 | IWL_DEBUG_RF_KILL(priv, "RF_KILL bit toggled to %s.\n", | 1070 | IWL_DEBUG_RF_KILL(priv, "RF_KILL bit toggled to %s.\n", |
1158 | hw_rf_kill ? "disable radio" : "enable radio"); | 1071 | hw_rf_kill ? "disable radio" : "enable radio"); |
1159 | 1072 | ||
1073 | priv->isr_stats.rfkill++; | ||
1074 | |||
1160 | /* driver only loads ucode once setting the interface up. | 1075 | /* driver only loads ucode once setting the interface up. |
1161 | * the driver allows loading the ucode even if the radio | 1076 | * the driver allows loading the ucode even if the radio |
1162 | * is killed. Hence update the killswitch state here. The | 1077 | * is killed. Hence update the killswitch state here. The |
@@ -1176,6 +1091,7 @@ static void iwl_irq_tasklet(struct iwl_priv *priv) | |||
1176 | /* Chip got too hot and stopped itself */ | 1091 | /* Chip got too hot and stopped itself */ |
1177 | if (inta & CSR_INT_BIT_CT_KILL) { | 1092 | if (inta & CSR_INT_BIT_CT_KILL) { |
1178 | IWL_ERR(priv, "Microcode CT kill error detected.\n"); | 1093 | IWL_ERR(priv, "Microcode CT kill error detected.\n"); |
1094 | priv->isr_stats.ctkill++; | ||
1179 | handled |= CSR_INT_BIT_CT_KILL; | 1095 | handled |= CSR_INT_BIT_CT_KILL; |
1180 | } | 1096 | } |
1181 | 1097 | ||
@@ -1183,6 +1099,8 @@ static void iwl_irq_tasklet(struct iwl_priv *priv) | |||
1183 | if (inta & CSR_INT_BIT_SW_ERR) { | 1099 | if (inta & CSR_INT_BIT_SW_ERR) { |
1184 | IWL_ERR(priv, "Microcode SW error detected. " | 1100 | IWL_ERR(priv, "Microcode SW error detected. " |
1185 | " Restarting 0x%X.\n", inta); | 1101 | " Restarting 0x%X.\n", inta); |
1102 | priv->isr_stats.sw++; | ||
1103 | priv->isr_stats.sw_err = inta; | ||
1186 | iwl_irq_handle_error(priv); | 1104 | iwl_irq_handle_error(priv); |
1187 | handled |= CSR_INT_BIT_SW_ERR; | 1105 | handled |= CSR_INT_BIT_SW_ERR; |
1188 | } | 1106 | } |
@@ -1198,6 +1116,8 @@ static void iwl_irq_tasklet(struct iwl_priv *priv) | |||
1198 | iwl_txq_update_write_ptr(priv, &priv->txq[4]); | 1116 | iwl_txq_update_write_ptr(priv, &priv->txq[4]); |
1199 | iwl_txq_update_write_ptr(priv, &priv->txq[5]); | 1117 | iwl_txq_update_write_ptr(priv, &priv->txq[5]); |
1200 | 1118 | ||
1119 | priv->isr_stats.wakeup++; | ||
1120 | |||
1201 | handled |= CSR_INT_BIT_WAKEUP; | 1121 | handled |= CSR_INT_BIT_WAKEUP; |
1202 | } | 1122 | } |
1203 | 1123 | ||
@@ -1206,19 +1126,23 @@ static void iwl_irq_tasklet(struct iwl_priv *priv) | |||
1206 | * notifications from uCode come through here*/ | 1126 | * notifications from uCode come through here*/ |
1207 | if (inta & (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX)) { | 1127 | if (inta & (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX)) { |
1208 | iwl_rx_handle(priv); | 1128 | iwl_rx_handle(priv); |
1129 | priv->isr_stats.rx++; | ||
1209 | handled |= (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX); | 1130 | handled |= (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX); |
1210 | } | 1131 | } |
1211 | 1132 | ||
1212 | if (inta & CSR_INT_BIT_FH_TX) { | 1133 | if (inta & CSR_INT_BIT_FH_TX) { |
1213 | IWL_DEBUG_ISR(priv, "Tx interrupt\n"); | 1134 | IWL_DEBUG_ISR(priv, "Tx interrupt\n"); |
1135 | priv->isr_stats.tx++; | ||
1214 | handled |= CSR_INT_BIT_FH_TX; | 1136 | handled |= CSR_INT_BIT_FH_TX; |
1215 | /* FH finished to write, send event */ | 1137 | /* FH finished to write, send event */ |
1216 | priv->ucode_write_complete = 1; | 1138 | priv->ucode_write_complete = 1; |
1217 | wake_up_interruptible(&priv->wait_command_queue); | 1139 | wake_up_interruptible(&priv->wait_command_queue); |
1218 | } | 1140 | } |
1219 | 1141 | ||
1220 | if (inta & ~handled) | 1142 | if (inta & ~handled) { |
1221 | IWL_ERR(priv, "Unhandled INTA bits 0x%08x\n", inta & ~handled); | 1143 | IWL_ERR(priv, "Unhandled INTA bits 0x%08x\n", inta & ~handled); |
1144 | priv->isr_stats.unhandled++; | ||
1145 | } | ||
1222 | 1146 | ||
1223 | if (inta & ~CSR_INI_SET_MASK) { | 1147 | if (inta & ~CSR_INI_SET_MASK) { |
1224 | IWL_WARN(priv, "Disabled INTA bits 0x%08x were pending\n", | 1148 | IWL_WARN(priv, "Disabled INTA bits 0x%08x were pending\n", |
@@ -1243,6 +1167,7 @@ static void iwl_irq_tasklet(struct iwl_priv *priv) | |||
1243 | spin_unlock_irqrestore(&priv->lock, flags); | 1167 | spin_unlock_irqrestore(&priv->lock, flags); |
1244 | } | 1168 | } |
1245 | 1169 | ||
1170 | |||
1246 | /****************************************************************************** | 1171 | /****************************************************************************** |
1247 | * | 1172 | * |
1248 | * uCode download functions | 1173 | * uCode download functions |
@@ -1508,10 +1433,6 @@ static int iwl_read_ucode(struct iwl_priv *priv) | |||
1508 | return ret; | 1433 | return ret; |
1509 | } | 1434 | } |
1510 | 1435 | ||
1511 | /* temporary */ | ||
1512 | static int iwl_mac_beacon_update(struct ieee80211_hw *hw, | ||
1513 | struct sk_buff *skb); | ||
1514 | |||
1515 | /** | 1436 | /** |
1516 | * iwl_alive_start - called after REPLY_ALIVE notification received | 1437 | * iwl_alive_start - called after REPLY_ALIVE notification received |
1517 | * from protocol/runtime uCode (initialization uCode's | 1438 | * from protocol/runtime uCode (initialization uCode's |
@@ -1540,7 +1461,7 @@ static void iwl_alive_start(struct iwl_priv *priv) | |||
1540 | goto restart; | 1461 | goto restart; |
1541 | } | 1462 | } |
1542 | 1463 | ||
1543 | iwl_clear_stations_table(priv); | 1464 | priv->cfg->ops->smgmt->clear_station_table(priv); |
1544 | ret = priv->cfg->ops->lib->alive_notify(priv); | 1465 | ret = priv->cfg->ops->lib->alive_notify(priv); |
1545 | if (ret) { | 1466 | if (ret) { |
1546 | IWL_WARN(priv, | 1467 | IWL_WARN(priv, |
@@ -1568,7 +1489,10 @@ static void iwl_alive_start(struct iwl_priv *priv) | |||
1568 | } else { | 1489 | } else { |
1569 | /* Initialize our rx_config data */ | 1490 | /* Initialize our rx_config data */ |
1570 | iwl_connection_init_rx_config(priv, priv->iw_mode); | 1491 | iwl_connection_init_rx_config(priv, priv->iw_mode); |
1571 | iwl_set_rxon_chain(priv); | 1492 | |
1493 | if (priv->cfg->ops->hcmd->set_rxon_chain) | ||
1494 | priv->cfg->ops->hcmd->set_rxon_chain(priv); | ||
1495 | |||
1572 | memcpy(priv->staging_rxon.node_addr, priv->mac_addr, ETH_ALEN); | 1496 | memcpy(priv->staging_rxon.node_addr, priv->mac_addr, ETH_ALEN); |
1573 | } | 1497 | } |
1574 | 1498 | ||
@@ -1578,7 +1502,7 @@ static void iwl_alive_start(struct iwl_priv *priv) | |||
1578 | iwl_reset_run_time_calib(priv); | 1502 | iwl_reset_run_time_calib(priv); |
1579 | 1503 | ||
1580 | /* Configure the adapter for unassociated operation */ | 1504 | /* Configure the adapter for unassociated operation */ |
1581 | iwl_commit_rxon(priv); | 1505 | iwlcore_commit_rxon(priv); |
1582 | 1506 | ||
1583 | /* At this point, the NIC is initialized and operational */ | 1507 | /* At this point, the NIC is initialized and operational */ |
1584 | iwl_rf_kill_ct_config(priv); | 1508 | iwl_rf_kill_ct_config(priv); |
@@ -1626,7 +1550,7 @@ static void __iwl_down(struct iwl_priv *priv) | |||
1626 | 1550 | ||
1627 | iwl_leds_unregister(priv); | 1551 | iwl_leds_unregister(priv); |
1628 | 1552 | ||
1629 | iwl_clear_stations_table(priv); | 1553 | priv->cfg->ops->smgmt->clear_station_table(priv); |
1630 | 1554 | ||
1631 | /* Unblock any waiting calls */ | 1555 | /* Unblock any waiting calls */ |
1632 | wake_up_interruptible_all(&priv->wait_command_queue); | 1556 | wake_up_interruptible_all(&priv->wait_command_queue); |
@@ -1649,7 +1573,7 @@ static void __iwl_down(struct iwl_priv *priv) | |||
1649 | ieee80211_stop_queues(priv->hw); | 1573 | ieee80211_stop_queues(priv->hw); |
1650 | 1574 | ||
1651 | /* If we have not previously called iwl_init() then | 1575 | /* If we have not previously called iwl_init() then |
1652 | * clear all bits but the RF Kill and SUSPEND bits and return */ | 1576 | * clear all bits but the RF Kill bits and return */ |
1653 | if (!iwl_is_init(priv)) { | 1577 | if (!iwl_is_init(priv)) { |
1654 | priv->status = test_bit(STATUS_RF_KILL_HW, &priv->status) << | 1578 | priv->status = test_bit(STATUS_RF_KILL_HW, &priv->status) << |
1655 | STATUS_RF_KILL_HW | | 1579 | STATUS_RF_KILL_HW | |
@@ -1657,23 +1581,19 @@ static void __iwl_down(struct iwl_priv *priv) | |||
1657 | STATUS_RF_KILL_SW | | 1581 | STATUS_RF_KILL_SW | |
1658 | test_bit(STATUS_GEO_CONFIGURED, &priv->status) << | 1582 | test_bit(STATUS_GEO_CONFIGURED, &priv->status) << |
1659 | STATUS_GEO_CONFIGURED | | 1583 | STATUS_GEO_CONFIGURED | |
1660 | test_bit(STATUS_IN_SUSPEND, &priv->status) << | ||
1661 | STATUS_IN_SUSPEND | | ||
1662 | test_bit(STATUS_EXIT_PENDING, &priv->status) << | 1584 | test_bit(STATUS_EXIT_PENDING, &priv->status) << |
1663 | STATUS_EXIT_PENDING; | 1585 | STATUS_EXIT_PENDING; |
1664 | goto exit; | 1586 | goto exit; |
1665 | } | 1587 | } |
1666 | 1588 | ||
1667 | /* ...otherwise clear out all the status bits but the RF Kill and | 1589 | /* ...otherwise clear out all the status bits but the RF Kill |
1668 | * SUSPEND bits and continue taking the NIC down. */ | 1590 | * bits and continue taking the NIC down. */ |
1669 | priv->status &= test_bit(STATUS_RF_KILL_HW, &priv->status) << | 1591 | priv->status &= test_bit(STATUS_RF_KILL_HW, &priv->status) << |
1670 | STATUS_RF_KILL_HW | | 1592 | STATUS_RF_KILL_HW | |
1671 | test_bit(STATUS_RF_KILL_SW, &priv->status) << | 1593 | test_bit(STATUS_RF_KILL_SW, &priv->status) << |
1672 | STATUS_RF_KILL_SW | | 1594 | STATUS_RF_KILL_SW | |
1673 | test_bit(STATUS_GEO_CONFIGURED, &priv->status) << | 1595 | test_bit(STATUS_GEO_CONFIGURED, &priv->status) << |
1674 | STATUS_GEO_CONFIGURED | | 1596 | STATUS_GEO_CONFIGURED | |
1675 | test_bit(STATUS_IN_SUSPEND, &priv->status) << | ||
1676 | STATUS_IN_SUSPEND | | ||
1677 | test_bit(STATUS_FW_ERROR, &priv->status) << | 1597 | test_bit(STATUS_FW_ERROR, &priv->status) << |
1678 | STATUS_FW_ERROR | | 1598 | STATUS_FW_ERROR | |
1679 | test_bit(STATUS_EXIT_PENDING, &priv->status) << | 1599 | test_bit(STATUS_EXIT_PENDING, &priv->status) << |
@@ -1698,7 +1618,7 @@ static void __iwl_down(struct iwl_priv *priv) | |||
1698 | udelay(5); | 1618 | udelay(5); |
1699 | 1619 | ||
1700 | /* FIXME: apm_ops.suspend(priv) */ | 1620 | /* FIXME: apm_ops.suspend(priv) */ |
1701 | if (exit_pending || test_bit(STATUS_IN_SUSPEND, &priv->status)) | 1621 | if (exit_pending) |
1702 | priv->cfg->ops->lib->apm_ops.stop(priv); | 1622 | priv->cfg->ops->lib->apm_ops.stop(priv); |
1703 | else | 1623 | else |
1704 | priv->cfg->ops->lib->apm_ops.reset(priv); | 1624 | priv->cfg->ops->lib->apm_ops.reset(priv); |
@@ -1781,7 +1701,7 @@ static int __iwl_up(struct iwl_priv *priv) | |||
1781 | 1701 | ||
1782 | for (i = 0; i < MAX_HW_RESTARTS; i++) { | 1702 | for (i = 0; i < MAX_HW_RESTARTS; i++) { |
1783 | 1703 | ||
1784 | iwl_clear_stations_table(priv); | 1704 | priv->cfg->ops->smgmt->clear_station_table(priv); |
1785 | 1705 | ||
1786 | /* load bootstrap state machine, | 1706 | /* load bootstrap state machine, |
1787 | * load bootstrap program into processor's memory, | 1707 | * load bootstrap program into processor's memory, |
@@ -1910,7 +1830,7 @@ static void iwl_bg_rx_replenish(struct work_struct *data) | |||
1910 | 1830 | ||
1911 | #define IWL_DELAY_NEXT_SCAN (HZ*2) | 1831 | #define IWL_DELAY_NEXT_SCAN (HZ*2) |
1912 | 1832 | ||
1913 | static void iwl_post_associate(struct iwl_priv *priv) | 1833 | void iwl_post_associate(struct iwl_priv *priv) |
1914 | { | 1834 | { |
1915 | struct ieee80211_conf *conf = NULL; | 1835 | struct ieee80211_conf *conf = NULL; |
1916 | int ret = 0; | 1836 | int ret = 0; |
@@ -1938,7 +1858,7 @@ static void iwl_post_associate(struct iwl_priv *priv) | |||
1938 | conf = ieee80211_get_hw_conf(priv->hw); | 1858 | conf = ieee80211_get_hw_conf(priv->hw); |
1939 | 1859 | ||
1940 | priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; | 1860 | priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; |
1941 | iwl_commit_rxon(priv); | 1861 | iwlcore_commit_rxon(priv); |
1942 | 1862 | ||
1943 | iwl_setup_rxon_timing(priv); | 1863 | iwl_setup_rxon_timing(priv); |
1944 | ret = iwl_send_cmd_pdu(priv, REPLY_RXON_TIMING, | 1864 | ret = iwl_send_cmd_pdu(priv, REPLY_RXON_TIMING, |
@@ -1951,7 +1871,9 @@ static void iwl_post_associate(struct iwl_priv *priv) | |||
1951 | 1871 | ||
1952 | iwl_set_rxon_ht(priv, &priv->current_ht_config); | 1872 | iwl_set_rxon_ht(priv, &priv->current_ht_config); |
1953 | 1873 | ||
1954 | iwl_set_rxon_chain(priv); | 1874 | if (priv->cfg->ops->hcmd->set_rxon_chain) |
1875 | priv->cfg->ops->hcmd->set_rxon_chain(priv); | ||
1876 | |||
1955 | priv->staging_rxon.assoc_id = cpu_to_le16(priv->assoc_id); | 1877 | priv->staging_rxon.assoc_id = cpu_to_le16(priv->assoc_id); |
1956 | 1878 | ||
1957 | IWL_DEBUG_ASSOC(priv, "assoc id %d beacon interval %d\n", | 1879 | IWL_DEBUG_ASSOC(priv, "assoc id %d beacon interval %d\n", |
@@ -1973,7 +1895,7 @@ static void iwl_post_associate(struct iwl_priv *priv) | |||
1973 | 1895 | ||
1974 | } | 1896 | } |
1975 | 1897 | ||
1976 | iwl_commit_rxon(priv); | 1898 | iwlcore_commit_rxon(priv); |
1977 | 1899 | ||
1978 | switch (priv->iw_mode) { | 1900 | switch (priv->iw_mode) { |
1979 | case NL80211_IFTYPE_STATION: | 1901 | case NL80211_IFTYPE_STATION: |
@@ -2059,9 +1981,6 @@ static int iwl_mac_start(struct ieee80211_hw *hw) | |||
2059 | 1981 | ||
2060 | IWL_DEBUG_INFO(priv, "Start UP work done.\n"); | 1982 | IWL_DEBUG_INFO(priv, "Start UP work done.\n"); |
2061 | 1983 | ||
2062 | if (test_bit(STATUS_IN_SUSPEND, &priv->status)) | ||
2063 | return 0; | ||
2064 | |||
2065 | /* Wait for START_ALIVE from Run Time ucode. Otherwise callbacks from | 1984 | /* Wait for START_ALIVE from Run Time ucode. Otherwise callbacks from |
2066 | * mac80211 will not be run successfully. */ | 1985 | * mac80211 will not be run successfully. */ |
2067 | ret = wait_event_interruptible_timeout(priv->wait_command_queue, | 1986 | 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) | |||
2130 | return NETDEV_TX_OK; | 2049 | return NETDEV_TX_OK; |
2131 | } | 2050 | } |
2132 | 2051 | ||
2133 | static int iwl_mac_add_interface(struct ieee80211_hw *hw, | 2052 | void iwl_config_ap(struct iwl_priv *priv) |
2134 | struct ieee80211_if_init_conf *conf) | ||
2135 | { | ||
2136 | struct iwl_priv *priv = hw->priv; | ||
2137 | unsigned long flags; | ||
2138 | |||
2139 | IWL_DEBUG_MAC80211(priv, "enter: type %d\n", conf->type); | ||
2140 | |||
2141 | if (priv->vif) { | ||
2142 | IWL_DEBUG_MAC80211(priv, "leave - vif != NULL\n"); | ||
2143 | return -EOPNOTSUPP; | ||
2144 | } | ||
2145 | |||
2146 | spin_lock_irqsave(&priv->lock, flags); | ||
2147 | priv->vif = conf->vif; | ||
2148 | priv->iw_mode = conf->type; | ||
2149 | |||
2150 | spin_unlock_irqrestore(&priv->lock, flags); | ||
2151 | |||
2152 | mutex_lock(&priv->mutex); | ||
2153 | |||
2154 | if (conf->mac_addr) { | ||
2155 | IWL_DEBUG_MAC80211(priv, "Set %pM\n", conf->mac_addr); | ||
2156 | memcpy(priv->mac_addr, conf->mac_addr, ETH_ALEN); | ||
2157 | } | ||
2158 | |||
2159 | if (iwl_set_mode(priv, conf->type) == -EAGAIN) | ||
2160 | /* we are not ready, will run again when ready */ | ||
2161 | set_bit(STATUS_MODE_PENDING, &priv->status); | ||
2162 | |||
2163 | mutex_unlock(&priv->mutex); | ||
2164 | |||
2165 | IWL_DEBUG_MAC80211(priv, "leave\n"); | ||
2166 | return 0; | ||
2167 | } | ||
2168 | |||
2169 | /** | ||
2170 | * iwl_mac_config - mac80211 config callback | ||
2171 | * | ||
2172 | * We ignore conf->flags & IEEE80211_CONF_SHORT_SLOT_TIME since it seems to | ||
2173 | * be set inappropriately and the driver currently sets the hardware up to | ||
2174 | * use it whenever needed. | ||
2175 | */ | ||
2176 | static int iwl_mac_config(struct ieee80211_hw *hw, u32 changed) | ||
2177 | { | ||
2178 | struct iwl_priv *priv = hw->priv; | ||
2179 | const struct iwl_channel_info *ch_info; | ||
2180 | struct ieee80211_conf *conf = &hw->conf; | ||
2181 | unsigned long flags = 0; | ||
2182 | int ret = 0; | ||
2183 | u16 ch; | ||
2184 | int scan_active = 0; | ||
2185 | |||
2186 | mutex_lock(&priv->mutex); | ||
2187 | IWL_DEBUG_MAC80211(priv, "enter to channel %d changed 0x%X\n", | ||
2188 | conf->channel->hw_value, changed); | ||
2189 | |||
2190 | if (unlikely(!priv->cfg->mod_params->disable_hw_scan && | ||
2191 | test_bit(STATUS_SCANNING, &priv->status))) { | ||
2192 | scan_active = 1; | ||
2193 | IWL_DEBUG_MAC80211(priv, "leave - scanning\n"); | ||
2194 | } | ||
2195 | |||
2196 | |||
2197 | /* during scanning mac80211 will delay channel setting until | ||
2198 | * scan finish with changed = 0 | ||
2199 | */ | ||
2200 | if (!changed || (changed & IEEE80211_CONF_CHANGE_CHANNEL)) { | ||
2201 | if (scan_active) | ||
2202 | goto set_ch_out; | ||
2203 | |||
2204 | ch = ieee80211_frequency_to_channel(conf->channel->center_freq); | ||
2205 | ch_info = iwl_get_channel_info(priv, conf->channel->band, ch); | ||
2206 | if (!is_channel_valid(ch_info)) { | ||
2207 | IWL_DEBUG_MAC80211(priv, "leave - invalid channel\n"); | ||
2208 | ret = -EINVAL; | ||
2209 | goto set_ch_out; | ||
2210 | } | ||
2211 | |||
2212 | if (priv->iw_mode == NL80211_IFTYPE_ADHOC && | ||
2213 | !is_channel_ibss(ch_info)) { | ||
2214 | IWL_ERR(priv, "channel %d in band %d not " | ||
2215 | "IBSS channel\n", | ||
2216 | conf->channel->hw_value, conf->channel->band); | ||
2217 | ret = -EINVAL; | ||
2218 | goto set_ch_out; | ||
2219 | } | ||
2220 | |||
2221 | priv->current_ht_config.is_ht = conf_is_ht(conf); | ||
2222 | |||
2223 | spin_lock_irqsave(&priv->lock, flags); | ||
2224 | |||
2225 | |||
2226 | /* if we are switching from ht to 2.4 clear flags | ||
2227 | * from any ht related info since 2.4 does not | ||
2228 | * support ht */ | ||
2229 | if ((le16_to_cpu(priv->staging_rxon.channel) != ch)) | ||
2230 | priv->staging_rxon.flags = 0; | ||
2231 | |||
2232 | iwl_set_rxon_channel(priv, conf->channel); | ||
2233 | |||
2234 | iwl_set_flags_for_band(priv, conf->channel->band); | ||
2235 | spin_unlock_irqrestore(&priv->lock, flags); | ||
2236 | set_ch_out: | ||
2237 | /* The list of supported rates and rate mask can be different | ||
2238 | * for each band; since the band may have changed, reset | ||
2239 | * the rate mask to what mac80211 lists */ | ||
2240 | iwl_set_rate(priv); | ||
2241 | } | ||
2242 | |||
2243 | if (changed & IEEE80211_CONF_CHANGE_PS) { | ||
2244 | if (conf->flags & IEEE80211_CONF_PS) | ||
2245 | ret = iwl_power_set_user_mode(priv, IWL_POWER_INDEX_3); | ||
2246 | else | ||
2247 | ret = iwl_power_set_user_mode(priv, IWL_POWER_MODE_CAM); | ||
2248 | if (ret) | ||
2249 | IWL_DEBUG_MAC80211(priv, "Error setting power level\n"); | ||
2250 | |||
2251 | } | ||
2252 | |||
2253 | if (changed & IEEE80211_CONF_CHANGE_POWER) { | ||
2254 | IWL_DEBUG_MAC80211(priv, "TX Power old=%d new=%d\n", | ||
2255 | priv->tx_power_user_lmt, conf->power_level); | ||
2256 | |||
2257 | iwl_set_tx_power(priv, conf->power_level, false); | ||
2258 | } | ||
2259 | |||
2260 | /* call to ensure that 4965 rx_chain is set properly in monitor mode */ | ||
2261 | iwl_set_rxon_chain(priv); | ||
2262 | |||
2263 | if (changed & IEEE80211_CONF_CHANGE_RADIO_ENABLED) { | ||
2264 | if (conf->radio_enabled && | ||
2265 | iwl_radio_kill_sw_enable_radio(priv)) { | ||
2266 | IWL_DEBUG_MAC80211(priv, "leave - RF-KILL - " | ||
2267 | "waiting for uCode\n"); | ||
2268 | goto out; | ||
2269 | } | ||
2270 | |||
2271 | if (!conf->radio_enabled) | ||
2272 | iwl_radio_kill_sw_disable_radio(priv); | ||
2273 | } | ||
2274 | |||
2275 | if (!conf->radio_enabled) { | ||
2276 | IWL_DEBUG_MAC80211(priv, "leave - radio disabled\n"); | ||
2277 | goto out; | ||
2278 | } | ||
2279 | |||
2280 | if (!iwl_is_ready(priv)) { | ||
2281 | IWL_DEBUG_MAC80211(priv, "leave - not ready\n"); | ||
2282 | goto out; | ||
2283 | } | ||
2284 | |||
2285 | if (scan_active) | ||
2286 | goto out; | ||
2287 | |||
2288 | if (memcmp(&priv->active_rxon, | ||
2289 | &priv->staging_rxon, sizeof(priv->staging_rxon))) | ||
2290 | iwl_commit_rxon(priv); | ||
2291 | else | ||
2292 | IWL_DEBUG_INFO(priv, "No re-sending same RXON configuration.\n"); | ||
2293 | |||
2294 | |||
2295 | out: | ||
2296 | IWL_DEBUG_MAC80211(priv, "leave\n"); | ||
2297 | mutex_unlock(&priv->mutex); | ||
2298 | return ret; | ||
2299 | } | ||
2300 | |||
2301 | static void iwl_config_ap(struct iwl_priv *priv) | ||
2302 | { | 2053 | { |
2303 | int ret = 0; | 2054 | int ret = 0; |
2304 | unsigned long flags; | 2055 | unsigned long flags; |
@@ -2311,7 +2062,7 @@ static void iwl_config_ap(struct iwl_priv *priv) | |||
2311 | 2062 | ||
2312 | /* RXON - unassoc (to set timing command) */ | 2063 | /* RXON - unassoc (to set timing command) */ |
2313 | priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; | 2064 | priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; |
2314 | iwl_commit_rxon(priv); | 2065 | iwlcore_commit_rxon(priv); |
2315 | 2066 | ||
2316 | /* RXON Timing */ | 2067 | /* RXON Timing */ |
2317 | iwl_setup_rxon_timing(priv); | 2068 | iwl_setup_rxon_timing(priv); |
@@ -2321,7 +2072,8 @@ static void iwl_config_ap(struct iwl_priv *priv) | |||
2321 | IWL_WARN(priv, "REPLY_RXON_TIMING failed - " | 2072 | IWL_WARN(priv, "REPLY_RXON_TIMING failed - " |
2322 | "Attempting to continue.\n"); | 2073 | "Attempting to continue.\n"); |
2323 | 2074 | ||
2324 | iwl_set_rxon_chain(priv); | 2075 | if (priv->cfg->ops->hcmd->set_rxon_chain) |
2076 | priv->cfg->ops->hcmd->set_rxon_chain(priv); | ||
2325 | 2077 | ||
2326 | /* FIXME: what should be the assoc_id for AP? */ | 2078 | /* FIXME: what should be the assoc_id for AP? */ |
2327 | priv->staging_rxon.assoc_id = cpu_to_le16(priv->assoc_id); | 2079 | priv->staging_rxon.assoc_id = cpu_to_le16(priv->assoc_id); |
@@ -2347,7 +2099,7 @@ static void iwl_config_ap(struct iwl_priv *priv) | |||
2347 | } | 2099 | } |
2348 | /* restore RXON assoc */ | 2100 | /* restore RXON assoc */ |
2349 | priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK; | 2101 | priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK; |
2350 | iwl_commit_rxon(priv); | 2102 | iwlcore_commit_rxon(priv); |
2351 | spin_lock_irqsave(&priv->lock, flags); | 2103 | spin_lock_irqsave(&priv->lock, flags); |
2352 | iwl_activate_qos(priv, 1); | 2104 | iwl_activate_qos(priv, 1); |
2353 | spin_unlock_irqrestore(&priv->lock, flags); | 2105 | spin_unlock_irqrestore(&priv->lock, flags); |
@@ -2360,194 +2112,6 @@ static void iwl_config_ap(struct iwl_priv *priv) | |||
2360 | * clear sta table, add BCAST sta... */ | 2112 | * clear sta table, add BCAST sta... */ |
2361 | } | 2113 | } |
2362 | 2114 | ||
2363 | |||
2364 | static int iwl_mac_config_interface(struct ieee80211_hw *hw, | ||
2365 | struct ieee80211_vif *vif, | ||
2366 | struct ieee80211_if_conf *conf) | ||
2367 | { | ||
2368 | struct iwl_priv *priv = hw->priv; | ||
2369 | int rc; | ||
2370 | |||
2371 | if (conf == NULL) | ||
2372 | return -EIO; | ||
2373 | |||
2374 | if (priv->vif != vif) { | ||
2375 | IWL_DEBUG_MAC80211(priv, "leave - priv->vif != vif\n"); | ||
2376 | return 0; | ||
2377 | } | ||
2378 | |||
2379 | if (priv->iw_mode == NL80211_IFTYPE_ADHOC && | ||
2380 | conf->changed & IEEE80211_IFCC_BEACON) { | ||
2381 | struct sk_buff *beacon = ieee80211_beacon_get(hw, vif); | ||
2382 | if (!beacon) | ||
2383 | return -ENOMEM; | ||
2384 | mutex_lock(&priv->mutex); | ||
2385 | rc = iwl_mac_beacon_update(hw, beacon); | ||
2386 | mutex_unlock(&priv->mutex); | ||
2387 | if (rc) | ||
2388 | return rc; | ||
2389 | } | ||
2390 | |||
2391 | if (!iwl_is_alive(priv)) | ||
2392 | return -EAGAIN; | ||
2393 | |||
2394 | mutex_lock(&priv->mutex); | ||
2395 | |||
2396 | if (conf->bssid) | ||
2397 | IWL_DEBUG_MAC80211(priv, "bssid: %pM\n", conf->bssid); | ||
2398 | |||
2399 | /* | ||
2400 | * very dubious code was here; the probe filtering flag is never set: | ||
2401 | * | ||
2402 | if (unlikely(test_bit(STATUS_SCANNING, &priv->status)) && | ||
2403 | !(priv->hw->flags & IEEE80211_HW_NO_PROBE_FILTERING)) { | ||
2404 | */ | ||
2405 | |||
2406 | if (priv->iw_mode == NL80211_IFTYPE_AP) { | ||
2407 | if (!conf->bssid) { | ||
2408 | conf->bssid = priv->mac_addr; | ||
2409 | memcpy(priv->bssid, priv->mac_addr, ETH_ALEN); | ||
2410 | IWL_DEBUG_MAC80211(priv, "bssid was set to: %pM\n", | ||
2411 | conf->bssid); | ||
2412 | } | ||
2413 | if (priv->ibss_beacon) | ||
2414 | dev_kfree_skb(priv->ibss_beacon); | ||
2415 | |||
2416 | priv->ibss_beacon = ieee80211_beacon_get(hw, vif); | ||
2417 | } | ||
2418 | |||
2419 | if (iwl_is_rfkill(priv)) | ||
2420 | goto done; | ||
2421 | |||
2422 | if (conf->bssid && !is_zero_ether_addr(conf->bssid) && | ||
2423 | !is_multicast_ether_addr(conf->bssid)) { | ||
2424 | /* If there is currently a HW scan going on in the background | ||
2425 | * then we need to cancel it else the RXON below will fail. */ | ||
2426 | if (iwl_scan_cancel_timeout(priv, 100)) { | ||
2427 | IWL_WARN(priv, "Aborted scan still in progress " | ||
2428 | "after 100ms\n"); | ||
2429 | IWL_DEBUG_MAC80211(priv, "leaving - scan abort failed.\n"); | ||
2430 | mutex_unlock(&priv->mutex); | ||
2431 | return -EAGAIN; | ||
2432 | } | ||
2433 | memcpy(priv->staging_rxon.bssid_addr, conf->bssid, ETH_ALEN); | ||
2434 | |||
2435 | /* TODO: Audit driver for usage of these members and see | ||
2436 | * if mac80211 deprecates them (priv->bssid looks like it | ||
2437 | * shouldn't be there, but I haven't scanned the IBSS code | ||
2438 | * to verify) - jpk */ | ||
2439 | memcpy(priv->bssid, conf->bssid, ETH_ALEN); | ||
2440 | |||
2441 | if (priv->iw_mode == NL80211_IFTYPE_AP) | ||
2442 | iwl_config_ap(priv); | ||
2443 | else { | ||
2444 | rc = iwl_commit_rxon(priv); | ||
2445 | if ((priv->iw_mode == NL80211_IFTYPE_STATION) && rc) | ||
2446 | iwl_rxon_add_station( | ||
2447 | priv, priv->active_rxon.bssid_addr, 1); | ||
2448 | } | ||
2449 | |||
2450 | } else { | ||
2451 | iwl_scan_cancel_timeout(priv, 100); | ||
2452 | priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; | ||
2453 | iwl_commit_rxon(priv); | ||
2454 | } | ||
2455 | |||
2456 | done: | ||
2457 | IWL_DEBUG_MAC80211(priv, "leave\n"); | ||
2458 | mutex_unlock(&priv->mutex); | ||
2459 | |||
2460 | return 0; | ||
2461 | } | ||
2462 | |||
2463 | static void iwl_mac_remove_interface(struct ieee80211_hw *hw, | ||
2464 | struct ieee80211_if_init_conf *conf) | ||
2465 | { | ||
2466 | struct iwl_priv *priv = hw->priv; | ||
2467 | |||
2468 | IWL_DEBUG_MAC80211(priv, "enter\n"); | ||
2469 | |||
2470 | mutex_lock(&priv->mutex); | ||
2471 | |||
2472 | if (iwl_is_ready_rf(priv)) { | ||
2473 | iwl_scan_cancel_timeout(priv, 100); | ||
2474 | priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; | ||
2475 | iwl_commit_rxon(priv); | ||
2476 | } | ||
2477 | if (priv->vif == conf->vif) { | ||
2478 | priv->vif = NULL; | ||
2479 | memset(priv->bssid, 0, ETH_ALEN); | ||
2480 | } | ||
2481 | mutex_unlock(&priv->mutex); | ||
2482 | |||
2483 | IWL_DEBUG_MAC80211(priv, "leave\n"); | ||
2484 | |||
2485 | } | ||
2486 | |||
2487 | #define IWL_DELAY_NEXT_SCAN_AFTER_ASSOC (HZ*6) | ||
2488 | static void iwl_bss_info_changed(struct ieee80211_hw *hw, | ||
2489 | struct ieee80211_vif *vif, | ||
2490 | struct ieee80211_bss_conf *bss_conf, | ||
2491 | u32 changes) | ||
2492 | { | ||
2493 | struct iwl_priv *priv = hw->priv; | ||
2494 | |||
2495 | IWL_DEBUG_MAC80211(priv, "changes = 0x%X\n", changes); | ||
2496 | |||
2497 | if (changes & BSS_CHANGED_ERP_PREAMBLE) { | ||
2498 | IWL_DEBUG_MAC80211(priv, "ERP_PREAMBLE %d\n", | ||
2499 | bss_conf->use_short_preamble); | ||
2500 | if (bss_conf->use_short_preamble) | ||
2501 | priv->staging_rxon.flags |= RXON_FLG_SHORT_PREAMBLE_MSK; | ||
2502 | else | ||
2503 | priv->staging_rxon.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK; | ||
2504 | } | ||
2505 | |||
2506 | if (changes & BSS_CHANGED_ERP_CTS_PROT) { | ||
2507 | IWL_DEBUG_MAC80211(priv, "ERP_CTS %d\n", bss_conf->use_cts_prot); | ||
2508 | if (bss_conf->use_cts_prot && (priv->band != IEEE80211_BAND_5GHZ)) | ||
2509 | priv->staging_rxon.flags |= RXON_FLG_TGG_PROTECT_MSK; | ||
2510 | else | ||
2511 | priv->staging_rxon.flags &= ~RXON_FLG_TGG_PROTECT_MSK; | ||
2512 | } | ||
2513 | |||
2514 | if (changes & BSS_CHANGED_HT) { | ||
2515 | iwl_ht_conf(priv, bss_conf); | ||
2516 | iwl_set_rxon_chain(priv); | ||
2517 | } | ||
2518 | |||
2519 | if (changes & BSS_CHANGED_ASSOC) { | ||
2520 | IWL_DEBUG_MAC80211(priv, "ASSOC %d\n", bss_conf->assoc); | ||
2521 | /* This should never happen as this function should | ||
2522 | * never be called from interrupt context. */ | ||
2523 | if (WARN_ON_ONCE(in_interrupt())) | ||
2524 | return; | ||
2525 | if (bss_conf->assoc) { | ||
2526 | priv->assoc_id = bss_conf->aid; | ||
2527 | priv->beacon_int = bss_conf->beacon_int; | ||
2528 | priv->power_data.dtim_period = bss_conf->dtim_period; | ||
2529 | priv->timestamp = bss_conf->timestamp; | ||
2530 | priv->assoc_capability = bss_conf->assoc_capability; | ||
2531 | |||
2532 | /* we have just associated, don't start scan too early | ||
2533 | * leave time for EAPOL exchange to complete | ||
2534 | */ | ||
2535 | priv->next_scan_jiffies = jiffies + | ||
2536 | IWL_DELAY_NEXT_SCAN_AFTER_ASSOC; | ||
2537 | mutex_lock(&priv->mutex); | ||
2538 | iwl_post_associate(priv); | ||
2539 | mutex_unlock(&priv->mutex); | ||
2540 | } else { | ||
2541 | priv->assoc_id = 0; | ||
2542 | IWL_DEBUG_MAC80211(priv, "DISASSOC %d\n", bss_conf->assoc); | ||
2543 | } | ||
2544 | } else if (changes && iwl_is_associated(priv) && priv->assoc_id) { | ||
2545 | IWL_DEBUG_MAC80211(priv, "Associated Changes %d\n", changes); | ||
2546 | iwl_send_rxon_assoc(priv); | ||
2547 | } | ||
2548 | |||
2549 | } | ||
2550 | |||
2551 | static void iwl_mac_update_tkip_key(struct ieee80211_hw *hw, | 2115 | static void iwl_mac_update_tkip_key(struct ieee80211_hw *hw, |
2552 | struct ieee80211_key_conf *keyconf, const u8 *addr, | 2116 | struct ieee80211_key_conf *keyconf, const u8 *addr, |
2553 | u32 iv32, u16 *phase1key) | 2117 | u32 iv32, u16 *phase1key) |
@@ -2579,7 +2143,7 @@ static int iwl_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, | |||
2579 | return -EOPNOTSUPP; | 2143 | return -EOPNOTSUPP; |
2580 | } | 2144 | } |
2581 | addr = sta ? sta->addr : iwl_bcast_addr; | 2145 | addr = sta ? sta->addr : iwl_bcast_addr; |
2582 | sta_id = iwl_find_station(priv, addr); | 2146 | sta_id = priv->cfg->ops->smgmt->find_station(priv, addr); |
2583 | if (sta_id == IWL_INVALID_STATION) { | 2147 | if (sta_id == IWL_INVALID_STATION) { |
2584 | IWL_DEBUG_MAC80211(priv, "leave - %pM not in station map.\n", | 2148 | IWL_DEBUG_MAC80211(priv, "leave - %pM not in station map.\n", |
2585 | addr); | 2149 | addr); |
@@ -2630,49 +2194,6 @@ static int iwl_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, | |||
2630 | return ret; | 2194 | return ret; |
2631 | } | 2195 | } |
2632 | 2196 | ||
2633 | static int iwl_mac_conf_tx(struct ieee80211_hw *hw, u16 queue, | ||
2634 | const struct ieee80211_tx_queue_params *params) | ||
2635 | { | ||
2636 | struct iwl_priv *priv = hw->priv; | ||
2637 | unsigned long flags; | ||
2638 | int q; | ||
2639 | |||
2640 | IWL_DEBUG_MAC80211(priv, "enter\n"); | ||
2641 | |||
2642 | if (!iwl_is_ready_rf(priv)) { | ||
2643 | IWL_DEBUG_MAC80211(priv, "leave - RF not ready\n"); | ||
2644 | return -EIO; | ||
2645 | } | ||
2646 | |||
2647 | if (queue >= AC_NUM) { | ||
2648 | IWL_DEBUG_MAC80211(priv, "leave - queue >= AC_NUM %d\n", queue); | ||
2649 | return 0; | ||
2650 | } | ||
2651 | |||
2652 | q = AC_NUM - 1 - queue; | ||
2653 | |||
2654 | spin_lock_irqsave(&priv->lock, flags); | ||
2655 | |||
2656 | priv->qos_data.def_qos_parm.ac[q].cw_min = cpu_to_le16(params->cw_min); | ||
2657 | priv->qos_data.def_qos_parm.ac[q].cw_max = cpu_to_le16(params->cw_max); | ||
2658 | priv->qos_data.def_qos_parm.ac[q].aifsn = params->aifs; | ||
2659 | priv->qos_data.def_qos_parm.ac[q].edca_txop = | ||
2660 | cpu_to_le16((params->txop * 32)); | ||
2661 | |||
2662 | priv->qos_data.def_qos_parm.ac[q].reserved1 = 0; | ||
2663 | priv->qos_data.qos_active = 1; | ||
2664 | |||
2665 | if (priv->iw_mode == NL80211_IFTYPE_AP) | ||
2666 | iwl_activate_qos(priv, 1); | ||
2667 | else if (priv->assoc_id && iwl_is_associated(priv)) | ||
2668 | iwl_activate_qos(priv, 0); | ||
2669 | |||
2670 | spin_unlock_irqrestore(&priv->lock, flags); | ||
2671 | |||
2672 | IWL_DEBUG_MAC80211(priv, "leave\n"); | ||
2673 | return 0; | ||
2674 | } | ||
2675 | |||
2676 | static int iwl_mac_ampdu_action(struct ieee80211_hw *hw, | 2197 | static int iwl_mac_ampdu_action(struct ieee80211_hw *hw, |
2677 | enum ieee80211_ampdu_mlme_action action, | 2198 | enum ieee80211_ampdu_mlme_action action, |
2678 | struct ieee80211_sta *sta, u16 tid, u16 *ssn) | 2199 | struct ieee80211_sta *sta, u16 tid, u16 *ssn) |
@@ -2715,41 +2236,6 @@ static int iwl_mac_ampdu_action(struct ieee80211_hw *hw, | |||
2715 | return 0; | 2236 | return 0; |
2716 | } | 2237 | } |
2717 | 2238 | ||
2718 | static int iwl_mac_get_tx_stats(struct ieee80211_hw *hw, | ||
2719 | struct ieee80211_tx_queue_stats *stats) | ||
2720 | { | ||
2721 | struct iwl_priv *priv = hw->priv; | ||
2722 | int i, avail; | ||
2723 | struct iwl_tx_queue *txq; | ||
2724 | struct iwl_queue *q; | ||
2725 | unsigned long flags; | ||
2726 | |||
2727 | IWL_DEBUG_MAC80211(priv, "enter\n"); | ||
2728 | |||
2729 | if (!iwl_is_ready_rf(priv)) { | ||
2730 | IWL_DEBUG_MAC80211(priv, "leave - RF not ready\n"); | ||
2731 | return -EIO; | ||
2732 | } | ||
2733 | |||
2734 | spin_lock_irqsave(&priv->lock, flags); | ||
2735 | |||
2736 | for (i = 0; i < AC_NUM; i++) { | ||
2737 | txq = &priv->txq[i]; | ||
2738 | q = &txq->q; | ||
2739 | avail = iwl_queue_space(q); | ||
2740 | |||
2741 | stats[i].len = q->n_window - avail; | ||
2742 | stats[i].limit = q->n_window - q->high_mark; | ||
2743 | stats[i].count = q->n_window; | ||
2744 | |||
2745 | } | ||
2746 | spin_unlock_irqrestore(&priv->lock, flags); | ||
2747 | |||
2748 | IWL_DEBUG_MAC80211(priv, "leave\n"); | ||
2749 | |||
2750 | return 0; | ||
2751 | } | ||
2752 | |||
2753 | static int iwl_mac_get_stats(struct ieee80211_hw *hw, | 2239 | static int iwl_mac_get_stats(struct ieee80211_hw *hw, |
2754 | struct ieee80211_low_level_stats *stats) | 2240 | struct ieee80211_low_level_stats *stats) |
2755 | { | 2241 | { |
@@ -2762,120 +2248,6 @@ static int iwl_mac_get_stats(struct ieee80211_hw *hw, | |||
2762 | return 0; | 2248 | return 0; |
2763 | } | 2249 | } |
2764 | 2250 | ||
2765 | static void iwl_mac_reset_tsf(struct ieee80211_hw *hw) | ||
2766 | { | ||
2767 | struct iwl_priv *priv = hw->priv; | ||
2768 | unsigned long flags; | ||
2769 | |||
2770 | mutex_lock(&priv->mutex); | ||
2771 | IWL_DEBUG_MAC80211(priv, "enter\n"); | ||
2772 | |||
2773 | spin_lock_irqsave(&priv->lock, flags); | ||
2774 | memset(&priv->current_ht_config, 0, sizeof(struct iwl_ht_info)); | ||
2775 | spin_unlock_irqrestore(&priv->lock, flags); | ||
2776 | |||
2777 | iwl_reset_qos(priv); | ||
2778 | |||
2779 | spin_lock_irqsave(&priv->lock, flags); | ||
2780 | priv->assoc_id = 0; | ||
2781 | priv->assoc_capability = 0; | ||
2782 | priv->assoc_station_added = 0; | ||
2783 | |||
2784 | /* new association get rid of ibss beacon skb */ | ||
2785 | if (priv->ibss_beacon) | ||
2786 | dev_kfree_skb(priv->ibss_beacon); | ||
2787 | |||
2788 | priv->ibss_beacon = NULL; | ||
2789 | |||
2790 | priv->beacon_int = priv->hw->conf.beacon_int; | ||
2791 | priv->timestamp = 0; | ||
2792 | if ((priv->iw_mode == NL80211_IFTYPE_STATION)) | ||
2793 | priv->beacon_int = 0; | ||
2794 | |||
2795 | spin_unlock_irqrestore(&priv->lock, flags); | ||
2796 | |||
2797 | if (!iwl_is_ready_rf(priv)) { | ||
2798 | IWL_DEBUG_MAC80211(priv, "leave - not ready\n"); | ||
2799 | mutex_unlock(&priv->mutex); | ||
2800 | return; | ||
2801 | } | ||
2802 | |||
2803 | /* we are restarting association process | ||
2804 | * clear RXON_FILTER_ASSOC_MSK bit | ||
2805 | */ | ||
2806 | if (priv->iw_mode != NL80211_IFTYPE_AP) { | ||
2807 | iwl_scan_cancel_timeout(priv, 100); | ||
2808 | priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; | ||
2809 | iwl_commit_rxon(priv); | ||
2810 | } | ||
2811 | |||
2812 | iwl_power_update_mode(priv, 0); | ||
2813 | |||
2814 | /* Per mac80211.h: This is only used in IBSS mode... */ | ||
2815 | if (priv->iw_mode != NL80211_IFTYPE_ADHOC) { | ||
2816 | |||
2817 | /* switch to CAM during association period. | ||
2818 | * the ucode will block any association/authentication | ||
2819 | * frome during assiciation period if it can not hear | ||
2820 | * the AP because of PM. the timer enable PM back is | ||
2821 | * association do not complete | ||
2822 | */ | ||
2823 | if (priv->hw->conf.channel->flags & (IEEE80211_CHAN_PASSIVE_SCAN | | ||
2824 | IEEE80211_CHAN_RADAR)) | ||
2825 | iwl_power_disable_management(priv, 3000); | ||
2826 | |||
2827 | IWL_DEBUG_MAC80211(priv, "leave - not in IBSS\n"); | ||
2828 | mutex_unlock(&priv->mutex); | ||
2829 | return; | ||
2830 | } | ||
2831 | |||
2832 | iwl_set_rate(priv); | ||
2833 | |||
2834 | mutex_unlock(&priv->mutex); | ||
2835 | |||
2836 | IWL_DEBUG_MAC80211(priv, "leave\n"); | ||
2837 | } | ||
2838 | |||
2839 | static int iwl_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb) | ||
2840 | { | ||
2841 | struct iwl_priv *priv = hw->priv; | ||
2842 | unsigned long flags; | ||
2843 | __le64 timestamp; | ||
2844 | |||
2845 | IWL_DEBUG_MAC80211(priv, "enter\n"); | ||
2846 | |||
2847 | if (!iwl_is_ready_rf(priv)) { | ||
2848 | IWL_DEBUG_MAC80211(priv, "leave - RF not ready\n"); | ||
2849 | return -EIO; | ||
2850 | } | ||
2851 | |||
2852 | if (priv->iw_mode != NL80211_IFTYPE_ADHOC) { | ||
2853 | IWL_DEBUG_MAC80211(priv, "leave - not IBSS\n"); | ||
2854 | return -EIO; | ||
2855 | } | ||
2856 | |||
2857 | spin_lock_irqsave(&priv->lock, flags); | ||
2858 | |||
2859 | if (priv->ibss_beacon) | ||
2860 | dev_kfree_skb(priv->ibss_beacon); | ||
2861 | |||
2862 | priv->ibss_beacon = skb; | ||
2863 | |||
2864 | priv->assoc_id = 0; | ||
2865 | timestamp = ((struct ieee80211_mgmt *)skb->data)->u.beacon.timestamp; | ||
2866 | priv->timestamp = le64_to_cpu(timestamp); | ||
2867 | |||
2868 | IWL_DEBUG_MAC80211(priv, "leave\n"); | ||
2869 | spin_unlock_irqrestore(&priv->lock, flags); | ||
2870 | |||
2871 | iwl_reset_qos(priv); | ||
2872 | |||
2873 | iwl_post_associate(priv); | ||
2874 | |||
2875 | |||
2876 | return 0; | ||
2877 | } | ||
2878 | |||
2879 | /***************************************************************************** | 2251 | /***************************************************************************** |
2880 | * | 2252 | * |
2881 | * sysfs attributes | 2253 | * sysfs attributes |
@@ -3025,7 +2397,7 @@ static ssize_t store_flags(struct device *d, | |||
3025 | else { | 2397 | else { |
3026 | IWL_DEBUG_INFO(priv, "Commit rxon.flags = 0x%04X\n", flags); | 2398 | IWL_DEBUG_INFO(priv, "Commit rxon.flags = 0x%04X\n", flags); |
3027 | priv->staging_rxon.flags = cpu_to_le32(flags); | 2399 | priv->staging_rxon.flags = cpu_to_le32(flags); |
3028 | iwl_commit_rxon(priv); | 2400 | iwlcore_commit_rxon(priv); |
3029 | } | 2401 | } |
3030 | } | 2402 | } |
3031 | mutex_unlock(&priv->mutex); | 2403 | mutex_unlock(&priv->mutex); |
@@ -3066,7 +2438,7 @@ static ssize_t store_filter_flags(struct device *d, | |||
3066 | "0x%04X\n", filter_flags); | 2438 | "0x%04X\n", filter_flags); |
3067 | priv->staging_rxon.filter_flags = | 2439 | priv->staging_rxon.filter_flags = |
3068 | cpu_to_le32(filter_flags); | 2440 | cpu_to_le32(filter_flags); |
3069 | iwl_commit_rxon(priv); | 2441 | iwlcore_commit_rxon(priv); |
3070 | } | 2442 | } |
3071 | } | 2443 | } |
3072 | mutex_unlock(&priv->mutex); | 2444 | mutex_unlock(&priv->mutex); |
@@ -3397,18 +2769,8 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
3397 | goto out_free_eeprom; | 2769 | goto out_free_eeprom; |
3398 | /* At this point both hw and priv are initialized. */ | 2770 | /* At this point both hw and priv are initialized. */ |
3399 | 2771 | ||
3400 | /********************************** | ||
3401 | * 7. Initialize module parameters | ||
3402 | **********************************/ | ||
3403 | |||
3404 | /* Disable radio (SW RF KILL) via parameter when loading driver */ | ||
3405 | if (priv->cfg->mod_params->disable) { | ||
3406 | set_bit(STATUS_RF_KILL_SW, &priv->status); | ||
3407 | IWL_DEBUG_INFO(priv, "Radio disabled.\n"); | ||
3408 | } | ||
3409 | |||
3410 | /******************** | 2772 | /******************** |
3411 | * 8. Setup services | 2773 | * 7. Setup services |
3412 | ********************/ | 2774 | ********************/ |
3413 | spin_lock_irqsave(&priv->lock, flags); | 2775 | spin_lock_irqsave(&priv->lock, flags); |
3414 | iwl_disable_interrupts(priv); | 2776 | iwl_disable_interrupts(priv); |
@@ -3432,7 +2794,7 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
3432 | iwl_setup_rx_handlers(priv); | 2794 | iwl_setup_rx_handlers(priv); |
3433 | 2795 | ||
3434 | /********************************** | 2796 | /********************************** |
3435 | * 9. Setup and register mac80211 | 2797 | * 8. Setup and register mac80211 |
3436 | **********************************/ | 2798 | **********************************/ |
3437 | 2799 | ||
3438 | /* enable interrupts if needed: hw bug w/a */ | 2800 | /* 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) | |||
3450 | 2812 | ||
3451 | err = iwl_dbgfs_register(priv, DRV_NAME); | 2813 | err = iwl_dbgfs_register(priv, DRV_NAME); |
3452 | if (err) | 2814 | if (err) |
3453 | IWL_ERR(priv, "failed to create debugfs files\n"); | 2815 | IWL_ERR(priv, "failed to create debugfs files. Ignoring error: %d\n", err); |
3454 | 2816 | ||
3455 | /* If platform's RF_KILL switch is NOT set to KILL */ | 2817 | /* If platform's RF_KILL switch is NOT set to KILL */ |
3456 | if (iwl_read32(priv, CSR_GP_CNTRL) & CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW) | 2818 | 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) | |||
3533 | iwl_rx_queue_free(priv, &priv->rxq); | 2895 | iwl_rx_queue_free(priv, &priv->rxq); |
3534 | iwl_hw_txq_ctx_free(priv); | 2896 | iwl_hw_txq_ctx_free(priv); |
3535 | 2897 | ||
3536 | iwl_clear_stations_table(priv); | 2898 | priv->cfg->ops->smgmt->clear_station_table(priv); |
3537 | iwl_eeprom_free(priv); | 2899 | iwl_eeprom_free(priv); |
3538 | 2900 | ||
3539 | 2901 | ||
@@ -3561,45 +2923,6 @@ static void __devexit iwl_pci_remove(struct pci_dev *pdev) | |||
3561 | ieee80211_free_hw(priv->hw); | 2923 | ieee80211_free_hw(priv->hw); |
3562 | } | 2924 | } |
3563 | 2925 | ||
3564 | #ifdef CONFIG_PM | ||
3565 | |||
3566 | static int iwl_pci_suspend(struct pci_dev *pdev, pm_message_t state) | ||
3567 | { | ||
3568 | struct iwl_priv *priv = pci_get_drvdata(pdev); | ||
3569 | |||
3570 | if (priv->is_open) { | ||
3571 | set_bit(STATUS_IN_SUSPEND, &priv->status); | ||
3572 | iwl_mac_stop(priv->hw); | ||
3573 | priv->is_open = 1; | ||
3574 | } | ||
3575 | |||
3576 | pci_save_state(pdev); | ||
3577 | pci_disable_device(pdev); | ||
3578 | pci_set_power_state(pdev, PCI_D3hot); | ||
3579 | |||
3580 | return 0; | ||
3581 | } | ||
3582 | |||
3583 | static int iwl_pci_resume(struct pci_dev *pdev) | ||
3584 | { | ||
3585 | struct iwl_priv *priv = pci_get_drvdata(pdev); | ||
3586 | int ret; | ||
3587 | |||
3588 | pci_set_power_state(pdev, PCI_D0); | ||
3589 | ret = pci_enable_device(pdev); | ||
3590 | if (ret) | ||
3591 | return ret; | ||
3592 | pci_restore_state(pdev); | ||
3593 | iwl_enable_interrupts(priv); | ||
3594 | |||
3595 | if (priv->is_open) | ||
3596 | iwl_mac_start(priv->hw); | ||
3597 | |||
3598 | clear_bit(STATUS_IN_SUSPEND, &priv->status); | ||
3599 | return 0; | ||
3600 | } | ||
3601 | |||
3602 | #endif /* CONFIG_PM */ | ||
3603 | 2926 | ||
3604 | /***************************************************************************** | 2927 | /***************************************************************************** |
3605 | * | 2928 | * |