aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/wireless/iwlwifi/Makefile3
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-1000.c4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945.c10
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945.h6
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-4965.c318
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-5000.c8
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-6000.c8
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-rxon.c562
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.c385
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.h34
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.c531
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.h30
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-dev.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-led.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-legacy.c560
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-legacy.h74
-rw-r--r--drivers/net/wireless/iwlwifi/iwl3945-base.c30
17 files changed, 1631 insertions, 936 deletions
diff --git a/drivers/net/wireless/iwlwifi/Makefile b/drivers/net/wireless/iwlwifi/Makefile
index 63edbe2e557f..ce05c260870e 100644
--- a/drivers/net/wireless/iwlwifi/Makefile
+++ b/drivers/net/wireless/iwlwifi/Makefile
@@ -2,6 +2,8 @@ obj-$(CONFIG_IWLWIFI) += iwlcore.o
2iwlcore-objs := iwl-core.o iwl-eeprom.o iwl-hcmd.o iwl-power.o 2iwlcore-objs := iwl-core.o iwl-eeprom.o iwl-hcmd.o iwl-power.o
3iwlcore-objs += iwl-rx.o iwl-tx.o iwl-sta.o 3iwlcore-objs += iwl-rx.o iwl-tx.o iwl-sta.o
4iwlcore-objs += iwl-scan.o iwl-led.o 4iwlcore-objs += iwl-scan.o iwl-led.o
5iwlcore-$(CONFIG_IWL3945) += iwl-legacy.o
6iwlcore-$(CONFIG_IWL4965) += iwl-legacy.o
5iwlcore-$(CONFIG_IWLWIFI_DEBUGFS) += iwl-debugfs.o 7iwlcore-$(CONFIG_IWLWIFI_DEBUGFS) += iwl-debugfs.o
6iwlcore-$(CONFIG_IWLWIFI_DEVICE_TRACING) += iwl-devtrace.o 8iwlcore-$(CONFIG_IWLWIFI_DEVICE_TRACING) += iwl-devtrace.o
7 9
@@ -16,6 +18,7 @@ iwlagn-objs += iwl-agn-tt.o iwl-agn-sta.o iwl-agn-eeprom.o
16iwlagn-$(CONFIG_IWLWIFI_DEBUGFS) += iwl-agn-debugfs.o 18iwlagn-$(CONFIG_IWLWIFI_DEBUGFS) += iwl-agn-debugfs.o
17 19
18iwlagn-$(CONFIG_IWL4965) += iwl-4965.o 20iwlagn-$(CONFIG_IWL4965) += iwl-4965.o
21iwlagn-$(CONFIG_IWL5000) += iwl-agn-rxon.o
19iwlagn-$(CONFIG_IWL5000) += iwl-5000.o 22iwlagn-$(CONFIG_IWL5000) += iwl-5000.o
20iwlagn-$(CONFIG_IWL5000) += iwl-6000.o 23iwlagn-$(CONFIG_IWL5000) += iwl-6000.o
21iwlagn-$(CONFIG_IWL5000) += iwl-1000.o 24iwlagn-$(CONFIG_IWL5000) += iwl-1000.o
diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c
index 4266c855a767..baedea8e4d04 100644
--- a/drivers/net/wireless/iwlwifi/iwl-1000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-1000.c
@@ -211,14 +211,10 @@ static struct iwl_lib_ops iwl1000_lib = {
211 .calib_version = iwlagn_eeprom_calib_version, 211 .calib_version = iwlagn_eeprom_calib_version,
212 .query_addr = iwlagn_eeprom_query_addr, 212 .query_addr = iwlagn_eeprom_query_addr,
213 }, 213 },
214 .post_associate = iwl_post_associate,
215 .isr = iwl_isr_ict, 214 .isr = iwl_isr_ict,
216 .config_ap = iwl_config_ap,
217 .temp_ops = { 215 .temp_ops = {
218 .temperature = iwlagn_temperature, 216 .temperature = iwlagn_temperature,
219 }, 217 },
220 .manage_ibss_station = iwlagn_manage_ibss_station,
221 .update_bcast_stations = iwl_update_bcast_stations,
222 .debugfs_ops = { 218 .debugfs_ops = {
223 .rx_stats_read = iwl_ucode_rx_stats_read, 219 .rx_stats_read = iwl_ucode_rx_stats_read,
224 .tx_stats_read = iwl_ucode_tx_stats_read, 220 .tx_stats_read = iwl_ucode_tx_stats_read,
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c
index 95fed1158452..d9e676480269 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945.c
@@ -2726,10 +2726,7 @@ static struct iwl_lib_ops iwl3945_lib = {
2726 }, 2726 },
2727 .send_tx_power = iwl3945_send_tx_power, 2727 .send_tx_power = iwl3945_send_tx_power,
2728 .is_valid_rtc_data_addr = iwl3945_hw_valid_rtc_data_addr, 2728 .is_valid_rtc_data_addr = iwl3945_hw_valid_rtc_data_addr,
2729 .post_associate = iwl3945_post_associate,
2730 .isr = iwl_isr_legacy, 2729 .isr = iwl_isr_legacy,
2731 .config_ap = iwl3945_config_ap,
2732 .manage_ibss_station = iwl3945_manage_ibss_station,
2733 .recover_from_tx_stall = iwl_bg_monitor_recover, 2730 .recover_from_tx_stall = iwl_bg_monitor_recover,
2734 .check_plcp_health = iwl3945_good_plcp_health, 2731 .check_plcp_health = iwl3945_good_plcp_health,
2735 2732
@@ -2740,6 +2737,12 @@ static struct iwl_lib_ops iwl3945_lib = {
2740 }, 2737 },
2741}; 2738};
2742 2739
2740static const struct iwl_legacy_ops iwl3945_legacy_ops = {
2741 .post_associate = iwl3945_post_associate,
2742 .config_ap = iwl3945_config_ap,
2743 .manage_ibss_station = iwl3945_manage_ibss_station,
2744};
2745
2743static struct iwl_hcmd_utils_ops iwl3945_hcmd_utils = { 2746static struct iwl_hcmd_utils_ops iwl3945_hcmd_utils = {
2744 .get_hcmd_size = iwl3945_get_hcmd_size, 2747 .get_hcmd_size = iwl3945_get_hcmd_size,
2745 .build_addsta_hcmd = iwl3945_build_addsta_hcmd, 2748 .build_addsta_hcmd = iwl3945_build_addsta_hcmd,
@@ -2753,6 +2756,7 @@ static const struct iwl_ops iwl3945_ops = {
2753 .hcmd = &iwl3945_hcmd, 2756 .hcmd = &iwl3945_hcmd,
2754 .utils = &iwl3945_hcmd_utils, 2757 .utils = &iwl3945_hcmd_utils,
2755 .led = &iwl3945_led_ops, 2758 .led = &iwl3945_led_ops,
2759 .legacy = &iwl3945_legacy_ops,
2756 .ieee80211_ops = &iwl3945_hw_ops, 2760 .ieee80211_ops = &iwl3945_hw_ops,
2757}; 2761};
2758 2762
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.h b/drivers/net/wireless/iwlwifi/iwl-3945.h
index b27f07cbf355..3eef1eb74a78 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945.h
+++ b/drivers/net/wireless/iwlwifi/iwl-3945.h
@@ -264,10 +264,8 @@ void iwl3945_reply_statistics(struct iwl_priv *priv,
264 struct iwl_rx_mem_buffer *rxb); 264 struct iwl_rx_mem_buffer *rxb);
265extern void iwl3945_disable_events(struct iwl_priv *priv); 265extern void iwl3945_disable_events(struct iwl_priv *priv);
266extern int iwl4965_get_temperature(const struct iwl_priv *priv); 266extern int iwl4965_get_temperature(const struct iwl_priv *priv);
267extern void iwl3945_post_associate(struct iwl_priv *priv, 267extern void iwl3945_post_associate(struct iwl_priv *priv);
268 struct ieee80211_vif *vif); 268extern void iwl3945_config_ap(struct iwl_priv *priv);
269extern void iwl3945_config_ap(struct iwl_priv *priv,
270 struct ieee80211_vif *vif);
271 269
272extern int iwl3945_commit_rxon(struct iwl_priv *priv, 270extern int iwl3945_commit_rxon(struct iwl_priv *priv,
273 struct iwl_rxon_context *ctx); 271 struct iwl_rxon_context *ctx);
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c
index 7921a910b34a..8f07964e4305 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965.c
+++ b/drivers/net/wireless/iwlwifi/iwl-4965.c
@@ -48,6 +48,7 @@
48#include "iwl-agn-led.h" 48#include "iwl-agn-led.h"
49#include "iwl-agn.h" 49#include "iwl-agn.h"
50#include "iwl-agn-debugfs.h" 50#include "iwl-agn-debugfs.h"
51#include "iwl-legacy.h"
51 52
52static int iwl4965_send_tx_power(struct iwl_priv *priv); 53static int iwl4965_send_tx_power(struct iwl_priv *priv);
53static int iwl4965_hw_get_temperature(struct iwl_priv *priv); 54static int iwl4965_hw_get_temperature(struct iwl_priv *priv);
@@ -1443,6 +1444,142 @@ static int iwl4965_send_rxon_assoc(struct iwl_priv *priv,
1443 return ret; 1444 return ret;
1444} 1445}
1445 1446
1447static int iwl4965_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
1448{
1449 /* cast away the const for active_rxon in this function */
1450 struct iwl_rxon_cmd *active_rxon = (void *)&ctx->active;
1451 int ret;
1452 bool new_assoc =
1453 !!(ctx->staging.filter_flags & RXON_FILTER_ASSOC_MSK);
1454
1455 if (!iwl_is_alive(priv))
1456 return -EBUSY;
1457
1458 if (!ctx->is_active)
1459 return 0;
1460
1461 /* always get timestamp with Rx frame */
1462 ctx->staging.flags |= RXON_FLG_TSF2HOST_MSK;
1463
1464 ret = iwl_check_rxon_cmd(priv, ctx);
1465 if (ret) {
1466 IWL_ERR(priv, "Invalid RXON configuration. Not committing.\n");
1467 return -EINVAL;
1468 }
1469
1470 /*
1471 * receive commit_rxon request
1472 * abort any previous channel switch if still in process
1473 */
1474 if (priv->switch_rxon.switch_in_progress &&
1475 (priv->switch_rxon.channel != ctx->staging.channel)) {
1476 IWL_DEBUG_11H(priv, "abort channel switch on %d\n",
1477 le16_to_cpu(priv->switch_rxon.channel));
1478 iwl_chswitch_done(priv, false);
1479 }
1480
1481 /* If we don't need to send a full RXON, we can use
1482 * iwl_rxon_assoc_cmd which is used to reconfigure filter
1483 * and other flags for the current radio configuration. */
1484 if (!iwl_full_rxon_required(priv, ctx)) {
1485 ret = iwl_send_rxon_assoc(priv, ctx);
1486 if (ret) {
1487 IWL_ERR(priv, "Error setting RXON_ASSOC (%d)\n", ret);
1488 return ret;
1489 }
1490
1491 memcpy(active_rxon, &ctx->staging, sizeof(*active_rxon));
1492 iwl_print_rx_config_cmd(priv, ctx);
1493 return 0;
1494 }
1495
1496 /* If we are currently associated and the new config requires
1497 * an RXON_ASSOC and the new config wants the associated mask enabled,
1498 * we must clear the associated from the active configuration
1499 * before we apply the new config */
1500 if (iwl_is_associated_ctx(ctx) && new_assoc) {
1501 IWL_DEBUG_INFO(priv, "Toggling associated bit on current RXON\n");
1502 active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK;
1503
1504 ret = iwl_send_cmd_pdu(priv, ctx->rxon_cmd,
1505 sizeof(struct iwl_rxon_cmd),
1506 active_rxon);
1507
1508 /* If the mask clearing failed then we set
1509 * active_rxon back to what it was previously */
1510 if (ret) {
1511 active_rxon->filter_flags |= RXON_FILTER_ASSOC_MSK;
1512 IWL_ERR(priv, "Error clearing ASSOC_MSK (%d)\n", ret);
1513 return ret;
1514 }
1515 iwl_clear_ucode_stations(priv, ctx);
1516 iwl_restore_stations(priv, ctx);
1517 ret = iwl_restore_default_wep_keys(priv, ctx);
1518 if (ret) {
1519 IWL_ERR(priv, "Failed to restore WEP keys (%d)\n", ret);
1520 return ret;
1521 }
1522 }
1523
1524 IWL_DEBUG_INFO(priv, "Sending RXON\n"
1525 "* with%s RXON_FILTER_ASSOC_MSK\n"
1526 "* channel = %d\n"
1527 "* bssid = %pM\n",
1528 (new_assoc ? "" : "out"),
1529 le16_to_cpu(ctx->staging.channel),
1530 ctx->staging.bssid_addr);
1531
1532 iwl_set_rxon_hwcrypto(priv, ctx, !priv->cfg->mod_params->sw_crypto);
1533
1534 /* Apply the new configuration
1535 * RXON unassoc clears the station table in uCode so restoration of
1536 * stations is needed after it (the RXON command) completes
1537 */
1538 if (!new_assoc) {
1539 ret = iwl_send_cmd_pdu(priv, ctx->rxon_cmd,
1540 sizeof(struct iwl_rxon_cmd), &ctx->staging);
1541 if (ret) {
1542 IWL_ERR(priv, "Error setting new RXON (%d)\n", ret);
1543 return ret;
1544 }
1545 IWL_DEBUG_INFO(priv, "Return from !new_assoc RXON.\n");
1546 memcpy(active_rxon, &ctx->staging, sizeof(*active_rxon));
1547 iwl_clear_ucode_stations(priv, ctx);
1548 iwl_restore_stations(priv, ctx);
1549 ret = iwl_restore_default_wep_keys(priv, ctx);
1550 if (ret) {
1551 IWL_ERR(priv, "Failed to restore WEP keys (%d)\n", ret);
1552 return ret;
1553 }
1554 }
1555 if (new_assoc) {
1556 priv->start_calib = 0;
1557 /* Apply the new configuration
1558 * RXON assoc doesn't clear the station table in uCode,
1559 */
1560 ret = iwl_send_cmd_pdu(priv, ctx->rxon_cmd,
1561 sizeof(struct iwl_rxon_cmd), &ctx->staging);
1562 if (ret) {
1563 IWL_ERR(priv, "Error setting new RXON (%d)\n", ret);
1564 return ret;
1565 }
1566 memcpy(active_rxon, &ctx->staging, sizeof(*active_rxon));
1567 }
1568 iwl_print_rx_config_cmd(priv, ctx);
1569
1570 iwl_init_sensitivity(priv);
1571
1572 /* If we issue a new RXON command which required a tune then we must
1573 * send a new TXPOWER command or we won't be able to Tx any frames */
1574 ret = iwl_set_tx_power(priv, priv->tx_power_user_lmt, true);
1575 if (ret) {
1576 IWL_ERR(priv, "Error sending TX power (%d)\n", ret);
1577 return ret;
1578 }
1579
1580 return 0;
1581}
1582
1446static int iwl4965_hw_channel_switch(struct iwl_priv *priv, 1583static int iwl4965_hw_channel_switch(struct iwl_priv *priv,
1447 struct ieee80211_channel_switch *ch_switch) 1584 struct ieee80211_channel_switch *ch_switch)
1448{ 1585{
@@ -2212,7 +2349,7 @@ static void iwl4965_cancel_deferred_work(struct iwl_priv *priv)
2212 2349
2213static struct iwl_hcmd_ops iwl4965_hcmd = { 2350static struct iwl_hcmd_ops iwl4965_hcmd = {
2214 .rxon_assoc = iwl4965_send_rxon_assoc, 2351 .rxon_assoc = iwl4965_send_rxon_assoc,
2215 .commit_rxon = iwlagn_commit_rxon, 2352 .commit_rxon = iwl4965_commit_rxon,
2216 .set_rxon_chain = iwlagn_set_rxon_chain, 2353 .set_rxon_chain = iwlagn_set_rxon_chain,
2217 .send_bt_config = iwl_send_bt_config, 2354 .send_bt_config = iwl_send_bt_config,
2218}; 2355};
@@ -2229,6 +2366,149 @@ static void iwl4965_post_scan(struct iwl_priv *priv)
2229 iwlcore_commit_rxon(priv, ctx); 2366 iwlcore_commit_rxon(priv, ctx);
2230} 2367}
2231 2368
2369static void iwl4965_post_associate(struct iwl_priv *priv)
2370{
2371 struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
2372 struct ieee80211_vif *vif = ctx->vif;
2373 struct ieee80211_conf *conf = NULL;
2374 int ret = 0;
2375
2376 if (!vif || !priv->is_open)
2377 return;
2378
2379 if (vif->type == NL80211_IFTYPE_AP) {
2380 IWL_ERR(priv, "%s Should not be called in AP mode\n", __func__);
2381 return;
2382 }
2383
2384 if (test_bit(STATUS_EXIT_PENDING, &priv->status))
2385 return;
2386
2387 iwl_scan_cancel_timeout(priv, 200);
2388
2389 conf = ieee80211_get_hw_conf(priv->hw);
2390
2391 ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
2392 iwlcore_commit_rxon(priv, ctx);
2393
2394 ret = iwl_send_rxon_timing(priv, ctx);
2395 if (ret)
2396 IWL_WARN(priv, "RXON timing - "
2397 "Attempting to continue.\n");
2398
2399 ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK;
2400
2401 iwl_set_rxon_ht(priv, &priv->current_ht_config);
2402
2403 if (priv->cfg->ops->hcmd->set_rxon_chain)
2404 priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx);
2405
2406 ctx->staging.assoc_id = cpu_to_le16(vif->bss_conf.aid);
2407
2408 IWL_DEBUG_ASSOC(priv, "assoc id %d beacon interval %d\n",
2409 vif->bss_conf.aid, vif->bss_conf.beacon_int);
2410
2411 if (vif->bss_conf.use_short_preamble)
2412 ctx->staging.flags |= RXON_FLG_SHORT_PREAMBLE_MSK;
2413 else
2414 ctx->staging.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK;
2415
2416 if (ctx->staging.flags & RXON_FLG_BAND_24G_MSK) {
2417 if (vif->bss_conf.use_short_slot)
2418 ctx->staging.flags |= RXON_FLG_SHORT_SLOT_MSK;
2419 else
2420 ctx->staging.flags &= ~RXON_FLG_SHORT_SLOT_MSK;
2421 }
2422
2423 iwlcore_commit_rxon(priv, ctx);
2424
2425 IWL_DEBUG_ASSOC(priv, "Associated as %d to: %pM\n",
2426 vif->bss_conf.aid, ctx->active.bssid_addr);
2427
2428 switch (vif->type) {
2429 case NL80211_IFTYPE_STATION:
2430 break;
2431 case NL80211_IFTYPE_ADHOC:
2432 iwlagn_send_beacon_cmd(priv);
2433 break;
2434 default:
2435 IWL_ERR(priv, "%s Should not be called in %d mode\n",
2436 __func__, vif->type);
2437 break;
2438 }
2439
2440 /* the chain noise calibration will enabled PM upon completion
2441 * If chain noise has already been run, then we need to enable
2442 * power management here */
2443 if (priv->chain_noise_data.state == IWL_CHAIN_NOISE_DONE)
2444 iwl_power_update_mode(priv, false);
2445
2446 /* Enable Rx differential gain and sensitivity calibrations */
2447 iwl_chain_noise_reset(priv);
2448 priv->start_calib = 1;
2449}
2450
2451static void iwl4965_config_ap(struct iwl_priv *priv)
2452{
2453 struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
2454 struct ieee80211_vif *vif = ctx->vif;
2455 int ret = 0;
2456
2457 lockdep_assert_held(&priv->mutex);
2458
2459 if (test_bit(STATUS_EXIT_PENDING, &priv->status))
2460 return;
2461
2462 /* The following should be done only at AP bring up */
2463 if (!iwl_is_associated_ctx(ctx)) {
2464
2465 /* RXON - unassoc (to set timing command) */
2466 ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
2467 iwlcore_commit_rxon(priv, ctx);
2468
2469 /* RXON Timing */
2470 ret = iwl_send_rxon_timing(priv, ctx);
2471 if (ret)
2472 IWL_WARN(priv, "RXON timing failed - "
2473 "Attempting to continue.\n");
2474
2475 /* AP has all antennas */
2476 priv->chain_noise_data.active_chains =
2477 priv->hw_params.valid_rx_ant;
2478 iwl_set_rxon_ht(priv, &priv->current_ht_config);
2479 if (priv->cfg->ops->hcmd->set_rxon_chain)
2480 priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx);
2481
2482 ctx->staging.assoc_id = 0;
2483
2484 if (vif->bss_conf.use_short_preamble)
2485 ctx->staging.flags |=
2486 RXON_FLG_SHORT_PREAMBLE_MSK;
2487 else
2488 ctx->staging.flags &=
2489 ~RXON_FLG_SHORT_PREAMBLE_MSK;
2490
2491 if (ctx->staging.flags & RXON_FLG_BAND_24G_MSK) {
2492 if (vif->bss_conf.use_short_slot)
2493 ctx->staging.flags |=
2494 RXON_FLG_SHORT_SLOT_MSK;
2495 else
2496 ctx->staging.flags &=
2497 ~RXON_FLG_SHORT_SLOT_MSK;
2498 }
2499 /* need to send beacon cmd before committing assoc RXON! */
2500 iwlagn_send_beacon_cmd(priv);
2501 /* restore RXON assoc */
2502 ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK;
2503 iwlcore_commit_rxon(priv, ctx);
2504 }
2505 iwlagn_send_beacon_cmd(priv);
2506
2507 /* FIXME - we need to add code here to detect a totally new
2508 * configuration, reset the AP, unassoc, rxon timing, assoc,
2509 * clear sta table, add BCAST sta... */
2510}
2511
2232static struct iwl_hcmd_utils_ops iwl4965_hcmd_utils = { 2512static struct iwl_hcmd_utils_ops iwl4965_hcmd_utils = {
2233 .get_hcmd_size = iwl4965_get_hcmd_size, 2513 .get_hcmd_size = iwl4965_get_hcmd_size,
2234 .build_addsta_hcmd = iwl4965_build_addsta_hcmd, 2514 .build_addsta_hcmd = iwl4965_build_addsta_hcmd,
@@ -2281,14 +2561,10 @@ static struct iwl_lib_ops iwl4965_lib = {
2281 }, 2561 },
2282 .send_tx_power = iwl4965_send_tx_power, 2562 .send_tx_power = iwl4965_send_tx_power,
2283 .update_chain_flags = iwl_update_chain_flags, 2563 .update_chain_flags = iwl_update_chain_flags,
2284 .post_associate = iwl_post_associate,
2285 .config_ap = iwl_config_ap,
2286 .isr = iwl_isr_legacy, 2564 .isr = iwl_isr_legacy,
2287 .temp_ops = { 2565 .temp_ops = {
2288 .temperature = iwl4965_temperature_calib, 2566 .temperature = iwl4965_temperature_calib,
2289 }, 2567 },
2290 .manage_ibss_station = iwlagn_manage_ibss_station,
2291 .update_bcast_stations = iwl_update_bcast_stations,
2292 .debugfs_ops = { 2568 .debugfs_ops = {
2293 .rx_stats_read = iwl_ucode_rx_stats_read, 2569 .rx_stats_read = iwl_ucode_rx_stats_read,
2294 .tx_stats_read = iwl_ucode_tx_stats_read, 2570 .tx_stats_read = iwl_ucode_tx_stats_read,
@@ -2300,12 +2576,42 @@ static struct iwl_lib_ops iwl4965_lib = {
2300 .check_plcp_health = iwl_good_plcp_health, 2576 .check_plcp_health = iwl_good_plcp_health,
2301}; 2577};
2302 2578
2579static const struct iwl_legacy_ops iwl4965_legacy_ops = {
2580 .post_associate = iwl4965_post_associate,
2581 .config_ap = iwl4965_config_ap,
2582 .manage_ibss_station = iwlagn_manage_ibss_station,
2583 .update_bcast_stations = iwl_update_bcast_stations,
2584};
2585
2586struct ieee80211_ops iwl4965_hw_ops = {
2587 .tx = iwlagn_mac_tx,
2588 .start = iwlagn_mac_start,
2589 .stop = iwlagn_mac_stop,
2590 .add_interface = iwl_mac_add_interface,
2591 .remove_interface = iwl_mac_remove_interface,
2592 .config = iwl_legacy_mac_config,
2593 .configure_filter = iwlagn_configure_filter,
2594 .set_key = iwlagn_mac_set_key,
2595 .update_tkip_key = iwlagn_mac_update_tkip_key,
2596 .conf_tx = iwl_mac_conf_tx,
2597 .reset_tsf = iwl_legacy_mac_reset_tsf,
2598 .bss_info_changed = iwl_legacy_mac_bss_info_changed,
2599 .ampdu_action = iwlagn_mac_ampdu_action,
2600 .hw_scan = iwl_mac_hw_scan,
2601 .sta_add = iwlagn_mac_sta_add,
2602 .sta_remove = iwl_mac_sta_remove,
2603 .channel_switch = iwlagn_mac_channel_switch,
2604 .flush = iwlagn_mac_flush,
2605 .tx_last_beacon = iwl_mac_tx_last_beacon,
2606};
2607
2303static const struct iwl_ops iwl4965_ops = { 2608static const struct iwl_ops iwl4965_ops = {
2304 .lib = &iwl4965_lib, 2609 .lib = &iwl4965_lib,
2305 .hcmd = &iwl4965_hcmd, 2610 .hcmd = &iwl4965_hcmd,
2306 .utils = &iwl4965_hcmd_utils, 2611 .utils = &iwl4965_hcmd_utils,
2307 .led = &iwlagn_led_ops, 2612 .led = &iwlagn_led_ops,
2308 .ieee80211_ops = &iwlagn_hw_ops, 2613 .legacy = &iwl4965_legacy_ops,
2614 .ieee80211_ops = &iwl4965_hw_ops,
2309}; 2615};
2310 2616
2311static struct iwl_base_params iwl4965_base_params = { 2617static struct iwl_base_params iwl4965_base_params = {
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c
index 5f0327721692..e1f412f915ae 100644
--- a/drivers/net/wireless/iwlwifi/iwl-5000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-5000.c
@@ -385,14 +385,10 @@ static struct iwl_lib_ops iwl5000_lib = {
385 .calib_version = iwlagn_eeprom_calib_version, 385 .calib_version = iwlagn_eeprom_calib_version,
386 .query_addr = iwlagn_eeprom_query_addr, 386 .query_addr = iwlagn_eeprom_query_addr,
387 }, 387 },
388 .post_associate = iwl_post_associate,
389 .isr = iwl_isr_ict, 388 .isr = iwl_isr_ict,
390 .config_ap = iwl_config_ap,
391 .temp_ops = { 389 .temp_ops = {
392 .temperature = iwlagn_temperature, 390 .temperature = iwlagn_temperature,
393 }, 391 },
394 .manage_ibss_station = iwlagn_manage_ibss_station,
395 .update_bcast_stations = iwl_update_bcast_stations,
396 .debugfs_ops = { 392 .debugfs_ops = {
397 .rx_stats_read = iwl_ucode_rx_stats_read, 393 .rx_stats_read = iwl_ucode_rx_stats_read,
398 .tx_stats_read = iwl_ucode_tx_stats_read, 394 .tx_stats_read = iwl_ucode_tx_stats_read,
@@ -453,14 +449,10 @@ static struct iwl_lib_ops iwl5150_lib = {
453 .calib_version = iwlagn_eeprom_calib_version, 449 .calib_version = iwlagn_eeprom_calib_version,
454 .query_addr = iwlagn_eeprom_query_addr, 450 .query_addr = iwlagn_eeprom_query_addr,
455 }, 451 },
456 .post_associate = iwl_post_associate,
457 .isr = iwl_isr_ict, 452 .isr = iwl_isr_ict,
458 .config_ap = iwl_config_ap,
459 .temp_ops = { 453 .temp_ops = {
460 .temperature = iwl5150_temperature, 454 .temperature = iwl5150_temperature,
461 }, 455 },
462 .manage_ibss_station = iwlagn_manage_ibss_station,
463 .update_bcast_stations = iwl_update_bcast_stations,
464 .debugfs_ops = { 456 .debugfs_ops = {
465 .rx_stats_read = iwl_ucode_rx_stats_read, 457 .rx_stats_read = iwl_ucode_rx_stats_read,
466 .tx_stats_read = iwl_ucode_tx_stats_read, 458 .tx_stats_read = iwl_ucode_tx_stats_read,
diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c
index 85bde701351e..eacbce0d88b6 100644
--- a/drivers/net/wireless/iwlwifi/iwl-6000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-6000.c
@@ -328,14 +328,10 @@ static struct iwl_lib_ops iwl6000_lib = {
328 .query_addr = iwlagn_eeprom_query_addr, 328 .query_addr = iwlagn_eeprom_query_addr,
329 .update_enhanced_txpower = iwlcore_eeprom_enhanced_txpower, 329 .update_enhanced_txpower = iwlcore_eeprom_enhanced_txpower,
330 }, 330 },
331 .post_associate = iwl_post_associate,
332 .isr = iwl_isr_ict, 331 .isr = iwl_isr_ict,
333 .config_ap = iwl_config_ap,
334 .temp_ops = { 332 .temp_ops = {
335 .temperature = iwlagn_temperature, 333 .temperature = iwlagn_temperature,
336 }, 334 },
337 .manage_ibss_station = iwlagn_manage_ibss_station,
338 .update_bcast_stations = iwl_update_bcast_stations,
339 .debugfs_ops = { 335 .debugfs_ops = {
340 .rx_stats_read = iwl_ucode_rx_stats_read, 336 .rx_stats_read = iwl_ucode_rx_stats_read,
341 .tx_stats_read = iwl_ucode_tx_stats_read, 337 .tx_stats_read = iwl_ucode_tx_stats_read,
@@ -399,14 +395,10 @@ static struct iwl_lib_ops iwl6000g2b_lib = {
399 .query_addr = iwlagn_eeprom_query_addr, 395 .query_addr = iwlagn_eeprom_query_addr,
400 .update_enhanced_txpower = iwlcore_eeprom_enhanced_txpower, 396 .update_enhanced_txpower = iwlcore_eeprom_enhanced_txpower,
401 }, 397 },
402 .post_associate = iwl_post_associate,
403 .isr = iwl_isr_ict, 398 .isr = iwl_isr_ict,
404 .config_ap = iwl_config_ap,
405 .temp_ops = { 399 .temp_ops = {
406 .temperature = iwlagn_temperature, 400 .temperature = iwlagn_temperature,
407 }, 401 },
408 .manage_ibss_station = iwlagn_manage_ibss_station,
409 .update_bcast_stations = iwl_update_bcast_stations,
410 .debugfs_ops = { 402 .debugfs_ops = {
411 .rx_stats_read = iwl_ucode_rx_stats_read, 403 .rx_stats_read = iwl_ucode_rx_stats_read,
412 .tx_stats_read = iwl_ucode_tx_stats_read, 404 .tx_stats_read = iwl_ucode_tx_stats_read,
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c
new file mode 100644
index 000000000000..58602457e415
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c
@@ -0,0 +1,562 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17 *
18 * The full GNU General Public License is included in this distribution in the
19 * file called LICENSE.
20 *
21 * Contact Information:
22 * Intel Linux Wireless <ilw@linux.intel.com>
23 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
24 *
25 *****************************************************************************/
26
27#include "iwl-dev.h"
28#include "iwl-agn.h"
29#include "iwl-sta.h"
30#include "iwl-core.h"
31#include "iwl-agn-calib.h"
32
33static int iwlagn_disable_bss(struct iwl_priv *priv,
34 struct iwl_rxon_context *ctx,
35 struct iwl_rxon_cmd *send)
36{
37 __le32 old_filter = send->filter_flags;
38 int ret;
39
40 send->filter_flags &= ~RXON_FILTER_ASSOC_MSK;
41 ret = iwl_send_cmd_pdu(priv, ctx->rxon_cmd, sizeof(*send), send);
42
43 send->filter_flags = old_filter;
44
45 if (ret)
46 IWL_ERR(priv, "Error clearing ASSOC_MSK on BSS (%d)\n", ret);
47
48 return ret;
49}
50
51static int iwlagn_disable_pan(struct iwl_priv *priv,
52 struct iwl_rxon_context *ctx,
53 struct iwl_rxon_cmd *send)
54{
55 __le32 old_filter = send->filter_flags;
56 u8 old_dev_type = send->dev_type;
57 int ret;
58
59 send->filter_flags &= ~RXON_FILTER_ASSOC_MSK;
60 send->dev_type = RXON_DEV_TYPE_P2P;
61 ret = iwl_send_cmd_pdu(priv, ctx->rxon_cmd, sizeof(*send), send);
62
63 send->filter_flags = old_filter;
64 send->dev_type = old_dev_type;
65
66 if (ret)
67 IWL_ERR(priv, "Error disabling PAN (%d)\n", ret);
68
69 /* FIXME: WAIT FOR PAN DISABLE */
70 msleep(300);
71
72 return ret;
73}
74
75/**
76 * iwlagn_commit_rxon - commit staging_rxon to hardware
77 *
78 * The RXON command in staging_rxon is committed to the hardware and
79 * the active_rxon structure is updated with the new data. This
80 * function correctly transitions out of the RXON_ASSOC_MSK state if
81 * a HW tune is required based on the RXON structure changes.
82 */
83int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
84{
85 /* cast away the const for active_rxon in this function */
86 struct iwl_rxon_cmd *active = (void *)&ctx->active;
87 bool old_assoc = !!(ctx->active.filter_flags & RXON_FILTER_ASSOC_MSK);
88 bool new_assoc = !!(ctx->staging.filter_flags & RXON_FILTER_ASSOC_MSK);
89 int ret;
90
91 lockdep_assert_held(&priv->mutex);
92
93 if (!iwl_is_alive(priv))
94 return -EBUSY;
95
96 /* This function hardcodes a bunch of dual-mode assumptions */
97 BUILD_BUG_ON(NUM_IWL_RXON_CTX != 2);
98
99 if (!ctx->is_active)
100 return 0;
101
102 /* always get timestamp with Rx frame */
103 ctx->staging.flags |= RXON_FLG_TSF2HOST_MSK;
104
105 if ((ctx->vif && ctx->vif->bss_conf.use_short_slot) ||
106 !(ctx->staging.flags & RXON_FLG_BAND_24G_MSK))
107 ctx->staging.flags |= RXON_FLG_SHORT_SLOT_MSK;
108 else
109 ctx->staging.flags &= ~RXON_FLG_SHORT_SLOT_MSK;
110
111 ret = iwl_check_rxon_cmd(priv, ctx);
112 if (ret) {
113 IWL_ERR(priv, "Invalid RXON configuration. Not committing.\n");
114 return -EINVAL;
115 }
116
117 /*
118 * receive commit_rxon request
119 * abort any previous channel switch if still in process
120 */
121 if (priv->switch_rxon.switch_in_progress &&
122 (priv->switch_rxon.channel != ctx->staging.channel)) {
123 IWL_DEBUG_11H(priv, "abort channel switch on %d\n",
124 le16_to_cpu(priv->switch_rxon.channel));
125 iwl_chswitch_done(priv, false);
126 }
127
128 /*
129 * If we don't need to send a full RXON, we can use
130 * iwl_rxon_assoc_cmd which is used to reconfigure filter
131 * and other flags for the current radio configuration.
132 */
133 if (!iwl_full_rxon_required(priv, ctx)) {
134 ret = iwl_send_rxon_assoc(priv, ctx);
135 if (ret) {
136 IWL_ERR(priv, "Error setting RXON_ASSOC (%d)\n", ret);
137 return ret;
138 }
139
140 memcpy(active, &ctx->staging, sizeof(*active));
141 iwl_print_rx_config_cmd(priv, ctx);
142 return 0;
143 }
144
145 if (priv->cfg->ops->hcmd->set_pan_params) {
146 ret = priv->cfg->ops->hcmd->set_pan_params(priv);
147 if (ret)
148 return ret;
149 }
150
151 iwl_set_rxon_hwcrypto(priv, ctx, !priv->cfg->mod_params->sw_crypto);
152
153 IWL_DEBUG_INFO(priv,
154 "Going to commit RXON\n"
155 " * with%s RXON_FILTER_ASSOC_MSK\n"
156 " * channel = %d\n"
157 " * bssid = %pM\n",
158 (new_assoc ? "" : "out"),
159 le16_to_cpu(ctx->staging.channel),
160 ctx->staging.bssid_addr);
161
162 /*
163 * If we are currently associated and the new config is also
164 * going to be associated, OR if the new config is simply not
165 * associated, clear associated.
166 */
167 if ((old_assoc && new_assoc) || !new_assoc) {
168 struct iwl_rxon_cmd *send = active;
169
170 if (!new_assoc)
171 send = &ctx->staging;
172
173 if (ctx->ctxid == IWL_RXON_CTX_BSS)
174 ret = iwlagn_disable_bss(priv, ctx, send);
175 else
176 ret = iwlagn_disable_pan(priv, ctx, send);
177 if (ret)
178 return ret;
179
180 if (send != active)
181 memcpy(active, send, sizeof(*active));
182
183 /*
184 * Un-assoc RXON clears the station table and WEP
185 * keys, so we have to restore those afterwards.
186 */
187 iwl_clear_ucode_stations(priv, ctx);
188 iwl_restore_stations(priv, ctx);
189 ret = iwl_restore_default_wep_keys(priv, ctx);
190 if (ret) {
191 IWL_ERR(priv, "Failed to restore WEP keys (%d)\n", ret);
192 return ret;
193 }
194 }
195
196 /* RXON timing must be before associated RXON */
197 ret = iwl_send_rxon_timing(priv, ctx);
198 if (ret) {
199 IWL_ERR(priv, "Failed to send timing (%d)!\n", ret);
200 return ret;
201 }
202
203 if (new_assoc) {
204 if (ctx->vif && (ctx->vif->type == NL80211_IFTYPE_AP ||
205 ctx->vif->type == NL80211_IFTYPE_ADHOC)) {
206 /*
207 * We'll run into this code path when beaconing is
208 * enabled, but then we also need to send the beacon
209 * to the device.
210 */
211 dev_kfree_skb(priv->beacon_skb);
212 priv->beacon_skb = ieee80211_beacon_get(priv->hw,
213 ctx->vif);
214 iwlagn_send_beacon_cmd(priv);
215 }
216
217 priv->start_calib = 0;
218 /*
219 * Apply the new configuration.
220 *
221 * Associated RXON doesn't clear the station table in uCode,
222 * so we don't need to restore stations etc. after this.
223 */
224 ret = iwl_send_cmd_pdu(priv, ctx->rxon_cmd,
225 sizeof(struct iwl_rxon_cmd), &ctx->staging);
226 if (ret) {
227 IWL_ERR(priv, "Error setting new RXON (%d)\n", ret);
228 return ret;
229 }
230 memcpy(active, &ctx->staging, sizeof(*active));
231 }
232
233 iwl_print_rx_config_cmd(priv, ctx);
234
235 iwl_init_sensitivity(priv);
236
237 /*
238 * If we issue a new RXON command which required a tune then we must
239 * send a new TXPOWER command or we won't be able to Tx any frames.
240 *
241 * FIXME: which RXON requires a tune? Can we optimise this out in
242 * some cases?
243 */
244 ret = iwl_set_tx_power(priv, priv->tx_power_user_lmt, true);
245 if (ret) {
246 IWL_ERR(priv, "Error sending TX power (%d)\n", ret);
247 return ret;
248 }
249
250 return 0;
251}
252
253int iwlagn_mac_config(struct ieee80211_hw *hw, u32 changed)
254{
255 struct iwl_priv *priv = hw->priv;
256 struct iwl_rxon_context *ctx;
257 struct ieee80211_conf *conf = &hw->conf;
258 struct ieee80211_channel *channel = conf->channel;
259 const struct iwl_channel_info *ch_info;
260 int ret = 0;
261
262 IWL_DEBUG_MAC80211(priv, "changed %#x", changed);
263
264 mutex_lock(&priv->mutex);
265
266 if (unlikely(test_bit(STATUS_SCANNING, &priv->status))) {
267 IWL_DEBUG_MAC80211(priv, "leave - scanning\n");
268 goto out;
269 }
270
271 if (!iwl_is_ready(priv)) {
272 IWL_DEBUG_MAC80211(priv, "leave - not ready\n");
273 goto out;
274 }
275
276 if (changed & (IEEE80211_CONF_CHANGE_SMPS |
277 IEEE80211_CONF_CHANGE_CHANNEL)) {
278 /* mac80211 uses static for non-HT which is what we want */
279 priv->current_ht_config.smps = conf->smps_mode;
280
281 /*
282 * Recalculate chain counts.
283 *
284 * If monitor mode is enabled then mac80211 will
285 * set up the SM PS mode to OFF if an HT channel is
286 * configured.
287 */
288 if (priv->cfg->ops->hcmd->set_rxon_chain)
289 for_each_context(priv, ctx)
290 priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx);
291 }
292
293 if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
294 unsigned long flags;
295
296 ch_info = iwl_get_channel_info(priv, channel->band,
297 channel->hw_value);
298 if (!is_channel_valid(ch_info)) {
299 IWL_DEBUG_MAC80211(priv, "leave - invalid channel\n");
300 ret = -EINVAL;
301 goto out;
302 }
303
304 spin_lock_irqsave(&priv->lock, flags);
305
306 for_each_context(priv, ctx) {
307 /* Configure HT40 channels */
308 ctx->ht.enabled = conf_is_ht(conf);
309 if (ctx->ht.enabled) {
310 if (conf_is_ht40_minus(conf)) {
311 ctx->ht.extension_chan_offset =
312 IEEE80211_HT_PARAM_CHA_SEC_BELOW;
313 ctx->ht.is_40mhz = true;
314 } else if (conf_is_ht40_plus(conf)) {
315 ctx->ht.extension_chan_offset =
316 IEEE80211_HT_PARAM_CHA_SEC_ABOVE;
317 ctx->ht.is_40mhz = true;
318 } else {
319 ctx->ht.extension_chan_offset =
320 IEEE80211_HT_PARAM_CHA_SEC_NONE;
321 ctx->ht.is_40mhz = false;
322 }
323 } else
324 ctx->ht.is_40mhz = false;
325
326 /*
327 * Default to no protection. Protection mode will
328 * later be set from BSS config in iwl_ht_conf
329 */
330 ctx->ht.protection = IEEE80211_HT_OP_MODE_PROTECTION_NONE;
331
332 /* if we are switching from ht to 2.4 clear flags
333 * from any ht related info since 2.4 does not
334 * support ht */
335 if (le16_to_cpu(ctx->staging.channel) !=
336 channel->hw_value)
337 ctx->staging.flags = 0;
338
339 iwl_set_rxon_channel(priv, channel, ctx);
340 iwl_set_rxon_ht(priv, &priv->current_ht_config);
341
342 iwl_set_flags_for_band(priv, ctx, channel->band,
343 ctx->vif);
344 }
345
346 spin_unlock_irqrestore(&priv->lock, flags);
347
348 iwl_update_bcast_stations(priv);
349
350 /*
351 * The list of supported rates and rate mask can be different
352 * for each band; since the band may have changed, reset
353 * the rate mask to what mac80211 lists.
354 */
355 iwl_set_rate(priv);
356 }
357
358 if (changed & (IEEE80211_CONF_CHANGE_PS |
359 IEEE80211_CONF_CHANGE_IDLE)) {
360 ret = iwl_power_update_mode(priv, false);
361 if (ret)
362 IWL_DEBUG_MAC80211(priv, "Error setting sleep level\n");
363 }
364
365 if (changed & IEEE80211_CONF_CHANGE_POWER) {
366 IWL_DEBUG_MAC80211(priv, "TX Power old=%d new=%d\n",
367 priv->tx_power_user_lmt, conf->power_level);
368
369 iwl_set_tx_power(priv, conf->power_level, false);
370 }
371
372 for_each_context(priv, ctx) {
373 if (!memcmp(&ctx->staging, &ctx->active, sizeof(ctx->staging)))
374 continue;
375 iwlagn_commit_rxon(priv, ctx);
376 }
377 out:
378 mutex_unlock(&priv->mutex);
379 return ret;
380}
381
382static void iwlagn_update_qos(struct iwl_priv *priv,
383 struct iwl_rxon_context *ctx)
384{
385 int ret;
386
387 if (!ctx->is_active)
388 return;
389
390 ctx->qos_data.def_qos_parm.qos_flags = 0;
391
392 if (ctx->qos_data.qos_active)
393 ctx->qos_data.def_qos_parm.qos_flags |=
394 QOS_PARAM_FLG_UPDATE_EDCA_MSK;
395
396 if (ctx->ht.enabled)
397 ctx->qos_data.def_qos_parm.qos_flags |= QOS_PARAM_FLG_TGN_MSK;
398
399 IWL_DEBUG_QOS(priv, "send QoS cmd with Qos active=%d FLAGS=0x%X\n",
400 ctx->qos_data.qos_active,
401 ctx->qos_data.def_qos_parm.qos_flags);
402
403 ret = iwl_send_cmd_pdu(priv, ctx->qos_cmd,
404 sizeof(struct iwl_qosparam_cmd),
405 &ctx->qos_data.def_qos_parm);
406 if (ret)
407 IWL_ERR(priv, "Failed to update QoS\n");
408}
409
410static void iwlagn_check_needed_chains(struct iwl_priv *priv,
411 struct iwl_rxon_context *ctx,
412 struct ieee80211_bss_conf *bss_conf)
413{
414 struct ieee80211_vif *vif = ctx->vif;
415 struct iwl_rxon_context *tmp;
416 struct ieee80211_sta *sta;
417 struct iwl_ht_config *ht_conf = &priv->current_ht_config;
418 bool need_multiple;
419
420 lockdep_assert_held(&priv->mutex);
421
422 switch (vif->type) {
423 case NL80211_IFTYPE_STATION:
424 rcu_read_lock();
425 sta = ieee80211_find_sta(vif, bss_conf->bssid);
426 if (sta) {
427 struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap;
428 int maxstreams;
429
430 maxstreams = (ht_cap->mcs.tx_params &
431 IEEE80211_HT_MCS_TX_MAX_STREAMS_MASK)
432 >> IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT;
433 maxstreams += 1;
434
435 if ((ht_cap->mcs.rx_mask[1] == 0) &&
436 (ht_cap->mcs.rx_mask[2] == 0))
437 need_multiple = false;
438 if (maxstreams <= 1)
439 need_multiple = true;
440 } else {
441 /*
442 * If at all, this can only happen through a race
443 * when the AP disconnects us while we're still
444 * setting up the connection, in that case mac80211
445 * will soon tell us about that.
446 */
447 need_multiple = false;
448 }
449 rcu_read_unlock();
450 break;
451 case NL80211_IFTYPE_ADHOC:
452 /* currently */
453 need_multiple = false;
454 break;
455 default:
456 /* only AP really */
457 need_multiple = true;
458 break;
459 }
460
461 ctx->ht_need_multiple_chains = need_multiple;
462
463 if (!need_multiple) {
464 /* check all contexts */
465 for_each_context(priv, tmp) {
466 if (!tmp->vif)
467 continue;
468 if (tmp->ht_need_multiple_chains) {
469 need_multiple = true;
470 break;
471 }
472 }
473 }
474
475 ht_conf->single_chain_sufficient = !need_multiple;
476}
477
478void iwlagn_bss_info_changed(struct ieee80211_hw *hw,
479 struct ieee80211_vif *vif,
480 struct ieee80211_bss_conf *bss_conf,
481 u32 changes)
482{
483 struct iwl_priv *priv = hw->priv;
484 struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif);
485 int ret;
486 bool force = false;
487
488 mutex_lock(&priv->mutex);
489
490 if (changes & BSS_CHANGED_BEACON_INT)
491 force = true;
492
493 if (changes & BSS_CHANGED_QOS) {
494 ctx->qos_data.qos_active = bss_conf->qos;
495 iwlagn_update_qos(priv, ctx);
496 }
497
498 ctx->staging.assoc_id = cpu_to_le16(vif->bss_conf.aid);
499 if (vif->bss_conf.use_short_preamble)
500 ctx->staging.flags |= RXON_FLG_SHORT_PREAMBLE_MSK;
501 else
502 ctx->staging.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK;
503
504 if (changes & BSS_CHANGED_ASSOC) {
505 if (bss_conf->assoc) {
506 iwl_led_associate(priv);
507 priv->timestamp = bss_conf->timestamp;
508 ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK;
509 } else {
510 ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
511 iwl_led_disassociate(priv);
512 }
513 }
514
515 if (ctx->ht.enabled) {
516 ctx->ht.protection = bss_conf->ht_operation_mode &
517 IEEE80211_HT_OP_MODE_PROTECTION;
518 ctx->ht.non_gf_sta_present = !!(bss_conf->ht_operation_mode &
519 IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT);
520 iwlagn_check_needed_chains(priv, ctx, bss_conf);
521 }
522
523 if (priv->cfg->ops->hcmd->set_rxon_chain)
524 priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx);
525
526 if (bss_conf->use_cts_prot && (priv->band != IEEE80211_BAND_5GHZ))
527 ctx->staging.flags |= RXON_FLG_TGG_PROTECT_MSK;
528 else
529 ctx->staging.flags &= ~RXON_FLG_TGG_PROTECT_MSK;
530
531 if (bss_conf->use_cts_prot)
532 ctx->staging.flags |= RXON_FLG_SELF_CTS_EN;
533 else
534 ctx->staging.flags &= ~RXON_FLG_SELF_CTS_EN;
535
536 memcpy(ctx->staging.bssid_addr, bss_conf->bssid, ETH_ALEN);
537
538 if (vif->type == NL80211_IFTYPE_AP ||
539 vif->type == NL80211_IFTYPE_ADHOC) {
540 if (vif->bss_conf.enable_beacon) {
541 ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK;
542 priv->beacon_ctx = ctx;
543 } else {
544 ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
545 priv->beacon_ctx = NULL;
546 }
547 }
548
549 if (force || memcmp(&ctx->staging, &ctx->active, sizeof(ctx->staging)))
550 iwlagn_commit_rxon(priv, ctx);
551
552 if (changes & BSS_CHANGED_IBSS) {
553 ret = iwlagn_manage_ibss_station(priv, vif,
554 bss_conf->ibss_joined);
555 if (ret)
556 IWL_ERR(priv, "failed to %s IBSS station %pM\n",
557 bss_conf->ibss_joined ? "add" : "remove",
558 bss_conf->bssid);
559 }
560
561 mutex_unlock(&priv->mutex);
562}
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index 3d1f6831cc20..1050f31d90a4 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -90,153 +90,6 @@ MODULE_ALIAS("iwl4965");
90static int iwlagn_ant_coupling; 90static int iwlagn_ant_coupling;
91static bool iwlagn_bt_ch_announce = 1; 91static bool iwlagn_bt_ch_announce = 1;
92 92
93/**
94 * iwlagn_commit_rxon - commit staging_rxon to hardware
95 *
96 * The RXON command in staging_rxon is committed to the hardware and
97 * the active_rxon structure is updated with the new data. This
98 * function correctly transitions out of the RXON_ASSOC_MSK state if
99 * a HW tune is required based on the RXON structure changes.
100 */
101int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
102{
103 /* cast away the const for active_rxon in this function */
104 struct iwl_rxon_cmd *active_rxon = (void *)&ctx->active;
105 int ret;
106 bool new_assoc =
107 !!(ctx->staging.filter_flags & RXON_FILTER_ASSOC_MSK);
108
109 if (!iwl_is_alive(priv))
110 return -EBUSY;
111
112 if (!ctx->is_active)
113 return 0;
114
115 /* always get timestamp with Rx frame */
116 ctx->staging.flags |= RXON_FLG_TSF2HOST_MSK;
117
118 ret = iwl_check_rxon_cmd(priv, ctx);
119 if (ret) {
120 IWL_ERR(priv, "Invalid RXON configuration. Not committing.\n");
121 return -EINVAL;
122 }
123
124 /*
125 * receive commit_rxon request
126 * abort any previous channel switch if still in process
127 */
128 if (priv->switch_rxon.switch_in_progress &&
129 (priv->switch_rxon.channel != ctx->staging.channel)) {
130 IWL_DEBUG_11H(priv, "abort channel switch on %d\n",
131 le16_to_cpu(priv->switch_rxon.channel));
132 iwl_chswitch_done(priv, false);
133 }
134
135 /* If we don't need to send a full RXON, we can use
136 * iwl_rxon_assoc_cmd which is used to reconfigure filter
137 * and other flags for the current radio configuration. */
138 if (!iwl_full_rxon_required(priv, ctx)) {
139 ret = iwl_send_rxon_assoc(priv, ctx);
140 if (ret) {
141 IWL_ERR(priv, "Error setting RXON_ASSOC (%d)\n", ret);
142 return ret;
143 }
144
145 memcpy(active_rxon, &ctx->staging, sizeof(*active_rxon));
146 iwl_print_rx_config_cmd(priv, ctx);
147 return 0;
148 }
149
150 /* If we are currently associated and the new config requires
151 * an RXON_ASSOC and the new config wants the associated mask enabled,
152 * we must clear the associated from the active configuration
153 * before we apply the new config */
154 if (iwl_is_associated_ctx(ctx) && new_assoc) {
155 IWL_DEBUG_INFO(priv, "Toggling associated bit on current RXON\n");
156 active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK;
157
158 ret = iwl_send_cmd_pdu(priv, ctx->rxon_cmd,
159 sizeof(struct iwl_rxon_cmd),
160 active_rxon);
161
162 /* If the mask clearing failed then we set
163 * active_rxon back to what it was previously */
164 if (ret) {
165 active_rxon->filter_flags |= RXON_FILTER_ASSOC_MSK;
166 IWL_ERR(priv, "Error clearing ASSOC_MSK (%d)\n", ret);
167 return ret;
168 }
169 iwl_clear_ucode_stations(priv, ctx);
170 iwl_restore_stations(priv, ctx);
171 ret = iwl_restore_default_wep_keys(priv, ctx);
172 if (ret) {
173 IWL_ERR(priv, "Failed to restore WEP keys (%d)\n", ret);
174 return ret;
175 }
176 }
177
178 IWL_DEBUG_INFO(priv, "Sending RXON\n"
179 "* with%s RXON_FILTER_ASSOC_MSK\n"
180 "* channel = %d\n"
181 "* bssid = %pM\n",
182 (new_assoc ? "" : "out"),
183 le16_to_cpu(ctx->staging.channel),
184 ctx->staging.bssid_addr);
185
186 iwl_set_rxon_hwcrypto(priv, ctx, !priv->cfg->mod_params->sw_crypto);
187
188 if (priv->cfg->ops->hcmd->set_pan_params) {
189 ret = priv->cfg->ops->hcmd->set_pan_params(priv);
190 if (ret)
191 return ret;
192 }
193
194 /* Apply the new configuration
195 * RXON unassoc clears the station table in uCode so restoration of
196 * stations is needed after it (the RXON command) completes
197 */
198 if (!new_assoc) {
199 ret = iwl_send_cmd_pdu(priv, ctx->rxon_cmd,
200 sizeof(struct iwl_rxon_cmd), &ctx->staging);
201 if (ret) {
202 IWL_ERR(priv, "Error setting new RXON (%d)\n", ret);
203 return ret;
204 }
205 IWL_DEBUG_INFO(priv, "Return from !new_assoc RXON.\n");
206 memcpy(active_rxon, &ctx->staging, sizeof(*active_rxon));
207 iwl_clear_ucode_stations(priv, ctx);
208 iwl_restore_stations(priv, ctx);
209 ret = iwl_restore_default_wep_keys(priv, ctx);
210 if (ret) {
211 IWL_ERR(priv, "Failed to restore WEP keys (%d)\n", ret);
212 return ret;
213 }
214 }
215 if (new_assoc) {
216 priv->start_calib = 0;
217 /* Apply the new configuration
218 * RXON assoc doesn't clear the station table in uCode,
219 */
220 ret = iwl_send_cmd_pdu(priv, ctx->rxon_cmd,
221 sizeof(struct iwl_rxon_cmd), &ctx->staging);
222 if (ret) {
223 IWL_ERR(priv, "Error setting new RXON (%d)\n", ret);
224 return ret;
225 }
226 memcpy(active_rxon, &ctx->staging, sizeof(*active_rxon));
227 }
228 iwl_print_rx_config_cmd(priv, ctx);
229
230 iwl_init_sensitivity(priv);
231
232 /* If we issue a new RXON command which required a tune then we must
233 * send a new TXPOWER command or we won't be able to Tx any frames */
234 ret = priv->cfg->ops->lib->send_tx_power(priv);
235 if (ret)
236 IWL_ERR(priv, "Error sending TX power (%d)\n", ret);
237 return ret;
238}
239
240void iwl_update_chain_flags(struct iwl_priv *priv) 93void iwl_update_chain_flags(struct iwl_priv *priv)
241{ 94{
242 struct iwl_rxon_context *ctx; 95 struct iwl_rxon_context *ctx;
@@ -394,7 +247,8 @@ static unsigned int iwl_hw_get_beacon_cmd(struct iwl_priv *priv,
394 247
395 return sizeof(*tx_beacon_cmd) + frame_size; 248 return sizeof(*tx_beacon_cmd) + frame_size;
396} 249}
397static int iwl_send_beacon_cmd(struct iwl_priv *priv) 250
251int iwlagn_send_beacon_cmd(struct iwl_priv *priv)
398{ 252{
399 struct iwl_frame *frame; 253 struct iwl_frame *frame;
400 unsigned int frame_size; 254 unsigned int frame_size;
@@ -644,7 +498,7 @@ static void iwl_bg_beacon_update(struct work_struct *work)
644 498
645 priv->beacon_skb = beacon; 499 priv->beacon_skb = beacon;
646 500
647 iwl_send_beacon_cmd(priv); 501 iwlagn_send_beacon_cmd(priv);
648 out: 502 out:
649 mutex_unlock(&priv->mutex); 503 mutex_unlock(&priv->mutex);
650} 504}
@@ -3292,92 +3146,6 @@ static void iwl_bg_rx_replenish(struct work_struct *data)
3292 mutex_unlock(&priv->mutex); 3146 mutex_unlock(&priv->mutex);
3293} 3147}
3294 3148
3295#define IWL_DELAY_NEXT_SCAN (HZ*2)
3296
3297void iwl_post_associate(struct iwl_priv *priv, struct ieee80211_vif *vif)
3298{
3299 struct iwl_rxon_context *ctx;
3300 struct ieee80211_conf *conf = NULL;
3301 int ret = 0;
3302
3303 if (!vif || !priv->is_open)
3304 return;
3305
3306 ctx = iwl_rxon_ctx_from_vif(vif);
3307
3308 if (vif->type == NL80211_IFTYPE_AP) {
3309 IWL_ERR(priv, "%s Should not be called in AP mode\n", __func__);
3310 return;
3311 }
3312
3313 if (test_bit(STATUS_EXIT_PENDING, &priv->status))
3314 return;
3315
3316 iwl_scan_cancel_timeout(priv, 200);
3317
3318 conf = ieee80211_get_hw_conf(priv->hw);
3319
3320 ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
3321 iwlcore_commit_rxon(priv, ctx);
3322
3323 ret = iwl_send_rxon_timing(priv, ctx);
3324 if (ret)
3325 IWL_WARN(priv, "RXON timing - "
3326 "Attempting to continue.\n");
3327
3328 ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK;
3329
3330 iwl_set_rxon_ht(priv, &priv->current_ht_config);
3331
3332 if (priv->cfg->ops->hcmd->set_rxon_chain)
3333 priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx);
3334
3335 ctx->staging.assoc_id = cpu_to_le16(vif->bss_conf.aid);
3336
3337 IWL_DEBUG_ASSOC(priv, "assoc id %d beacon interval %d\n",
3338 vif->bss_conf.aid, vif->bss_conf.beacon_int);
3339
3340 if (vif->bss_conf.use_short_preamble)
3341 ctx->staging.flags |= RXON_FLG_SHORT_PREAMBLE_MSK;
3342 else
3343 ctx->staging.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK;
3344
3345 if (ctx->staging.flags & RXON_FLG_BAND_24G_MSK) {
3346 if (vif->bss_conf.use_short_slot)
3347 ctx->staging.flags |= RXON_FLG_SHORT_SLOT_MSK;
3348 else
3349 ctx->staging.flags &= ~RXON_FLG_SHORT_SLOT_MSK;
3350 }
3351
3352 iwlcore_commit_rxon(priv, ctx);
3353
3354 IWL_DEBUG_ASSOC(priv, "Associated as %d to: %pM\n",
3355 vif->bss_conf.aid, ctx->active.bssid_addr);
3356
3357 switch (vif->type) {
3358 case NL80211_IFTYPE_STATION:
3359 break;
3360 case NL80211_IFTYPE_ADHOC:
3361 iwl_send_beacon_cmd(priv);
3362 break;
3363 default:
3364 IWL_ERR(priv, "%s Should not be called in %d mode\n",
3365 __func__, vif->type);
3366 break;
3367 }
3368
3369 /* the chain noise calibration will enabled PM upon completion
3370 * If chain noise has already been run, then we need to enable
3371 * power management here */
3372 if (priv->chain_noise_data.state == IWL_CHAIN_NOISE_DONE)
3373 iwl_power_update_mode(priv, false);
3374
3375 /* Enable Rx differential gain and sensitivity calibrations */
3376 iwl_chain_noise_reset(priv);
3377 priv->start_calib = 1;
3378
3379}
3380
3381/***************************************************************************** 3149/*****************************************************************************
3382 * 3150 *
3383 * mac80211 entry point functions 3151 * mac80211 entry point functions
@@ -3457,7 +3225,7 @@ static int iwl_mac_setup_register(struct iwl_priv *priv,
3457} 3225}
3458 3226
3459 3227
3460static int iwl_mac_start(struct ieee80211_hw *hw) 3228int iwlagn_mac_start(struct ieee80211_hw *hw)
3461{ 3229{
3462 struct iwl_priv *priv = hw->priv; 3230 struct iwl_priv *priv = hw->priv;
3463 int ret; 3231 int ret;
@@ -3498,7 +3266,7 @@ out:
3498 return 0; 3266 return 0;
3499} 3267}
3500 3268
3501static void iwl_mac_stop(struct ieee80211_hw *hw) 3269void iwlagn_mac_stop(struct ieee80211_hw *hw)
3502{ 3270{
3503 struct iwl_priv *priv = hw->priv; 3271 struct iwl_priv *priv = hw->priv;
3504 3272
@@ -3520,7 +3288,7 @@ static void iwl_mac_stop(struct ieee80211_hw *hw)
3520 IWL_DEBUG_MAC80211(priv, "leave\n"); 3288 IWL_DEBUG_MAC80211(priv, "leave\n");
3521} 3289}
3522 3290
3523static int iwl_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb) 3291int iwlagn_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
3524{ 3292{
3525 struct iwl_priv *priv = hw->priv; 3293 struct iwl_priv *priv = hw->priv;
3526 3294
@@ -3536,73 +3304,12 @@ static int iwl_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
3536 return NETDEV_TX_OK; 3304 return NETDEV_TX_OK;
3537} 3305}
3538 3306
3539void iwl_config_ap(struct iwl_priv *priv, struct ieee80211_vif *vif) 3307void iwlagn_mac_update_tkip_key(struct ieee80211_hw *hw,
3540{ 3308 struct ieee80211_vif *vif,
3541 struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif); 3309 struct ieee80211_key_conf *keyconf,
3542 int ret = 0; 3310 struct ieee80211_sta *sta,
3543 3311 u32 iv32, u16 *phase1key)
3544 lockdep_assert_held(&priv->mutex);
3545
3546 if (test_bit(STATUS_EXIT_PENDING, &priv->status))
3547 return;
3548
3549 /* The following should be done only at AP bring up */
3550 if (!iwl_is_associated_ctx(ctx)) {
3551
3552 /* RXON - unassoc (to set timing command) */
3553 ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
3554 iwlcore_commit_rxon(priv, ctx);
3555
3556 /* RXON Timing */
3557 ret = iwl_send_rxon_timing(priv, ctx);
3558 if (ret)
3559 IWL_WARN(priv, "RXON timing failed - "
3560 "Attempting to continue.\n");
3561
3562 /* AP has all antennas */
3563 priv->chain_noise_data.active_chains =
3564 priv->hw_params.valid_rx_ant;
3565 iwl_set_rxon_ht(priv, &priv->current_ht_config);
3566 if (priv->cfg->ops->hcmd->set_rxon_chain)
3567 priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx);
3568
3569 ctx->staging.assoc_id = 0;
3570
3571 if (vif->bss_conf.use_short_preamble)
3572 ctx->staging.flags |=
3573 RXON_FLG_SHORT_PREAMBLE_MSK;
3574 else
3575 ctx->staging.flags &=
3576 ~RXON_FLG_SHORT_PREAMBLE_MSK;
3577
3578 if (ctx->staging.flags & RXON_FLG_BAND_24G_MSK) {
3579 if (vif->bss_conf.use_short_slot)
3580 ctx->staging.flags |=
3581 RXON_FLG_SHORT_SLOT_MSK;
3582 else
3583 ctx->staging.flags &=
3584 ~RXON_FLG_SHORT_SLOT_MSK;
3585 }
3586 /* need to send beacon cmd before committing assoc RXON! */
3587 iwl_send_beacon_cmd(priv);
3588 /* restore RXON assoc */
3589 ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK;
3590 iwlcore_commit_rxon(priv, ctx);
3591 }
3592 iwl_send_beacon_cmd(priv);
3593
3594 /* FIXME - we need to add code here to detect a totally new
3595 * configuration, reset the AP, unassoc, rxon timing, assoc,
3596 * clear sta table, add BCAST sta... */
3597}
3598
3599static void iwl_mac_update_tkip_key(struct ieee80211_hw *hw,
3600 struct ieee80211_vif *vif,
3601 struct ieee80211_key_conf *keyconf,
3602 struct ieee80211_sta *sta,
3603 u32 iv32, u16 *phase1key)
3604{ 3312{
3605
3606 struct iwl_priv *priv = hw->priv; 3313 struct iwl_priv *priv = hw->priv;
3607 struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv; 3314 struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv;
3608 3315
@@ -3614,10 +3321,9 @@ static void iwl_mac_update_tkip_key(struct ieee80211_hw *hw,
3614 IWL_DEBUG_MAC80211(priv, "leave\n"); 3321 IWL_DEBUG_MAC80211(priv, "leave\n");
3615} 3322}
3616 3323
3617static int iwl_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, 3324int iwlagn_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
3618 struct ieee80211_vif *vif, 3325 struct ieee80211_vif *vif, struct ieee80211_sta *sta,
3619 struct ieee80211_sta *sta, 3326 struct ieee80211_key_conf *key)
3620 struct ieee80211_key_conf *key)
3621{ 3327{
3622 struct iwl_priv *priv = hw->priv; 3328 struct iwl_priv *priv = hw->priv;
3623 struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv; 3329 struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv;
@@ -3684,10 +3390,10 @@ static int iwl_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
3684 return ret; 3390 return ret;
3685} 3391}
3686 3392
3687static int iwl_mac_ampdu_action(struct ieee80211_hw *hw, 3393int iwlagn_mac_ampdu_action(struct ieee80211_hw *hw,
3688 struct ieee80211_vif *vif, 3394 struct ieee80211_vif *vif,
3689 enum ieee80211_ampdu_mlme_action action, 3395 enum ieee80211_ampdu_mlme_action action,
3690 struct ieee80211_sta *sta, u16 tid, u16 *ssn) 3396 struct ieee80211_sta *sta, u16 tid, u16 *ssn)
3691{ 3397{
3692 struct iwl_priv *priv = hw->priv; 3398 struct iwl_priv *priv = hw->priv;
3693 int ret = -EINVAL; 3399 int ret = -EINVAL;
@@ -3768,10 +3474,10 @@ static int iwl_mac_ampdu_action(struct ieee80211_hw *hw,
3768 return ret; 3474 return ret;
3769} 3475}
3770 3476
3771static void iwl_mac_sta_notify(struct ieee80211_hw *hw, 3477static void iwlagn_mac_sta_notify(struct ieee80211_hw *hw,
3772 struct ieee80211_vif *vif, 3478 struct ieee80211_vif *vif,
3773 enum sta_notify_cmd cmd, 3479 enum sta_notify_cmd cmd,
3774 struct ieee80211_sta *sta) 3480 struct ieee80211_sta *sta)
3775{ 3481{
3776 struct iwl_priv *priv = hw->priv; 3482 struct iwl_priv *priv = hw->priv;
3777 struct iwl_station_priv *sta_priv = (void *)sta->drv_priv; 3483 struct iwl_station_priv *sta_priv = (void *)sta->drv_priv;
@@ -3798,9 +3504,9 @@ static void iwl_mac_sta_notify(struct ieee80211_hw *hw,
3798 } 3504 }
3799} 3505}
3800 3506
3801static int iwlagn_mac_sta_add(struct ieee80211_hw *hw, 3507int iwlagn_mac_sta_add(struct ieee80211_hw *hw,
3802 struct ieee80211_vif *vif, 3508 struct ieee80211_vif *vif,
3803 struct ieee80211_sta *sta) 3509 struct ieee80211_sta *sta)
3804{ 3510{
3805 struct iwl_priv *priv = hw->priv; 3511 struct iwl_priv *priv = hw->priv;
3806 struct iwl_station_priv *sta_priv = (void *)sta->drv_priv; 3512 struct iwl_station_priv *sta_priv = (void *)sta->drv_priv;
@@ -3841,8 +3547,8 @@ static int iwlagn_mac_sta_add(struct ieee80211_hw *hw,
3841 return 0; 3547 return 0;
3842} 3548}
3843 3549
3844static void iwl_mac_channel_switch(struct ieee80211_hw *hw, 3550void iwlagn_mac_channel_switch(struct ieee80211_hw *hw,
3845 struct ieee80211_channel_switch *ch_switch) 3551 struct ieee80211_channel_switch *ch_switch)
3846{ 3552{
3847 struct iwl_priv *priv = hw->priv; 3553 struct iwl_priv *priv = hw->priv;
3848 const struct iwl_channel_info *ch_info; 3554 const struct iwl_channel_info *ch_info;
@@ -3939,10 +3645,10 @@ out_exit:
3939 IWL_DEBUG_MAC80211(priv, "leave\n"); 3645 IWL_DEBUG_MAC80211(priv, "leave\n");
3940} 3646}
3941 3647
3942static void iwlagn_configure_filter(struct ieee80211_hw *hw, 3648void iwlagn_configure_filter(struct ieee80211_hw *hw,
3943 unsigned int changed_flags, 3649 unsigned int changed_flags,
3944 unsigned int *total_flags, 3650 unsigned int *total_flags,
3945 u64 multicast) 3651 u64 multicast)
3946{ 3652{
3947 struct iwl_priv *priv = hw->priv; 3653 struct iwl_priv *priv = hw->priv;
3948 __le32 filter_or = 0, filter_nand = 0; 3654 __le32 filter_or = 0, filter_nand = 0;
@@ -3988,7 +3694,7 @@ static void iwlagn_configure_filter(struct ieee80211_hw *hw,
3988 FIF_BCN_PRBRESP_PROMISC | FIF_CONTROL; 3694 FIF_BCN_PRBRESP_PROMISC | FIF_CONTROL;
3989} 3695}
3990 3696
3991static void iwl_mac_flush(struct ieee80211_hw *hw, bool drop) 3697void iwlagn_mac_flush(struct ieee80211_hw *hw, bool drop)
3992{ 3698{
3993 struct iwl_priv *priv = hw->priv; 3699 struct iwl_priv *priv = hw->priv;
3994 3700
@@ -4198,25 +3904,24 @@ static void iwl_uninit_drv(struct iwl_priv *priv)
4198} 3904}
4199 3905
4200struct ieee80211_ops iwlagn_hw_ops = { 3906struct ieee80211_ops iwlagn_hw_ops = {
4201 .tx = iwl_mac_tx, 3907 .tx = iwlagn_mac_tx,
4202 .start = iwl_mac_start, 3908 .start = iwlagn_mac_start,
4203 .stop = iwl_mac_stop, 3909 .stop = iwlagn_mac_stop,
4204 .add_interface = iwl_mac_add_interface, 3910 .add_interface = iwl_mac_add_interface,
4205 .remove_interface = iwl_mac_remove_interface, 3911 .remove_interface = iwl_mac_remove_interface,
4206 .config = iwl_mac_config, 3912 .config = iwlagn_mac_config,
4207 .configure_filter = iwlagn_configure_filter, 3913 .configure_filter = iwlagn_configure_filter,
4208 .set_key = iwl_mac_set_key, 3914 .set_key = iwlagn_mac_set_key,
4209 .update_tkip_key = iwl_mac_update_tkip_key, 3915 .update_tkip_key = iwlagn_mac_update_tkip_key,
4210 .conf_tx = iwl_mac_conf_tx, 3916 .conf_tx = iwl_mac_conf_tx,
4211 .reset_tsf = iwl_mac_reset_tsf, 3917 .bss_info_changed = iwlagn_bss_info_changed,
4212 .bss_info_changed = iwl_bss_info_changed, 3918 .ampdu_action = iwlagn_mac_ampdu_action,
4213 .ampdu_action = iwl_mac_ampdu_action,
4214 .hw_scan = iwl_mac_hw_scan, 3919 .hw_scan = iwl_mac_hw_scan,
4215 .sta_notify = iwl_mac_sta_notify, 3920 .sta_notify = iwlagn_mac_sta_notify,
4216 .sta_add = iwlagn_mac_sta_add, 3921 .sta_add = iwlagn_mac_sta_add,
4217 .sta_remove = iwl_mac_sta_remove, 3922 .sta_remove = iwl_mac_sta_remove,
4218 .channel_switch = iwl_mac_channel_switch, 3923 .channel_switch = iwlagn_mac_channel_switch,
4219 .flush = iwl_mac_flush, 3924 .flush = iwlagn_mac_flush,
4220 .tx_last_beacon = iwl_mac_tx_last_beacon, 3925 .tx_last_beacon = iwl_mac_tx_last_beacon,
4221}; 3926};
4222 3927
@@ -4287,6 +3992,9 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
4287 dev_printk(KERN_DEBUG, &(pdev->dev), 3992 dev_printk(KERN_DEBUG, &(pdev->dev),
4288 "sw scan support is deprecated\n"); 3993 "sw scan support is deprecated\n");
4289 iwlagn_hw_ops.hw_scan = NULL; 3994 iwlagn_hw_ops.hw_scan = NULL;
3995#ifdef CONFIG_IWL4965
3996 iwl4965_hw_ops.hw_scan = NULL;
3997#endif
4290 } 3998 }
4291 3999
4292 hw = iwl_alloc_all(cfg); 4000 hw = iwl_alloc_all(cfg);
@@ -4321,6 +4029,7 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
4321 BIT(NL80211_IFTYPE_ADHOC); 4029 BIT(NL80211_IFTYPE_ADHOC);
4322 priv->contexts[IWL_RXON_CTX_BSS].interface_modes = 4030 priv->contexts[IWL_RXON_CTX_BSS].interface_modes =
4323 BIT(NL80211_IFTYPE_STATION); 4031 BIT(NL80211_IFTYPE_STATION);
4032 priv->contexts[IWL_RXON_CTX_BSS].ap_devtype = RXON_DEV_TYPE_AP;
4324 priv->contexts[IWL_RXON_CTX_BSS].ibss_devtype = RXON_DEV_TYPE_IBSS; 4033 priv->contexts[IWL_RXON_CTX_BSS].ibss_devtype = RXON_DEV_TYPE_IBSS;
4325 priv->contexts[IWL_RXON_CTX_BSS].station_devtype = RXON_DEV_TYPE_ESS; 4034 priv->contexts[IWL_RXON_CTX_BSS].station_devtype = RXON_DEV_TYPE_ESS;
4326 priv->contexts[IWL_RXON_CTX_BSS].unused_devtype = RXON_DEV_TYPE_ESS; 4035 priv->contexts[IWL_RXON_CTX_BSS].unused_devtype = RXON_DEV_TYPE_ESS;
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h
index ba88e78e6116..aca93f4477a8 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.h
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.h
@@ -103,6 +103,7 @@ extern struct iwl_hcmd_ops iwlagn_bt_hcmd;
103extern struct iwl_hcmd_utils_ops iwlagn_hcmd_utils; 103extern struct iwl_hcmd_utils_ops iwlagn_hcmd_utils;
104 104
105extern struct ieee80211_ops iwlagn_hw_ops; 105extern struct ieee80211_ops iwlagn_hw_ops;
106extern struct ieee80211_ops iwl4965_hw_ops;
106 107
107int iwl_reset_ict(struct iwl_priv *priv); 108int iwl_reset_ict(struct iwl_priv *priv);
108void iwl_disable_ict(struct iwl_priv *priv); 109void iwl_disable_ict(struct iwl_priv *priv);
@@ -134,6 +135,11 @@ void iwl_free_tfds_in_queue(struct iwl_priv *priv,
134/* RXON */ 135/* RXON */
135int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx); 136int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx);
136void iwlagn_set_rxon_chain(struct iwl_priv *priv, struct iwl_rxon_context *ctx); 137void iwlagn_set_rxon_chain(struct iwl_priv *priv, struct iwl_rxon_context *ctx);
138int iwlagn_mac_config(struct ieee80211_hw *hw, u32 changed);
139void iwlagn_bss_info_changed(struct ieee80211_hw *hw,
140 struct ieee80211_vif *vif,
141 struct ieee80211_bss_conf *bss_conf,
142 u32 changes);
137 143
138/* uCode */ 144/* uCode */
139int iwlagn_load_ucode(struct iwl_priv *priv); 145int iwlagn_load_ucode(struct iwl_priv *priv);
@@ -251,6 +257,7 @@ int iwlagn_manage_ibss_station(struct iwl_priv *priv,
251int iwlagn_send_rxon_assoc(struct iwl_priv *priv, 257int iwlagn_send_rxon_assoc(struct iwl_priv *priv,
252 struct iwl_rxon_context *ctx); 258 struct iwl_rxon_context *ctx);
253int iwlagn_send_tx_ant_config(struct iwl_priv *priv, u8 valid_tx_ant); 259int iwlagn_send_tx_ant_config(struct iwl_priv *priv, u8 valid_tx_ant);
260int iwlagn_send_beacon_cmd(struct iwl_priv *priv);
254 261
255/* bt coex */ 262/* bt coex */
256void iwlagn_send_advance_bt_config(struct iwl_priv *priv); 263void iwlagn_send_advance_bt_config(struct iwl_priv *priv);
@@ -320,4 +327,31 @@ void iwl_eeprom_get_mac(const struct iwl_priv *priv, u8 *mac);
320int iwlcore_eeprom_acquire_semaphore(struct iwl_priv *priv); 327int iwlcore_eeprom_acquire_semaphore(struct iwl_priv *priv);
321void iwlcore_eeprom_release_semaphore(struct iwl_priv *priv); 328void iwlcore_eeprom_release_semaphore(struct iwl_priv *priv);
322 329
330/* mac80211 handlers (for 4965) */
331int iwlagn_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb);
332int iwlagn_mac_start(struct ieee80211_hw *hw);
333void iwlagn_mac_stop(struct ieee80211_hw *hw);
334void iwlagn_configure_filter(struct ieee80211_hw *hw,
335 unsigned int changed_flags,
336 unsigned int *total_flags,
337 u64 multicast);
338int iwlagn_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
339 struct ieee80211_vif *vif, struct ieee80211_sta *sta,
340 struct ieee80211_key_conf *key);
341void iwlagn_mac_update_tkip_key(struct ieee80211_hw *hw,
342 struct ieee80211_vif *vif,
343 struct ieee80211_key_conf *keyconf,
344 struct ieee80211_sta *sta,
345 u32 iv32, u16 *phase1key);
346int iwlagn_mac_ampdu_action(struct ieee80211_hw *hw,
347 struct ieee80211_vif *vif,
348 enum ieee80211_ampdu_mlme_action action,
349 struct ieee80211_sta *sta, u16 tid, u16 *ssn);
350int iwlagn_mac_sta_add(struct ieee80211_hw *hw,
351 struct ieee80211_vif *vif,
352 struct ieee80211_sta *sta);
353void iwlagn_mac_channel_switch(struct ieee80211_hw *hw,
354 struct ieee80211_channel_switch *ch_switch);
355void iwlagn_mac_flush(struct ieee80211_hw *hw, bool drop);
356
323#endif /* __iwl_agn_h__ */ 357#endif /* __iwl_agn_h__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c
index c93368083e1a..776713c6a7ff 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.c
+++ b/drivers/net/wireless/iwlwifi/iwl-core.c
@@ -100,35 +100,6 @@ out:
100} 100}
101EXPORT_SYMBOL(iwl_alloc_all); 101EXPORT_SYMBOL(iwl_alloc_all);
102 102
103/*
104 * QoS support
105*/
106static void iwl_update_qos(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
107{
108 if (test_bit(STATUS_EXIT_PENDING, &priv->status))
109 return;
110
111 if (!ctx->is_active)
112 return;
113
114 ctx->qos_data.def_qos_parm.qos_flags = 0;
115
116 if (ctx->qos_data.qos_active)
117 ctx->qos_data.def_qos_parm.qos_flags |=
118 QOS_PARAM_FLG_UPDATE_EDCA_MSK;
119
120 if (ctx->ht.enabled)
121 ctx->qos_data.def_qos_parm.qos_flags |= QOS_PARAM_FLG_TGN_MSK;
122
123 IWL_DEBUG_QOS(priv, "send QoS cmd with Qos active=%d FLAGS=0x%X\n",
124 ctx->qos_data.qos_active,
125 ctx->qos_data.def_qos_parm.qos_flags);
126
127 iwl_send_cmd_pdu_async(priv, ctx->qos_cmd,
128 sizeof(struct iwl_qosparam_cmd),
129 &ctx->qos_data.def_qos_parm, NULL);
130}
131
132#define MAX_BIT_RATE_40_MHZ 150 /* Mbps */ 103#define MAX_BIT_RATE_40_MHZ 150 /* Mbps */
133#define MAX_BIT_RATE_20_MHZ 72 /* Mbps */ 104#define MAX_BIT_RATE_20_MHZ 72 /* Mbps */
134static void iwlcore_init_ht_hw_capab(const struct iwl_priv *priv, 105static void iwlcore_init_ht_hw_capab(const struct iwl_priv *priv,
@@ -1456,310 +1427,6 @@ int iwl_mac_tx_last_beacon(struct ieee80211_hw *hw)
1456} 1427}
1457EXPORT_SYMBOL_GPL(iwl_mac_tx_last_beacon); 1428EXPORT_SYMBOL_GPL(iwl_mac_tx_last_beacon);
1458 1429
1459static void iwl_ht_conf(struct iwl_priv *priv,
1460 struct ieee80211_vif *vif)
1461{
1462 struct iwl_ht_config *ht_conf = &priv->current_ht_config;
1463 struct ieee80211_sta *sta;
1464 struct ieee80211_bss_conf *bss_conf = &vif->bss_conf;
1465 struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif);
1466
1467 IWL_DEBUG_MAC80211(priv, "enter:\n");
1468
1469 if (!ctx->ht.enabled)
1470 return;
1471
1472 ctx->ht.protection =
1473 bss_conf->ht_operation_mode & IEEE80211_HT_OP_MODE_PROTECTION;
1474 ctx->ht.non_gf_sta_present =
1475 !!(bss_conf->ht_operation_mode & IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT);
1476
1477 ht_conf->single_chain_sufficient = false;
1478
1479 switch (vif->type) {
1480 case NL80211_IFTYPE_STATION:
1481 rcu_read_lock();
1482 sta = ieee80211_find_sta(vif, bss_conf->bssid);
1483 if (sta) {
1484 struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap;
1485 int maxstreams;
1486
1487 maxstreams = (ht_cap->mcs.tx_params &
1488 IEEE80211_HT_MCS_TX_MAX_STREAMS_MASK)
1489 >> IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT;
1490 maxstreams += 1;
1491
1492 if ((ht_cap->mcs.rx_mask[1] == 0) &&
1493 (ht_cap->mcs.rx_mask[2] == 0))
1494 ht_conf->single_chain_sufficient = true;
1495 if (maxstreams <= 1)
1496 ht_conf->single_chain_sufficient = true;
1497 } else {
1498 /*
1499 * If at all, this can only happen through a race
1500 * when the AP disconnects us while we're still
1501 * setting up the connection, in that case mac80211
1502 * will soon tell us about that.
1503 */
1504 ht_conf->single_chain_sufficient = true;
1505 }
1506 rcu_read_unlock();
1507 break;
1508 case NL80211_IFTYPE_ADHOC:
1509 ht_conf->single_chain_sufficient = true;
1510 break;
1511 default:
1512 break;
1513 }
1514
1515 IWL_DEBUG_MAC80211(priv, "leave\n");
1516}
1517
1518static inline void iwl_set_no_assoc(struct iwl_priv *priv,
1519 struct ieee80211_vif *vif)
1520{
1521 struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif);
1522
1523 iwl_led_disassociate(priv);
1524 /*
1525 * inform the ucode that there is no longer an
1526 * association and that no more packets should be
1527 * sent
1528 */
1529 ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
1530 ctx->staging.assoc_id = 0;
1531 iwlcore_commit_rxon(priv, ctx);
1532}
1533
1534static void iwlcore_beacon_update(struct ieee80211_hw *hw,
1535 struct ieee80211_vif *vif)
1536{
1537 struct iwl_priv *priv = hw->priv;
1538 unsigned long flags;
1539 __le64 timestamp;
1540 struct sk_buff *skb = ieee80211_beacon_get(hw, vif);
1541
1542 if (!skb)
1543 return;
1544
1545 IWL_DEBUG_ASSOC(priv, "enter\n");
1546
1547 lockdep_assert_held(&priv->mutex);
1548
1549 if (!priv->beacon_ctx) {
1550 IWL_ERR(priv, "update beacon but no beacon context!\n");
1551 dev_kfree_skb(skb);
1552 return;
1553 }
1554
1555 spin_lock_irqsave(&priv->lock, flags);
1556
1557 if (priv->beacon_skb)
1558 dev_kfree_skb(priv->beacon_skb);
1559
1560 priv->beacon_skb = skb;
1561
1562 timestamp = ((struct ieee80211_mgmt *)skb->data)->u.beacon.timestamp;
1563 priv->timestamp = le64_to_cpu(timestamp);
1564
1565 IWL_DEBUG_ASSOC(priv, "leave\n");
1566
1567 spin_unlock_irqrestore(&priv->lock, flags);
1568
1569 if (!iwl_is_ready_rf(priv)) {
1570 IWL_DEBUG_MAC80211(priv, "leave - RF not ready\n");
1571 return;
1572 }
1573
1574 priv->cfg->ops->lib->post_associate(priv, priv->beacon_ctx->vif);
1575}
1576
1577void iwl_bss_info_changed(struct ieee80211_hw *hw,
1578 struct ieee80211_vif *vif,
1579 struct ieee80211_bss_conf *bss_conf,
1580 u32 changes)
1581{
1582 struct iwl_priv *priv = hw->priv;
1583 struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif);
1584 int ret;
1585
1586 IWL_DEBUG_MAC80211(priv, "changes = 0x%X\n", changes);
1587
1588 if (!iwl_is_alive(priv))
1589 return;
1590
1591 mutex_lock(&priv->mutex);
1592
1593 if (changes & (BSS_CHANGED_BSSID | BSS_CHANGED_ASSOC |
1594 BSS_CHANGED_BEACON_ENABLED)) {
1595 /*
1596 * If there is currently a HW scan going on in the
1597 * background then we need to cancel it else the RXON
1598 * below in post_associate or set_no_assoc can fail.
1599 */
1600 if (iwl_scan_cancel_timeout(priv, 200)) {
1601 IWL_WARN(priv, "Can not cancel scan\n");
1602 goto out;
1603 }
1604 }
1605
1606 if (changes & BSS_CHANGED_QOS) {
1607 unsigned long flags;
1608
1609 spin_lock_irqsave(&priv->lock, flags);
1610 ctx->qos_data.qos_active = bss_conf->qos;
1611 iwl_update_qos(priv, ctx);
1612 spin_unlock_irqrestore(&priv->lock, flags);
1613 }
1614
1615 if (changes & BSS_CHANGED_BEACON_ENABLED) {
1616 /*
1617 * the add_interface code must make sure we only ever
1618 * have a single interface that could be beaconing at
1619 * any time.
1620 */
1621 if (vif->bss_conf.enable_beacon)
1622 priv->beacon_ctx = ctx;
1623 else
1624 priv->beacon_ctx = NULL;
1625 }
1626
1627 if (changes & BSS_CHANGED_BEACON && vif->type == NL80211_IFTYPE_AP) {
1628 dev_kfree_skb(priv->beacon_skb);
1629 priv->beacon_skb = ieee80211_beacon_get(hw, vif);
1630 }
1631
1632 if (changes & BSS_CHANGED_BEACON_INT && vif->type == NL80211_IFTYPE_AP)
1633 iwl_send_rxon_timing(priv, ctx);
1634
1635 if (changes & BSS_CHANGED_BSSID) {
1636 IWL_DEBUG_MAC80211(priv, "BSSID %pM\n", bss_conf->bssid);
1637
1638 /* mac80211 only sets assoc when in STATION mode */
1639 if (vif->type == NL80211_IFTYPE_ADHOC || bss_conf->assoc) {
1640 memcpy(ctx->staging.bssid_addr,
1641 bss_conf->bssid, ETH_ALEN);
1642
1643 /* currently needed in a few places */
1644 memcpy(priv->bssid, bss_conf->bssid, ETH_ALEN);
1645 } else {
1646 ctx->staging.filter_flags &=
1647 ~RXON_FILTER_ASSOC_MSK;
1648 }
1649
1650 }
1651
1652 /*
1653 * This needs to be after setting the BSSID in case
1654 * mac80211 decides to do both changes at once because
1655 * it will invoke post_associate.
1656 */
1657 if (vif->type == NL80211_IFTYPE_ADHOC && changes & BSS_CHANGED_BEACON)
1658 iwlcore_beacon_update(hw, vif);
1659
1660 if (changes & BSS_CHANGED_ERP_PREAMBLE) {
1661 IWL_DEBUG_MAC80211(priv, "ERP_PREAMBLE %d\n",
1662 bss_conf->use_short_preamble);
1663 if (bss_conf->use_short_preamble)
1664 ctx->staging.flags |= RXON_FLG_SHORT_PREAMBLE_MSK;
1665 else
1666 ctx->staging.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK;
1667 }
1668
1669 if (changes & BSS_CHANGED_ERP_CTS_PROT) {
1670 IWL_DEBUG_MAC80211(priv, "ERP_CTS %d\n", bss_conf->use_cts_prot);
1671 if (bss_conf->use_cts_prot && (priv->band != IEEE80211_BAND_5GHZ))
1672 ctx->staging.flags |= RXON_FLG_TGG_PROTECT_MSK;
1673 else
1674 ctx->staging.flags &= ~RXON_FLG_TGG_PROTECT_MSK;
1675 if (bss_conf->use_cts_prot)
1676 ctx->staging.flags |= RXON_FLG_SELF_CTS_EN;
1677 else
1678 ctx->staging.flags &= ~RXON_FLG_SELF_CTS_EN;
1679 }
1680
1681 if (changes & BSS_CHANGED_BASIC_RATES) {
1682 /* XXX use this information
1683 *
1684 * To do that, remove code from iwl_set_rate() and put something
1685 * like this here:
1686 *
1687 if (A-band)
1688 ctx->staging.ofdm_basic_rates =
1689 bss_conf->basic_rates;
1690 else
1691 ctx->staging.ofdm_basic_rates =
1692 bss_conf->basic_rates >> 4;
1693 ctx->staging.cck_basic_rates =
1694 bss_conf->basic_rates & 0xF;
1695 */
1696 }
1697
1698 if (changes & BSS_CHANGED_HT) {
1699 iwl_ht_conf(priv, vif);
1700
1701 if (priv->cfg->ops->hcmd->set_rxon_chain)
1702 priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx);
1703 }
1704
1705 if (changes & BSS_CHANGED_ASSOC) {
1706 IWL_DEBUG_MAC80211(priv, "ASSOC %d\n", bss_conf->assoc);
1707 if (bss_conf->assoc) {
1708 priv->timestamp = bss_conf->timestamp;
1709
1710 iwl_led_associate(priv);
1711
1712 if (!iwl_is_rfkill(priv))
1713 priv->cfg->ops->lib->post_associate(priv, vif);
1714 } else
1715 iwl_set_no_assoc(priv, vif);
1716 }
1717
1718 if (changes && iwl_is_associated_ctx(ctx) && bss_conf->aid) {
1719 IWL_DEBUG_MAC80211(priv, "Changes (%#x) while associated\n",
1720 changes);
1721 ret = iwl_send_rxon_assoc(priv, ctx);
1722 if (!ret) {
1723 /* Sync active_rxon with latest change. */
1724 memcpy((void *)&ctx->active,
1725 &ctx->staging,
1726 sizeof(struct iwl_rxon_cmd));
1727 }
1728 }
1729
1730 if (changes & BSS_CHANGED_BEACON_ENABLED) {
1731 if (vif->bss_conf.enable_beacon) {
1732 memcpy(ctx->staging.bssid_addr,
1733 bss_conf->bssid, ETH_ALEN);
1734 memcpy(priv->bssid, bss_conf->bssid, ETH_ALEN);
1735 iwl_led_associate(priv);
1736 iwlcore_config_ap(priv, vif);
1737 } else
1738 iwl_set_no_assoc(priv, vif);
1739 }
1740
1741 if (changes & BSS_CHANGED_IBSS) {
1742 ret = priv->cfg->ops->lib->manage_ibss_station(priv, vif,
1743 bss_conf->ibss_joined);
1744 if (ret)
1745 IWL_ERR(priv, "failed to %s IBSS station %pM\n",
1746 bss_conf->ibss_joined ? "add" : "remove",
1747 bss_conf->bssid);
1748 }
1749
1750 if (changes & BSS_CHANGED_IDLE &&
1751 priv->cfg->ops->hcmd->set_pan_params) {
1752 if (priv->cfg->ops->hcmd->set_pan_params(priv))
1753 IWL_ERR(priv, "failed to update PAN params\n");
1754 }
1755
1756out:
1757 mutex_unlock(&priv->mutex);
1758
1759 IWL_DEBUG_MAC80211(priv, "leave\n");
1760}
1761EXPORT_SYMBOL(iwl_bss_info_changed);
1762
1763static int iwl_set_mode(struct iwl_priv *priv, struct ieee80211_vif *vif) 1430static int iwl_set_mode(struct iwl_priv *priv, struct ieee80211_vif *vif)
1764{ 1431{
1765 struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif); 1432 struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif);
@@ -1899,204 +1566,6 @@ void iwl_mac_remove_interface(struct ieee80211_hw *hw,
1899} 1566}
1900EXPORT_SYMBOL(iwl_mac_remove_interface); 1567EXPORT_SYMBOL(iwl_mac_remove_interface);
1901 1568
1902/**
1903 * iwl_mac_config - mac80211 config callback
1904 */
1905int iwl_mac_config(struct ieee80211_hw *hw, u32 changed)
1906{
1907 struct iwl_priv *priv = hw->priv;
1908 const struct iwl_channel_info *ch_info;
1909 struct ieee80211_conf *conf = &hw->conf;
1910 struct ieee80211_channel *channel = conf->channel;
1911 struct iwl_ht_config *ht_conf = &priv->current_ht_config;
1912 struct iwl_rxon_context *ctx;
1913 unsigned long flags = 0;
1914 int ret = 0;
1915 u16 ch;
1916 int scan_active = 0;
1917
1918 mutex_lock(&priv->mutex);
1919
1920 IWL_DEBUG_MAC80211(priv, "enter to channel %d changed 0x%X\n",
1921 channel->hw_value, changed);
1922
1923 if (unlikely(!priv->cfg->mod_params->disable_hw_scan &&
1924 test_bit(STATUS_SCANNING, &priv->status))) {
1925 scan_active = 1;
1926 IWL_DEBUG_MAC80211(priv, "leave - scanning\n");
1927 }
1928
1929 if (changed & (IEEE80211_CONF_CHANGE_SMPS |
1930 IEEE80211_CONF_CHANGE_CHANNEL)) {
1931 /* mac80211 uses static for non-HT which is what we want */
1932 priv->current_ht_config.smps = conf->smps_mode;
1933
1934 /*
1935 * Recalculate chain counts.
1936 *
1937 * If monitor mode is enabled then mac80211 will
1938 * set up the SM PS mode to OFF if an HT channel is
1939 * configured.
1940 */
1941 if (priv->cfg->ops->hcmd->set_rxon_chain)
1942 for_each_context(priv, ctx)
1943 priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx);
1944 }
1945
1946 /* during scanning mac80211 will delay channel setting until
1947 * scan finish with changed = 0
1948 */
1949 if (!changed || (changed & IEEE80211_CONF_CHANGE_CHANNEL)) {
1950 if (scan_active)
1951 goto set_ch_out;
1952
1953 ch = channel->hw_value;
1954 ch_info = iwl_get_channel_info(priv, channel->band, ch);
1955 if (!is_channel_valid(ch_info)) {
1956 IWL_DEBUG_MAC80211(priv, "leave - invalid channel\n");
1957 ret = -EINVAL;
1958 goto set_ch_out;
1959 }
1960
1961 spin_lock_irqsave(&priv->lock, flags);
1962
1963 for_each_context(priv, ctx) {
1964 /* Configure HT40 channels */
1965 ctx->ht.enabled = conf_is_ht(conf);
1966 if (ctx->ht.enabled) {
1967 if (conf_is_ht40_minus(conf)) {
1968 ctx->ht.extension_chan_offset =
1969 IEEE80211_HT_PARAM_CHA_SEC_BELOW;
1970 ctx->ht.is_40mhz = true;
1971 } else if (conf_is_ht40_plus(conf)) {
1972 ctx->ht.extension_chan_offset =
1973 IEEE80211_HT_PARAM_CHA_SEC_ABOVE;
1974 ctx->ht.is_40mhz = true;
1975 } else {
1976 ctx->ht.extension_chan_offset =
1977 IEEE80211_HT_PARAM_CHA_SEC_NONE;
1978 ctx->ht.is_40mhz = false;
1979 }
1980 } else
1981 ctx->ht.is_40mhz = false;
1982
1983 /*
1984 * Default to no protection. Protection mode will
1985 * later be set from BSS config in iwl_ht_conf
1986 */
1987 ctx->ht.protection = IEEE80211_HT_OP_MODE_PROTECTION_NONE;
1988
1989 /* if we are switching from ht to 2.4 clear flags
1990 * from any ht related info since 2.4 does not
1991 * support ht */
1992 if ((le16_to_cpu(ctx->staging.channel) != ch))
1993 ctx->staging.flags = 0;
1994
1995 iwl_set_rxon_channel(priv, channel, ctx);
1996 iwl_set_rxon_ht(priv, ht_conf);
1997
1998 iwl_set_flags_for_band(priv, ctx, channel->band,
1999 ctx->vif);
2000 }
2001
2002 spin_unlock_irqrestore(&priv->lock, flags);
2003
2004 if (priv->cfg->ops->lib->update_bcast_stations)
2005 ret = priv->cfg->ops->lib->update_bcast_stations(priv);
2006
2007 set_ch_out:
2008 /* The list of supported rates and rate mask can be different
2009 * for each band; since the band may have changed, reset
2010 * the rate mask to what mac80211 lists */
2011 iwl_set_rate(priv);
2012 }
2013
2014 if (changed & (IEEE80211_CONF_CHANGE_PS |
2015 IEEE80211_CONF_CHANGE_IDLE)) {
2016 ret = iwl_power_update_mode(priv, false);
2017 if (ret)
2018 IWL_DEBUG_MAC80211(priv, "Error setting sleep level\n");
2019 }
2020
2021 if (changed & IEEE80211_CONF_CHANGE_POWER) {
2022 IWL_DEBUG_MAC80211(priv, "TX Power old=%d new=%d\n",
2023 priv->tx_power_user_lmt, conf->power_level);
2024
2025 ret = iwl_set_tx_power(priv, conf->power_level, false);
2026 if (ret)
2027 IWL_ERR(priv, "Error sending TX power (%d)\n", ret);
2028 }
2029
2030 if (!iwl_is_ready(priv)) {
2031 IWL_DEBUG_MAC80211(priv, "leave - not ready\n");
2032 goto out;
2033 }
2034
2035 if (scan_active)
2036 goto out;
2037
2038 for_each_context(priv, ctx) {
2039 if (memcmp(&ctx->active, &ctx->staging, sizeof(ctx->staging)))
2040 iwlcore_commit_rxon(priv, ctx);
2041 else
2042 IWL_DEBUG_INFO(priv,
2043 "Not re-sending same RXON configuration.\n");
2044 }
2045
2046out:
2047 IWL_DEBUG_MAC80211(priv, "leave\n");
2048 mutex_unlock(&priv->mutex);
2049 return ret;
2050}
2051EXPORT_SYMBOL(iwl_mac_config);
2052
2053void iwl_mac_reset_tsf(struct ieee80211_hw *hw)
2054{
2055 struct iwl_priv *priv = hw->priv;
2056 unsigned long flags;
2057 /* IBSS can only be the IWL_RXON_CTX_BSS context */
2058 struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
2059
2060 mutex_lock(&priv->mutex);
2061 IWL_DEBUG_MAC80211(priv, "enter\n");
2062
2063 spin_lock_irqsave(&priv->lock, flags);
2064 memset(&priv->current_ht_config, 0, sizeof(struct iwl_ht_config));
2065 spin_unlock_irqrestore(&priv->lock, flags);
2066
2067 spin_lock_irqsave(&priv->lock, flags);
2068
2069 /* new association get rid of ibss beacon skb */
2070 if (priv->beacon_skb)
2071 dev_kfree_skb(priv->beacon_skb);
2072
2073 priv->beacon_skb = NULL;
2074
2075 priv->timestamp = 0;
2076
2077 spin_unlock_irqrestore(&priv->lock, flags);
2078
2079 iwl_scan_cancel_timeout(priv, 100);
2080 if (!iwl_is_ready_rf(priv)) {
2081 IWL_DEBUG_MAC80211(priv, "leave - not ready\n");
2082 mutex_unlock(&priv->mutex);
2083 return;
2084 }
2085
2086 /* we are restarting association process
2087 * clear RXON_FILTER_ASSOC_MSK bit
2088 */
2089 ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
2090 iwlcore_commit_rxon(priv, ctx);
2091
2092 iwl_set_rate(priv);
2093
2094 mutex_unlock(&priv->mutex);
2095
2096 IWL_DEBUG_MAC80211(priv, "leave\n");
2097}
2098EXPORT_SYMBOL(iwl_mac_reset_tsf);
2099
2100int iwl_alloc_txq_mem(struct iwl_priv *priv) 1569int iwl_alloc_txq_mem(struct iwl_priv *priv)
2101{ 1570{
2102 if (!priv->txq) 1571 if (!priv->txq)
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h
index 917d42eae55a..854613e4f2be 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.h
+++ b/drivers/net/wireless/iwlwifi/iwl-core.h
@@ -193,9 +193,6 @@ struct iwl_lib_ops {
193 /* power */ 193 /* power */
194 int (*send_tx_power) (struct iwl_priv *priv); 194 int (*send_tx_power) (struct iwl_priv *priv);
195 void (*update_chain_flags)(struct iwl_priv *priv); 195 void (*update_chain_flags)(struct iwl_priv *priv);
196 void (*post_associate)(struct iwl_priv *priv,
197 struct ieee80211_vif *vif);
198 void (*config_ap)(struct iwl_priv *priv, struct ieee80211_vif *vif);
199 irqreturn_t (*isr) (int irq, void *data); 196 irqreturn_t (*isr) (int irq, void *data);
200 197
201 /* eeprom operations (as defined in iwl-eeprom.h) */ 198 /* eeprom operations (as defined in iwl-eeprom.h) */
@@ -203,10 +200,6 @@ struct iwl_lib_ops {
203 200
204 /* temperature */ 201 /* temperature */
205 struct iwl_temp_ops temp_ops; 202 struct iwl_temp_ops temp_ops;
206 /* station management */
207 int (*manage_ibss_station)(struct iwl_priv *priv,
208 struct ieee80211_vif *vif, bool add);
209 int (*update_bcast_stations)(struct iwl_priv *priv);
210 /* recover from tx queue stall */ 203 /* recover from tx queue stall */
211 void (*recover_from_tx_stall)(unsigned long data); 204 void (*recover_from_tx_stall)(unsigned long data);
212 /* check for plcp health */ 205 /* check for plcp health */
@@ -235,12 +228,22 @@ struct iwl_nic_ops {
235 void (*additional_nic_config)(struct iwl_priv *priv); 228 void (*additional_nic_config)(struct iwl_priv *priv);
236}; 229};
237 230
231struct iwl_legacy_ops {
232 void (*post_associate)(struct iwl_priv *priv);
233 void (*config_ap)(struct iwl_priv *priv);
234 /* station management */
235 int (*update_bcast_stations)(struct iwl_priv *priv);
236 int (*manage_ibss_station)(struct iwl_priv *priv,
237 struct ieee80211_vif *vif, bool add);
238};
239
238struct iwl_ops { 240struct iwl_ops {
239 const struct iwl_lib_ops *lib; 241 const struct iwl_lib_ops *lib;
240 const struct iwl_hcmd_ops *hcmd; 242 const struct iwl_hcmd_ops *hcmd;
241 const struct iwl_hcmd_utils_ops *utils; 243 const struct iwl_hcmd_utils_ops *utils;
242 const struct iwl_led_ops *led; 244 const struct iwl_led_ops *led;
243 const struct iwl_nic_ops *nic; 245 const struct iwl_nic_ops *nic;
246 const struct iwl_legacy_ops *legacy;
244 const struct ieee80211_ops *ieee80211_ops; 247 const struct ieee80211_ops *ieee80211_ops;
245}; 248};
246 249
@@ -425,18 +428,10 @@ int iwl_set_decrypted_flag(struct iwl_priv *priv,
425 u32 decrypt_res, 428 u32 decrypt_res,
426 struct ieee80211_rx_status *stats); 429 struct ieee80211_rx_status *stats);
427void iwl_irq_handle_error(struct iwl_priv *priv); 430void iwl_irq_handle_error(struct iwl_priv *priv);
428void iwl_post_associate(struct iwl_priv *priv, struct ieee80211_vif *vif);
429void iwl_bss_info_changed(struct ieee80211_hw *hw,
430 struct ieee80211_vif *vif,
431 struct ieee80211_bss_conf *bss_conf,
432 u32 changes);
433int iwl_mac_add_interface(struct ieee80211_hw *hw, 431int iwl_mac_add_interface(struct ieee80211_hw *hw,
434 struct ieee80211_vif *vif); 432 struct ieee80211_vif *vif);
435void iwl_mac_remove_interface(struct ieee80211_hw *hw, 433void iwl_mac_remove_interface(struct ieee80211_hw *hw,
436 struct ieee80211_vif *vif); 434 struct ieee80211_vif *vif);
437int iwl_mac_config(struct ieee80211_hw *hw, u32 changed);
438void iwl_config_ap(struct iwl_priv *priv, struct ieee80211_vif *vif);
439void iwl_mac_reset_tsf(struct ieee80211_hw *hw);
440int iwl_alloc_txq_mem(struct iwl_priv *priv); 435int iwl_alloc_txq_mem(struct iwl_priv *priv);
441void iwl_free_txq_mem(struct iwl_priv *priv); 436void iwl_free_txq_mem(struct iwl_priv *priv);
442void iwlcore_tx_cmd_protection(struct iwl_priv *priv, 437void iwlcore_tx_cmd_protection(struct iwl_priv *priv,
@@ -732,11 +727,6 @@ static inline int iwlcore_commit_rxon(struct iwl_priv *priv,
732{ 727{
733 return priv->cfg->ops->hcmd->commit_rxon(priv, ctx); 728 return priv->cfg->ops->hcmd->commit_rxon(priv, ctx);
734} 729}
735static inline void iwlcore_config_ap(struct iwl_priv *priv,
736 struct ieee80211_vif *vif)
737{
738 priv->cfg->ops->lib->config_ap(priv, vif);
739}
740static inline const struct ieee80211_supported_band *iwl_get_hw_mode( 730static inline const struct ieee80211_supported_band *iwl_get_hw_mode(
741 struct iwl_priv *priv, enum ieee80211_band band) 731 struct iwl_priv *priv, enum ieee80211_band band)
742{ 732{
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h
index cd6daed99931..9fcaaf0cfe93 100644
--- a/drivers/net/wireless/iwlwifi/iwl-dev.h
+++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
@@ -1162,6 +1162,8 @@ struct iwl_rxon_context {
1162 */ 1162 */
1163 bool always_active, is_active; 1163 bool always_active, is_active;
1164 1164
1165 bool ht_need_multiple_chains;
1166
1165 enum iwl_rxon_context_id ctxid; 1167 enum iwl_rxon_context_id ctxid;
1166 1168
1167 u32 interface_modes, exclusive_interface_modes; 1169 u32 interface_modes, exclusive_interface_modes;
diff --git a/drivers/net/wireless/iwlwifi/iwl-led.c b/drivers/net/wireless/iwlwifi/iwl-led.c
index 86c2b6fed0c6..5a9129219c90 100644
--- a/drivers/net/wireless/iwlwifi/iwl-led.c
+++ b/drivers/net/wireless/iwlwifi/iwl-led.c
@@ -134,6 +134,7 @@ int iwl_led_associate(struct iwl_priv *priv)
134 134
135 return 0; 135 return 0;
136} 136}
137EXPORT_SYMBOL(iwl_led_associate);
137 138
138int iwl_led_disassociate(struct iwl_priv *priv) 139int iwl_led_disassociate(struct iwl_priv *priv)
139{ 140{
@@ -141,6 +142,7 @@ int iwl_led_disassociate(struct iwl_priv *priv)
141 142
142 return 0; 143 return 0;
143} 144}
145EXPORT_SYMBOL(iwl_led_disassociate);
144 146
145/* 147/*
146 * calculate blink rate according to last second Tx/Rx activities 148 * calculate blink rate according to last second Tx/Rx activities
diff --git a/drivers/net/wireless/iwlwifi/iwl-legacy.c b/drivers/net/wireless/iwlwifi/iwl-legacy.c
new file mode 100644
index 000000000000..b735fef9ee4b
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/iwl-legacy.c
@@ -0,0 +1,560 @@
1/******************************************************************************
2 *
3 * GPL LICENSE SUMMARY
4 *
5 * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of version 2 of the GNU General Public License as
9 * published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
19 * USA
20 *
21 * The full GNU General Public License is included in this distribution
22 * in the file called LICENSE.GPL.
23 *
24 * Contact Information:
25 * Intel Linux Wireless <ilw@linux.intel.com>
26 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
27 *****************************************************************************/
28
29#include <linux/kernel.h>
30#include <net/mac80211.h>
31
32#include "iwl-dev.h"
33#include "iwl-core.h"
34#include "iwl-legacy.h"
35
36/**
37 * iwl_legacy_mac_config - mac80211 config callback
38 */
39int iwl_legacy_mac_config(struct ieee80211_hw *hw, u32 changed)
40{
41 struct iwl_priv *priv = hw->priv;
42 const struct iwl_channel_info *ch_info;
43 struct ieee80211_conf *conf = &hw->conf;
44 struct ieee80211_channel *channel = conf->channel;
45 struct iwl_ht_config *ht_conf = &priv->current_ht_config;
46 struct iwl_rxon_context *ctx;
47 unsigned long flags = 0;
48 int ret = 0;
49 u16 ch;
50 int scan_active = 0;
51
52 if (WARN_ON(!priv->cfg->ops->legacy))
53 return -EOPNOTSUPP;
54
55 mutex_lock(&priv->mutex);
56
57 IWL_DEBUG_MAC80211(priv, "enter to channel %d changed 0x%X\n",
58 channel->hw_value, changed);
59
60 if (unlikely(!priv->cfg->mod_params->disable_hw_scan &&
61 test_bit(STATUS_SCANNING, &priv->status))) {
62 scan_active = 1;
63 IWL_DEBUG_MAC80211(priv, "leave - scanning\n");
64 }
65
66 if (changed & (IEEE80211_CONF_CHANGE_SMPS |
67 IEEE80211_CONF_CHANGE_CHANNEL)) {
68 /* mac80211 uses static for non-HT which is what we want */
69 priv->current_ht_config.smps = conf->smps_mode;
70
71 /*
72 * Recalculate chain counts.
73 *
74 * If monitor mode is enabled then mac80211 will
75 * set up the SM PS mode to OFF if an HT channel is
76 * configured.
77 */
78 if (priv->cfg->ops->hcmd->set_rxon_chain)
79 for_each_context(priv, ctx)
80 priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx);
81 }
82
83 /* during scanning mac80211 will delay channel setting until
84 * scan finish with changed = 0
85 */
86 if (!changed || (changed & IEEE80211_CONF_CHANGE_CHANNEL)) {
87 if (scan_active)
88 goto set_ch_out;
89
90 ch = channel->hw_value;
91 ch_info = iwl_get_channel_info(priv, channel->band, ch);
92 if (!is_channel_valid(ch_info)) {
93 IWL_DEBUG_MAC80211(priv, "leave - invalid channel\n");
94 ret = -EINVAL;
95 goto set_ch_out;
96 }
97
98 spin_lock_irqsave(&priv->lock, flags);
99
100 for_each_context(priv, ctx) {
101 /* Configure HT40 channels */
102 ctx->ht.enabled = conf_is_ht(conf);
103 if (ctx->ht.enabled) {
104 if (conf_is_ht40_minus(conf)) {
105 ctx->ht.extension_chan_offset =
106 IEEE80211_HT_PARAM_CHA_SEC_BELOW;
107 ctx->ht.is_40mhz = true;
108 } else if (conf_is_ht40_plus(conf)) {
109 ctx->ht.extension_chan_offset =
110 IEEE80211_HT_PARAM_CHA_SEC_ABOVE;
111 ctx->ht.is_40mhz = true;
112 } else {
113 ctx->ht.extension_chan_offset =
114 IEEE80211_HT_PARAM_CHA_SEC_NONE;
115 ctx->ht.is_40mhz = false;
116 }
117 } else
118 ctx->ht.is_40mhz = false;
119
120 /*
121 * Default to no protection. Protection mode will
122 * later be set from BSS config in iwl_ht_conf
123 */
124 ctx->ht.protection = IEEE80211_HT_OP_MODE_PROTECTION_NONE;
125
126 /* if we are switching from ht to 2.4 clear flags
127 * from any ht related info since 2.4 does not
128 * support ht */
129 if ((le16_to_cpu(ctx->staging.channel) != ch))
130 ctx->staging.flags = 0;
131
132 iwl_set_rxon_channel(priv, channel, ctx);
133 iwl_set_rxon_ht(priv, ht_conf);
134
135 iwl_set_flags_for_band(priv, ctx, channel->band,
136 ctx->vif);
137 }
138
139 spin_unlock_irqrestore(&priv->lock, flags);
140
141 if (priv->cfg->ops->legacy->update_bcast_stations)
142 ret = priv->cfg->ops->legacy->update_bcast_stations(priv);
143
144 set_ch_out:
145 /* The list of supported rates and rate mask can be different
146 * for each band; since the band may have changed, reset
147 * the rate mask to what mac80211 lists */
148 iwl_set_rate(priv);
149 }
150
151 if (changed & (IEEE80211_CONF_CHANGE_PS |
152 IEEE80211_CONF_CHANGE_IDLE)) {
153 ret = iwl_power_update_mode(priv, false);
154 if (ret)
155 IWL_DEBUG_MAC80211(priv, "Error setting sleep level\n");
156 }
157
158 if (changed & IEEE80211_CONF_CHANGE_POWER) {
159 IWL_DEBUG_MAC80211(priv, "TX Power old=%d new=%d\n",
160 priv->tx_power_user_lmt, conf->power_level);
161
162 iwl_set_tx_power(priv, conf->power_level, false);
163 }
164
165 if (!iwl_is_ready(priv)) {
166 IWL_DEBUG_MAC80211(priv, "leave - not ready\n");
167 goto out;
168 }
169
170 if (scan_active)
171 goto out;
172
173 for_each_context(priv, ctx) {
174 if (memcmp(&ctx->active, &ctx->staging, sizeof(ctx->staging)))
175 iwlcore_commit_rxon(priv, ctx);
176 else
177 IWL_DEBUG_INFO(priv,
178 "Not re-sending same RXON configuration.\n");
179 }
180
181out:
182 IWL_DEBUG_MAC80211(priv, "leave\n");
183 mutex_unlock(&priv->mutex);
184 return ret;
185}
186EXPORT_SYMBOL(iwl_legacy_mac_config);
187
188void iwl_legacy_mac_reset_tsf(struct ieee80211_hw *hw)
189{
190 struct iwl_priv *priv = hw->priv;
191 unsigned long flags;
192 /* IBSS can only be the IWL_RXON_CTX_BSS context */
193 struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
194
195 if (WARN_ON(!priv->cfg->ops->legacy))
196 return;
197
198 mutex_lock(&priv->mutex);
199 IWL_DEBUG_MAC80211(priv, "enter\n");
200
201 spin_lock_irqsave(&priv->lock, flags);
202 memset(&priv->current_ht_config, 0, sizeof(struct iwl_ht_config));
203 spin_unlock_irqrestore(&priv->lock, flags);
204
205 spin_lock_irqsave(&priv->lock, flags);
206
207 /* new association get rid of ibss beacon skb */
208 if (priv->beacon_skb)
209 dev_kfree_skb(priv->beacon_skb);
210
211 priv->beacon_skb = NULL;
212
213 priv->timestamp = 0;
214
215 spin_unlock_irqrestore(&priv->lock, flags);
216
217 iwl_scan_cancel_timeout(priv, 100);
218 if (!iwl_is_ready_rf(priv)) {
219 IWL_DEBUG_MAC80211(priv, "leave - not ready\n");
220 mutex_unlock(&priv->mutex);
221 return;
222 }
223
224 /* we are restarting association process
225 * clear RXON_FILTER_ASSOC_MSK bit
226 */
227 ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
228 iwlcore_commit_rxon(priv, ctx);
229
230 iwl_set_rate(priv);
231
232 mutex_unlock(&priv->mutex);
233
234 IWL_DEBUG_MAC80211(priv, "leave\n");
235}
236EXPORT_SYMBOL(iwl_legacy_mac_reset_tsf);
237
238static void iwl_ht_conf(struct iwl_priv *priv,
239 struct ieee80211_vif *vif)
240{
241 struct iwl_ht_config *ht_conf = &priv->current_ht_config;
242 struct ieee80211_sta *sta;
243 struct ieee80211_bss_conf *bss_conf = &vif->bss_conf;
244 struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif);
245
246 IWL_DEBUG_ASSOC(priv, "enter:\n");
247
248 if (!ctx->ht.enabled)
249 return;
250
251 ctx->ht.protection =
252 bss_conf->ht_operation_mode & IEEE80211_HT_OP_MODE_PROTECTION;
253 ctx->ht.non_gf_sta_present =
254 !!(bss_conf->ht_operation_mode & IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT);
255
256 ht_conf->single_chain_sufficient = false;
257
258 switch (vif->type) {
259 case NL80211_IFTYPE_STATION:
260 rcu_read_lock();
261 sta = ieee80211_find_sta(vif, bss_conf->bssid);
262 if (sta) {
263 struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap;
264 int maxstreams;
265
266 maxstreams = (ht_cap->mcs.tx_params &
267 IEEE80211_HT_MCS_TX_MAX_STREAMS_MASK)
268 >> IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT;
269 maxstreams += 1;
270
271 if ((ht_cap->mcs.rx_mask[1] == 0) &&
272 (ht_cap->mcs.rx_mask[2] == 0))
273 ht_conf->single_chain_sufficient = true;
274 if (maxstreams <= 1)
275 ht_conf->single_chain_sufficient = true;
276 } else {
277 /*
278 * If at all, this can only happen through a race
279 * when the AP disconnects us while we're still
280 * setting up the connection, in that case mac80211
281 * will soon tell us about that.
282 */
283 ht_conf->single_chain_sufficient = true;
284 }
285 rcu_read_unlock();
286 break;
287 case NL80211_IFTYPE_ADHOC:
288 ht_conf->single_chain_sufficient = true;
289 break;
290 default:
291 break;
292 }
293
294 IWL_DEBUG_ASSOC(priv, "leave\n");
295}
296
297static void iwl_update_qos(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
298{
299 if (test_bit(STATUS_EXIT_PENDING, &priv->status))
300 return;
301
302 if (!ctx->is_active)
303 return;
304
305 ctx->qos_data.def_qos_parm.qos_flags = 0;
306
307 if (ctx->qos_data.qos_active)
308 ctx->qos_data.def_qos_parm.qos_flags |=
309 QOS_PARAM_FLG_UPDATE_EDCA_MSK;
310
311 if (ctx->ht.enabled)
312 ctx->qos_data.def_qos_parm.qos_flags |= QOS_PARAM_FLG_TGN_MSK;
313
314 IWL_DEBUG_QOS(priv, "send QoS cmd with Qos active=%d FLAGS=0x%X\n",
315 ctx->qos_data.qos_active,
316 ctx->qos_data.def_qos_parm.qos_flags);
317
318 iwl_send_cmd_pdu_async(priv, ctx->qos_cmd,
319 sizeof(struct iwl_qosparam_cmd),
320 &ctx->qos_data.def_qos_parm, NULL);
321}
322
323static inline void iwl_set_no_assoc(struct iwl_priv *priv,
324 struct ieee80211_vif *vif)
325{
326 struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif);
327
328 iwl_led_disassociate(priv);
329 /*
330 * inform the ucode that there is no longer an
331 * association and that no more packets should be
332 * sent
333 */
334 ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
335 ctx->staging.assoc_id = 0;
336 iwlcore_commit_rxon(priv, ctx);
337}
338
339static void iwlcore_beacon_update(struct ieee80211_hw *hw,
340 struct ieee80211_vif *vif)
341{
342 struct iwl_priv *priv = hw->priv;
343 unsigned long flags;
344 __le64 timestamp;
345 struct sk_buff *skb = ieee80211_beacon_get(hw, vif);
346
347 if (!skb)
348 return;
349
350 IWL_DEBUG_MAC80211(priv, "enter\n");
351
352 lockdep_assert_held(&priv->mutex);
353
354 if (!priv->beacon_ctx) {
355 IWL_ERR(priv, "update beacon but no beacon context!\n");
356 dev_kfree_skb(skb);
357 return;
358 }
359
360 spin_lock_irqsave(&priv->lock, flags);
361
362 if (priv->beacon_skb)
363 dev_kfree_skb(priv->beacon_skb);
364
365 priv->beacon_skb = skb;
366
367 timestamp = ((struct ieee80211_mgmt *)skb->data)->u.beacon.timestamp;
368 priv->timestamp = le64_to_cpu(timestamp);
369
370 IWL_DEBUG_MAC80211(priv, "leave\n");
371 spin_unlock_irqrestore(&priv->lock, flags);
372
373 if (!iwl_is_ready_rf(priv)) {
374 IWL_DEBUG_MAC80211(priv, "leave - RF not ready\n");
375 return;
376 }
377
378 priv->cfg->ops->legacy->post_associate(priv);
379}
380
381void iwl_legacy_mac_bss_info_changed(struct ieee80211_hw *hw,
382 struct ieee80211_vif *vif,
383 struct ieee80211_bss_conf *bss_conf,
384 u32 changes)
385{
386 struct iwl_priv *priv = hw->priv;
387 struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif);
388 int ret;
389
390 if (WARN_ON(!priv->cfg->ops->legacy))
391 return;
392
393 IWL_DEBUG_MAC80211(priv, "changes = 0x%X\n", changes);
394
395 if (!iwl_is_alive(priv))
396 return;
397
398 mutex_lock(&priv->mutex);
399
400 if (changes & BSS_CHANGED_QOS) {
401 unsigned long flags;
402
403 spin_lock_irqsave(&priv->lock, flags);
404 ctx->qos_data.qos_active = bss_conf->qos;
405 iwl_update_qos(priv, ctx);
406 spin_unlock_irqrestore(&priv->lock, flags);
407 }
408
409 if (changes & BSS_CHANGED_BEACON_ENABLED) {
410 /*
411 * the add_interface code must make sure we only ever
412 * have a single interface that could be beaconing at
413 * any time.
414 */
415 if (vif->bss_conf.enable_beacon)
416 priv->beacon_ctx = ctx;
417 else
418 priv->beacon_ctx = NULL;
419 }
420
421 if (changes & BSS_CHANGED_BEACON && vif->type == NL80211_IFTYPE_AP) {
422 dev_kfree_skb(priv->beacon_skb);
423 priv->beacon_skb = ieee80211_beacon_get(hw, vif);
424 }
425
426 if (changes & BSS_CHANGED_BEACON_INT && vif->type == NL80211_IFTYPE_AP)
427 iwl_send_rxon_timing(priv, ctx);
428
429 if (changes & BSS_CHANGED_BSSID) {
430 IWL_DEBUG_MAC80211(priv, "BSSID %pM\n", bss_conf->bssid);
431
432 /*
433 * If there is currently a HW scan going on in the
434 * background then we need to cancel it else the RXON
435 * below/in post_associate will fail.
436 */
437 if (iwl_scan_cancel_timeout(priv, 100)) {
438 IWL_WARN(priv, "Aborted scan still in progress after 100ms\n");
439 IWL_DEBUG_MAC80211(priv, "leaving - scan abort failed.\n");
440 mutex_unlock(&priv->mutex);
441 return;
442 }
443
444 /* mac80211 only sets assoc when in STATION mode */
445 if (vif->type == NL80211_IFTYPE_ADHOC || bss_conf->assoc) {
446 memcpy(ctx->staging.bssid_addr,
447 bss_conf->bssid, ETH_ALEN);
448
449 /* currently needed in a few places */
450 memcpy(priv->bssid, bss_conf->bssid, ETH_ALEN);
451 } else {
452 ctx->staging.filter_flags &=
453 ~RXON_FILTER_ASSOC_MSK;
454 }
455
456 }
457
458 /*
459 * This needs to be after setting the BSSID in case
460 * mac80211 decides to do both changes at once because
461 * it will invoke post_associate.
462 */
463 if (vif->type == NL80211_IFTYPE_ADHOC && changes & BSS_CHANGED_BEACON)
464 iwlcore_beacon_update(hw, vif);
465
466 if (changes & BSS_CHANGED_ERP_PREAMBLE) {
467 IWL_DEBUG_MAC80211(priv, "ERP_PREAMBLE %d\n",
468 bss_conf->use_short_preamble);
469 if (bss_conf->use_short_preamble)
470 ctx->staging.flags |= RXON_FLG_SHORT_PREAMBLE_MSK;
471 else
472 ctx->staging.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK;
473 }
474
475 if (changes & BSS_CHANGED_ERP_CTS_PROT) {
476 IWL_DEBUG_MAC80211(priv, "ERP_CTS %d\n", bss_conf->use_cts_prot);
477 if (bss_conf->use_cts_prot && (priv->band != IEEE80211_BAND_5GHZ))
478 ctx->staging.flags |= RXON_FLG_TGG_PROTECT_MSK;
479 else
480 ctx->staging.flags &= ~RXON_FLG_TGG_PROTECT_MSK;
481 if (bss_conf->use_cts_prot)
482 ctx->staging.flags |= RXON_FLG_SELF_CTS_EN;
483 else
484 ctx->staging.flags &= ~RXON_FLG_SELF_CTS_EN;
485 }
486
487 if (changes & BSS_CHANGED_BASIC_RATES) {
488 /* XXX use this information
489 *
490 * To do that, remove code from iwl_set_rate() and put something
491 * like this here:
492 *
493 if (A-band)
494 ctx->staging.ofdm_basic_rates =
495 bss_conf->basic_rates;
496 else
497 ctx->staging.ofdm_basic_rates =
498 bss_conf->basic_rates >> 4;
499 ctx->staging.cck_basic_rates =
500 bss_conf->basic_rates & 0xF;
501 */
502 }
503
504 if (changes & BSS_CHANGED_HT) {
505 iwl_ht_conf(priv, vif);
506
507 if (priv->cfg->ops->hcmd->set_rxon_chain)
508 priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx);
509 }
510
511 if (changes & BSS_CHANGED_ASSOC) {
512 IWL_DEBUG_MAC80211(priv, "ASSOC %d\n", bss_conf->assoc);
513 if (bss_conf->assoc) {
514 priv->timestamp = bss_conf->timestamp;
515
516 iwl_led_associate(priv);
517
518 if (!iwl_is_rfkill(priv))
519 priv->cfg->ops->legacy->post_associate(priv);
520 } else
521 iwl_set_no_assoc(priv, vif);
522 }
523
524 if (changes && iwl_is_associated_ctx(ctx) && bss_conf->aid) {
525 IWL_DEBUG_MAC80211(priv, "Changes (%#x) while associated\n",
526 changes);
527 ret = iwl_send_rxon_assoc(priv, ctx);
528 if (!ret) {
529 /* Sync active_rxon with latest change. */
530 memcpy((void *)&ctx->active,
531 &ctx->staging,
532 sizeof(struct iwl_rxon_cmd));
533 }
534 }
535
536 if (changes & BSS_CHANGED_BEACON_ENABLED) {
537 if (vif->bss_conf.enable_beacon) {
538 memcpy(ctx->staging.bssid_addr,
539 bss_conf->bssid, ETH_ALEN);
540 memcpy(priv->bssid, bss_conf->bssid, ETH_ALEN);
541 iwl_led_associate(priv);
542 priv->cfg->ops->legacy->config_ap(priv);
543 } else
544 iwl_set_no_assoc(priv, vif);
545 }
546
547 if (changes & BSS_CHANGED_IBSS) {
548 ret = priv->cfg->ops->legacy->manage_ibss_station(priv, vif,
549 bss_conf->ibss_joined);
550 if (ret)
551 IWL_ERR(priv, "failed to %s IBSS station %pM\n",
552 bss_conf->ibss_joined ? "add" : "remove",
553 bss_conf->bssid);
554 }
555
556 mutex_unlock(&priv->mutex);
557
558 IWL_DEBUG_MAC80211(priv, "leave\n");
559}
560EXPORT_SYMBOL(iwl_legacy_mac_bss_info_changed);
diff --git a/drivers/net/wireless/iwlwifi/iwl-legacy.h b/drivers/net/wireless/iwlwifi/iwl-legacy.h
new file mode 100644
index 000000000000..2a746cbc30fe
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/iwl-legacy.h
@@ -0,0 +1,74 @@
1/******************************************************************************
2 *
3 * This file is provided under a dual BSD/GPLv2 license. When using or
4 * redistributing this file, you may do so under either license.
5 *
6 * GPL LICENSE SUMMARY
7 *
8 * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as
12 * published by the Free Software Foundation.
13 *
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
22 * USA
23 *
24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL.
26 *
27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com>
29 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
30 *
31 * BSD LICENSE
32 *
33 * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved.
34 * All rights reserved.
35 *
36 * Redistribution and use in source and binary forms, with or without
37 * modification, are permitted provided that the following conditions
38 * are met:
39 *
40 * * Redistributions of source code must retain the above copyright
41 * notice, this list of conditions and the following disclaimer.
42 * * Redistributions in binary form must reproduce the above copyright
43 * notice, this list of conditions and the following disclaimer in
44 * the documentation and/or other materials provided with the
45 * distribution.
46 * * Neither the name Intel Corporation nor the names of its
47 * contributors may be used to endorse or promote products derived
48 * from this software without specific prior written permission.
49 *
50 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
51 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
52 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
53 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
54 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
55 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
56 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
57 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
58 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
59 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
60 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
61 *****************************************************************************/
62
63#ifndef __iwl_legacy_h__
64#define __iwl_legacy_h__
65
66/* mac80211 handlers */
67int iwl_legacy_mac_config(struct ieee80211_hw *hw, u32 changed);
68void iwl_legacy_mac_reset_tsf(struct ieee80211_hw *hw);
69void iwl_legacy_mac_bss_info_changed(struct ieee80211_hw *hw,
70 struct ieee80211_vif *vif,
71 struct ieee80211_bss_conf *bss_conf,
72 u32 changes);
73
74#endif /* __iwl_legacy_h__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index d42bb22e5ed5..73f2f3fcb49c 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -61,6 +61,7 @@
61#include "iwl-helpers.h" 61#include "iwl-helpers.h"
62#include "iwl-dev.h" 62#include "iwl-dev.h"
63#include "iwl-spectrum.h" 63#include "iwl-spectrum.h"
64#include "iwl-legacy.h"
64 65
65/* 66/*
66 * module name, copyright, version, etc. 67 * module name, copyright, version, etc.
@@ -3057,22 +3058,22 @@ static void iwl3945_bg_rx_replenish(struct work_struct *data)
3057 mutex_unlock(&priv->mutex); 3058 mutex_unlock(&priv->mutex);
3058} 3059}
3059 3060
3060void iwl3945_post_associate(struct iwl_priv *priv, struct ieee80211_vif *vif) 3061void iwl3945_post_associate(struct iwl_priv *priv)
3061{ 3062{
3062 int rc = 0; 3063 int rc = 0;
3063 struct ieee80211_conf *conf = NULL; 3064 struct ieee80211_conf *conf = NULL;
3064 struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; 3065 struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
3065 3066
3066 if (!vif || !priv->is_open) 3067 if (!ctx->vif || !priv->is_open)
3067 return; 3068 return;
3068 3069
3069 if (vif->type == NL80211_IFTYPE_AP) { 3070 if (ctx->vif->type == NL80211_IFTYPE_AP) {
3070 IWL_ERR(priv, "%s Should not be called in AP mode\n", __func__); 3071 IWL_ERR(priv, "%s Should not be called in AP mode\n", __func__);
3071 return; 3072 return;
3072 } 3073 }
3073 3074
3074 IWL_DEBUG_ASSOC(priv, "Associated as %d to: %pM\n", 3075 IWL_DEBUG_ASSOC(priv, "Associated as %d to: %pM\n",
3075 vif->bss_conf.aid, ctx->active.bssid_addr); 3076 ctx->vif->bss_conf.aid, ctx->active.bssid_addr);
3076 3077
3077 if (test_bit(STATUS_EXIT_PENDING, &priv->status)) 3078 if (test_bit(STATUS_EXIT_PENDING, &priv->status))
3078 return; 3079 return;
@@ -3091,18 +3092,18 @@ void iwl3945_post_associate(struct iwl_priv *priv, struct ieee80211_vif *vif)
3091 3092
3092 ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK; 3093 ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK;
3093 3094
3094 ctx->staging.assoc_id = cpu_to_le16(vif->bss_conf.aid); 3095 ctx->staging.assoc_id = cpu_to_le16(ctx->vif->bss_conf.aid);
3095 3096
3096 IWL_DEBUG_ASSOC(priv, "assoc id %d beacon interval %d\n", 3097 IWL_DEBUG_ASSOC(priv, "assoc id %d beacon interval %d\n",
3097 vif->bss_conf.aid, vif->bss_conf.beacon_int); 3098 ctx->vif->bss_conf.aid, ctx->vif->bss_conf.beacon_int);
3098 3099
3099 if (vif->bss_conf.use_short_preamble) 3100 if (ctx->vif->bss_conf.use_short_preamble)
3100 ctx->staging.flags |= RXON_FLG_SHORT_PREAMBLE_MSK; 3101 ctx->staging.flags |= RXON_FLG_SHORT_PREAMBLE_MSK;
3101 else 3102 else
3102 ctx->staging.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK; 3103 ctx->staging.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK;
3103 3104
3104 if (ctx->staging.flags & RXON_FLG_BAND_24G_MSK) { 3105 if (ctx->staging.flags & RXON_FLG_BAND_24G_MSK) {
3105 if (vif->bss_conf.use_short_slot) 3106 if (ctx->vif->bss_conf.use_short_slot)
3106 ctx->staging.flags |= RXON_FLG_SHORT_SLOT_MSK; 3107 ctx->staging.flags |= RXON_FLG_SHORT_SLOT_MSK;
3107 else 3108 else
3108 ctx->staging.flags &= ~RXON_FLG_SHORT_SLOT_MSK; 3109 ctx->staging.flags &= ~RXON_FLG_SHORT_SLOT_MSK;
@@ -3110,7 +3111,7 @@ void iwl3945_post_associate(struct iwl_priv *priv, struct ieee80211_vif *vif)
3110 3111
3111 iwl3945_commit_rxon(priv, ctx); 3112 iwl3945_commit_rxon(priv, ctx);
3112 3113
3113 switch (vif->type) { 3114 switch (ctx->vif->type) {
3114 case NL80211_IFTYPE_STATION: 3115 case NL80211_IFTYPE_STATION:
3115 iwl3945_rate_scale_init(priv->hw, IWL_AP_ID); 3116 iwl3945_rate_scale_init(priv->hw, IWL_AP_ID);
3116 break; 3117 break;
@@ -3119,7 +3120,7 @@ void iwl3945_post_associate(struct iwl_priv *priv, struct ieee80211_vif *vif)
3119 break; 3120 break;
3120 default: 3121 default:
3121 IWL_ERR(priv, "%s Should not be called in %d mode\n", 3122 IWL_ERR(priv, "%s Should not be called in %d mode\n",
3122 __func__, vif->type); 3123 __func__, ctx->vif->type);
3123 break; 3124 break;
3124 } 3125 }
3125} 3126}
@@ -3234,9 +3235,10 @@ static int iwl3945_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
3234 return NETDEV_TX_OK; 3235 return NETDEV_TX_OK;
3235} 3236}
3236 3237
3237void iwl3945_config_ap(struct iwl_priv *priv, struct ieee80211_vif *vif) 3238void iwl3945_config_ap(struct iwl_priv *priv)
3238{ 3239{
3239 struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; 3240 struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
3241 struct ieee80211_vif *vif = ctx->vif;
3240 int rc = 0; 3242 int rc = 0;
3241 3243
3242 if (test_bit(STATUS_EXIT_PENDING, &priv->status)) 3244 if (test_bit(STATUS_EXIT_PENDING, &priv->status))
@@ -3830,12 +3832,12 @@ struct ieee80211_ops iwl3945_hw_ops = {
3830 .stop = iwl3945_mac_stop, 3832 .stop = iwl3945_mac_stop,
3831 .add_interface = iwl_mac_add_interface, 3833 .add_interface = iwl_mac_add_interface,
3832 .remove_interface = iwl_mac_remove_interface, 3834 .remove_interface = iwl_mac_remove_interface,
3833 .config = iwl_mac_config, 3835 .config = iwl_legacy_mac_config,
3834 .configure_filter = iwl3945_configure_filter, 3836 .configure_filter = iwl3945_configure_filter,
3835 .set_key = iwl3945_mac_set_key, 3837 .set_key = iwl3945_mac_set_key,
3836 .conf_tx = iwl_mac_conf_tx, 3838 .conf_tx = iwl_mac_conf_tx,
3837 .reset_tsf = iwl_mac_reset_tsf, 3839 .reset_tsf = iwl_legacy_mac_reset_tsf,
3838 .bss_info_changed = iwl_bss_info_changed, 3840 .bss_info_changed = iwl_legacy_mac_bss_info_changed,
3839 .hw_scan = iwl_mac_hw_scan, 3841 .hw_scan = iwl_mac_hw_scan,
3840 .sta_add = iwl3945_mac_sta_add, 3842 .sta_add = iwl3945_mac_sta_add,
3841 .sta_remove = iwl_mac_sta_remove, 3843 .sta_remove = iwl_mac_sta_remove,