diff options
author | John W. Linville <linville@tuxdriver.com> | 2012-06-11 14:50:59 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2012-06-11 14:50:59 -0400 |
commit | b6038961dfeed49533e43fbedd86951a16cb4d2c (patch) | |
tree | 8df5f6b6ec01a0d53d5327bd63915902a18a4fbe /drivers | |
parent | 2e48686835370dfe78697839ca293d250793809d (diff) | |
parent | b1abedada3fd0aa100723aa9b60b7e31c17945cb (diff) |
Merge branch 'for-john' of git://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi/iwlwifi-next
Conflicts:
drivers/net/wireless/iwlwifi/iwl-eeprom.c
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/net/wireless/iwlwifi/Makefile | 26 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/dvm/Makefile | 13 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/dvm/agn.h (renamed from drivers/net/wireless/iwlwifi/iwl-agn.h) | 94 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/dvm/calib.c (renamed from drivers/net/wireless/iwlwifi/iwl-agn-calib.c) | 24 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/dvm/calib.h (renamed from drivers/net/wireless/iwlwifi/iwl-agn-calib.h) | 4 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/dvm/commands.h (renamed from drivers/net/wireless/iwlwifi/iwl-commands.h) | 4 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/dvm/debugfs.c (renamed from drivers/net/wireless/iwlwifi/iwl-debugfs.c) | 31 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/dvm/dev.h (renamed from drivers/net/wireless/iwlwifi/iwl-dev.h) | 148 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/dvm/devices.c (renamed from drivers/net/wireless/iwlwifi/iwl-agn-devices.c) | 178 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/dvm/led.c (renamed from drivers/net/wireless/iwlwifi/iwl-led.c) | 5 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/dvm/led.h (renamed from drivers/net/wireless/iwlwifi/iwl-led.h) | 0 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/dvm/lib.c (renamed from drivers/net/wireless/iwlwifi/iwl-agn-lib.c) | 18 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/dvm/mac80211.c (renamed from drivers/net/wireless/iwlwifi/iwl-mac80211.c) | 133 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/dvm/main.c (renamed from drivers/net/wireless/iwlwifi/iwl-agn.c) | 408 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/dvm/power.c (renamed from drivers/net/wireless/iwlwifi/iwl-power.c) | 11 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/dvm/power.h (renamed from drivers/net/wireless/iwlwifi/iwl-power.h) | 2 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/dvm/rs.c (renamed from drivers/net/wireless/iwlwifi/iwl-agn-rs.c) | 50 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/dvm/rs.h (renamed from drivers/net/wireless/iwlwifi/iwl-agn-rs.h) | 3 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/dvm/rx.c (renamed from drivers/net/wireless/iwlwifi/iwl-agn-rx.c) | 10 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/dvm/rxon.c (renamed from drivers/net/wireless/iwlwifi/iwl-agn-rxon.c) | 52 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/dvm/scan.c (renamed from drivers/net/wireless/iwlwifi/iwl-scan.c) | 111 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/dvm/sta.c (renamed from drivers/net/wireless/iwlwifi/iwl-agn-sta.c) | 59 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/dvm/testmode.c (renamed from drivers/net/wireless/iwlwifi/iwl-testmode.c) | 21 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/dvm/testmode.h (renamed from drivers/net/wireless/iwlwifi/iwl-testmode.h) | 0 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/dvm/tt.c (renamed from drivers/net/wireless/iwlwifi/iwl-agn-tt.c) | 13 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/dvm/tt.h (renamed from drivers/net/wireless/iwlwifi/iwl-agn-tt.h) | 2 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/dvm/tx.c (renamed from drivers/net/wireless/iwlwifi/iwl-agn-tx.c) | 58 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/dvm/ucode.c (renamed from drivers/net/wireless/iwlwifi/iwl-ucode.c) | 34 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-config.h | 26 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-csr.h | 28 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-debug.h | 5 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-devtrace.h | 1 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-eeprom-parse.c | 900 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-eeprom-parse.h | 138 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-eeprom-read.c | 463 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-eeprom-read.h | 70 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-eeprom.c | 1148 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-eeprom.h | 269 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-io.c | 18 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-io.h | 2 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-op-mode.h | 5 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-prph.h | 2 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-trans.h | 51 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/pcie/1000.c (renamed from drivers/net/wireless/iwlwifi/iwl-1000.c) | 19 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/pcie/2000.c (renamed from drivers/net/wireless/iwlwifi/iwl-2000.c) | 22 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/pcie/5000.c (renamed from drivers/net/wireless/iwlwifi/iwl-5000.c) | 20 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/pcie/6000.c (renamed from drivers/net/wireless/iwlwifi/iwl-6000.c) | 24 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/pcie/cfg.h (renamed from drivers/net/wireless/iwlwifi/iwl-cfg.h) | 0 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/pcie/drv.c (renamed from drivers/net/wireless/iwlwifi/iwl-pci.c) | 5 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/pcie/internal.h (renamed from drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h) | 9 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/pcie/rx.c (renamed from drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c) | 2 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/pcie/trans.c (renamed from drivers/net/wireless/iwlwifi/iwl-trans-pcie.c) | 89 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/pcie/tx.c (renamed from drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c) | 54 |
53 files changed, 2329 insertions, 2553 deletions
diff --git a/drivers/net/wireless/iwlwifi/Makefile b/drivers/net/wireless/iwlwifi/Makefile index 931002738c9f..98c8f6449649 100644 --- a/drivers/net/wireless/iwlwifi/Makefile +++ b/drivers/net/wireless/iwlwifi/Makefile | |||
@@ -1,31 +1,17 @@ | |||
1 | # DVM | 1 | obj-$(CONFIG_IWLDVM) += dvm/ |
2 | obj-$(CONFIG_IWLDVM) += iwldvm.o | ||
3 | iwldvm-objs := iwl-agn.o iwl-agn-rs.o iwl-mac80211.o | ||
4 | iwldvm-objs += iwl-ucode.o iwl-agn-tx.o | ||
5 | iwldvm-objs += iwl-agn-lib.o iwl-agn-calib.o | ||
6 | iwldvm-objs += iwl-agn-tt.o iwl-agn-sta.o iwl-agn-rx.o | ||
7 | iwldvm-objs += iwl-eeprom.o iwl-power.o | ||
8 | iwldvm-objs += iwl-scan.o iwl-led.o | ||
9 | iwldvm-objs += iwl-agn-rxon.o iwl-agn-devices.o | ||
10 | |||
11 | iwldvm-$(CONFIG_IWLWIFI_DEBUGFS) += iwl-debugfs.o | ||
12 | iwldvm-$(CONFIG_IWLWIFI_DEVICE_TESTMODE) += iwl-testmode.o | ||
13 | 2 | ||
14 | CFLAGS_iwl-devtrace.o := -I$(src) | 3 | CFLAGS_iwl-devtrace.o := -I$(src) |
15 | 4 | ||
16 | # WIFI | 5 | # common |
17 | obj-$(CONFIG_IWLWIFI) += iwlwifi.o | 6 | obj-$(CONFIG_IWLWIFI) += iwlwifi.o |
18 | iwlwifi-objs += iwl-5000.o | ||
19 | iwlwifi-objs += iwl-6000.o | ||
20 | iwlwifi-objs += iwl-1000.o | ||
21 | iwlwifi-objs += iwl-2000.o | ||
22 | iwlwifi-objs += iwl-io.o | 7 | iwlwifi-objs += iwl-io.o |
23 | iwlwifi-objs += iwl-pci.o | ||
24 | iwlwifi-objs += iwl-drv.o | 8 | iwlwifi-objs += iwl-drv.o |
25 | iwlwifi-objs += iwl-debug.o | 9 | iwlwifi-objs += iwl-debug.o |
26 | iwlwifi-objs += iwl-notif-wait.o | 10 | iwlwifi-objs += iwl-notif-wait.o |
27 | iwlwifi-objs += iwl-trans-pcie.o iwl-trans-pcie-rx.o iwl-trans-pcie-tx.o | 11 | iwlwifi-objs += iwl-eeprom-read.o iwl-eeprom-parse.o |
12 | iwlwifi-objs += pcie/drv.o pcie/rx.o pcie/tx.o pcie/trans.o | ||
13 | iwlwifi-objs += pcie/1000.o pcie/2000.o pcie/5000.o pcie/6000.o | ||
28 | 14 | ||
29 | iwlwifi-$(CONFIG_IWLWIFI_DEVICE_TRACING) += iwl-devtrace.o | 15 | iwlwifi-$(CONFIG_IWLWIFI_DEVICE_TRACING) += iwl-devtrace.o |
30 | 16 | ||
31 | ccflags-y += -D__CHECK_ENDIAN__ | 17 | ccflags-y += -D__CHECK_ENDIAN__ -I$(src) |
diff --git a/drivers/net/wireless/iwlwifi/dvm/Makefile b/drivers/net/wireless/iwlwifi/dvm/Makefile new file mode 100644 index 000000000000..5ff76b204141 --- /dev/null +++ b/drivers/net/wireless/iwlwifi/dvm/Makefile | |||
@@ -0,0 +1,13 @@ | |||
1 | # DVM | ||
2 | obj-$(CONFIG_IWLDVM) += iwldvm.o | ||
3 | iwldvm-objs += main.o rs.o mac80211.o ucode.o tx.o | ||
4 | iwldvm-objs += lib.o calib.o tt.o sta.o rx.o | ||
5 | |||
6 | iwldvm-objs += power.o | ||
7 | iwldvm-objs += scan.o led.o | ||
8 | iwldvm-objs += rxon.o devices.o | ||
9 | |||
10 | iwldvm-$(CONFIG_IWLWIFI_DEBUGFS) += debugfs.o | ||
11 | iwldvm-$(CONFIG_IWLWIFI_DEVICE_TESTMODE) += testmode.o | ||
12 | |||
13 | ccflags-y += -D__CHECK_ENDIAN__ -I$(src)/../ | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/dvm/agn.h index 79c0fe06f4db..2ae3608472a6 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.h +++ b/drivers/net/wireless/iwlwifi/dvm/agn.h | |||
@@ -63,9 +63,10 @@ | |||
63 | #ifndef __iwl_agn_h__ | 63 | #ifndef __iwl_agn_h__ |
64 | #define __iwl_agn_h__ | 64 | #define __iwl_agn_h__ |
65 | 65 | ||
66 | #include "iwl-dev.h" | ||
67 | #include "iwl-config.h" | 66 | #include "iwl-config.h" |
68 | 67 | ||
68 | #include "dev.h" | ||
69 | |||
69 | /* The first 11 queues (0-10) are used otherwise */ | 70 | /* The first 11 queues (0-10) are used otherwise */ |
70 | #define IWLAGN_FIRST_AMPDU_QUEUE 11 | 71 | #define IWLAGN_FIRST_AMPDU_QUEUE 11 |
71 | 72 | ||
@@ -91,7 +92,6 @@ extern struct iwl_lib_ops iwl6030_lib; | |||
91 | #define STATUS_CT_KILL 1 | 92 | #define STATUS_CT_KILL 1 |
92 | #define STATUS_ALIVE 2 | 93 | #define STATUS_ALIVE 2 |
93 | #define STATUS_READY 3 | 94 | #define STATUS_READY 3 |
94 | #define STATUS_GEO_CONFIGURED 4 | ||
95 | #define STATUS_EXIT_PENDING 5 | 95 | #define STATUS_EXIT_PENDING 5 |
96 | #define STATUS_STATISTICS 6 | 96 | #define STATUS_STATISTICS 6 |
97 | #define STATUS_SCANNING 7 | 97 | #define STATUS_SCANNING 7 |
@@ -101,6 +101,7 @@ extern struct iwl_lib_ops iwl6030_lib; | |||
101 | #define STATUS_CHANNEL_SWITCH_PENDING 11 | 101 | #define STATUS_CHANNEL_SWITCH_PENDING 11 |
102 | #define STATUS_SCAN_COMPLETE 12 | 102 | #define STATUS_SCAN_COMPLETE 12 |
103 | #define STATUS_POWER_PMI 13 | 103 | #define STATUS_POWER_PMI 13 |
104 | #define STATUS_SCAN_ROC_EXPIRED 14 | ||
104 | 105 | ||
105 | struct iwl_ucode_capabilities; | 106 | struct iwl_ucode_capabilities; |
106 | 107 | ||
@@ -255,6 +256,10 @@ int __must_check iwl_scan_initiate(struct iwl_priv *priv, | |||
255 | enum iwl_scan_type scan_type, | 256 | enum iwl_scan_type scan_type, |
256 | enum ieee80211_band band); | 257 | enum ieee80211_band band); |
257 | 258 | ||
259 | void iwl_scan_roc_expired(struct iwl_priv *priv); | ||
260 | void iwl_scan_offchannel_skb(struct iwl_priv *priv); | ||
261 | void iwl_scan_offchannel_skb_status(struct iwl_priv *priv); | ||
262 | |||
258 | /* For faster active scanning, scan will move to the next channel if fewer than | 263 | /* For faster active scanning, scan will move to the next channel if fewer than |
259 | * PLCP_QUIET_THRESH packets are heard on this channel within | 264 | * PLCP_QUIET_THRESH packets are heard on this channel within |
260 | * ACTIVE_QUIET_TIME after sending probe request. This shortens the dwell | 265 | * ACTIVE_QUIET_TIME after sending probe request. This shortens the dwell |
@@ -437,10 +442,8 @@ static inline void iwl_print_rx_config_cmd(struct iwl_priv *priv, | |||
437 | 442 | ||
438 | static inline int iwl_is_ready(struct iwl_priv *priv) | 443 | static inline int iwl_is_ready(struct iwl_priv *priv) |
439 | { | 444 | { |
440 | /* The adapter is 'ready' if READY and GEO_CONFIGURED bits are | 445 | /* The adapter is 'ready' if READY EXIT_PENDING is not set */ |
441 | * set but EXIT_PENDING is not */ | ||
442 | return test_bit(STATUS_READY, &priv->status) && | 446 | return test_bit(STATUS_READY, &priv->status) && |
443 | test_bit(STATUS_GEO_CONFIGURED, &priv->status) && | ||
444 | !test_bit(STATUS_EXIT_PENDING, &priv->status); | 447 | !test_bit(STATUS_EXIT_PENDING, &priv->status); |
445 | } | 448 | } |
446 | 449 | ||
@@ -518,85 +521,4 @@ static inline const char *iwl_dvm_get_cmd_string(u8 cmd) | |||
518 | return s; | 521 | return s; |
519 | return "UNKNOWN"; | 522 | return "UNKNOWN"; |
520 | } | 523 | } |
521 | |||
522 | /* API method exported for mvm hybrid state */ | ||
523 | void iwl_setup_deferred_work(struct iwl_priv *priv); | ||
524 | int iwl_send_wimax_coex(struct iwl_priv *priv); | ||
525 | int iwl_send_bt_env(struct iwl_priv *priv, u8 action, u8 type); | ||
526 | void iwl_option_config(struct iwl_priv *priv); | ||
527 | void iwl_set_hw_params(struct iwl_priv *priv); | ||
528 | void iwl_init_context(struct iwl_priv *priv, u32 ucode_flags); | ||
529 | int iwl_init_drv(struct iwl_priv *priv); | ||
530 | void iwl_uninit_drv(struct iwl_priv *priv); | ||
531 | void iwl_send_bt_config(struct iwl_priv *priv); | ||
532 | void iwl_rf_kill_ct_config(struct iwl_priv *priv); | ||
533 | int iwl_setup_interface(struct iwl_priv *priv, struct iwl_rxon_context *ctx); | ||
534 | void iwl_teardown_interface(struct iwl_priv *priv, | ||
535 | struct ieee80211_vif *vif, | ||
536 | bool mode_change); | ||
537 | int iwl_full_rxon_required(struct iwl_priv *priv, struct iwl_rxon_context *ctx); | ||
538 | void iwlagn_update_qos(struct iwl_priv *priv, struct iwl_rxon_context *ctx); | ||
539 | void iwlagn_check_needed_chains(struct iwl_priv *priv, | ||
540 | struct iwl_rxon_context *ctx, | ||
541 | struct ieee80211_bss_conf *bss_conf); | ||
542 | void iwlagn_chain_noise_reset(struct iwl_priv *priv); | ||
543 | int iwlagn_update_beacon(struct iwl_priv *priv, | ||
544 | struct ieee80211_vif *vif); | ||
545 | void iwl_tt_handler(struct iwl_priv *priv); | ||
546 | void iwl_op_mode_dvm_stop(struct iwl_op_mode *op_mode); | ||
547 | void iwl_stop_sw_queue(struct iwl_op_mode *op_mode, int queue); | ||
548 | void iwl_set_hw_rfkill_state(struct iwl_op_mode *op_mode, bool state); | ||
549 | void iwl_free_skb(struct iwl_op_mode *op_mode, struct sk_buff *skb); | ||
550 | void iwl_nic_error(struct iwl_op_mode *op_mode); | ||
551 | void iwl_cmd_queue_full(struct iwl_op_mode *op_mode); | ||
552 | void iwl_nic_config(struct iwl_op_mode *op_mode); | ||
553 | int iwlagn_mac_set_tim(struct ieee80211_hw *hw, | ||
554 | struct ieee80211_sta *sta, bool set); | ||
555 | void iwlagn_mac_rssi_callback(struct ieee80211_hw *hw, | ||
556 | enum ieee80211_rssi_event rssi_event); | ||
557 | int iwlagn_mac_cancel_remain_on_channel(struct ieee80211_hw *hw); | ||
558 | int iwlagn_mac_tx_last_beacon(struct ieee80211_hw *hw); | ||
559 | void iwlagn_mac_flush(struct ieee80211_hw *hw, bool drop); | ||
560 | void iwl_wake_sw_queue(struct iwl_op_mode *op_mode, int queue); | ||
561 | void iwlagn_mac_channel_switch(struct ieee80211_hw *hw, | ||
562 | struct ieee80211_channel_switch *ch_switch); | ||
563 | int iwlagn_mac_sta_state(struct ieee80211_hw *hw, | ||
564 | struct ieee80211_vif *vif, | ||
565 | struct ieee80211_sta *sta, | ||
566 | enum ieee80211_sta_state old_state, | ||
567 | enum ieee80211_sta_state new_state); | ||
568 | int iwlagn_mac_ampdu_action(struct ieee80211_hw *hw, | ||
569 | struct ieee80211_vif *vif, | ||
570 | enum ieee80211_ampdu_mlme_action action, | ||
571 | struct ieee80211_sta *sta, u16 tid, u16 *ssn, | ||
572 | u8 buf_size); | ||
573 | int iwlagn_mac_hw_scan(struct ieee80211_hw *hw, | ||
574 | struct ieee80211_vif *vif, | ||
575 | struct cfg80211_scan_request *req); | ||
576 | void iwlagn_mac_sta_notify(struct ieee80211_hw *hw, | ||
577 | struct ieee80211_vif *vif, | ||
578 | enum sta_notify_cmd cmd, | ||
579 | struct ieee80211_sta *sta); | ||
580 | void iwlagn_configure_filter(struct ieee80211_hw *hw, | ||
581 | unsigned int changed_flags, | ||
582 | unsigned int *total_flags, | ||
583 | u64 multicast); | ||
584 | int iwlagn_mac_conf_tx(struct ieee80211_hw *hw, | ||
585 | struct ieee80211_vif *vif, u16 queue, | ||
586 | const struct ieee80211_tx_queue_params *params); | ||
587 | void iwlagn_mac_set_rekey_data(struct ieee80211_hw *hw, | ||
588 | struct ieee80211_vif *vif, | ||
589 | struct cfg80211_gtk_rekey_data *data); | ||
590 | void iwlagn_mac_update_tkip_key(struct ieee80211_hw *hw, | ||
591 | struct ieee80211_vif *vif, | ||
592 | struct ieee80211_key_conf *keyconf, | ||
593 | struct ieee80211_sta *sta, | ||
594 | u32 iv32, u16 *phase1key); | ||
595 | int iwlagn_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, | ||
596 | struct ieee80211_vif *vif, | ||
597 | struct ieee80211_sta *sta, | ||
598 | struct ieee80211_key_conf *key); | ||
599 | void iwlagn_mac_stop(struct ieee80211_hw *hw); | ||
600 | void iwlagn_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb); | ||
601 | int iwlagn_mac_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan); | ||
602 | #endif /* __iwl_agn_h__ */ | 524 | #endif /* __iwl_agn_h__ */ |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-calib.c b/drivers/net/wireless/iwlwifi/dvm/calib.c index 95f27f1a423b..f2dd671d7dc8 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-calib.c +++ b/drivers/net/wireless/iwlwifi/dvm/calib.c | |||
@@ -63,10 +63,11 @@ | |||
63 | #include <linux/slab.h> | 63 | #include <linux/slab.h> |
64 | #include <net/mac80211.h> | 64 | #include <net/mac80211.h> |
65 | 65 | ||
66 | #include "iwl-dev.h" | ||
67 | #include "iwl-agn-calib.h" | ||
68 | #include "iwl-trans.h" | 66 | #include "iwl-trans.h" |
69 | #include "iwl-agn.h" | 67 | |
68 | #include "dev.h" | ||
69 | #include "calib.h" | ||
70 | #include "agn.h" | ||
70 | 71 | ||
71 | /***************************************************************************** | 72 | /***************************************************************************** |
72 | * INIT calibrations framework | 73 | * INIT calibrations framework |
@@ -832,14 +833,14 @@ static void iwl_find_disconn_antenna(struct iwl_priv *priv, u32* average_sig, | |||
832 | * To be safe, simply mask out any chains that we know | 833 | * To be safe, simply mask out any chains that we know |
833 | * are not on the device. | 834 | * are not on the device. |
834 | */ | 835 | */ |
835 | active_chains &= priv->hw_params.valid_rx_ant; | 836 | active_chains &= priv->eeprom_data->valid_rx_ant; |
836 | 837 | ||
837 | num_tx_chains = 0; | 838 | num_tx_chains = 0; |
838 | for (i = 0; i < NUM_RX_CHAINS; i++) { | 839 | for (i = 0; i < NUM_RX_CHAINS; i++) { |
839 | /* loops on all the bits of | 840 | /* loops on all the bits of |
840 | * priv->hw_setting.valid_tx_ant */ | 841 | * priv->hw_setting.valid_tx_ant */ |
841 | u8 ant_msk = (1 << i); | 842 | u8 ant_msk = (1 << i); |
842 | if (!(priv->hw_params.valid_tx_ant & ant_msk)) | 843 | if (!(priv->eeprom_data->valid_tx_ant & ant_msk)) |
843 | continue; | 844 | continue; |
844 | 845 | ||
845 | num_tx_chains++; | 846 | num_tx_chains++; |
@@ -853,7 +854,7 @@ static void iwl_find_disconn_antenna(struct iwl_priv *priv, u32* average_sig, | |||
853 | * connect the first valid tx chain | 854 | * connect the first valid tx chain |
854 | */ | 855 | */ |
855 | first_chain = | 856 | first_chain = |
856 | find_first_chain(priv->hw_params.valid_tx_ant); | 857 | find_first_chain(priv->eeprom_data->valid_tx_ant); |
857 | data->disconn_array[first_chain] = 0; | 858 | data->disconn_array[first_chain] = 0; |
858 | active_chains |= BIT(first_chain); | 859 | active_chains |= BIT(first_chain); |
859 | IWL_DEBUG_CALIB(priv, | 860 | IWL_DEBUG_CALIB(priv, |
@@ -863,13 +864,13 @@ static void iwl_find_disconn_antenna(struct iwl_priv *priv, u32* average_sig, | |||
863 | } | 864 | } |
864 | } | 865 | } |
865 | 866 | ||
866 | if (active_chains != priv->hw_params.valid_rx_ant && | 867 | if (active_chains != priv->eeprom_data->valid_rx_ant && |
867 | active_chains != priv->chain_noise_data.active_chains) | 868 | active_chains != priv->chain_noise_data.active_chains) |
868 | IWL_DEBUG_CALIB(priv, | 869 | IWL_DEBUG_CALIB(priv, |
869 | "Detected that not all antennas are connected! " | 870 | "Detected that not all antennas are connected! " |
870 | "Connected: %#x, valid: %#x.\n", | 871 | "Connected: %#x, valid: %#x.\n", |
871 | active_chains, | 872 | active_chains, |
872 | priv->hw_params.valid_rx_ant); | 873 | priv->eeprom_data->valid_rx_ant); |
873 | 874 | ||
874 | /* Save for use within RXON, TX, SCAN commands, etc. */ | 875 | /* Save for use within RXON, TX, SCAN commands, etc. */ |
875 | data->active_chains = active_chains; | 876 | data->active_chains = active_chains; |
@@ -1054,7 +1055,7 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv) | |||
1054 | priv->cfg->bt_params->advanced_bt_coexist) { | 1055 | priv->cfg->bt_params->advanced_bt_coexist) { |
1055 | /* Disable disconnected antenna algorithm for advanced | 1056 | /* Disable disconnected antenna algorithm for advanced |
1056 | bt coex, assuming valid antennas are connected */ | 1057 | bt coex, assuming valid antennas are connected */ |
1057 | data->active_chains = priv->hw_params.valid_rx_ant; | 1058 | data->active_chains = priv->eeprom_data->valid_rx_ant; |
1058 | for (i = 0; i < NUM_RX_CHAINS; i++) | 1059 | for (i = 0; i < NUM_RX_CHAINS; i++) |
1059 | if (!(data->active_chains & (1<<i))) | 1060 | if (!(data->active_chains & (1<<i))) |
1060 | data->disconn_array[i] = 1; | 1061 | data->disconn_array[i] = 1; |
@@ -1083,8 +1084,9 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv) | |||
1083 | IWL_DEBUG_CALIB(priv, "min_average_noise = %d, antenna %d\n", | 1084 | IWL_DEBUG_CALIB(priv, "min_average_noise = %d, antenna %d\n", |
1084 | min_average_noise, min_average_noise_antenna_i); | 1085 | min_average_noise, min_average_noise_antenna_i); |
1085 | 1086 | ||
1086 | iwlagn_gain_computation(priv, average_noise, | 1087 | iwlagn_gain_computation( |
1087 | find_first_chain(priv->hw_params.valid_rx_ant)); | 1088 | priv, average_noise, |
1089 | find_first_chain(priv->eeprom_data->valid_rx_ant)); | ||
1088 | 1090 | ||
1089 | /* Some power changes may have been made during the calibration. | 1091 | /* Some power changes may have been made during the calibration. |
1090 | * Update and commit the RXON | 1092 | * Update and commit the RXON |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-calib.h b/drivers/net/wireless/iwlwifi/dvm/calib.h index dbe13787f272..2349f393cc42 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-calib.h +++ b/drivers/net/wireless/iwlwifi/dvm/calib.h | |||
@@ -62,8 +62,8 @@ | |||
62 | #ifndef __iwl_calib_h__ | 62 | #ifndef __iwl_calib_h__ |
63 | #define __iwl_calib_h__ | 63 | #define __iwl_calib_h__ |
64 | 64 | ||
65 | #include "iwl-dev.h" | 65 | #include "dev.h" |
66 | #include "iwl-commands.h" | 66 | #include "commands.h" |
67 | 67 | ||
68 | void iwl_chain_noise_calibration(struct iwl_priv *priv); | 68 | void iwl_chain_noise_calibration(struct iwl_priv *priv); |
69 | void iwl_sensitivity_calibration(struct iwl_priv *priv); | 69 | void iwl_sensitivity_calibration(struct iwl_priv *priv); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/dvm/commands.h index b9f7361d2426..64811cd91635 100644 --- a/drivers/net/wireless/iwlwifi/iwl-commands.h +++ b/drivers/net/wireless/iwlwifi/dvm/commands.h | |||
@@ -61,9 +61,9 @@ | |||
61 | * | 61 | * |
62 | *****************************************************************************/ | 62 | *****************************************************************************/ |
63 | /* | 63 | /* |
64 | * Please use this file (iwl-commands.h) only for uCode API definitions. | 64 | * Please use this file (commands.h) only for uCode API definitions. |
65 | * Please use iwl-xxxx-hw.h for hardware-related definitions. | 65 | * Please use iwl-xxxx-hw.h for hardware-related definitions. |
66 | * Please use iwl-dev.h for driver implementation definitions. | 66 | * Please use dev.h for driver implementation definitions. |
67 | */ | 67 | */ |
68 | 68 | ||
69 | #ifndef __iwl_commands_h__ | 69 | #ifndef __iwl_commands_h__ |
diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/dvm/debugfs.c index e7c157e5ebeb..8a2d9e643b14 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c +++ b/drivers/net/wireless/iwlwifi/dvm/debugfs.c | |||
@@ -30,16 +30,12 @@ | |||
30 | #include <linux/kernel.h> | 30 | #include <linux/kernel.h> |
31 | #include <linux/module.h> | 31 | #include <linux/module.h> |
32 | #include <linux/debugfs.h> | 32 | #include <linux/debugfs.h> |
33 | |||
34 | #include <linux/ieee80211.h> | 33 | #include <linux/ieee80211.h> |
35 | #include <net/mac80211.h> | 34 | #include <net/mac80211.h> |
36 | |||
37 | |||
38 | #include "iwl-dev.h" | ||
39 | #include "iwl-debug.h" | 35 | #include "iwl-debug.h" |
40 | #include "iwl-io.h" | 36 | #include "iwl-io.h" |
41 | #include "iwl-agn.h" | 37 | #include "dev.h" |
42 | #include "iwl-modparams.h" | 38 | #include "agn.h" |
43 | 39 | ||
44 | /* create and remove of files */ | 40 | /* create and remove of files */ |
45 | #define DEBUGFS_ADD_FILE(name, parent, mode) do { \ | 41 | #define DEBUGFS_ADD_FILE(name, parent, mode) do { \ |
@@ -307,13 +303,13 @@ static ssize_t iwl_dbgfs_nvm_read(struct file *file, | |||
307 | const u8 *ptr; | 303 | const u8 *ptr; |
308 | char *buf; | 304 | char *buf; |
309 | u16 eeprom_ver; | 305 | u16 eeprom_ver; |
310 | size_t eeprom_len = priv->cfg->base_params->eeprom_size; | 306 | size_t eeprom_len = priv->eeprom_blob_size; |
311 | buf_size = 4 * eeprom_len + 256; | 307 | buf_size = 4 * eeprom_len + 256; |
312 | 308 | ||
313 | if (eeprom_len % 16) | 309 | if (eeprom_len % 16) |
314 | return -ENODATA; | 310 | return -ENODATA; |
315 | 311 | ||
316 | ptr = priv->eeprom; | 312 | ptr = priv->eeprom_blob; |
317 | if (!ptr) | 313 | if (!ptr) |
318 | return -ENOMEM; | 314 | return -ENOMEM; |
319 | 315 | ||
@@ -322,11 +318,9 @@ static ssize_t iwl_dbgfs_nvm_read(struct file *file, | |||
322 | if (!buf) | 318 | if (!buf) |
323 | return -ENOMEM; | 319 | return -ENOMEM; |
324 | 320 | ||
325 | eeprom_ver = iwl_eeprom_query16(priv, EEPROM_VERSION); | 321 | eeprom_ver = priv->eeprom_data->eeprom_version; |
326 | pos += scnprintf(buf + pos, buf_size - pos, "NVM Type: %s, " | 322 | pos += scnprintf(buf + pos, buf_size - pos, |
327 | "version: 0x%x\n", | 323 | "NVM version: 0x%x\n", eeprom_ver); |
328 | (priv->nvm_device_type == NVM_DEVICE_TYPE_OTP) | ||
329 | ? "OTP" : "EEPROM", eeprom_ver); | ||
330 | for (ofs = 0 ; ofs < eeprom_len ; ofs += 16) { | 324 | for (ofs = 0 ; ofs < eeprom_len ; ofs += 16) { |
331 | pos += scnprintf(buf + pos, buf_size - pos, "0x%.4x ", ofs); | 325 | pos += scnprintf(buf + pos, buf_size - pos, "0x%.4x ", ofs); |
332 | hex_dump_to_buffer(ptr + ofs, 16 , 16, 2, buf + pos, | 326 | hex_dump_to_buffer(ptr + ofs, 16 , 16, 2, buf + pos, |
@@ -351,9 +345,6 @@ static ssize_t iwl_dbgfs_channels_read(struct file *file, char __user *user_buf, | |||
351 | char *buf; | 345 | char *buf; |
352 | ssize_t ret; | 346 | ssize_t ret; |
353 | 347 | ||
354 | if (!test_bit(STATUS_GEO_CONFIGURED, &priv->status)) | ||
355 | return -EAGAIN; | ||
356 | |||
357 | buf = kzalloc(bufsz, GFP_KERNEL); | 348 | buf = kzalloc(bufsz, GFP_KERNEL); |
358 | if (!buf) | 349 | if (!buf) |
359 | return -ENOMEM; | 350 | return -ENOMEM; |
@@ -426,8 +417,6 @@ static ssize_t iwl_dbgfs_status_read(struct file *file, | |||
426 | test_bit(STATUS_ALIVE, &priv->status)); | 417 | test_bit(STATUS_ALIVE, &priv->status)); |
427 | pos += scnprintf(buf + pos, bufsz - pos, "STATUS_READY:\t\t %d\n", | 418 | pos += scnprintf(buf + pos, bufsz - pos, "STATUS_READY:\t\t %d\n", |
428 | test_bit(STATUS_READY, &priv->status)); | 419 | test_bit(STATUS_READY, &priv->status)); |
429 | pos += scnprintf(buf + pos, bufsz - pos, "STATUS_GEO_CONFIGURED:\t %d\n", | ||
430 | test_bit(STATUS_GEO_CONFIGURED, &priv->status)); | ||
431 | pos += scnprintf(buf + pos, bufsz - pos, "STATUS_EXIT_PENDING:\t %d\n", | 420 | pos += scnprintf(buf + pos, bufsz - pos, "STATUS_EXIT_PENDING:\t %d\n", |
432 | test_bit(STATUS_EXIT_PENDING, &priv->status)); | 421 | test_bit(STATUS_EXIT_PENDING, &priv->status)); |
433 | pos += scnprintf(buf + pos, bufsz - pos, "STATUS_STATISTICS:\t %d\n", | 422 | pos += scnprintf(buf + pos, bufsz - pos, "STATUS_STATISTICS:\t %d\n", |
@@ -1341,17 +1330,17 @@ static ssize_t iwl_dbgfs_ucode_tx_stats_read(struct file *file, | |||
1341 | if (tx->tx_power.ant_a || tx->tx_power.ant_b || tx->tx_power.ant_c) { | 1330 | if (tx->tx_power.ant_a || tx->tx_power.ant_b || tx->tx_power.ant_c) { |
1342 | pos += scnprintf(buf + pos, bufsz - pos, | 1331 | pos += scnprintf(buf + pos, bufsz - pos, |
1343 | "tx power: (1/2 dB step)\n"); | 1332 | "tx power: (1/2 dB step)\n"); |
1344 | if ((priv->hw_params.valid_tx_ant & ANT_A) && | 1333 | if ((priv->eeprom_data->valid_tx_ant & ANT_A) && |
1345 | tx->tx_power.ant_a) | 1334 | tx->tx_power.ant_a) |
1346 | pos += scnprintf(buf + pos, bufsz - pos, | 1335 | pos += scnprintf(buf + pos, bufsz - pos, |
1347 | fmt_hex, "antenna A:", | 1336 | fmt_hex, "antenna A:", |
1348 | tx->tx_power.ant_a); | 1337 | tx->tx_power.ant_a); |
1349 | if ((priv->hw_params.valid_tx_ant & ANT_B) && | 1338 | if ((priv->eeprom_data->valid_tx_ant & ANT_B) && |
1350 | tx->tx_power.ant_b) | 1339 | tx->tx_power.ant_b) |
1351 | pos += scnprintf(buf + pos, bufsz - pos, | 1340 | pos += scnprintf(buf + pos, bufsz - pos, |
1352 | fmt_hex, "antenna B:", | 1341 | fmt_hex, "antenna B:", |
1353 | tx->tx_power.ant_b); | 1342 | tx->tx_power.ant_b); |
1354 | if ((priv->hw_params.valid_tx_ant & ANT_C) && | 1343 | if ((priv->eeprom_data->valid_tx_ant & ANT_C) && |
1355 | tx->tx_power.ant_c) | 1344 | tx->tx_power.ant_c) |
1356 | pos += scnprintf(buf + pos, bufsz - pos, | 1345 | pos += scnprintf(buf + pos, bufsz - pos, |
1357 | fmt_hex, "antenna C:", | 1346 | fmt_hex, "antenna C:", |
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/dvm/dev.h index 70062379d0ec..89f2e1040e7f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/dvm/dev.h | |||
@@ -24,8 +24,8 @@ | |||
24 | * | 24 | * |
25 | *****************************************************************************/ | 25 | *****************************************************************************/ |
26 | /* | 26 | /* |
27 | * Please use this file (iwl-dev.h) for driver implementation definitions. | 27 | * Please use this file (dev.h) for driver implementation definitions. |
28 | * Please use iwl-commands.h for uCode API definitions. | 28 | * Please use commands.h for uCode API definitions. |
29 | */ | 29 | */ |
30 | 30 | ||
31 | #ifndef __iwl_dev_h__ | 31 | #ifndef __iwl_dev_h__ |
@@ -39,17 +39,18 @@ | |||
39 | #include <linux/mutex.h> | 39 | #include <linux/mutex.h> |
40 | 40 | ||
41 | #include "iwl-fw.h" | 41 | #include "iwl-fw.h" |
42 | #include "iwl-eeprom.h" | 42 | #include "iwl-eeprom-parse.h" |
43 | #include "iwl-csr.h" | 43 | #include "iwl-csr.h" |
44 | #include "iwl-debug.h" | 44 | #include "iwl-debug.h" |
45 | #include "iwl-agn-hw.h" | 45 | #include "iwl-agn-hw.h" |
46 | #include "iwl-led.h" | ||
47 | #include "iwl-power.h" | ||
48 | #include "iwl-agn-rs.h" | ||
49 | #include "iwl-agn-tt.h" | ||
50 | #include "iwl-trans.h" | ||
51 | #include "iwl-op-mode.h" | 46 | #include "iwl-op-mode.h" |
52 | #include "iwl-notif-wait.h" | 47 | #include "iwl-notif-wait.h" |
48 | #include "iwl-trans.h" | ||
49 | |||
50 | #include "led.h" | ||
51 | #include "power.h" | ||
52 | #include "rs.h" | ||
53 | #include "tt.h" | ||
53 | 54 | ||
54 | /* CT-KILL constants */ | 55 | /* CT-KILL constants */ |
55 | #define CT_KILL_THRESHOLD_LEGACY 110 /* in Celsius */ | 56 | #define CT_KILL_THRESHOLD_LEGACY 110 /* in Celsius */ |
@@ -88,33 +89,6 @@ | |||
88 | #define IWL_NUM_SCAN_RATES (2) | 89 | #define IWL_NUM_SCAN_RATES (2) |
89 | 90 | ||
90 | /* | 91 | /* |
91 | * One for each channel, holds all channel setup data | ||
92 | * Some of the fields (e.g. eeprom and flags/max_power_avg) are redundant | ||
93 | * with one another! | ||
94 | */ | ||
95 | struct iwl_channel_info { | ||
96 | struct iwl_eeprom_channel eeprom; /* EEPROM regulatory limit */ | ||
97 | struct iwl_eeprom_channel ht40_eeprom; /* EEPROM regulatory limit for | ||
98 | * HT40 channel */ | ||
99 | |||
100 | u8 channel; /* channel number */ | ||
101 | u8 flags; /* flags copied from EEPROM */ | ||
102 | s8 max_power_avg; /* (dBm) regul. eeprom, normal Tx, any rate */ | ||
103 | s8 curr_txpow; /* (dBm) regulatory/spectrum/user (not h/w) limit */ | ||
104 | s8 min_power; /* always 0 */ | ||
105 | s8 scan_power; /* (dBm) regul. eeprom, direct scans, any rate */ | ||
106 | |||
107 | u8 group_index; /* 0-4, maps channel to group1/2/3/4/5 */ | ||
108 | u8 band_index; /* 0-4, maps channel to band1/2/3/4/5 */ | ||
109 | enum ieee80211_band band; | ||
110 | |||
111 | /* HT40 channel info */ | ||
112 | s8 ht40_max_power_avg; /* (dBm) regul. eeprom, normal Tx, any rate */ | ||
113 | u8 ht40_flags; /* flags copied from EEPROM */ | ||
114 | u8 ht40_extension_channel; /* HT_IE_EXT_CHANNEL_* */ | ||
115 | }; | ||
116 | |||
117 | /* | ||
118 | * Minimum number of queues. MAX_NUM is defined in hw specific files. | 92 | * Minimum number of queues. MAX_NUM is defined in hw specific files. |
119 | * Set the minimum to accommodate | 93 | * Set the minimum to accommodate |
120 | * - 4 standard TX queues | 94 | * - 4 standard TX queues |
@@ -153,29 +127,6 @@ union iwl_ht_rate_supp { | |||
153 | }; | 127 | }; |
154 | }; | 128 | }; |
155 | 129 | ||
156 | #define CFG_HT_RX_AMPDU_FACTOR_8K (0x0) | ||
157 | #define CFG_HT_RX_AMPDU_FACTOR_16K (0x1) | ||
158 | #define CFG_HT_RX_AMPDU_FACTOR_32K (0x2) | ||
159 | #define CFG_HT_RX_AMPDU_FACTOR_64K (0x3) | ||
160 | #define CFG_HT_RX_AMPDU_FACTOR_DEF CFG_HT_RX_AMPDU_FACTOR_64K | ||
161 | #define CFG_HT_RX_AMPDU_FACTOR_MAX CFG_HT_RX_AMPDU_FACTOR_64K | ||
162 | #define CFG_HT_RX_AMPDU_FACTOR_MIN CFG_HT_RX_AMPDU_FACTOR_8K | ||
163 | |||
164 | /* | ||
165 | * Maximal MPDU density for TX aggregation | ||
166 | * 4 - 2us density | ||
167 | * 5 - 4us density | ||
168 | * 6 - 8us density | ||
169 | * 7 - 16us density | ||
170 | */ | ||
171 | #define CFG_HT_MPDU_DENSITY_2USEC (0x4) | ||
172 | #define CFG_HT_MPDU_DENSITY_4USEC (0x5) | ||
173 | #define CFG_HT_MPDU_DENSITY_8USEC (0x6) | ||
174 | #define CFG_HT_MPDU_DENSITY_16USEC (0x7) | ||
175 | #define CFG_HT_MPDU_DENSITY_DEF CFG_HT_MPDU_DENSITY_4USEC | ||
176 | #define CFG_HT_MPDU_DENSITY_MAX CFG_HT_MPDU_DENSITY_16USEC | ||
177 | #define CFG_HT_MPDU_DENSITY_MIN (0x1) | ||
178 | |||
179 | struct iwl_ht_config { | 130 | struct iwl_ht_config { |
180 | bool single_chain_sufficient; | 131 | bool single_chain_sufficient; |
181 | enum ieee80211_smps_mode smps; /* current smps mode */ | 132 | enum ieee80211_smps_mode smps; /* current smps mode */ |
@@ -445,23 +396,6 @@ enum { | |||
445 | MEASUREMENT_ACTIVE = (1 << 1), | 396 | MEASUREMENT_ACTIVE = (1 << 1), |
446 | }; | 397 | }; |
447 | 398 | ||
448 | enum iwl_nvm_type { | ||
449 | NVM_DEVICE_TYPE_EEPROM = 0, | ||
450 | NVM_DEVICE_TYPE_OTP, | ||
451 | }; | ||
452 | |||
453 | /* | ||
454 | * Two types of OTP memory access modes | ||
455 | * IWL_OTP_ACCESS_ABSOLUTE - absolute address mode, | ||
456 | * based on physical memory addressing | ||
457 | * IWL_OTP_ACCESS_RELATIVE - relative address mode, | ||
458 | * based on logical memory addressing | ||
459 | */ | ||
460 | enum iwl_access_mode { | ||
461 | IWL_OTP_ACCESS_ABSOLUTE, | ||
462 | IWL_OTP_ACCESS_RELATIVE, | ||
463 | }; | ||
464 | |||
465 | /* reply_tx_statistics (for _agn devices) */ | 399 | /* reply_tx_statistics (for _agn devices) */ |
466 | struct reply_tx_error_statistics { | 400 | struct reply_tx_error_statistics { |
467 | u32 pp_delay; | 401 | u32 pp_delay; |
@@ -632,9 +566,6 @@ enum iwl_scan_type { | |||
632 | * | 566 | * |
633 | * @tx_chains_num: Number of TX chains | 567 | * @tx_chains_num: Number of TX chains |
634 | * @rx_chains_num: Number of RX chains | 568 | * @rx_chains_num: Number of RX chains |
635 | * @valid_tx_ant: usable antennas for TX | ||
636 | * @valid_rx_ant: usable antennas for RX | ||
637 | * @ht40_channel: is 40MHz width possible: BIT(IEEE80211_BAND_XXX) | ||
638 | * @sku: sku read from EEPROM | 569 | * @sku: sku read from EEPROM |
639 | * @ct_kill_threshold: temperature threshold - in hw dependent unit | 570 | * @ct_kill_threshold: temperature threshold - in hw dependent unit |
640 | * @ct_kill_exit_threshold: when to reeable the device - in hw dependent unit | 571 | * @ct_kill_exit_threshold: when to reeable the device - in hw dependent unit |
@@ -645,9 +576,6 @@ enum iwl_scan_type { | |||
645 | struct iwl_hw_params { | 576 | struct iwl_hw_params { |
646 | u8 tx_chains_num; | 577 | u8 tx_chains_num; |
647 | u8 rx_chains_num; | 578 | u8 rx_chains_num; |
648 | u8 valid_tx_ant; | ||
649 | u8 valid_rx_ant; | ||
650 | u8 ht40_channel; | ||
651 | bool use_rts_for_aggregation; | 579 | bool use_rts_for_aggregation; |
652 | u16 sku; | 580 | u16 sku; |
653 | u32 ct_kill_threshold; | 581 | u32 ct_kill_threshold; |
@@ -664,9 +592,6 @@ struct iwl_lib_ops { | |||
664 | /* device specific configuration */ | 592 | /* device specific configuration */ |
665 | void (*nic_config)(struct iwl_priv *priv); | 593 | void (*nic_config)(struct iwl_priv *priv); |
666 | 594 | ||
667 | /* eeprom operations (as defined in iwl-eeprom.h) */ | ||
668 | struct iwl_eeprom_ops eeprom_ops; | ||
669 | |||
670 | /* temperature */ | 595 | /* temperature */ |
671 | void (*temperature)(struct iwl_priv *priv); | 596 | void (*temperature)(struct iwl_priv *priv); |
672 | }; | 597 | }; |
@@ -735,8 +660,6 @@ struct iwl_priv { | |||
735 | 660 | ||
736 | /* ieee device used by generic ieee processing code */ | 661 | /* ieee device used by generic ieee processing code */ |
737 | struct ieee80211_hw *hw; | 662 | struct ieee80211_hw *hw; |
738 | struct ieee80211_channel *ieee_channels; | ||
739 | struct ieee80211_rate *ieee_rates; | ||
740 | 663 | ||
741 | struct list_head calib_results; | 664 | struct list_head calib_results; |
742 | 665 | ||
@@ -755,8 +678,6 @@ struct iwl_priv { | |||
755 | 678 | ||
756 | struct iwl_notif_wait_data notif_wait; | 679 | struct iwl_notif_wait_data notif_wait; |
757 | 680 | ||
758 | struct ieee80211_supported_band bands[IEEE80211_NUM_BANDS]; | ||
759 | |||
760 | /* spectrum measurement report caching */ | 681 | /* spectrum measurement report caching */ |
761 | struct iwl_spectrum_notification measure_report; | 682 | struct iwl_spectrum_notification measure_report; |
762 | u8 measurement_status; | 683 | u8 measurement_status; |
@@ -787,11 +708,6 @@ struct iwl_priv { | |||
787 | bool ucode_loaded; | 708 | bool ucode_loaded; |
788 | bool init_ucode_run; /* Don't run init uCode again */ | 709 | bool init_ucode_run; /* Don't run init uCode again */ |
789 | 710 | ||
790 | /* we allocate array of iwl_channel_info for NIC's valid channels. | ||
791 | * Access via channel # using indirect index array */ | ||
792 | struct iwl_channel_info *channel_info; /* channel info array */ | ||
793 | u8 channel_count; /* # of channels */ | ||
794 | |||
795 | u8 plcp_delta_threshold; | 711 | u8 plcp_delta_threshold; |
796 | 712 | ||
797 | /* thermal calibration */ | 713 | /* thermal calibration */ |
@@ -846,6 +762,7 @@ struct iwl_priv { | |||
846 | struct iwl_station_entry stations[IWLAGN_STATION_COUNT]; | 762 | struct iwl_station_entry stations[IWLAGN_STATION_COUNT]; |
847 | unsigned long ucode_key_table; | 763 | unsigned long ucode_key_table; |
848 | struct iwl_tid_data tid_data[IWLAGN_STATION_COUNT][IWL_MAX_TID_COUNT]; | 764 | struct iwl_tid_data tid_data[IWLAGN_STATION_COUNT][IWL_MAX_TID_COUNT]; |
765 | atomic_t num_aux_in_flight; | ||
849 | 766 | ||
850 | u8 mac80211_registered; | 767 | u8 mac80211_registered; |
851 | 768 | ||
@@ -950,10 +867,8 @@ struct iwl_priv { | |||
950 | 867 | ||
951 | struct delayed_work scan_check; | 868 | struct delayed_work scan_check; |
952 | 869 | ||
953 | /* TX Power */ | 870 | /* TX Power settings */ |
954 | s8 tx_power_user_lmt; | 871 | s8 tx_power_user_lmt; |
955 | s8 tx_power_device_lmt; | ||
956 | s8 tx_power_lmt_in_half_dbm; /* max tx power in half-dBm format */ | ||
957 | s8 tx_power_next; | 872 | s8 tx_power_next; |
958 | 873 | ||
959 | #ifdef CONFIG_IWLWIFI_DEBUGFS | 874 | #ifdef CONFIG_IWLWIFI_DEBUGFS |
@@ -964,9 +879,10 @@ struct iwl_priv { | |||
964 | void *wowlan_sram; | 879 | void *wowlan_sram; |
965 | #endif /* CONFIG_IWLWIFI_DEBUGFS */ | 880 | #endif /* CONFIG_IWLWIFI_DEBUGFS */ |
966 | 881 | ||
967 | /* eeprom -- this is in the card's little endian byte order */ | 882 | struct iwl_eeprom_data *eeprom_data; |
968 | u8 *eeprom; | 883 | /* eeprom blob for debugfs/testmode */ |
969 | enum iwl_nvm_type nvm_device_type; | 884 | u8 *eeprom_blob; |
885 | size_t eeprom_blob_size; | ||
970 | 886 | ||
971 | struct work_struct txpower_work; | 887 | struct work_struct txpower_work; |
972 | u32 calib_disabled; | 888 | u32 calib_disabled; |
@@ -1001,8 +917,6 @@ struct iwl_priv { | |||
1001 | enum iwl_ucode_type cur_ucode; | 917 | enum iwl_ucode_type cur_ucode; |
1002 | }; /*iwl_priv */ | 918 | }; /*iwl_priv */ |
1003 | 919 | ||
1004 | extern struct kmem_cache *iwl_tx_cmd_pool; | ||
1005 | |||
1006 | static inline struct iwl_rxon_context * | 920 | static inline struct iwl_rxon_context * |
1007 | iwl_rxon_ctx_from_vif(struct ieee80211_vif *vif) | 921 | iwl_rxon_ctx_from_vif(struct ieee80211_vif *vif) |
1008 | { | 922 | { |
@@ -1036,36 +950,4 @@ static inline int iwl_is_any_associated(struct iwl_priv *priv) | |||
1036 | return false; | 950 | return false; |
1037 | } | 951 | } |
1038 | 952 | ||
1039 | static inline int is_channel_valid(const struct iwl_channel_info *ch_info) | ||
1040 | { | ||
1041 | if (ch_info == NULL) | ||
1042 | return 0; | ||
1043 | return (ch_info->flags & EEPROM_CHANNEL_VALID) ? 1 : 0; | ||
1044 | } | ||
1045 | |||
1046 | static inline int is_channel_radar(const struct iwl_channel_info *ch_info) | ||
1047 | { | ||
1048 | return (ch_info->flags & EEPROM_CHANNEL_RADAR) ? 1 : 0; | ||
1049 | } | ||
1050 | |||
1051 | static inline u8 is_channel_a_band(const struct iwl_channel_info *ch_info) | ||
1052 | { | ||
1053 | return ch_info->band == IEEE80211_BAND_5GHZ; | ||
1054 | } | ||
1055 | |||
1056 | static inline u8 is_channel_bg_band(const struct iwl_channel_info *ch_info) | ||
1057 | { | ||
1058 | return ch_info->band == IEEE80211_BAND_2GHZ; | ||
1059 | } | ||
1060 | |||
1061 | static inline int is_channel_passive(const struct iwl_channel_info *ch) | ||
1062 | { | ||
1063 | return (!(ch->flags & EEPROM_CHANNEL_ACTIVE)) ? 1 : 0; | ||
1064 | } | ||
1065 | |||
1066 | static inline int is_channel_ibss(const struct iwl_channel_info *ch) | ||
1067 | { | ||
1068 | return ((ch->flags & EEPROM_CHANNEL_IBSS)) ? 1 : 0; | ||
1069 | } | ||
1070 | |||
1071 | #endif /* __iwl_dev_h__ */ | 953 | #endif /* __iwl_dev_h__ */ |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-devices.c b/drivers/net/wireless/iwlwifi/dvm/devices.c index 48533b3a0f9a..0521a6be09d2 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-devices.c +++ b/drivers/net/wireless/iwlwifi/dvm/devices.c | |||
@@ -27,11 +27,14 @@ | |||
27 | /* | 27 | /* |
28 | * DVM device-specific data & functions | 28 | * DVM device-specific data & functions |
29 | */ | 29 | */ |
30 | #include "iwl-agn.h" | ||
31 | #include "iwl-dev.h" | ||
32 | #include "iwl-commands.h" | ||
33 | #include "iwl-io.h" | 30 | #include "iwl-io.h" |
34 | #include "iwl-prph.h" | 31 | #include "iwl-prph.h" |
32 | #include "iwl-eeprom-parse.h" | ||
33 | |||
34 | #include "agn.h" | ||
35 | #include "dev.h" | ||
36 | #include "commands.h" | ||
37 | |||
35 | 38 | ||
36 | /* | 39 | /* |
37 | * 1000 series | 40 | * 1000 series |
@@ -58,11 +61,6 @@ static void iwl1000_set_ct_threshold(struct iwl_priv *priv) | |||
58 | /* NIC configuration for 1000 series */ | 61 | /* NIC configuration for 1000 series */ |
59 | static void iwl1000_nic_config(struct iwl_priv *priv) | 62 | static void iwl1000_nic_config(struct iwl_priv *priv) |
60 | { | 63 | { |
61 | /* set CSR_HW_CONFIG_REG for uCode use */ | ||
62 | iwl_set_bit(priv->trans, CSR_HW_IF_CONFIG_REG, | ||
63 | CSR_HW_IF_CONFIG_REG_BIT_RADIO_SI | | ||
64 | CSR_HW_IF_CONFIG_REG_BIT_MAC_SI); | ||
65 | |||
66 | /* Setting digital SVR for 1000 card to 1.32V */ | 64 | /* Setting digital SVR for 1000 card to 1.32V */ |
67 | /* locking is acquired in iwl_set_bits_mask_prph() function */ | 65 | /* locking is acquired in iwl_set_bits_mask_prph() function */ |
68 | iwl_set_bits_mask_prph(priv->trans, APMG_DIGITAL_SVR_REG, | 66 | iwl_set_bits_mask_prph(priv->trans, APMG_DIGITAL_SVR_REG, |
@@ -170,16 +168,6 @@ static const struct iwl_sensitivity_ranges iwl1000_sensitivity = { | |||
170 | 168 | ||
171 | static void iwl1000_hw_set_hw_params(struct iwl_priv *priv) | 169 | static void iwl1000_hw_set_hw_params(struct iwl_priv *priv) |
172 | { | 170 | { |
173 | priv->hw_params.ht40_channel = BIT(IEEE80211_BAND_2GHZ); | ||
174 | |||
175 | priv->hw_params.tx_chains_num = | ||
176 | num_of_ant(priv->hw_params.valid_tx_ant); | ||
177 | if (priv->cfg->rx_with_siso_diversity) | ||
178 | priv->hw_params.rx_chains_num = 1; | ||
179 | else | ||
180 | priv->hw_params.rx_chains_num = | ||
181 | num_of_ant(priv->hw_params.valid_rx_ant); | ||
182 | |||
183 | iwl1000_set_ct_threshold(priv); | 171 | iwl1000_set_ct_threshold(priv); |
184 | 172 | ||
185 | /* Set initial sensitivity parameters */ | 173 | /* Set initial sensitivity parameters */ |
@@ -189,17 +177,6 @@ static void iwl1000_hw_set_hw_params(struct iwl_priv *priv) | |||
189 | struct iwl_lib_ops iwl1000_lib = { | 177 | struct iwl_lib_ops iwl1000_lib = { |
190 | .set_hw_params = iwl1000_hw_set_hw_params, | 178 | .set_hw_params = iwl1000_hw_set_hw_params, |
191 | .nic_config = iwl1000_nic_config, | 179 | .nic_config = iwl1000_nic_config, |
192 | .eeprom_ops = { | ||
193 | .regulatory_bands = { | ||
194 | EEPROM_REG_BAND_1_CHANNELS, | ||
195 | EEPROM_REG_BAND_2_CHANNELS, | ||
196 | EEPROM_REG_BAND_3_CHANNELS, | ||
197 | EEPROM_REG_BAND_4_CHANNELS, | ||
198 | EEPROM_REG_BAND_5_CHANNELS, | ||
199 | EEPROM_REG_BAND_24_HT40_CHANNELS, | ||
200 | EEPROM_REGULATORY_BAND_NO_HT40, | ||
201 | }, | ||
202 | }, | ||
203 | .temperature = iwlagn_temperature, | 180 | .temperature = iwlagn_temperature, |
204 | }; | 181 | }; |
205 | 182 | ||
@@ -219,8 +196,6 @@ static void iwl2000_set_ct_threshold(struct iwl_priv *priv) | |||
219 | /* NIC configuration for 2000 series */ | 196 | /* NIC configuration for 2000 series */ |
220 | static void iwl2000_nic_config(struct iwl_priv *priv) | 197 | static void iwl2000_nic_config(struct iwl_priv *priv) |
221 | { | 198 | { |
222 | iwl_rf_config(priv); | ||
223 | |||
224 | iwl_set_bit(priv->trans, CSR_GP_DRIVER_REG, | 199 | iwl_set_bit(priv->trans, CSR_GP_DRIVER_REG, |
225 | CSR_GP_DRIVER_REG_BIT_RADIO_IQ_INVER); | 200 | CSR_GP_DRIVER_REG_BIT_RADIO_IQ_INVER); |
226 | } | 201 | } |
@@ -251,16 +226,6 @@ static const struct iwl_sensitivity_ranges iwl2000_sensitivity = { | |||
251 | 226 | ||
252 | static void iwl2000_hw_set_hw_params(struct iwl_priv *priv) | 227 | static void iwl2000_hw_set_hw_params(struct iwl_priv *priv) |
253 | { | 228 | { |
254 | priv->hw_params.ht40_channel = BIT(IEEE80211_BAND_2GHZ); | ||
255 | |||
256 | priv->hw_params.tx_chains_num = | ||
257 | num_of_ant(priv->hw_params.valid_tx_ant); | ||
258 | if (priv->cfg->rx_with_siso_diversity) | ||
259 | priv->hw_params.rx_chains_num = 1; | ||
260 | else | ||
261 | priv->hw_params.rx_chains_num = | ||
262 | num_of_ant(priv->hw_params.valid_rx_ant); | ||
263 | |||
264 | iwl2000_set_ct_threshold(priv); | 229 | iwl2000_set_ct_threshold(priv); |
265 | 230 | ||
266 | /* Set initial sensitivity parameters */ | 231 | /* Set initial sensitivity parameters */ |
@@ -270,36 +235,12 @@ static void iwl2000_hw_set_hw_params(struct iwl_priv *priv) | |||
270 | struct iwl_lib_ops iwl2000_lib = { | 235 | struct iwl_lib_ops iwl2000_lib = { |
271 | .set_hw_params = iwl2000_hw_set_hw_params, | 236 | .set_hw_params = iwl2000_hw_set_hw_params, |
272 | .nic_config = iwl2000_nic_config, | 237 | .nic_config = iwl2000_nic_config, |
273 | .eeprom_ops = { | ||
274 | .regulatory_bands = { | ||
275 | EEPROM_REG_BAND_1_CHANNELS, | ||
276 | EEPROM_REG_BAND_2_CHANNELS, | ||
277 | EEPROM_REG_BAND_3_CHANNELS, | ||
278 | EEPROM_REG_BAND_4_CHANNELS, | ||
279 | EEPROM_REG_BAND_5_CHANNELS, | ||
280 | EEPROM_6000_REG_BAND_24_HT40_CHANNELS, | ||
281 | EEPROM_REGULATORY_BAND_NO_HT40, | ||
282 | }, | ||
283 | .enhanced_txpower = true, | ||
284 | }, | ||
285 | .temperature = iwlagn_temperature, | 238 | .temperature = iwlagn_temperature, |
286 | }; | 239 | }; |
287 | 240 | ||
288 | struct iwl_lib_ops iwl2030_lib = { | 241 | struct iwl_lib_ops iwl2030_lib = { |
289 | .set_hw_params = iwl2000_hw_set_hw_params, | 242 | .set_hw_params = iwl2000_hw_set_hw_params, |
290 | .nic_config = iwl2000_nic_config, | 243 | .nic_config = iwl2000_nic_config, |
291 | .eeprom_ops = { | ||
292 | .regulatory_bands = { | ||
293 | EEPROM_REG_BAND_1_CHANNELS, | ||
294 | EEPROM_REG_BAND_2_CHANNELS, | ||
295 | EEPROM_REG_BAND_3_CHANNELS, | ||
296 | EEPROM_REG_BAND_4_CHANNELS, | ||
297 | EEPROM_REG_BAND_5_CHANNELS, | ||
298 | EEPROM_6000_REG_BAND_24_HT40_CHANNELS, | ||
299 | EEPROM_REGULATORY_BAND_NO_HT40, | ||
300 | }, | ||
301 | .enhanced_txpower = true, | ||
302 | }, | ||
303 | .temperature = iwlagn_temperature, | 244 | .temperature = iwlagn_temperature, |
304 | }; | 245 | }; |
305 | 246 | ||
@@ -311,8 +252,6 @@ struct iwl_lib_ops iwl2030_lib = { | |||
311 | /* NIC configuration for 5000 series */ | 252 | /* NIC configuration for 5000 series */ |
312 | static void iwl5000_nic_config(struct iwl_priv *priv) | 253 | static void iwl5000_nic_config(struct iwl_priv *priv) |
313 | { | 254 | { |
314 | iwl_rf_config(priv); | ||
315 | |||
316 | /* W/A : NIC is stuck in a reset state after Early PCIe power off | 255 | /* W/A : NIC is stuck in a reset state after Early PCIe power off |
317 | * (PCIe power is lost before PERST# is asserted), | 256 | * (PCIe power is lost before PERST# is asserted), |
318 | * causing ME FW to lose ownership and not being able to obtain it back. | 257 | * causing ME FW to lose ownership and not being able to obtain it back. |
@@ -376,11 +315,9 @@ static struct iwl_sensitivity_ranges iwl5150_sensitivity = { | |||
376 | static s32 iwl_temp_calib_to_offset(struct iwl_priv *priv) | 315 | static s32 iwl_temp_calib_to_offset(struct iwl_priv *priv) |
377 | { | 316 | { |
378 | u16 temperature, voltage; | 317 | u16 temperature, voltage; |
379 | __le16 *temp_calib = (__le16 *)iwl_eeprom_query_addr(priv, | ||
380 | EEPROM_KELVIN_TEMPERATURE); | ||
381 | 318 | ||
382 | temperature = le16_to_cpu(temp_calib[0]); | 319 | temperature = le16_to_cpu(priv->eeprom_data->kelvin_temperature); |
383 | voltage = le16_to_cpu(temp_calib[1]); | 320 | voltage = le16_to_cpu(priv->eeprom_data->kelvin_voltage); |
384 | 321 | ||
385 | /* offset = temp - volt / coeff */ | 322 | /* offset = temp - volt / coeff */ |
386 | return (s32)(temperature - | 323 | return (s32)(temperature - |
@@ -404,14 +341,6 @@ static void iwl5000_set_ct_threshold(struct iwl_priv *priv) | |||
404 | 341 | ||
405 | static void iwl5000_hw_set_hw_params(struct iwl_priv *priv) | 342 | static void iwl5000_hw_set_hw_params(struct iwl_priv *priv) |
406 | { | 343 | { |
407 | priv->hw_params.ht40_channel = BIT(IEEE80211_BAND_2GHZ) | | ||
408 | BIT(IEEE80211_BAND_5GHZ); | ||
409 | |||
410 | priv->hw_params.tx_chains_num = | ||
411 | num_of_ant(priv->hw_params.valid_tx_ant); | ||
412 | priv->hw_params.rx_chains_num = | ||
413 | num_of_ant(priv->hw_params.valid_rx_ant); | ||
414 | |||
415 | iwl5000_set_ct_threshold(priv); | 344 | iwl5000_set_ct_threshold(priv); |
416 | 345 | ||
417 | /* Set initial sensitivity parameters */ | 346 | /* Set initial sensitivity parameters */ |
@@ -420,14 +349,6 @@ static void iwl5000_hw_set_hw_params(struct iwl_priv *priv) | |||
420 | 349 | ||
421 | static void iwl5150_hw_set_hw_params(struct iwl_priv *priv) | 350 | static void iwl5150_hw_set_hw_params(struct iwl_priv *priv) |
422 | { | 351 | { |
423 | priv->hw_params.ht40_channel = BIT(IEEE80211_BAND_2GHZ) | | ||
424 | BIT(IEEE80211_BAND_5GHZ); | ||
425 | |||
426 | priv->hw_params.tx_chains_num = | ||
427 | num_of_ant(priv->hw_params.valid_tx_ant); | ||
428 | priv->hw_params.rx_chains_num = | ||
429 | num_of_ant(priv->hw_params.valid_rx_ant); | ||
430 | |||
431 | iwl5150_set_ct_threshold(priv); | 352 | iwl5150_set_ct_threshold(priv); |
432 | 353 | ||
433 | /* Set initial sensitivity parameters */ | 354 | /* Set initial sensitivity parameters */ |
@@ -455,7 +376,6 @@ static int iwl5000_hw_channel_switch(struct iwl_priv *priv, | |||
455 | */ | 376 | */ |
456 | struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; | 377 | struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; |
457 | struct iwl5000_channel_switch_cmd cmd; | 378 | struct iwl5000_channel_switch_cmd cmd; |
458 | const struct iwl_channel_info *ch_info; | ||
459 | u32 switch_time_in_usec, ucode_switch_time; | 379 | u32 switch_time_in_usec, ucode_switch_time; |
460 | u16 ch; | 380 | u16 ch; |
461 | u32 tsf_low; | 381 | u32 tsf_low; |
@@ -505,14 +425,7 @@ static int iwl5000_hw_channel_switch(struct iwl_priv *priv, | |||
505 | } | 425 | } |
506 | IWL_DEBUG_11H(priv, "uCode time for the switch is 0x%x\n", | 426 | IWL_DEBUG_11H(priv, "uCode time for the switch is 0x%x\n", |
507 | cmd.switch_time); | 427 | cmd.switch_time); |
508 | ch_info = iwl_get_channel_info(priv, priv->band, ch); | 428 | cmd.expect_beacon = ch_switch->channel->flags & IEEE80211_CHAN_RADAR; |
509 | if (ch_info) | ||
510 | cmd.expect_beacon = is_channel_radar(ch_info); | ||
511 | else { | ||
512 | IWL_ERR(priv, "invalid channel switch from %u to %u\n", | ||
513 | ctx->active.channel, ch); | ||
514 | return -EFAULT; | ||
515 | } | ||
516 | 429 | ||
517 | return iwl_dvm_send_cmd(priv, &hcmd); | 430 | return iwl_dvm_send_cmd(priv, &hcmd); |
518 | } | 431 | } |
@@ -521,17 +434,6 @@ struct iwl_lib_ops iwl5000_lib = { | |||
521 | .set_hw_params = iwl5000_hw_set_hw_params, | 434 | .set_hw_params = iwl5000_hw_set_hw_params, |
522 | .set_channel_switch = iwl5000_hw_channel_switch, | 435 | .set_channel_switch = iwl5000_hw_channel_switch, |
523 | .nic_config = iwl5000_nic_config, | 436 | .nic_config = iwl5000_nic_config, |
524 | .eeprom_ops = { | ||
525 | .regulatory_bands = { | ||
526 | EEPROM_REG_BAND_1_CHANNELS, | ||
527 | EEPROM_REG_BAND_2_CHANNELS, | ||
528 | EEPROM_REG_BAND_3_CHANNELS, | ||
529 | EEPROM_REG_BAND_4_CHANNELS, | ||
530 | EEPROM_REG_BAND_5_CHANNELS, | ||
531 | EEPROM_REG_BAND_24_HT40_CHANNELS, | ||
532 | EEPROM_REG_BAND_52_HT40_CHANNELS | ||
533 | }, | ||
534 | }, | ||
535 | .temperature = iwlagn_temperature, | 437 | .temperature = iwlagn_temperature, |
536 | }; | 438 | }; |
537 | 439 | ||
@@ -539,17 +441,6 @@ struct iwl_lib_ops iwl5150_lib = { | |||
539 | .set_hw_params = iwl5150_hw_set_hw_params, | 441 | .set_hw_params = iwl5150_hw_set_hw_params, |
540 | .set_channel_switch = iwl5000_hw_channel_switch, | 442 | .set_channel_switch = iwl5000_hw_channel_switch, |
541 | .nic_config = iwl5000_nic_config, | 443 | .nic_config = iwl5000_nic_config, |
542 | .eeprom_ops = { | ||
543 | .regulatory_bands = { | ||
544 | EEPROM_REG_BAND_1_CHANNELS, | ||
545 | EEPROM_REG_BAND_2_CHANNELS, | ||
546 | EEPROM_REG_BAND_3_CHANNELS, | ||
547 | EEPROM_REG_BAND_4_CHANNELS, | ||
548 | EEPROM_REG_BAND_5_CHANNELS, | ||
549 | EEPROM_REG_BAND_24_HT40_CHANNELS, | ||
550 | EEPROM_REG_BAND_52_HT40_CHANNELS | ||
551 | }, | ||
552 | }, | ||
553 | .temperature = iwl5150_temperature, | 444 | .temperature = iwl5150_temperature, |
554 | }; | 445 | }; |
555 | 446 | ||
@@ -570,8 +461,6 @@ static void iwl6000_set_ct_threshold(struct iwl_priv *priv) | |||
570 | /* NIC configuration for 6000 series */ | 461 | /* NIC configuration for 6000 series */ |
571 | static void iwl6000_nic_config(struct iwl_priv *priv) | 462 | static void iwl6000_nic_config(struct iwl_priv *priv) |
572 | { | 463 | { |
573 | iwl_rf_config(priv); | ||
574 | |||
575 | switch (priv->cfg->device_family) { | 464 | switch (priv->cfg->device_family) { |
576 | case IWL_DEVICE_FAMILY_6005: | 465 | case IWL_DEVICE_FAMILY_6005: |
577 | case IWL_DEVICE_FAMILY_6030: | 466 | case IWL_DEVICE_FAMILY_6030: |
@@ -584,13 +473,13 @@ static void iwl6000_nic_config(struct iwl_priv *priv) | |||
584 | break; | 473 | break; |
585 | case IWL_DEVICE_FAMILY_6050: | 474 | case IWL_DEVICE_FAMILY_6050: |
586 | /* Indicate calibration version to uCode. */ | 475 | /* Indicate calibration version to uCode. */ |
587 | if (iwl_eeprom_calib_version(priv) >= 6) | 476 | if (priv->eeprom_data->calib_version >= 6) |
588 | iwl_set_bit(priv->trans, CSR_GP_DRIVER_REG, | 477 | iwl_set_bit(priv->trans, CSR_GP_DRIVER_REG, |
589 | CSR_GP_DRIVER_REG_BIT_CALIB_VERSION6); | 478 | CSR_GP_DRIVER_REG_BIT_CALIB_VERSION6); |
590 | break; | 479 | break; |
591 | case IWL_DEVICE_FAMILY_6150: | 480 | case IWL_DEVICE_FAMILY_6150: |
592 | /* Indicate calibration version to uCode. */ | 481 | /* Indicate calibration version to uCode. */ |
593 | if (iwl_eeprom_calib_version(priv) >= 6) | 482 | if (priv->eeprom_data->calib_version >= 6) |
594 | iwl_set_bit(priv->trans, CSR_GP_DRIVER_REG, | 483 | iwl_set_bit(priv->trans, CSR_GP_DRIVER_REG, |
595 | CSR_GP_DRIVER_REG_BIT_CALIB_VERSION6); | 484 | CSR_GP_DRIVER_REG_BIT_CALIB_VERSION6); |
596 | iwl_set_bit(priv->trans, CSR_GP_DRIVER_REG, | 485 | iwl_set_bit(priv->trans, CSR_GP_DRIVER_REG, |
@@ -627,17 +516,6 @@ static const struct iwl_sensitivity_ranges iwl6000_sensitivity = { | |||
627 | 516 | ||
628 | static void iwl6000_hw_set_hw_params(struct iwl_priv *priv) | 517 | static void iwl6000_hw_set_hw_params(struct iwl_priv *priv) |
629 | { | 518 | { |
630 | priv->hw_params.ht40_channel = BIT(IEEE80211_BAND_2GHZ) | | ||
631 | BIT(IEEE80211_BAND_5GHZ); | ||
632 | |||
633 | priv->hw_params.tx_chains_num = | ||
634 | num_of_ant(priv->hw_params.valid_tx_ant); | ||
635 | if (priv->cfg->rx_with_siso_diversity) | ||
636 | priv->hw_params.rx_chains_num = 1; | ||
637 | else | ||
638 | priv->hw_params.rx_chains_num = | ||
639 | num_of_ant(priv->hw_params.valid_rx_ant); | ||
640 | |||
641 | iwl6000_set_ct_threshold(priv); | 519 | iwl6000_set_ct_threshold(priv); |
642 | 520 | ||
643 | /* Set initial sensitivity parameters */ | 521 | /* Set initial sensitivity parameters */ |
@@ -654,7 +532,6 @@ static int iwl6000_hw_channel_switch(struct iwl_priv *priv, | |||
654 | */ | 532 | */ |
655 | struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; | 533 | struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; |
656 | struct iwl6000_channel_switch_cmd cmd; | 534 | struct iwl6000_channel_switch_cmd cmd; |
657 | const struct iwl_channel_info *ch_info; | ||
658 | u32 switch_time_in_usec, ucode_switch_time; | 535 | u32 switch_time_in_usec, ucode_switch_time; |
659 | u16 ch; | 536 | u16 ch; |
660 | u32 tsf_low; | 537 | u32 tsf_low; |
@@ -704,14 +581,7 @@ static int iwl6000_hw_channel_switch(struct iwl_priv *priv, | |||
704 | } | 581 | } |
705 | IWL_DEBUG_11H(priv, "uCode time for the switch is 0x%x\n", | 582 | IWL_DEBUG_11H(priv, "uCode time for the switch is 0x%x\n", |
706 | cmd.switch_time); | 583 | cmd.switch_time); |
707 | ch_info = iwl_get_channel_info(priv, priv->band, ch); | 584 | cmd.expect_beacon = ch_switch->channel->flags & IEEE80211_CHAN_RADAR; |
708 | if (ch_info) | ||
709 | cmd.expect_beacon = is_channel_radar(ch_info); | ||
710 | else { | ||
711 | IWL_ERR(priv, "invalid channel switch from %u to %u\n", | ||
712 | ctx->active.channel, ch); | ||
713 | return -EFAULT; | ||
714 | } | ||
715 | 585 | ||
716 | return iwl_dvm_send_cmd(priv, &hcmd); | 586 | return iwl_dvm_send_cmd(priv, &hcmd); |
717 | } | 587 | } |
@@ -720,18 +590,6 @@ struct iwl_lib_ops iwl6000_lib = { | |||
720 | .set_hw_params = iwl6000_hw_set_hw_params, | 590 | .set_hw_params = iwl6000_hw_set_hw_params, |
721 | .set_channel_switch = iwl6000_hw_channel_switch, | 591 | .set_channel_switch = iwl6000_hw_channel_switch, |
722 | .nic_config = iwl6000_nic_config, | 592 | .nic_config = iwl6000_nic_config, |
723 | .eeprom_ops = { | ||
724 | .regulatory_bands = { | ||
725 | EEPROM_REG_BAND_1_CHANNELS, | ||
726 | EEPROM_REG_BAND_2_CHANNELS, | ||
727 | EEPROM_REG_BAND_3_CHANNELS, | ||
728 | EEPROM_REG_BAND_4_CHANNELS, | ||
729 | EEPROM_REG_BAND_5_CHANNELS, | ||
730 | EEPROM_6000_REG_BAND_24_HT40_CHANNELS, | ||
731 | EEPROM_REG_BAND_52_HT40_CHANNELS | ||
732 | }, | ||
733 | .enhanced_txpower = true, | ||
734 | }, | ||
735 | .temperature = iwlagn_temperature, | 593 | .temperature = iwlagn_temperature, |
736 | }; | 594 | }; |
737 | 595 | ||
@@ -739,17 +597,5 @@ struct iwl_lib_ops iwl6030_lib = { | |||
739 | .set_hw_params = iwl6000_hw_set_hw_params, | 597 | .set_hw_params = iwl6000_hw_set_hw_params, |
740 | .set_channel_switch = iwl6000_hw_channel_switch, | 598 | .set_channel_switch = iwl6000_hw_channel_switch, |
741 | .nic_config = iwl6000_nic_config, | 599 | .nic_config = iwl6000_nic_config, |
742 | .eeprom_ops = { | ||
743 | .regulatory_bands = { | ||
744 | EEPROM_REG_BAND_1_CHANNELS, | ||
745 | EEPROM_REG_BAND_2_CHANNELS, | ||
746 | EEPROM_REG_BAND_3_CHANNELS, | ||
747 | EEPROM_REG_BAND_4_CHANNELS, | ||
748 | EEPROM_REG_BAND_5_CHANNELS, | ||
749 | EEPROM_6000_REG_BAND_24_HT40_CHANNELS, | ||
750 | EEPROM_REG_BAND_52_HT40_CHANNELS | ||
751 | }, | ||
752 | .enhanced_txpower = true, | ||
753 | }, | ||
754 | .temperature = iwlagn_temperature, | 600 | .temperature = iwlagn_temperature, |
755 | }; | 601 | }; |
diff --git a/drivers/net/wireless/iwlwifi/iwl-led.c b/drivers/net/wireless/iwlwifi/dvm/led.c index 47000419f916..bf479f709091 100644 --- a/drivers/net/wireless/iwlwifi/iwl-led.c +++ b/drivers/net/wireless/iwlwifi/dvm/led.c | |||
@@ -34,12 +34,11 @@ | |||
34 | #include <net/mac80211.h> | 34 | #include <net/mac80211.h> |
35 | #include <linux/etherdevice.h> | 35 | #include <linux/etherdevice.h> |
36 | #include <asm/unaligned.h> | 36 | #include <asm/unaligned.h> |
37 | |||
38 | #include "iwl-dev.h" | ||
39 | #include "iwl-agn.h" | ||
40 | #include "iwl-io.h" | 37 | #include "iwl-io.h" |
41 | #include "iwl-trans.h" | 38 | #include "iwl-trans.h" |
42 | #include "iwl-modparams.h" | 39 | #include "iwl-modparams.h" |
40 | #include "dev.h" | ||
41 | #include "agn.h" | ||
43 | 42 | ||
44 | /* Throughput OFF time(ms) ON time (ms) | 43 | /* Throughput OFF time(ms) ON time (ms) |
45 | * >300 25 25 | 44 | * >300 25 25 |
diff --git a/drivers/net/wireless/iwlwifi/iwl-led.h b/drivers/net/wireless/iwlwifi/dvm/led.h index b02a853103d3..b02a853103d3 100644 --- a/drivers/net/wireless/iwlwifi/iwl-led.h +++ b/drivers/net/wireless/iwlwifi/dvm/led.h | |||
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/dvm/lib.c index e55ec6c8a920..cb1ca7a25dd5 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c +++ b/drivers/net/wireless/iwlwifi/dvm/lib.c | |||
@@ -33,13 +33,14 @@ | |||
33 | #include <linux/sched.h> | 33 | #include <linux/sched.h> |
34 | #include <net/mac80211.h> | 34 | #include <net/mac80211.h> |
35 | 35 | ||
36 | #include "iwl-dev.h" | ||
37 | #include "iwl-io.h" | 36 | #include "iwl-io.h" |
38 | #include "iwl-agn-hw.h" | 37 | #include "iwl-agn-hw.h" |
39 | #include "iwl-agn.h" | ||
40 | #include "iwl-trans.h" | 38 | #include "iwl-trans.h" |
41 | #include "iwl-modparams.h" | 39 | #include "iwl-modparams.h" |
42 | 40 | ||
41 | #include "dev.h" | ||
42 | #include "agn.h" | ||
43 | |||
43 | int iwlagn_hw_valid_rtc_data_addr(u32 addr) | 44 | int iwlagn_hw_valid_rtc_data_addr(u32 addr) |
44 | { | 45 | { |
45 | return (addr >= IWLAGN_RTC_DATA_LOWER_BOUND) && | 46 | return (addr >= IWLAGN_RTC_DATA_LOWER_BOUND) && |
@@ -58,8 +59,7 @@ int iwlagn_send_tx_power(struct iwl_priv *priv) | |||
58 | /* half dBm need to multiply */ | 59 | /* half dBm need to multiply */ |
59 | tx_power_cmd.global_lmt = (s8)(2 * priv->tx_power_user_lmt); | 60 | tx_power_cmd.global_lmt = (s8)(2 * priv->tx_power_user_lmt); |
60 | 61 | ||
61 | if (priv->tx_power_lmt_in_half_dbm && | 62 | if (tx_power_cmd.global_lmt > priv->eeprom_data->max_tx_pwr_half_dbm) { |
62 | priv->tx_power_lmt_in_half_dbm < tx_power_cmd.global_lmt) { | ||
63 | /* | 63 | /* |
64 | * For the newer devices which using enhanced/extend tx power | 64 | * For the newer devices which using enhanced/extend tx power |
65 | * table in EEPROM, the format is in half dBm. driver need to | 65 | * table in EEPROM, the format is in half dBm. driver need to |
@@ -71,7 +71,8 @@ int iwlagn_send_tx_power(struct iwl_priv *priv) | |||
71 | * "tx_power_user_lmt" is higher than EEPROM value (in | 71 | * "tx_power_user_lmt" is higher than EEPROM value (in |
72 | * half-dBm format), lower the tx power based on EEPROM | 72 | * half-dBm format), lower the tx power based on EEPROM |
73 | */ | 73 | */ |
74 | tx_power_cmd.global_lmt = priv->tx_power_lmt_in_half_dbm; | 74 | tx_power_cmd.global_lmt = |
75 | priv->eeprom_data->max_tx_pwr_half_dbm; | ||
75 | } | 76 | } |
76 | tx_power_cmd.flags = IWLAGN_TX_POWER_NO_CLOSED; | 77 | tx_power_cmd.flags = IWLAGN_TX_POWER_NO_CLOSED; |
77 | tx_power_cmd.srv_chan_lmt = IWLAGN_TX_POWER_AUTO; | 78 | tx_power_cmd.srv_chan_lmt = IWLAGN_TX_POWER_AUTO; |
@@ -617,6 +618,11 @@ static bool iwlagn_fill_txpower_mode(struct iwl_priv *priv, | |||
617 | struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; | 618 | struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; |
618 | int ave_rssi; | 619 | int ave_rssi; |
619 | 620 | ||
621 | if (!ctx->vif || (ctx->vif->type != NL80211_IFTYPE_STATION)) { | ||
622 | IWL_DEBUG_INFO(priv, "BSS ctx not active or not in sta mode\n"); | ||
623 | return false; | ||
624 | } | ||
625 | |||
620 | ave_rssi = ieee80211_ave_rssi(ctx->vif); | 626 | ave_rssi = ieee80211_ave_rssi(ctx->vif); |
621 | if (!ave_rssi) { | 627 | if (!ave_rssi) { |
622 | /* no rssi data, no changes to reduce tx power */ | 628 | /* no rssi data, no changes to reduce tx power */ |
@@ -818,7 +824,7 @@ void iwlagn_set_rxon_chain(struct iwl_priv *priv, struct iwl_rxon_context *ctx) | |||
818 | if (priv->chain_noise_data.active_chains) | 824 | if (priv->chain_noise_data.active_chains) |
819 | active_chains = priv->chain_noise_data.active_chains; | 825 | active_chains = priv->chain_noise_data.active_chains; |
820 | else | 826 | else |
821 | active_chains = priv->hw_params.valid_rx_ant; | 827 | active_chains = priv->eeprom_data->valid_rx_ant; |
822 | 828 | ||
823 | if (priv->cfg->bt_params && | 829 | if (priv->cfg->bt_params && |
824 | priv->cfg->bt_params->advanced_bt_coexist && | 830 | priv->cfg->bt_params->advanced_bt_coexist && |
diff --git a/drivers/net/wireless/iwlwifi/iwl-mac80211.c b/drivers/net/wireless/iwlwifi/dvm/mac80211.c index a55012609cac..599e8b41f5a8 100644 --- a/drivers/net/wireless/iwlwifi/iwl-mac80211.c +++ b/drivers/net/wireless/iwlwifi/dvm/mac80211.c | |||
@@ -38,19 +38,20 @@ | |||
38 | #include <linux/etherdevice.h> | 38 | #include <linux/etherdevice.h> |
39 | #include <linux/if_arp.h> | 39 | #include <linux/if_arp.h> |
40 | 40 | ||
41 | #include <net/ieee80211_radiotap.h> | ||
41 | #include <net/mac80211.h> | 42 | #include <net/mac80211.h> |
42 | 43 | ||
43 | #include <asm/div64.h> | 44 | #include <asm/div64.h> |
44 | 45 | ||
45 | #include "iwl-eeprom.h" | ||
46 | #include "iwl-dev.h" | ||
47 | #include "iwl-io.h" | 46 | #include "iwl-io.h" |
48 | #include "iwl-agn-calib.h" | ||
49 | #include "iwl-agn.h" | ||
50 | #include "iwl-trans.h" | 47 | #include "iwl-trans.h" |
51 | #include "iwl-op-mode.h" | 48 | #include "iwl-op-mode.h" |
52 | #include "iwl-modparams.h" | 49 | #include "iwl-modparams.h" |
53 | 50 | ||
51 | #include "dev.h" | ||
52 | #include "calib.h" | ||
53 | #include "agn.h" | ||
54 | |||
54 | /***************************************************************************** | 55 | /***************************************************************************** |
55 | * | 56 | * |
56 | * mac80211 entry point functions | 57 | * mac80211 entry point functions |
@@ -154,6 +155,7 @@ int iwlagn_mac_setup_register(struct iwl_priv *priv, | |||
154 | IEEE80211_HW_SCAN_WHILE_IDLE; | 155 | IEEE80211_HW_SCAN_WHILE_IDLE; |
155 | 156 | ||
156 | hw->offchannel_tx_hw_queue = IWL_AUX_QUEUE; | 157 | hw->offchannel_tx_hw_queue = IWL_AUX_QUEUE; |
158 | hw->radiotap_mcs_details |= IEEE80211_RADIOTAP_MCS_HAVE_FMT; | ||
157 | 159 | ||
158 | /* | 160 | /* |
159 | * Including the following line will crash some AP's. This | 161 | * Including the following line will crash some AP's. This |
@@ -237,12 +239,12 @@ int iwlagn_mac_setup_register(struct iwl_priv *priv, | |||
237 | 239 | ||
238 | hw->max_listen_interval = IWL_CONN_MAX_LISTEN_INTERVAL; | 240 | hw->max_listen_interval = IWL_CONN_MAX_LISTEN_INTERVAL; |
239 | 241 | ||
240 | if (priv->bands[IEEE80211_BAND_2GHZ].n_channels) | 242 | if (priv->eeprom_data->bands[IEEE80211_BAND_2GHZ].n_channels) |
241 | priv->hw->wiphy->bands[IEEE80211_BAND_2GHZ] = | 243 | priv->hw->wiphy->bands[IEEE80211_BAND_2GHZ] = |
242 | &priv->bands[IEEE80211_BAND_2GHZ]; | 244 | &priv->eeprom_data->bands[IEEE80211_BAND_2GHZ]; |
243 | if (priv->bands[IEEE80211_BAND_5GHZ].n_channels) | 245 | if (priv->eeprom_data->bands[IEEE80211_BAND_5GHZ].n_channels) |
244 | priv->hw->wiphy->bands[IEEE80211_BAND_5GHZ] = | 246 | priv->hw->wiphy->bands[IEEE80211_BAND_5GHZ] = |
245 | &priv->bands[IEEE80211_BAND_5GHZ]; | 247 | &priv->eeprom_data->bands[IEEE80211_BAND_5GHZ]; |
246 | 248 | ||
247 | hw->wiphy->hw_version = priv->trans->hw_id; | 249 | hw->wiphy->hw_version = priv->trans->hw_id; |
248 | 250 | ||
@@ -341,7 +343,7 @@ static int iwlagn_mac_start(struct ieee80211_hw *hw) | |||
341 | return 0; | 343 | return 0; |
342 | } | 344 | } |
343 | 345 | ||
344 | void iwlagn_mac_stop(struct ieee80211_hw *hw) | 346 | static void iwlagn_mac_stop(struct ieee80211_hw *hw) |
345 | { | 347 | { |
346 | struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); | 348 | struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); |
347 | 349 | ||
@@ -369,9 +371,9 @@ void iwlagn_mac_stop(struct ieee80211_hw *hw) | |||
369 | IWL_DEBUG_MAC80211(priv, "leave\n"); | 371 | IWL_DEBUG_MAC80211(priv, "leave\n"); |
370 | } | 372 | } |
371 | 373 | ||
372 | void iwlagn_mac_set_rekey_data(struct ieee80211_hw *hw, | 374 | static void iwlagn_mac_set_rekey_data(struct ieee80211_hw *hw, |
373 | struct ieee80211_vif *vif, | 375 | struct ieee80211_vif *vif, |
374 | struct cfg80211_gtk_rekey_data *data) | 376 | struct cfg80211_gtk_rekey_data *data) |
375 | { | 377 | { |
376 | struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); | 378 | struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); |
377 | 379 | ||
@@ -397,7 +399,8 @@ void iwlagn_mac_set_rekey_data(struct ieee80211_hw *hw, | |||
397 | 399 | ||
398 | #ifdef CONFIG_PM_SLEEP | 400 | #ifdef CONFIG_PM_SLEEP |
399 | 401 | ||
400 | int iwlagn_mac_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan) | 402 | static int iwlagn_mac_suspend(struct ieee80211_hw *hw, |
403 | struct cfg80211_wowlan *wowlan) | ||
401 | { | 404 | { |
402 | struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); | 405 | struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); |
403 | struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; | 406 | struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; |
@@ -508,7 +511,7 @@ static void iwlagn_mac_set_wakeup(struct ieee80211_hw *hw, bool enabled) | |||
508 | } | 511 | } |
509 | #endif | 512 | #endif |
510 | 513 | ||
511 | void iwlagn_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb) | 514 | static void iwlagn_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb) |
512 | { | 515 | { |
513 | struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); | 516 | struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); |
514 | 517 | ||
@@ -519,21 +522,21 @@ void iwlagn_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
519 | dev_kfree_skb_any(skb); | 522 | dev_kfree_skb_any(skb); |
520 | } | 523 | } |
521 | 524 | ||
522 | void iwlagn_mac_update_tkip_key(struct ieee80211_hw *hw, | 525 | static void iwlagn_mac_update_tkip_key(struct ieee80211_hw *hw, |
523 | struct ieee80211_vif *vif, | 526 | struct ieee80211_vif *vif, |
524 | struct ieee80211_key_conf *keyconf, | 527 | struct ieee80211_key_conf *keyconf, |
525 | struct ieee80211_sta *sta, | 528 | struct ieee80211_sta *sta, |
526 | u32 iv32, u16 *phase1key) | 529 | u32 iv32, u16 *phase1key) |
527 | { | 530 | { |
528 | struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); | 531 | struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); |
529 | 532 | ||
530 | iwl_update_tkip_key(priv, vif, keyconf, sta, iv32, phase1key); | 533 | iwl_update_tkip_key(priv, vif, keyconf, sta, iv32, phase1key); |
531 | } | 534 | } |
532 | 535 | ||
533 | int iwlagn_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, | 536 | static int iwlagn_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, |
534 | struct ieee80211_vif *vif, | 537 | struct ieee80211_vif *vif, |
535 | struct ieee80211_sta *sta, | 538 | struct ieee80211_sta *sta, |
536 | struct ieee80211_key_conf *key) | 539 | struct ieee80211_key_conf *key) |
537 | { | 540 | { |
538 | struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); | 541 | struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); |
539 | struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv; | 542 | struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv; |
@@ -633,11 +636,11 @@ int iwlagn_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, | |||
633 | return ret; | 636 | return ret; |
634 | } | 637 | } |
635 | 638 | ||
636 | int iwlagn_mac_ampdu_action(struct ieee80211_hw *hw, | 639 | static int iwlagn_mac_ampdu_action(struct ieee80211_hw *hw, |
637 | struct ieee80211_vif *vif, | 640 | struct ieee80211_vif *vif, |
638 | enum ieee80211_ampdu_mlme_action action, | 641 | enum ieee80211_ampdu_mlme_action action, |
639 | struct ieee80211_sta *sta, u16 tid, u16 *ssn, | 642 | struct ieee80211_sta *sta, u16 tid, u16 *ssn, |
640 | u8 buf_size) | 643 | u8 buf_size) |
641 | { | 644 | { |
642 | struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); | 645 | struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); |
643 | int ret = -EINVAL; | 646 | int ret = -EINVAL; |
@@ -664,7 +667,7 @@ int iwlagn_mac_ampdu_action(struct ieee80211_hw *hw, | |||
664 | ret = iwl_sta_rx_agg_stop(priv, sta, tid); | 667 | ret = iwl_sta_rx_agg_stop(priv, sta, tid); |
665 | break; | 668 | break; |
666 | case IEEE80211_AMPDU_TX_START: | 669 | case IEEE80211_AMPDU_TX_START: |
667 | if (!priv->trans->ops->tx_agg_setup) | 670 | if (!priv->trans->ops->txq_enable) |
668 | break; | 671 | break; |
669 | if (iwlwifi_mod_params.disable_11n & IWL_DISABLE_HT_TXAGG) | 672 | if (iwlwifi_mod_params.disable_11n & IWL_DISABLE_HT_TXAGG) |
670 | break; | 673 | break; |
@@ -759,11 +762,11 @@ static int iwlagn_mac_sta_remove(struct ieee80211_hw *hw, | |||
759 | return ret; | 762 | return ret; |
760 | } | 763 | } |
761 | 764 | ||
762 | int iwlagn_mac_sta_state(struct ieee80211_hw *hw, | 765 | static int iwlagn_mac_sta_state(struct ieee80211_hw *hw, |
763 | struct ieee80211_vif *vif, | 766 | struct ieee80211_vif *vif, |
764 | struct ieee80211_sta *sta, | 767 | struct ieee80211_sta *sta, |
765 | enum ieee80211_sta_state old_state, | 768 | enum ieee80211_sta_state old_state, |
766 | enum ieee80211_sta_state new_state) | 769 | enum ieee80211_sta_state new_state) |
767 | { | 770 | { |
768 | struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); | 771 | struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); |
769 | struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv; | 772 | struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv; |
@@ -842,11 +845,10 @@ int iwlagn_mac_sta_state(struct ieee80211_hw *hw, | |||
842 | return ret; | 845 | return ret; |
843 | } | 846 | } |
844 | 847 | ||
845 | void iwlagn_mac_channel_switch(struct ieee80211_hw *hw, | 848 | static void iwlagn_mac_channel_switch(struct ieee80211_hw *hw, |
846 | struct ieee80211_channel_switch *ch_switch) | 849 | struct ieee80211_channel_switch *ch_switch) |
847 | { | 850 | { |
848 | struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); | 851 | struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); |
849 | const struct iwl_channel_info *ch_info; | ||
850 | struct ieee80211_conf *conf = &hw->conf; | 852 | struct ieee80211_conf *conf = &hw->conf; |
851 | struct ieee80211_channel *channel = ch_switch->channel; | 853 | struct ieee80211_channel *channel = ch_switch->channel; |
852 | struct iwl_ht_config *ht_conf = &priv->current_ht_config; | 854 | struct iwl_ht_config *ht_conf = &priv->current_ht_config; |
@@ -883,12 +885,6 @@ void iwlagn_mac_channel_switch(struct ieee80211_hw *hw, | |||
883 | if (le16_to_cpu(ctx->active.channel) == ch) | 885 | if (le16_to_cpu(ctx->active.channel) == ch) |
884 | goto out; | 886 | goto out; |
885 | 887 | ||
886 | ch_info = iwl_get_channel_info(priv, channel->band, ch); | ||
887 | if (!is_channel_valid(ch_info)) { | ||
888 | IWL_DEBUG_MAC80211(priv, "invalid channel\n"); | ||
889 | goto out; | ||
890 | } | ||
891 | |||
892 | priv->current_ht_config.smps = conf->smps_mode; | 888 | priv->current_ht_config.smps = conf->smps_mode; |
893 | 889 | ||
894 | /* Configure HT40 channels */ | 890 | /* Configure HT40 channels */ |
@@ -937,10 +933,10 @@ void iwl_chswitch_done(struct iwl_priv *priv, bool is_success) | |||
937 | ieee80211_chswitch_done(ctx->vif, is_success); | 933 | ieee80211_chswitch_done(ctx->vif, is_success); |
938 | } | 934 | } |
939 | 935 | ||
940 | void iwlagn_configure_filter(struct ieee80211_hw *hw, | 936 | static void iwlagn_configure_filter(struct ieee80211_hw *hw, |
941 | unsigned int changed_flags, | 937 | unsigned int changed_flags, |
942 | unsigned int *total_flags, | 938 | unsigned int *total_flags, |
943 | u64 multicast) | 939 | u64 multicast) |
944 | { | 940 | { |
945 | struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); | 941 | struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); |
946 | __le32 filter_or = 0, filter_nand = 0; | 942 | __le32 filter_or = 0, filter_nand = 0; |
@@ -987,7 +983,7 @@ void iwlagn_configure_filter(struct ieee80211_hw *hw, | |||
987 | FIF_BCN_PRBRESP_PROMISC | FIF_CONTROL; | 983 | FIF_BCN_PRBRESP_PROMISC | FIF_CONTROL; |
988 | } | 984 | } |
989 | 985 | ||
990 | void iwlagn_mac_flush(struct ieee80211_hw *hw, bool drop) | 986 | static void iwlagn_mac_flush(struct ieee80211_hw *hw, bool drop) |
991 | { | 987 | { |
992 | struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); | 988 | struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); |
993 | 989 | ||
@@ -1114,7 +1110,7 @@ static int iwlagn_mac_remain_on_channel(struct ieee80211_hw *hw, | |||
1114 | return err; | 1110 | return err; |
1115 | } | 1111 | } |
1116 | 1112 | ||
1117 | int iwlagn_mac_cancel_remain_on_channel(struct ieee80211_hw *hw) | 1113 | static int iwlagn_mac_cancel_remain_on_channel(struct ieee80211_hw *hw) |
1118 | { | 1114 | { |
1119 | struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); | 1115 | struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); |
1120 | 1116 | ||
@@ -1131,8 +1127,8 @@ int iwlagn_mac_cancel_remain_on_channel(struct ieee80211_hw *hw) | |||
1131 | return 0; | 1127 | return 0; |
1132 | } | 1128 | } |
1133 | 1129 | ||
1134 | void iwlagn_mac_rssi_callback(struct ieee80211_hw *hw, | 1130 | static void iwlagn_mac_rssi_callback(struct ieee80211_hw *hw, |
1135 | enum ieee80211_rssi_event rssi_event) | 1131 | enum ieee80211_rssi_event rssi_event) |
1136 | { | 1132 | { |
1137 | struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); | 1133 | struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); |
1138 | 1134 | ||
@@ -1156,8 +1152,8 @@ void iwlagn_mac_rssi_callback(struct ieee80211_hw *hw, | |||
1156 | IWL_DEBUG_MAC80211(priv, "leave\n"); | 1152 | IWL_DEBUG_MAC80211(priv, "leave\n"); |
1157 | } | 1153 | } |
1158 | 1154 | ||
1159 | int iwlagn_mac_set_tim(struct ieee80211_hw *hw, | 1155 | static int iwlagn_mac_set_tim(struct ieee80211_hw *hw, |
1160 | struct ieee80211_sta *sta, bool set) | 1156 | struct ieee80211_sta *sta, bool set) |
1161 | { | 1157 | { |
1162 | struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); | 1158 | struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); |
1163 | 1159 | ||
@@ -1166,9 +1162,9 @@ int iwlagn_mac_set_tim(struct ieee80211_hw *hw, | |||
1166 | return 0; | 1162 | return 0; |
1167 | } | 1163 | } |
1168 | 1164 | ||
1169 | int iwlagn_mac_conf_tx(struct ieee80211_hw *hw, | 1165 | static int iwlagn_mac_conf_tx(struct ieee80211_hw *hw, |
1170 | struct ieee80211_vif *vif, u16 queue, | 1166 | struct ieee80211_vif *vif, u16 queue, |
1171 | const struct ieee80211_tx_queue_params *params) | 1167 | const struct ieee80211_tx_queue_params *params) |
1172 | { | 1168 | { |
1173 | struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); | 1169 | struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); |
1174 | struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv; | 1170 | struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv; |
@@ -1210,7 +1206,7 @@ int iwlagn_mac_conf_tx(struct ieee80211_hw *hw, | |||
1210 | return 0; | 1206 | return 0; |
1211 | } | 1207 | } |
1212 | 1208 | ||
1213 | int iwlagn_mac_tx_last_beacon(struct ieee80211_hw *hw) | 1209 | static int iwlagn_mac_tx_last_beacon(struct ieee80211_hw *hw) |
1214 | { | 1210 | { |
1215 | struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); | 1211 | struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); |
1216 | 1212 | ||
@@ -1226,7 +1222,8 @@ static int iwl_set_mode(struct iwl_priv *priv, struct iwl_rxon_context *ctx) | |||
1226 | return iwlagn_commit_rxon(priv, ctx); | 1222 | return iwlagn_commit_rxon(priv, ctx); |
1227 | } | 1223 | } |
1228 | 1224 | ||
1229 | int iwl_setup_interface(struct iwl_priv *priv, struct iwl_rxon_context *ctx) | 1225 | static int iwl_setup_interface(struct iwl_priv *priv, |
1226 | struct iwl_rxon_context *ctx) | ||
1230 | { | 1227 | { |
1231 | struct ieee80211_vif *vif = ctx->vif; | 1228 | struct ieee80211_vif *vif = ctx->vif; |
1232 | int err, ac; | 1229 | int err, ac; |
@@ -1346,9 +1343,9 @@ static int iwlagn_mac_add_interface(struct ieee80211_hw *hw, | |||
1346 | return err; | 1343 | return err; |
1347 | } | 1344 | } |
1348 | 1345 | ||
1349 | void iwl_teardown_interface(struct iwl_priv *priv, | 1346 | static void iwl_teardown_interface(struct iwl_priv *priv, |
1350 | struct ieee80211_vif *vif, | 1347 | struct ieee80211_vif *vif, |
1351 | bool mode_change) | 1348 | bool mode_change) |
1352 | { | 1349 | { |
1353 | struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif); | 1350 | struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif); |
1354 | 1351 | ||
@@ -1489,9 +1486,9 @@ static int iwlagn_mac_change_interface(struct ieee80211_hw *hw, | |||
1489 | return err; | 1486 | return err; |
1490 | } | 1487 | } |
1491 | 1488 | ||
1492 | int iwlagn_mac_hw_scan(struct ieee80211_hw *hw, | 1489 | static int iwlagn_mac_hw_scan(struct ieee80211_hw *hw, |
1493 | struct ieee80211_vif *vif, | 1490 | struct ieee80211_vif *vif, |
1494 | struct cfg80211_scan_request *req) | 1491 | struct cfg80211_scan_request *req) |
1495 | { | 1492 | { |
1496 | struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); | 1493 | struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); |
1497 | int ret; | 1494 | int ret; |
@@ -1546,10 +1543,10 @@ static void iwl_sta_modify_ps_wake(struct iwl_priv *priv, int sta_id) | |||
1546 | iwl_send_add_sta(priv, &cmd, CMD_ASYNC); | 1543 | iwl_send_add_sta(priv, &cmd, CMD_ASYNC); |
1547 | } | 1544 | } |
1548 | 1545 | ||
1549 | void iwlagn_mac_sta_notify(struct ieee80211_hw *hw, | 1546 | static void iwlagn_mac_sta_notify(struct ieee80211_hw *hw, |
1550 | struct ieee80211_vif *vif, | 1547 | struct ieee80211_vif *vif, |
1551 | enum sta_notify_cmd cmd, | 1548 | enum sta_notify_cmd cmd, |
1552 | struct ieee80211_sta *sta) | 1549 | struct ieee80211_sta *sta) |
1553 | { | 1550 | { |
1554 | struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); | 1551 | struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); |
1555 | struct iwl_station_priv *sta_priv = (void *)sta->drv_priv; | 1552 | struct iwl_station_priv *sta_priv = (void *)sta->drv_priv; |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/dvm/main.c index 5149e6f72945..1c2d0233a405 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/dvm/main.c | |||
@@ -44,16 +44,18 @@ | |||
44 | 44 | ||
45 | #include <asm/div64.h> | 45 | #include <asm/div64.h> |
46 | 46 | ||
47 | #include "iwl-eeprom.h" | 47 | #include "iwl-eeprom-read.h" |
48 | #include "iwl-dev.h" | 48 | #include "iwl-eeprom-parse.h" |
49 | #include "iwl-io.h" | 49 | #include "iwl-io.h" |
50 | #include "iwl-agn-calib.h" | ||
51 | #include "iwl-agn.h" | ||
52 | #include "iwl-trans.h" | 50 | #include "iwl-trans.h" |
53 | #include "iwl-op-mode.h" | 51 | #include "iwl-op-mode.h" |
54 | #include "iwl-drv.h" | 52 | #include "iwl-drv.h" |
55 | #include "iwl-modparams.h" | 53 | #include "iwl-modparams.h" |
56 | 54 | ||
55 | #include "dev.h" | ||
56 | #include "calib.h" | ||
57 | #include "agn.h" | ||
58 | |||
57 | /****************************************************************************** | 59 | /****************************************************************************** |
58 | * | 60 | * |
59 | * module boiler plate | 61 | * module boiler plate |
@@ -79,6 +81,8 @@ MODULE_VERSION(DRV_VERSION); | |||
79 | MODULE_AUTHOR(DRV_COPYRIGHT " " DRV_AUTHOR); | 81 | MODULE_AUTHOR(DRV_COPYRIGHT " " DRV_AUTHOR); |
80 | MODULE_LICENSE("GPL"); | 82 | MODULE_LICENSE("GPL"); |
81 | 83 | ||
84 | static const struct iwl_op_mode_ops iwl_dvm_ops; | ||
85 | |||
82 | void iwl_update_chain_flags(struct iwl_priv *priv) | 86 | void iwl_update_chain_flags(struct iwl_priv *priv) |
83 | { | 87 | { |
84 | struct iwl_rxon_context *ctx; | 88 | struct iwl_rxon_context *ctx; |
@@ -179,7 +183,7 @@ int iwlagn_send_beacon_cmd(struct iwl_priv *priv) | |||
179 | rate = info->control.rates[0].idx; | 183 | rate = info->control.rates[0].idx; |
180 | 184 | ||
181 | priv->mgmt_tx_ant = iwl_toggle_tx_ant(priv, priv->mgmt_tx_ant, | 185 | priv->mgmt_tx_ant = iwl_toggle_tx_ant(priv, priv->mgmt_tx_ant, |
182 | priv->hw_params.valid_tx_ant); | 186 | priv->eeprom_data->valid_tx_ant); |
183 | rate_flags = iwl_ant_idx_to_flags(priv->mgmt_tx_ant); | 187 | rate_flags = iwl_ant_idx_to_flags(priv->mgmt_tx_ant); |
184 | 188 | ||
185 | /* In mac80211, rates for 5 GHz start at 0 */ | 189 | /* In mac80211, rates for 5 GHz start at 0 */ |
@@ -577,7 +581,7 @@ static const u8 iwlagn_pan_ac_to_queue[] = { | |||
577 | 7, 6, 5, 4, | 581 | 7, 6, 5, 4, |
578 | }; | 582 | }; |
579 | 583 | ||
580 | void iwl_init_context(struct iwl_priv *priv, u32 ucode_flags) | 584 | static void iwl_init_context(struct iwl_priv *priv, u32 ucode_flags) |
581 | { | 585 | { |
582 | int i; | 586 | int i; |
583 | 587 | ||
@@ -644,7 +648,7 @@ void iwl_init_context(struct iwl_priv *priv, u32 ucode_flags) | |||
644 | BUILD_BUG_ON(NUM_IWL_RXON_CTX != 2); | 648 | BUILD_BUG_ON(NUM_IWL_RXON_CTX != 2); |
645 | } | 649 | } |
646 | 650 | ||
647 | void iwl_rf_kill_ct_config(struct iwl_priv *priv) | 651 | static void iwl_rf_kill_ct_config(struct iwl_priv *priv) |
648 | { | 652 | { |
649 | struct iwl_ct_kill_config cmd; | 653 | struct iwl_ct_kill_config cmd; |
650 | struct iwl_ct_kill_throttling_config adv_cmd; | 654 | struct iwl_ct_kill_throttling_config adv_cmd; |
@@ -725,7 +729,7 @@ static int iwlagn_send_tx_ant_config(struct iwl_priv *priv, u8 valid_tx_ant) | |||
725 | } | 729 | } |
726 | } | 730 | } |
727 | 731 | ||
728 | void iwl_send_bt_config(struct iwl_priv *priv) | 732 | static void iwl_send_bt_config(struct iwl_priv *priv) |
729 | { | 733 | { |
730 | struct iwl_bt_cmd bt_cmd = { | 734 | struct iwl_bt_cmd bt_cmd = { |
731 | .lead_time = BT_LEAD_TIME_DEF, | 735 | .lead_time = BT_LEAD_TIME_DEF, |
@@ -813,7 +817,7 @@ int iwl_alive_start(struct iwl_priv *priv) | |||
813 | ieee80211_wake_queues(priv->hw); | 817 | ieee80211_wake_queues(priv->hw); |
814 | 818 | ||
815 | /* Configure Tx antenna selection based on H/W config */ | 819 | /* Configure Tx antenna selection based on H/W config */ |
816 | iwlagn_send_tx_ant_config(priv, priv->hw_params.valid_tx_ant); | 820 | iwlagn_send_tx_ant_config(priv, priv->eeprom_data->valid_tx_ant); |
817 | 821 | ||
818 | if (iwl_is_associated_ctx(ctx) && !priv->wowlan) { | 822 | if (iwl_is_associated_ctx(ctx) && !priv->wowlan) { |
819 | struct iwl_rxon_cmd *active_rxon = | 823 | struct iwl_rxon_cmd *active_rxon = |
@@ -931,11 +935,12 @@ void iwl_down(struct iwl_priv *priv) | |||
931 | priv->ucode_loaded = false; | 935 | priv->ucode_loaded = false; |
932 | iwl_trans_stop_device(priv->trans); | 936 | iwl_trans_stop_device(priv->trans); |
933 | 937 | ||
938 | /* Set num_aux_in_flight must be done after the transport is stopped */ | ||
939 | atomic_set(&priv->num_aux_in_flight, 0); | ||
940 | |||
934 | /* Clear out all status bits but a few that are stable across reset */ | 941 | /* Clear out all status bits but a few that are stable across reset */ |
935 | priv->status &= test_bit(STATUS_RF_KILL_HW, &priv->status) << | 942 | priv->status &= test_bit(STATUS_RF_KILL_HW, &priv->status) << |
936 | STATUS_RF_KILL_HW | | 943 | STATUS_RF_KILL_HW | |
937 | test_bit(STATUS_GEO_CONFIGURED, &priv->status) << | ||
938 | STATUS_GEO_CONFIGURED | | ||
939 | test_bit(STATUS_FW_ERROR, &priv->status) << | 944 | test_bit(STATUS_FW_ERROR, &priv->status) << |
940 | STATUS_FW_ERROR | | 945 | STATUS_FW_ERROR | |
941 | test_bit(STATUS_EXIT_PENDING, &priv->status) << | 946 | test_bit(STATUS_EXIT_PENDING, &priv->status) << |
@@ -1077,7 +1082,7 @@ static void iwlagn_disable_roc_work(struct work_struct *work) | |||
1077 | * | 1082 | * |
1078 | *****************************************************************************/ | 1083 | *****************************************************************************/ |
1079 | 1084 | ||
1080 | void iwl_setup_deferred_work(struct iwl_priv *priv) | 1085 | static void iwl_setup_deferred_work(struct iwl_priv *priv) |
1081 | { | 1086 | { |
1082 | priv->workqueue = create_singlethread_workqueue(DRV_NAME); | 1087 | priv->workqueue = create_singlethread_workqueue(DRV_NAME); |
1083 | 1088 | ||
@@ -1122,224 +1127,14 @@ void iwl_cancel_deferred_work(struct iwl_priv *priv) | |||
1122 | del_timer_sync(&priv->ucode_trace); | 1127 | del_timer_sync(&priv->ucode_trace); |
1123 | } | 1128 | } |
1124 | 1129 | ||
1125 | static void iwl_init_hw_rates(struct ieee80211_rate *rates) | 1130 | static int iwl_init_drv(struct iwl_priv *priv) |
1126 | { | ||
1127 | int i; | ||
1128 | |||
1129 | for (i = 0; i < IWL_RATE_COUNT_LEGACY; i++) { | ||
1130 | rates[i].bitrate = iwl_rates[i].ieee * 5; | ||
1131 | rates[i].hw_value = i; /* Rate scaling will work on indexes */ | ||
1132 | rates[i].hw_value_short = i; | ||
1133 | rates[i].flags = 0; | ||
1134 | if ((i >= IWL_FIRST_CCK_RATE) && (i <= IWL_LAST_CCK_RATE)) { | ||
1135 | /* | ||
1136 | * If CCK != 1M then set short preamble rate flag. | ||
1137 | */ | ||
1138 | rates[i].flags |= | ||
1139 | (iwl_rates[i].plcp == IWL_RATE_1M_PLCP) ? | ||
1140 | 0 : IEEE80211_RATE_SHORT_PREAMBLE; | ||
1141 | } | ||
1142 | } | ||
1143 | } | ||
1144 | |||
1145 | #define MAX_BIT_RATE_40_MHZ 150 /* Mbps */ | ||
1146 | #define MAX_BIT_RATE_20_MHZ 72 /* Mbps */ | ||
1147 | static void iwl_init_ht_hw_capab(const struct iwl_priv *priv, | ||
1148 | struct ieee80211_sta_ht_cap *ht_info, | ||
1149 | enum ieee80211_band band) | ||
1150 | { | ||
1151 | u16 max_bit_rate = 0; | ||
1152 | u8 rx_chains_num = priv->hw_params.rx_chains_num; | ||
1153 | u8 tx_chains_num = priv->hw_params.tx_chains_num; | ||
1154 | |||
1155 | ht_info->cap = 0; | ||
1156 | memset(&ht_info->mcs, 0, sizeof(ht_info->mcs)); | ||
1157 | |||
1158 | ht_info->ht_supported = true; | ||
1159 | |||
1160 | if (priv->cfg->ht_params && | ||
1161 | priv->cfg->ht_params->ht_greenfield_support) | ||
1162 | ht_info->cap |= IEEE80211_HT_CAP_GRN_FLD; | ||
1163 | ht_info->cap |= IEEE80211_HT_CAP_SGI_20; | ||
1164 | max_bit_rate = MAX_BIT_RATE_20_MHZ; | ||
1165 | if (priv->hw_params.ht40_channel & BIT(band)) { | ||
1166 | ht_info->cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40; | ||
1167 | ht_info->cap |= IEEE80211_HT_CAP_SGI_40; | ||
1168 | ht_info->mcs.rx_mask[4] = 0x01; | ||
1169 | max_bit_rate = MAX_BIT_RATE_40_MHZ; | ||
1170 | } | ||
1171 | |||
1172 | if (iwlwifi_mod_params.amsdu_size_8K) | ||
1173 | ht_info->cap |= IEEE80211_HT_CAP_MAX_AMSDU; | ||
1174 | |||
1175 | ht_info->ampdu_factor = CFG_HT_RX_AMPDU_FACTOR_DEF; | ||
1176 | ht_info->ampdu_density = CFG_HT_MPDU_DENSITY_DEF; | ||
1177 | |||
1178 | ht_info->mcs.rx_mask[0] = 0xFF; | ||
1179 | if (rx_chains_num >= 2) | ||
1180 | ht_info->mcs.rx_mask[1] = 0xFF; | ||
1181 | if (rx_chains_num >= 3) | ||
1182 | ht_info->mcs.rx_mask[2] = 0xFF; | ||
1183 | |||
1184 | /* Highest supported Rx data rate */ | ||
1185 | max_bit_rate *= rx_chains_num; | ||
1186 | WARN_ON(max_bit_rate & ~IEEE80211_HT_MCS_RX_HIGHEST_MASK); | ||
1187 | ht_info->mcs.rx_highest = cpu_to_le16(max_bit_rate); | ||
1188 | |||
1189 | /* Tx MCS capabilities */ | ||
1190 | ht_info->mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED; | ||
1191 | if (tx_chains_num != rx_chains_num) { | ||
1192 | ht_info->mcs.tx_params |= IEEE80211_HT_MCS_TX_RX_DIFF; | ||
1193 | ht_info->mcs.tx_params |= ((tx_chains_num - 1) << | ||
1194 | IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT); | ||
1195 | } | ||
1196 | } | ||
1197 | |||
1198 | /** | ||
1199 | * iwl_init_geos - Initialize mac80211's geo/channel info based from eeprom | ||
1200 | */ | ||
1201 | static int iwl_init_geos(struct iwl_priv *priv) | ||
1202 | { | ||
1203 | struct iwl_channel_info *ch; | ||
1204 | struct ieee80211_supported_band *sband; | ||
1205 | struct ieee80211_channel *channels; | ||
1206 | struct ieee80211_channel *geo_ch; | ||
1207 | struct ieee80211_rate *rates; | ||
1208 | int i = 0; | ||
1209 | s8 max_tx_power = IWLAGN_TX_POWER_TARGET_POWER_MIN; | ||
1210 | |||
1211 | if (priv->bands[IEEE80211_BAND_2GHZ].n_bitrates || | ||
1212 | priv->bands[IEEE80211_BAND_5GHZ].n_bitrates) { | ||
1213 | IWL_DEBUG_INFO(priv, "Geography modes already initialized.\n"); | ||
1214 | set_bit(STATUS_GEO_CONFIGURED, &priv->status); | ||
1215 | return 0; | ||
1216 | } | ||
1217 | |||
1218 | channels = kcalloc(priv->channel_count, | ||
1219 | sizeof(struct ieee80211_channel), GFP_KERNEL); | ||
1220 | if (!channels) | ||
1221 | return -ENOMEM; | ||
1222 | |||
1223 | rates = kcalloc(IWL_RATE_COUNT_LEGACY, sizeof(struct ieee80211_rate), | ||
1224 | GFP_KERNEL); | ||
1225 | if (!rates) { | ||
1226 | kfree(channels); | ||
1227 | return -ENOMEM; | ||
1228 | } | ||
1229 | |||
1230 | /* 5.2GHz channels start after the 2.4GHz channels */ | ||
1231 | sband = &priv->bands[IEEE80211_BAND_5GHZ]; | ||
1232 | sband->channels = &channels[ARRAY_SIZE(iwl_eeprom_band_1)]; | ||
1233 | /* just OFDM */ | ||
1234 | sband->bitrates = &rates[IWL_FIRST_OFDM_RATE]; | ||
1235 | sband->n_bitrates = IWL_RATE_COUNT_LEGACY - IWL_FIRST_OFDM_RATE; | ||
1236 | |||
1237 | if (priv->hw_params.sku & EEPROM_SKU_CAP_11N_ENABLE) | ||
1238 | iwl_init_ht_hw_capab(priv, &sband->ht_cap, | ||
1239 | IEEE80211_BAND_5GHZ); | ||
1240 | |||
1241 | sband = &priv->bands[IEEE80211_BAND_2GHZ]; | ||
1242 | sband->channels = channels; | ||
1243 | /* OFDM & CCK */ | ||
1244 | sband->bitrates = rates; | ||
1245 | sband->n_bitrates = IWL_RATE_COUNT_LEGACY; | ||
1246 | |||
1247 | if (priv->hw_params.sku & EEPROM_SKU_CAP_11N_ENABLE) | ||
1248 | iwl_init_ht_hw_capab(priv, &sband->ht_cap, | ||
1249 | IEEE80211_BAND_2GHZ); | ||
1250 | |||
1251 | priv->ieee_channels = channels; | ||
1252 | priv->ieee_rates = rates; | ||
1253 | |||
1254 | for (i = 0; i < priv->channel_count; i++) { | ||
1255 | ch = &priv->channel_info[i]; | ||
1256 | |||
1257 | /* FIXME: might be removed if scan is OK */ | ||
1258 | if (!is_channel_valid(ch)) | ||
1259 | continue; | ||
1260 | |||
1261 | sband = &priv->bands[ch->band]; | ||
1262 | |||
1263 | geo_ch = &sband->channels[sband->n_channels++]; | ||
1264 | |||
1265 | geo_ch->center_freq = | ||
1266 | ieee80211_channel_to_frequency(ch->channel, ch->band); | ||
1267 | geo_ch->max_power = ch->max_power_avg; | ||
1268 | geo_ch->max_antenna_gain = 0xff; | ||
1269 | geo_ch->hw_value = ch->channel; | ||
1270 | |||
1271 | if (is_channel_valid(ch)) { | ||
1272 | if (!(ch->flags & EEPROM_CHANNEL_IBSS)) | ||
1273 | geo_ch->flags |= IEEE80211_CHAN_NO_IBSS; | ||
1274 | |||
1275 | if (!(ch->flags & EEPROM_CHANNEL_ACTIVE)) | ||
1276 | geo_ch->flags |= IEEE80211_CHAN_PASSIVE_SCAN; | ||
1277 | |||
1278 | if (ch->flags & EEPROM_CHANNEL_RADAR) | ||
1279 | geo_ch->flags |= IEEE80211_CHAN_RADAR; | ||
1280 | |||
1281 | geo_ch->flags |= ch->ht40_extension_channel; | ||
1282 | |||
1283 | if (ch->max_power_avg > max_tx_power) | ||
1284 | max_tx_power = ch->max_power_avg; | ||
1285 | } else { | ||
1286 | geo_ch->flags |= IEEE80211_CHAN_DISABLED; | ||
1287 | } | ||
1288 | |||
1289 | IWL_DEBUG_INFO(priv, "Channel %d Freq=%d[%sGHz] %s flag=0x%X\n", | ||
1290 | ch->channel, geo_ch->center_freq, | ||
1291 | is_channel_a_band(ch) ? "5.2" : "2.4", | ||
1292 | geo_ch->flags & IEEE80211_CHAN_DISABLED ? | ||
1293 | "restricted" : "valid", | ||
1294 | geo_ch->flags); | ||
1295 | } | ||
1296 | |||
1297 | priv->tx_power_device_lmt = max_tx_power; | ||
1298 | priv->tx_power_user_lmt = max_tx_power; | ||
1299 | priv->tx_power_next = max_tx_power; | ||
1300 | |||
1301 | if ((priv->bands[IEEE80211_BAND_5GHZ].n_channels == 0) && | ||
1302 | priv->hw_params.sku & EEPROM_SKU_CAP_BAND_52GHZ) { | ||
1303 | IWL_INFO(priv, "Incorrectly detected BG card as ABG. " | ||
1304 | "Please send your %s to maintainer.\n", | ||
1305 | priv->trans->hw_id_str); | ||
1306 | priv->hw_params.sku &= ~EEPROM_SKU_CAP_BAND_52GHZ; | ||
1307 | } | ||
1308 | |||
1309 | if (iwlwifi_mod_params.disable_5ghz) | ||
1310 | priv->bands[IEEE80211_BAND_5GHZ].n_channels = 0; | ||
1311 | |||
1312 | IWL_INFO(priv, "Tunable channels: %d 802.11bg, %d 802.11a channels\n", | ||
1313 | priv->bands[IEEE80211_BAND_2GHZ].n_channels, | ||
1314 | priv->bands[IEEE80211_BAND_5GHZ].n_channels); | ||
1315 | |||
1316 | set_bit(STATUS_GEO_CONFIGURED, &priv->status); | ||
1317 | |||
1318 | return 0; | ||
1319 | } | ||
1320 | |||
1321 | /* | ||
1322 | * iwl_free_geos - undo allocations in iwl_init_geos | ||
1323 | */ | ||
1324 | static void iwl_free_geos(struct iwl_priv *priv) | ||
1325 | { | 1131 | { |
1326 | kfree(priv->ieee_channels); | ||
1327 | kfree(priv->ieee_rates); | ||
1328 | clear_bit(STATUS_GEO_CONFIGURED, &priv->status); | ||
1329 | } | ||
1330 | |||
1331 | int iwl_init_drv(struct iwl_priv *priv) | ||
1332 | { | ||
1333 | int ret; | ||
1334 | |||
1335 | spin_lock_init(&priv->sta_lock); | 1132 | spin_lock_init(&priv->sta_lock); |
1336 | 1133 | ||
1337 | mutex_init(&priv->mutex); | 1134 | mutex_init(&priv->mutex); |
1338 | 1135 | ||
1339 | INIT_LIST_HEAD(&priv->calib_results); | 1136 | INIT_LIST_HEAD(&priv->calib_results); |
1340 | 1137 | ||
1341 | priv->ieee_channels = NULL; | ||
1342 | priv->ieee_rates = NULL; | ||
1343 | priv->band = IEEE80211_BAND_2GHZ; | 1138 | priv->band = IEEE80211_BAND_2GHZ; |
1344 | 1139 | ||
1345 | priv->plcp_delta_threshold = | 1140 | priv->plcp_delta_threshold = |
@@ -1370,31 +1165,11 @@ int iwl_init_drv(struct iwl_priv *priv) | |||
1370 | priv->dynamic_frag_thresh = BT_FRAG_THRESHOLD_DEF; | 1165 | priv->dynamic_frag_thresh = BT_FRAG_THRESHOLD_DEF; |
1371 | } | 1166 | } |
1372 | 1167 | ||
1373 | ret = iwl_init_channel_map(priv); | ||
1374 | if (ret) { | ||
1375 | IWL_ERR(priv, "initializing regulatory failed: %d\n", ret); | ||
1376 | goto err; | ||
1377 | } | ||
1378 | |||
1379 | ret = iwl_init_geos(priv); | ||
1380 | if (ret) { | ||
1381 | IWL_ERR(priv, "initializing geos failed: %d\n", ret); | ||
1382 | goto err_free_channel_map; | ||
1383 | } | ||
1384 | iwl_init_hw_rates(priv->ieee_rates); | ||
1385 | |||
1386 | return 0; | 1168 | return 0; |
1387 | |||
1388 | err_free_channel_map: | ||
1389 | iwl_free_channel_map(priv); | ||
1390 | err: | ||
1391 | return ret; | ||
1392 | } | 1169 | } |
1393 | 1170 | ||
1394 | void iwl_uninit_drv(struct iwl_priv *priv) | 1171 | static void iwl_uninit_drv(struct iwl_priv *priv) |
1395 | { | 1172 | { |
1396 | iwl_free_geos(priv); | ||
1397 | iwl_free_channel_map(priv); | ||
1398 | kfree(priv->scan_cmd); | 1173 | kfree(priv->scan_cmd); |
1399 | kfree(priv->beacon_cmd); | 1174 | kfree(priv->beacon_cmd); |
1400 | kfree(rcu_dereference_raw(priv->noa_data)); | 1175 | kfree(rcu_dereference_raw(priv->noa_data)); |
@@ -1404,7 +1179,7 @@ void iwl_uninit_drv(struct iwl_priv *priv) | |||
1404 | #endif | 1179 | #endif |
1405 | } | 1180 | } |
1406 | 1181 | ||
1407 | void iwl_set_hw_params(struct iwl_priv *priv) | 1182 | static void iwl_set_hw_params(struct iwl_priv *priv) |
1408 | { | 1183 | { |
1409 | if (priv->cfg->ht_params) | 1184 | if (priv->cfg->ht_params) |
1410 | priv->hw_params.use_rts_for_aggregation = | 1185 | priv->hw_params.use_rts_for_aggregation = |
@@ -1420,7 +1195,7 @@ void iwl_set_hw_params(struct iwl_priv *priv) | |||
1420 | 1195 | ||
1421 | 1196 | ||
1422 | /* show what optional capabilities we have */ | 1197 | /* show what optional capabilities we have */ |
1423 | void iwl_option_config(struct iwl_priv *priv) | 1198 | static void iwl_option_config(struct iwl_priv *priv) |
1424 | { | 1199 | { |
1425 | #ifdef CONFIG_IWLWIFI_DEBUG | 1200 | #ifdef CONFIG_IWLWIFI_DEBUG |
1426 | IWL_INFO(priv, "CONFIG_IWLWIFI_DEBUG enabled\n"); | 1201 | IWL_INFO(priv, "CONFIG_IWLWIFI_DEBUG enabled\n"); |
@@ -1453,6 +1228,42 @@ void iwl_option_config(struct iwl_priv *priv) | |||
1453 | #endif | 1228 | #endif |
1454 | } | 1229 | } |
1455 | 1230 | ||
1231 | static int iwl_eeprom_init_hw_params(struct iwl_priv *priv) | ||
1232 | { | ||
1233 | u16 radio_cfg; | ||
1234 | |||
1235 | priv->hw_params.sku = priv->eeprom_data->sku; | ||
1236 | |||
1237 | if (priv->hw_params.sku & EEPROM_SKU_CAP_11N_ENABLE && | ||
1238 | !priv->cfg->ht_params) { | ||
1239 | IWL_ERR(priv, "Invalid 11n configuration\n"); | ||
1240 | return -EINVAL; | ||
1241 | } | ||
1242 | |||
1243 | if (!priv->hw_params.sku) { | ||
1244 | IWL_ERR(priv, "Invalid device sku\n"); | ||
1245 | return -EINVAL; | ||
1246 | } | ||
1247 | |||
1248 | IWL_INFO(priv, "Device SKU: 0x%X\n", priv->hw_params.sku); | ||
1249 | |||
1250 | radio_cfg = priv->eeprom_data->radio_cfg; | ||
1251 | |||
1252 | priv->hw_params.tx_chains_num = | ||
1253 | num_of_ant(priv->eeprom_data->valid_tx_ant); | ||
1254 | if (priv->cfg->rx_with_siso_diversity) | ||
1255 | priv->hw_params.rx_chains_num = 1; | ||
1256 | else | ||
1257 | priv->hw_params.rx_chains_num = | ||
1258 | num_of_ant(priv->eeprom_data->valid_rx_ant); | ||
1259 | |||
1260 | IWL_INFO(priv, "Valid Tx ant: 0x%X, Valid Rx ant: 0x%X\n", | ||
1261 | priv->eeprom_data->valid_tx_ant, | ||
1262 | priv->eeprom_data->valid_rx_ant); | ||
1263 | |||
1264 | return 0; | ||
1265 | } | ||
1266 | |||
1456 | static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans, | 1267 | static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans, |
1457 | const struct iwl_cfg *cfg, | 1268 | const struct iwl_cfg *cfg, |
1458 | const struct iwl_fw *fw) | 1269 | const struct iwl_fw *fw) |
@@ -1538,7 +1349,7 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans, | |||
1538 | trans_cfg.queue_watchdog_timeout = | 1349 | trans_cfg.queue_watchdog_timeout = |
1539 | priv->cfg->base_params->wd_timeout; | 1350 | priv->cfg->base_params->wd_timeout; |
1540 | else | 1351 | else |
1541 | trans_cfg.queue_watchdog_timeout = IWL_WATCHHDOG_DISABLED; | 1352 | trans_cfg.queue_watchdog_timeout = IWL_WATCHDOG_DISABLED; |
1542 | trans_cfg.command_names = iwl_dvm_cmd_strings; | 1353 | trans_cfg.command_names = iwl_dvm_cmd_strings; |
1543 | 1354 | ||
1544 | ucode_flags = fw->ucode_capa.flags; | 1355 | ucode_flags = fw->ucode_capa.flags; |
@@ -1598,25 +1409,33 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans, | |||
1598 | goto out_free_hw; | 1409 | goto out_free_hw; |
1599 | 1410 | ||
1600 | /* Read the EEPROM */ | 1411 | /* Read the EEPROM */ |
1601 | if (iwl_eeprom_init(priv, priv->trans->hw_rev)) { | 1412 | if (iwl_read_eeprom(priv->trans, &priv->eeprom_blob, |
1413 | &priv->eeprom_blob_size)) { | ||
1602 | IWL_ERR(priv, "Unable to init EEPROM\n"); | 1414 | IWL_ERR(priv, "Unable to init EEPROM\n"); |
1603 | goto out_free_hw; | 1415 | goto out_free_hw; |
1604 | } | 1416 | } |
1417 | |||
1605 | /* Reset chip to save power until we load uCode during "up". */ | 1418 | /* Reset chip to save power until we load uCode during "up". */ |
1606 | iwl_trans_stop_hw(priv->trans, false); | 1419 | iwl_trans_stop_hw(priv->trans, false); |
1607 | 1420 | ||
1608 | if (iwl_eeprom_check_version(priv)) | 1421 | priv->eeprom_data = iwl_parse_eeprom_data(priv->trans->dev, priv->cfg, |
1422 | priv->eeprom_blob, | ||
1423 | priv->eeprom_blob_size); | ||
1424 | if (!priv->eeprom_data) | ||
1425 | goto out_free_eeprom_blob; | ||
1426 | |||
1427 | if (iwl_eeprom_check_version(priv->eeprom_data, priv->trans)) | ||
1609 | goto out_free_eeprom; | 1428 | goto out_free_eeprom; |
1610 | 1429 | ||
1611 | if (iwl_eeprom_init_hw_params(priv)) | 1430 | if (iwl_eeprom_init_hw_params(priv)) |
1612 | goto out_free_eeprom; | 1431 | goto out_free_eeprom; |
1613 | 1432 | ||
1614 | /* extract MAC Address */ | 1433 | /* extract MAC Address */ |
1615 | iwl_eeprom_get_mac(priv, priv->addresses[0].addr); | 1434 | memcpy(priv->addresses[0].addr, priv->eeprom_data->hw_addr, ETH_ALEN); |
1616 | IWL_DEBUG_INFO(priv, "MAC address: %pM\n", priv->addresses[0].addr); | 1435 | IWL_DEBUG_INFO(priv, "MAC address: %pM\n", priv->addresses[0].addr); |
1617 | priv->hw->wiphy->addresses = priv->addresses; | 1436 | priv->hw->wiphy->addresses = priv->addresses; |
1618 | priv->hw->wiphy->n_addresses = 1; | 1437 | priv->hw->wiphy->n_addresses = 1; |
1619 | num_mac = iwl_eeprom_query16(priv, EEPROM_NUM_MAC_ADDRESS); | 1438 | num_mac = priv->eeprom_data->n_hw_addrs; |
1620 | if (num_mac > 1) { | 1439 | if (num_mac > 1) { |
1621 | memcpy(priv->addresses[1].addr, priv->addresses[0].addr, | 1440 | memcpy(priv->addresses[1].addr, priv->addresses[0].addr, |
1622 | ETH_ALEN); | 1441 | ETH_ALEN); |
@@ -1710,8 +1529,10 @@ out_destroy_workqueue: | |||
1710 | destroy_workqueue(priv->workqueue); | 1529 | destroy_workqueue(priv->workqueue); |
1711 | priv->workqueue = NULL; | 1530 | priv->workqueue = NULL; |
1712 | iwl_uninit_drv(priv); | 1531 | iwl_uninit_drv(priv); |
1532 | out_free_eeprom_blob: | ||
1533 | kfree(priv->eeprom_blob); | ||
1713 | out_free_eeprom: | 1534 | out_free_eeprom: |
1714 | iwl_eeprom_free(priv); | 1535 | iwl_free_eeprom_data(priv->eeprom_data); |
1715 | out_free_hw: | 1536 | out_free_hw: |
1716 | ieee80211_free_hw(priv->hw); | 1537 | ieee80211_free_hw(priv->hw); |
1717 | out: | 1538 | out: |
@@ -1719,7 +1540,7 @@ out: | |||
1719 | return op_mode; | 1540 | return op_mode; |
1720 | } | 1541 | } |
1721 | 1542 | ||
1722 | void iwl_op_mode_dvm_stop(struct iwl_op_mode *op_mode) | 1543 | static void iwl_op_mode_dvm_stop(struct iwl_op_mode *op_mode) |
1723 | { | 1544 | { |
1724 | struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode); | 1545 | struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode); |
1725 | 1546 | ||
@@ -1736,7 +1557,8 @@ void iwl_op_mode_dvm_stop(struct iwl_op_mode *op_mode) | |||
1736 | priv->ucode_loaded = false; | 1557 | priv->ucode_loaded = false; |
1737 | iwl_trans_stop_device(priv->trans); | 1558 | iwl_trans_stop_device(priv->trans); |
1738 | 1559 | ||
1739 | iwl_eeprom_free(priv); | 1560 | kfree(priv->eeprom_blob); |
1561 | iwl_free_eeprom_data(priv->eeprom_data); | ||
1740 | 1562 | ||
1741 | /*netif_stop_queue(dev); */ | 1563 | /*netif_stop_queue(dev); */ |
1742 | flush_workqueue(priv->workqueue); | 1564 | flush_workqueue(priv->workqueue); |
@@ -2184,7 +2006,7 @@ static void iwlagn_fw_error(struct iwl_priv *priv, bool ondemand) | |||
2184 | } | 2006 | } |
2185 | } | 2007 | } |
2186 | 2008 | ||
2187 | void iwl_nic_error(struct iwl_op_mode *op_mode) | 2009 | static void iwl_nic_error(struct iwl_op_mode *op_mode) |
2188 | { | 2010 | { |
2189 | struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode); | 2011 | struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode); |
2190 | 2012 | ||
@@ -2197,7 +2019,7 @@ void iwl_nic_error(struct iwl_op_mode *op_mode) | |||
2197 | iwlagn_fw_error(priv, false); | 2019 | iwlagn_fw_error(priv, false); |
2198 | } | 2020 | } |
2199 | 2021 | ||
2200 | void iwl_cmd_queue_full(struct iwl_op_mode *op_mode) | 2022 | static void iwl_cmd_queue_full(struct iwl_op_mode *op_mode) |
2201 | { | 2023 | { |
2202 | struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode); | 2024 | struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode); |
2203 | 2025 | ||
@@ -2207,9 +2029,49 @@ void iwl_cmd_queue_full(struct iwl_op_mode *op_mode) | |||
2207 | } | 2029 | } |
2208 | } | 2030 | } |
2209 | 2031 | ||
2210 | void iwl_nic_config(struct iwl_op_mode *op_mode) | 2032 | #define EEPROM_RF_CONFIG_TYPE_MAX 0x3 |
2033 | |||
2034 | static void iwl_nic_config(struct iwl_op_mode *op_mode) | ||
2211 | { | 2035 | { |
2212 | struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode); | 2036 | struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode); |
2037 | u16 radio_cfg = priv->eeprom_data->radio_cfg; | ||
2038 | |||
2039 | /* SKU Control */ | ||
2040 | iwl_set_bits_mask(priv->trans, CSR_HW_IF_CONFIG_REG, | ||
2041 | CSR_HW_IF_CONFIG_REG_MSK_MAC_DASH | | ||
2042 | CSR_HW_IF_CONFIG_REG_MSK_MAC_STEP, | ||
2043 | (CSR_HW_REV_STEP(priv->trans->hw_rev) << | ||
2044 | CSR_HW_IF_CONFIG_REG_POS_MAC_STEP) | | ||
2045 | (CSR_HW_REV_DASH(priv->trans->hw_rev) << | ||
2046 | CSR_HW_IF_CONFIG_REG_POS_MAC_DASH)); | ||
2047 | |||
2048 | /* write radio config values to register */ | ||
2049 | if (EEPROM_RF_CFG_TYPE_MSK(radio_cfg) <= EEPROM_RF_CONFIG_TYPE_MAX) { | ||
2050 | u32 reg_val = | ||
2051 | EEPROM_RF_CFG_TYPE_MSK(radio_cfg) << | ||
2052 | CSR_HW_IF_CONFIG_REG_POS_PHY_TYPE | | ||
2053 | EEPROM_RF_CFG_STEP_MSK(radio_cfg) << | ||
2054 | CSR_HW_IF_CONFIG_REG_POS_PHY_STEP | | ||
2055 | EEPROM_RF_CFG_DASH_MSK(radio_cfg) << | ||
2056 | CSR_HW_IF_CONFIG_REG_POS_PHY_DASH; | ||
2057 | |||
2058 | iwl_set_bits_mask(priv->trans, CSR_HW_IF_CONFIG_REG, | ||
2059 | CSR_HW_IF_CONFIG_REG_MSK_PHY_TYPE | | ||
2060 | CSR_HW_IF_CONFIG_REG_MSK_PHY_STEP | | ||
2061 | CSR_HW_IF_CONFIG_REG_MSK_PHY_DASH, reg_val); | ||
2062 | |||
2063 | IWL_INFO(priv, "Radio type=0x%x-0x%x-0x%x\n", | ||
2064 | EEPROM_RF_CFG_TYPE_MSK(radio_cfg), | ||
2065 | EEPROM_RF_CFG_STEP_MSK(radio_cfg), | ||
2066 | EEPROM_RF_CFG_DASH_MSK(radio_cfg)); | ||
2067 | } else { | ||
2068 | WARN_ON(1); | ||
2069 | } | ||
2070 | |||
2071 | /* set CSR_HW_CONFIG_REG for uCode use */ | ||
2072 | iwl_set_bit(priv->trans, CSR_HW_IF_CONFIG_REG, | ||
2073 | CSR_HW_IF_CONFIG_REG_BIT_RADIO_SI | | ||
2074 | CSR_HW_IF_CONFIG_REG_BIT_MAC_SI); | ||
2213 | 2075 | ||
2214 | priv->lib->nic_config(priv); | 2076 | priv->lib->nic_config(priv); |
2215 | } | 2077 | } |
@@ -2222,7 +2084,7 @@ static void iwl_wimax_active(struct iwl_op_mode *op_mode) | |||
2222 | IWL_ERR(priv, "RF is used by WiMAX\n"); | 2084 | IWL_ERR(priv, "RF is used by WiMAX\n"); |
2223 | } | 2085 | } |
2224 | 2086 | ||
2225 | void iwl_stop_sw_queue(struct iwl_op_mode *op_mode, int queue) | 2087 | static void iwl_stop_sw_queue(struct iwl_op_mode *op_mode, int queue) |
2226 | { | 2088 | { |
2227 | struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode); | 2089 | struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode); |
2228 | int mq = priv->queue_to_mac80211[queue]; | 2090 | int mq = priv->queue_to_mac80211[queue]; |
@@ -2241,7 +2103,7 @@ void iwl_stop_sw_queue(struct iwl_op_mode *op_mode, int queue) | |||
2241 | ieee80211_stop_queue(priv->hw, mq); | 2103 | ieee80211_stop_queue(priv->hw, mq); |
2242 | } | 2104 | } |
2243 | 2105 | ||
2244 | void iwl_wake_sw_queue(struct iwl_op_mode *op_mode, int queue) | 2106 | static void iwl_wake_sw_queue(struct iwl_op_mode *op_mode, int queue) |
2245 | { | 2107 | { |
2246 | struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode); | 2108 | struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode); |
2247 | int mq = priv->queue_to_mac80211[queue]; | 2109 | int mq = priv->queue_to_mac80211[queue]; |
@@ -2281,16 +2143,17 @@ void iwlagn_lift_passive_no_rx(struct iwl_priv *priv) | |||
2281 | priv->passive_no_rx = false; | 2143 | priv->passive_no_rx = false; |
2282 | } | 2144 | } |
2283 | 2145 | ||
2284 | void iwl_free_skb(struct iwl_op_mode *op_mode, struct sk_buff *skb) | 2146 | static void iwl_free_skb(struct iwl_op_mode *op_mode, struct sk_buff *skb) |
2285 | { | 2147 | { |
2148 | struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode); | ||
2286 | struct ieee80211_tx_info *info; | 2149 | struct ieee80211_tx_info *info; |
2287 | 2150 | ||
2288 | info = IEEE80211_SKB_CB(skb); | 2151 | info = IEEE80211_SKB_CB(skb); |
2289 | kmem_cache_free(iwl_tx_cmd_pool, (info->driver_data[1])); | 2152 | iwl_trans_free_tx_cmd(priv->trans, info->driver_data[1]); |
2290 | dev_kfree_skb_any(skb); | 2153 | dev_kfree_skb_any(skb); |
2291 | } | 2154 | } |
2292 | 2155 | ||
2293 | void iwl_set_hw_rfkill_state(struct iwl_op_mode *op_mode, bool state) | 2156 | static void iwl_set_hw_rfkill_state(struct iwl_op_mode *op_mode, bool state) |
2294 | { | 2157 | { |
2295 | struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode); | 2158 | struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode); |
2296 | 2159 | ||
@@ -2302,7 +2165,7 @@ void iwl_set_hw_rfkill_state(struct iwl_op_mode *op_mode, bool state) | |||
2302 | wiphy_rfkill_set_hw_state(priv->hw->wiphy, state); | 2165 | wiphy_rfkill_set_hw_state(priv->hw->wiphy, state); |
2303 | } | 2166 | } |
2304 | 2167 | ||
2305 | const struct iwl_op_mode_ops iwl_dvm_ops = { | 2168 | static const struct iwl_op_mode_ops iwl_dvm_ops = { |
2306 | .start = iwl_op_mode_dvm_start, | 2169 | .start = iwl_op_mode_dvm_start, |
2307 | .stop = iwl_op_mode_dvm_stop, | 2170 | .stop = iwl_op_mode_dvm_stop, |
2308 | .rx = iwl_rx_dispatch, | 2171 | .rx = iwl_rx_dispatch, |
@@ -2321,9 +2184,6 @@ const struct iwl_op_mode_ops iwl_dvm_ops = { | |||
2321 | * driver and module entry point | 2184 | * driver and module entry point |
2322 | * | 2185 | * |
2323 | *****************************************************************************/ | 2186 | *****************************************************************************/ |
2324 | |||
2325 | struct kmem_cache *iwl_tx_cmd_pool; | ||
2326 | |||
2327 | static int __init iwl_init(void) | 2187 | static int __init iwl_init(void) |
2328 | { | 2188 | { |
2329 | 2189 | ||
@@ -2331,29 +2191,18 @@ static int __init iwl_init(void) | |||
2331 | pr_info(DRV_DESCRIPTION ", " DRV_VERSION "\n"); | 2191 | pr_info(DRV_DESCRIPTION ", " DRV_VERSION "\n"); |
2332 | pr_info(DRV_COPYRIGHT "\n"); | 2192 | pr_info(DRV_COPYRIGHT "\n"); |
2333 | 2193 | ||
2334 | iwl_tx_cmd_pool = kmem_cache_create("iwl_dev_cmd", | ||
2335 | sizeof(struct iwl_device_cmd), | ||
2336 | sizeof(void *), 0, NULL); | ||
2337 | if (!iwl_tx_cmd_pool) | ||
2338 | return -ENOMEM; | ||
2339 | |||
2340 | ret = iwlagn_rate_control_register(); | 2194 | ret = iwlagn_rate_control_register(); |
2341 | if (ret) { | 2195 | if (ret) { |
2342 | pr_err("Unable to register rate control algorithm: %d\n", ret); | 2196 | pr_err("Unable to register rate control algorithm: %d\n", ret); |
2343 | goto error_rc_register; | 2197 | return ret; |
2344 | } | 2198 | } |
2345 | 2199 | ||
2346 | ret = iwl_opmode_register("iwldvm", &iwl_dvm_ops); | 2200 | ret = iwl_opmode_register("iwldvm", &iwl_dvm_ops); |
2347 | if (ret) { | 2201 | if (ret) { |
2348 | pr_err("Unable to register op_mode: %d\n", ret); | 2202 | pr_err("Unable to register op_mode: %d\n", ret); |
2349 | goto error_opmode_register; | 2203 | iwlagn_rate_control_unregister(); |
2350 | } | 2204 | } |
2351 | return ret; | ||
2352 | 2205 | ||
2353 | error_opmode_register: | ||
2354 | iwlagn_rate_control_unregister(); | ||
2355 | error_rc_register: | ||
2356 | kmem_cache_destroy(iwl_tx_cmd_pool); | ||
2357 | return ret; | 2206 | return ret; |
2358 | } | 2207 | } |
2359 | module_init(iwl_init); | 2208 | module_init(iwl_init); |
@@ -2362,6 +2211,5 @@ static void __exit iwl_exit(void) | |||
2362 | { | 2211 | { |
2363 | iwl_opmode_deregister("iwldvm"); | 2212 | iwl_opmode_deregister("iwldvm"); |
2364 | iwlagn_rate_control_unregister(); | 2213 | iwlagn_rate_control_unregister(); |
2365 | kmem_cache_destroy(iwl_tx_cmd_pool); | ||
2366 | } | 2214 | } |
2367 | module_exit(iwl_exit); | 2215 | module_exit(iwl_exit); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-power.c b/drivers/net/wireless/iwlwifi/dvm/power.c index 544ddf17f5bd..518cf3715809 100644 --- a/drivers/net/wireless/iwlwifi/iwl-power.c +++ b/drivers/net/wireless/iwlwifi/dvm/power.c | |||
@@ -31,18 +31,15 @@ | |||
31 | #include <linux/module.h> | 31 | #include <linux/module.h> |
32 | #include <linux/slab.h> | 32 | #include <linux/slab.h> |
33 | #include <linux/init.h> | 33 | #include <linux/init.h> |
34 | |||
35 | #include <net/mac80211.h> | 34 | #include <net/mac80211.h> |
36 | |||
37 | #include "iwl-eeprom.h" | ||
38 | #include "iwl-dev.h" | ||
39 | #include "iwl-agn.h" | ||
40 | #include "iwl-io.h" | 35 | #include "iwl-io.h" |
41 | #include "iwl-commands.h" | ||
42 | #include "iwl-debug.h" | 36 | #include "iwl-debug.h" |
43 | #include "iwl-power.h" | ||
44 | #include "iwl-trans.h" | 37 | #include "iwl-trans.h" |
45 | #include "iwl-modparams.h" | 38 | #include "iwl-modparams.h" |
39 | #include "dev.h" | ||
40 | #include "agn.h" | ||
41 | #include "commands.h" | ||
42 | #include "power.h" | ||
46 | 43 | ||
47 | /* | 44 | /* |
48 | * Setting power level allows the card to go to sleep when not busy. | 45 | * Setting power level allows the card to go to sleep when not busy. |
diff --git a/drivers/net/wireless/iwlwifi/iwl-power.h b/drivers/net/wireless/iwlwifi/dvm/power.h index 21afc92efacb..a2cee7f04848 100644 --- a/drivers/net/wireless/iwlwifi/iwl-power.h +++ b/drivers/net/wireless/iwlwifi/dvm/power.h | |||
@@ -28,7 +28,7 @@ | |||
28 | #ifndef __iwl_power_setting_h__ | 28 | #ifndef __iwl_power_setting_h__ |
29 | #define __iwl_power_setting_h__ | 29 | #define __iwl_power_setting_h__ |
30 | 30 | ||
31 | #include "iwl-commands.h" | 31 | #include "commands.h" |
32 | 32 | ||
33 | struct iwl_power_mgr { | 33 | struct iwl_power_mgr { |
34 | struct iwl_powertable_cmd sleep_cmd; | 34 | struct iwl_powertable_cmd sleep_cmd; |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/dvm/rs.c index 8cebd7c363fc..6fddd2785e6e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c +++ b/drivers/net/wireless/iwlwifi/dvm/rs.c | |||
@@ -35,10 +35,8 @@ | |||
35 | 35 | ||
36 | #include <linux/workqueue.h> | 36 | #include <linux/workqueue.h> |
37 | 37 | ||
38 | #include "iwl-dev.h" | 38 | #include "dev.h" |
39 | #include "iwl-agn.h" | 39 | #include "agn.h" |
40 | #include "iwl-op-mode.h" | ||
41 | #include "iwl-modparams.h" | ||
42 | 40 | ||
43 | #define RS_NAME "iwl-agn-rs" | 41 | #define RS_NAME "iwl-agn-rs" |
44 | 42 | ||
@@ -819,7 +817,7 @@ static u32 rs_get_lower_rate(struct iwl_lq_sta *lq_sta, | |||
819 | 817 | ||
820 | if (num_of_ant(tbl->ant_type) > 1) | 818 | if (num_of_ant(tbl->ant_type) > 1) |
821 | tbl->ant_type = | 819 | tbl->ant_type = |
822 | first_antenna(priv->hw_params.valid_tx_ant); | 820 | first_antenna(priv->eeprom_data->valid_tx_ant); |
823 | 821 | ||
824 | tbl->is_ht40 = 0; | 822 | tbl->is_ht40 = 0; |
825 | tbl->is_SGI = 0; | 823 | tbl->is_SGI = 0; |
@@ -1447,7 +1445,7 @@ static int rs_move_legacy_other(struct iwl_priv *priv, | |||
1447 | u32 sz = (sizeof(struct iwl_scale_tbl_info) - | 1445 | u32 sz = (sizeof(struct iwl_scale_tbl_info) - |
1448 | (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT)); | 1446 | (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT)); |
1449 | u8 start_action; | 1447 | u8 start_action; |
1450 | u8 valid_tx_ant = priv->hw_params.valid_tx_ant; | 1448 | u8 valid_tx_ant = priv->eeprom_data->valid_tx_ant; |
1451 | u8 tx_chains_num = priv->hw_params.tx_chains_num; | 1449 | u8 tx_chains_num = priv->hw_params.tx_chains_num; |
1452 | int ret = 0; | 1450 | int ret = 0; |
1453 | u8 update_search_tbl_counter = 0; | 1451 | u8 update_search_tbl_counter = 0; |
@@ -1465,7 +1463,7 @@ static int rs_move_legacy_other(struct iwl_priv *priv, | |||
1465 | case IWL_BT_COEX_TRAFFIC_LOAD_CONTINUOUS: | 1463 | case IWL_BT_COEX_TRAFFIC_LOAD_CONTINUOUS: |
1466 | /* avoid antenna B and MIMO */ | 1464 | /* avoid antenna B and MIMO */ |
1467 | valid_tx_ant = | 1465 | valid_tx_ant = |
1468 | first_antenna(priv->hw_params.valid_tx_ant); | 1466 | first_antenna(priv->eeprom_data->valid_tx_ant); |
1469 | if (tbl->action >= IWL_LEGACY_SWITCH_ANTENNA2 && | 1467 | if (tbl->action >= IWL_LEGACY_SWITCH_ANTENNA2 && |
1470 | tbl->action != IWL_LEGACY_SWITCH_SISO) | 1468 | tbl->action != IWL_LEGACY_SWITCH_SISO) |
1471 | tbl->action = IWL_LEGACY_SWITCH_SISO; | 1469 | tbl->action = IWL_LEGACY_SWITCH_SISO; |
@@ -1489,7 +1487,7 @@ static int rs_move_legacy_other(struct iwl_priv *priv, | |||
1489 | else if (tbl->action >= IWL_LEGACY_SWITCH_ANTENNA2) | 1487 | else if (tbl->action >= IWL_LEGACY_SWITCH_ANTENNA2) |
1490 | tbl->action = IWL_LEGACY_SWITCH_SISO; | 1488 | tbl->action = IWL_LEGACY_SWITCH_SISO; |
1491 | valid_tx_ant = | 1489 | valid_tx_ant = |
1492 | first_antenna(priv->hw_params.valid_tx_ant); | 1490 | first_antenna(priv->eeprom_data->valid_tx_ant); |
1493 | } | 1491 | } |
1494 | 1492 | ||
1495 | start_action = tbl->action; | 1493 | start_action = tbl->action; |
@@ -1623,7 +1621,7 @@ static int rs_move_siso_to_other(struct iwl_priv *priv, | |||
1623 | u32 sz = (sizeof(struct iwl_scale_tbl_info) - | 1621 | u32 sz = (sizeof(struct iwl_scale_tbl_info) - |
1624 | (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT)); | 1622 | (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT)); |
1625 | u8 start_action; | 1623 | u8 start_action; |
1626 | u8 valid_tx_ant = priv->hw_params.valid_tx_ant; | 1624 | u8 valid_tx_ant = priv->eeprom_data->valid_tx_ant; |
1627 | u8 tx_chains_num = priv->hw_params.tx_chains_num; | 1625 | u8 tx_chains_num = priv->hw_params.tx_chains_num; |
1628 | u8 update_search_tbl_counter = 0; | 1626 | u8 update_search_tbl_counter = 0; |
1629 | int ret; | 1627 | int ret; |
@@ -1641,7 +1639,7 @@ static int rs_move_siso_to_other(struct iwl_priv *priv, | |||
1641 | case IWL_BT_COEX_TRAFFIC_LOAD_CONTINUOUS: | 1639 | case IWL_BT_COEX_TRAFFIC_LOAD_CONTINUOUS: |
1642 | /* avoid antenna B and MIMO */ | 1640 | /* avoid antenna B and MIMO */ |
1643 | valid_tx_ant = | 1641 | valid_tx_ant = |
1644 | first_antenna(priv->hw_params.valid_tx_ant); | 1642 | first_antenna(priv->eeprom_data->valid_tx_ant); |
1645 | if (tbl->action != IWL_SISO_SWITCH_ANTENNA1) | 1643 | if (tbl->action != IWL_SISO_SWITCH_ANTENNA1) |
1646 | tbl->action = IWL_SISO_SWITCH_ANTENNA1; | 1644 | tbl->action = IWL_SISO_SWITCH_ANTENNA1; |
1647 | break; | 1645 | break; |
@@ -1659,7 +1657,7 @@ static int rs_move_siso_to_other(struct iwl_priv *priv, | |||
1659 | /* configure as 1x1 if bt full concurrency */ | 1657 | /* configure as 1x1 if bt full concurrency */ |
1660 | if (priv->bt_full_concurrent) { | 1658 | if (priv->bt_full_concurrent) { |
1661 | valid_tx_ant = | 1659 | valid_tx_ant = |
1662 | first_antenna(priv->hw_params.valid_tx_ant); | 1660 | first_antenna(priv->eeprom_data->valid_tx_ant); |
1663 | if (tbl->action >= IWL_LEGACY_SWITCH_ANTENNA2) | 1661 | if (tbl->action >= IWL_LEGACY_SWITCH_ANTENNA2) |
1664 | tbl->action = IWL_SISO_SWITCH_ANTENNA1; | 1662 | tbl->action = IWL_SISO_SWITCH_ANTENNA1; |
1665 | } | 1663 | } |
@@ -1795,7 +1793,7 @@ static int rs_move_mimo2_to_other(struct iwl_priv *priv, | |||
1795 | u32 sz = (sizeof(struct iwl_scale_tbl_info) - | 1793 | u32 sz = (sizeof(struct iwl_scale_tbl_info) - |
1796 | (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT)); | 1794 | (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT)); |
1797 | u8 start_action; | 1795 | u8 start_action; |
1798 | u8 valid_tx_ant = priv->hw_params.valid_tx_ant; | 1796 | u8 valid_tx_ant = priv->eeprom_data->valid_tx_ant; |
1799 | u8 tx_chains_num = priv->hw_params.tx_chains_num; | 1797 | u8 tx_chains_num = priv->hw_params.tx_chains_num; |
1800 | u8 update_search_tbl_counter = 0; | 1798 | u8 update_search_tbl_counter = 0; |
1801 | int ret; | 1799 | int ret; |
@@ -1965,7 +1963,7 @@ static int rs_move_mimo3_to_other(struct iwl_priv *priv, | |||
1965 | u32 sz = (sizeof(struct iwl_scale_tbl_info) - | 1963 | u32 sz = (sizeof(struct iwl_scale_tbl_info) - |
1966 | (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT)); | 1964 | (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT)); |
1967 | u8 start_action; | 1965 | u8 start_action; |
1968 | u8 valid_tx_ant = priv->hw_params.valid_tx_ant; | 1966 | u8 valid_tx_ant = priv->eeprom_data->valid_tx_ant; |
1969 | u8 tx_chains_num = priv->hw_params.tx_chains_num; | 1967 | u8 tx_chains_num = priv->hw_params.tx_chains_num; |
1970 | int ret; | 1968 | int ret; |
1971 | u8 update_search_tbl_counter = 0; | 1969 | u8 update_search_tbl_counter = 0; |
@@ -2699,7 +2697,7 @@ static void rs_initialize_lq(struct iwl_priv *priv, | |||
2699 | 2697 | ||
2700 | i = lq_sta->last_txrate_idx; | 2698 | i = lq_sta->last_txrate_idx; |
2701 | 2699 | ||
2702 | valid_tx_ant = priv->hw_params.valid_tx_ant; | 2700 | valid_tx_ant = priv->eeprom_data->valid_tx_ant; |
2703 | 2701 | ||
2704 | if (!lq_sta->search_better_tbl) | 2702 | if (!lq_sta->search_better_tbl) |
2705 | active_tbl = lq_sta->active_tbl; | 2703 | active_tbl = lq_sta->active_tbl; |
@@ -2893,15 +2891,15 @@ void iwl_rs_rate_init(struct iwl_priv *priv, struct ieee80211_sta *sta, u8 sta_i | |||
2893 | 2891 | ||
2894 | /* These values will be overridden later */ | 2892 | /* These values will be overridden later */ |
2895 | lq_sta->lq.general_params.single_stream_ant_msk = | 2893 | lq_sta->lq.general_params.single_stream_ant_msk = |
2896 | first_antenna(priv->hw_params.valid_tx_ant); | 2894 | first_antenna(priv->eeprom_data->valid_tx_ant); |
2897 | lq_sta->lq.general_params.dual_stream_ant_msk = | 2895 | lq_sta->lq.general_params.dual_stream_ant_msk = |
2898 | priv->hw_params.valid_tx_ant & | 2896 | priv->eeprom_data->valid_tx_ant & |
2899 | ~first_antenna(priv->hw_params.valid_tx_ant); | 2897 | ~first_antenna(priv->eeprom_data->valid_tx_ant); |
2900 | if (!lq_sta->lq.general_params.dual_stream_ant_msk) { | 2898 | if (!lq_sta->lq.general_params.dual_stream_ant_msk) { |
2901 | lq_sta->lq.general_params.dual_stream_ant_msk = ANT_AB; | 2899 | lq_sta->lq.general_params.dual_stream_ant_msk = ANT_AB; |
2902 | } else if (num_of_ant(priv->hw_params.valid_tx_ant) == 2) { | 2900 | } else if (num_of_ant(priv->eeprom_data->valid_tx_ant) == 2) { |
2903 | lq_sta->lq.general_params.dual_stream_ant_msk = | 2901 | lq_sta->lq.general_params.dual_stream_ant_msk = |
2904 | priv->hw_params.valid_tx_ant; | 2902 | priv->eeprom_data->valid_tx_ant; |
2905 | } | 2903 | } |
2906 | 2904 | ||
2907 | /* as default allow aggregation for all tids */ | 2905 | /* as default allow aggregation for all tids */ |
@@ -2947,7 +2945,7 @@ static void rs_fill_link_cmd(struct iwl_priv *priv, | |||
2947 | if (priv && priv->bt_full_concurrent) { | 2945 | if (priv && priv->bt_full_concurrent) { |
2948 | /* 1x1 only */ | 2946 | /* 1x1 only */ |
2949 | tbl_type.ant_type = | 2947 | tbl_type.ant_type = |
2950 | first_antenna(priv->hw_params.valid_tx_ant); | 2948 | first_antenna(priv->eeprom_data->valid_tx_ant); |
2951 | } | 2949 | } |
2952 | 2950 | ||
2953 | /* How many times should we repeat the initial rate? */ | 2951 | /* How many times should we repeat the initial rate? */ |
@@ -2979,7 +2977,7 @@ static void rs_fill_link_cmd(struct iwl_priv *priv, | |||
2979 | if (priv->bt_full_concurrent) | 2977 | if (priv->bt_full_concurrent) |
2980 | valid_tx_ant = ANT_A; | 2978 | valid_tx_ant = ANT_A; |
2981 | else | 2979 | else |
2982 | valid_tx_ant = priv->hw_params.valid_tx_ant; | 2980 | valid_tx_ant = priv->eeprom_data->valid_tx_ant; |
2983 | } | 2981 | } |
2984 | 2982 | ||
2985 | /* Fill rest of rate table */ | 2983 | /* Fill rest of rate table */ |
@@ -3013,7 +3011,7 @@ static void rs_fill_link_cmd(struct iwl_priv *priv, | |||
3013 | if (priv && priv->bt_full_concurrent) { | 3011 | if (priv && priv->bt_full_concurrent) { |
3014 | /* 1x1 only */ | 3012 | /* 1x1 only */ |
3015 | tbl_type.ant_type = | 3013 | tbl_type.ant_type = |
3016 | first_antenna(priv->hw_params.valid_tx_ant); | 3014 | first_antenna(priv->eeprom_data->valid_tx_ant); |
3017 | } | 3015 | } |
3018 | 3016 | ||
3019 | /* Indicate to uCode which entries might be MIMO. | 3017 | /* Indicate to uCode which entries might be MIMO. |
@@ -3100,7 +3098,7 @@ static void rs_dbgfs_set_mcs(struct iwl_lq_sta *lq_sta, | |||
3100 | u8 ant_sel_tx; | 3098 | u8 ant_sel_tx; |
3101 | 3099 | ||
3102 | priv = lq_sta->drv; | 3100 | priv = lq_sta->drv; |
3103 | valid_tx_ant = priv->hw_params.valid_tx_ant; | 3101 | valid_tx_ant = priv->eeprom_data->valid_tx_ant; |
3104 | if (lq_sta->dbg_fixed_rate) { | 3102 | if (lq_sta->dbg_fixed_rate) { |
3105 | ant_sel_tx = | 3103 | ant_sel_tx = |
3106 | ((lq_sta->dbg_fixed_rate & RATE_MCS_ANT_ABC_MSK) | 3104 | ((lq_sta->dbg_fixed_rate & RATE_MCS_ANT_ABC_MSK) |
@@ -3171,9 +3169,9 @@ static ssize_t rs_sta_dbgfs_scale_table_read(struct file *file, | |||
3171 | desc += sprintf(buff+desc, "fixed rate 0x%X\n", | 3169 | desc += sprintf(buff+desc, "fixed rate 0x%X\n", |
3172 | lq_sta->dbg_fixed_rate); | 3170 | lq_sta->dbg_fixed_rate); |
3173 | desc += sprintf(buff+desc, "valid_tx_ant %s%s%s\n", | 3171 | desc += sprintf(buff+desc, "valid_tx_ant %s%s%s\n", |
3174 | (priv->hw_params.valid_tx_ant & ANT_A) ? "ANT_A," : "", | 3172 | (priv->eeprom_data->valid_tx_ant & ANT_A) ? "ANT_A," : "", |
3175 | (priv->hw_params.valid_tx_ant & ANT_B) ? "ANT_B," : "", | 3173 | (priv->eeprom_data->valid_tx_ant & ANT_B) ? "ANT_B," : "", |
3176 | (priv->hw_params.valid_tx_ant & ANT_C) ? "ANT_C" : ""); | 3174 | (priv->eeprom_data->valid_tx_ant & ANT_C) ? "ANT_C" : ""); |
3177 | desc += sprintf(buff+desc, "lq type %s\n", | 3175 | desc += sprintf(buff+desc, "lq type %s\n", |
3178 | (is_legacy(tbl->lq_type)) ? "legacy" : "HT"); | 3176 | (is_legacy(tbl->lq_type)) ? "legacy" : "HT"); |
3179 | if (is_Ht(tbl->lq_type)) { | 3177 | if (is_Ht(tbl->lq_type)) { |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.h b/drivers/net/wireless/iwlwifi/dvm/rs.h index 82d02e1ae89f..ad3aea8f626a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.h +++ b/drivers/net/wireless/iwlwifi/dvm/rs.h | |||
@@ -29,9 +29,10 @@ | |||
29 | 29 | ||
30 | #include <net/mac80211.h> | 30 | #include <net/mac80211.h> |
31 | 31 | ||
32 | #include "iwl-commands.h" | ||
33 | #include "iwl-config.h" | 32 | #include "iwl-config.h" |
34 | 33 | ||
34 | #include "commands.h" | ||
35 | |||
35 | struct iwl_rate_info { | 36 | struct iwl_rate_info { |
36 | u8 plcp; /* uCode API: IWL_RATE_6M_PLCP, etc. */ | 37 | u8 plcp; /* uCode API: IWL_RATE_6M_PLCP, etc. */ |
37 | u8 plcp_siso; /* uCode API: IWL_RATE_SISO_6M_PLCP, etc. */ | 38 | u8 plcp_siso; /* uCode API: IWL_RATE_SISO_6M_PLCP, etc. */ |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rx.c b/drivers/net/wireless/iwlwifi/dvm/rx.c index 403de96f9747..0ed90bb8b56a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rx.c +++ b/drivers/net/wireless/iwlwifi/dvm/rx.c | |||
@@ -32,12 +32,10 @@ | |||
32 | #include <linux/sched.h> | 32 | #include <linux/sched.h> |
33 | #include <net/mac80211.h> | 33 | #include <net/mac80211.h> |
34 | #include <asm/unaligned.h> | 34 | #include <asm/unaligned.h> |
35 | #include "iwl-eeprom.h" | ||
36 | #include "iwl-dev.h" | ||
37 | #include "iwl-io.h" | 35 | #include "iwl-io.h" |
38 | #include "iwl-agn-calib.h" | 36 | #include "dev.h" |
39 | #include "iwl-agn.h" | 37 | #include "calib.h" |
40 | #include "iwl-modparams.h" | 38 | #include "agn.h" |
41 | 39 | ||
42 | #define IWL_CMD_ENTRY(x) [x] = #x | 40 | #define IWL_CMD_ENTRY(x) [x] = #x |
43 | 41 | ||
@@ -1012,6 +1010,8 @@ static int iwlagn_rx_reply_rx(struct iwl_priv *priv, | |||
1012 | rx_status.flag |= RX_FLAG_40MHZ; | 1010 | rx_status.flag |= RX_FLAG_40MHZ; |
1013 | if (rate_n_flags & RATE_MCS_SGI_MSK) | 1011 | if (rate_n_flags & RATE_MCS_SGI_MSK) |
1014 | rx_status.flag |= RX_FLAG_SHORT_GI; | 1012 | rx_status.flag |= RX_FLAG_SHORT_GI; |
1013 | if (rate_n_flags & RATE_MCS_GF_MSK) | ||
1014 | rx_status.flag |= RX_FLAG_HT_GF; | ||
1015 | 1015 | ||
1016 | iwlagn_pass_packet_to_mac80211(priv, header, len, ampdu_status, | 1016 | iwlagn_pass_packet_to_mac80211(priv, header, len, ampdu_status, |
1017 | rxb, &rx_status); | 1017 | rxb, &rx_status); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c b/drivers/net/wireless/iwlwifi/dvm/rxon.c index 0a3aa7c83003..6ee940f497f9 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c +++ b/drivers/net/wireless/iwlwifi/dvm/rxon.c | |||
@@ -25,11 +25,11 @@ | |||
25 | *****************************************************************************/ | 25 | *****************************************************************************/ |
26 | 26 | ||
27 | #include <linux/etherdevice.h> | 27 | #include <linux/etherdevice.h> |
28 | #include "iwl-dev.h" | ||
29 | #include "iwl-agn.h" | ||
30 | #include "iwl-agn-calib.h" | ||
31 | #include "iwl-trans.h" | 28 | #include "iwl-trans.h" |
32 | #include "iwl-modparams.h" | 29 | #include "iwl-modparams.h" |
30 | #include "dev.h" | ||
31 | #include "agn.h" | ||
32 | #include "calib.h" | ||
33 | 33 | ||
34 | /* | 34 | /* |
35 | * initialize rxon structure with default values from eeprom | 35 | * initialize rxon structure with default values from eeprom |
@@ -37,8 +37,6 @@ | |||
37 | void iwl_connection_init_rx_config(struct iwl_priv *priv, | 37 | void iwl_connection_init_rx_config(struct iwl_priv *priv, |
38 | struct iwl_rxon_context *ctx) | 38 | struct iwl_rxon_context *ctx) |
39 | { | 39 | { |
40 | const struct iwl_channel_info *ch_info; | ||
41 | |||
42 | memset(&ctx->staging, 0, sizeof(ctx->staging)); | 40 | memset(&ctx->staging, 0, sizeof(ctx->staging)); |
43 | 41 | ||
44 | if (!ctx->vif) { | 42 | if (!ctx->vif) { |
@@ -80,14 +78,8 @@ void iwl_connection_init_rx_config(struct iwl_priv *priv, | |||
80 | ctx->staging.flags |= RXON_FLG_SHORT_PREAMBLE_MSK; | 78 | ctx->staging.flags |= RXON_FLG_SHORT_PREAMBLE_MSK; |
81 | #endif | 79 | #endif |
82 | 80 | ||
83 | ch_info = iwl_get_channel_info(priv, priv->band, | 81 | ctx->staging.channel = cpu_to_le16(priv->hw->conf.channel->hw_value); |
84 | le16_to_cpu(ctx->active.channel)); | 82 | priv->band = priv->hw->conf.channel->band; |
85 | |||
86 | if (!ch_info) | ||
87 | ch_info = &priv->channel_info[0]; | ||
88 | |||
89 | ctx->staging.channel = cpu_to_le16(ch_info->channel); | ||
90 | priv->band = ch_info->band; | ||
91 | 83 | ||
92 | iwl_set_flags_for_band(priv, ctx, priv->band, ctx->vif); | 84 | iwl_set_flags_for_band(priv, ctx, priv->band, ctx->vif); |
93 | 85 | ||
@@ -175,7 +167,8 @@ static int iwlagn_disconn_pan(struct iwl_priv *priv, | |||
175 | return ret; | 167 | return ret; |
176 | } | 168 | } |
177 | 169 | ||
178 | void iwlagn_update_qos(struct iwl_priv *priv, struct iwl_rxon_context *ctx) | 170 | static void iwlagn_update_qos(struct iwl_priv *priv, |
171 | struct iwl_rxon_context *ctx) | ||
179 | { | 172 | { |
180 | int ret; | 173 | int ret; |
181 | 174 | ||
@@ -202,8 +195,8 @@ void iwlagn_update_qos(struct iwl_priv *priv, struct iwl_rxon_context *ctx) | |||
202 | IWL_DEBUG_QUIET_RFKILL(priv, "Failed to update QoS\n"); | 195 | IWL_DEBUG_QUIET_RFKILL(priv, "Failed to update QoS\n"); |
203 | } | 196 | } |
204 | 197 | ||
205 | int iwlagn_update_beacon(struct iwl_priv *priv, | 198 | static int iwlagn_update_beacon(struct iwl_priv *priv, |
206 | struct ieee80211_vif *vif) | 199 | struct ieee80211_vif *vif) |
207 | { | 200 | { |
208 | lockdep_assert_held(&priv->mutex); | 201 | lockdep_assert_held(&priv->mutex); |
209 | 202 | ||
@@ -215,7 +208,7 @@ int iwlagn_update_beacon(struct iwl_priv *priv, | |||
215 | } | 208 | } |
216 | 209 | ||
217 | static int iwlagn_send_rxon_assoc(struct iwl_priv *priv, | 210 | static int iwlagn_send_rxon_assoc(struct iwl_priv *priv, |
218 | struct iwl_rxon_context *ctx) | 211 | struct iwl_rxon_context *ctx) |
219 | { | 212 | { |
220 | int ret = 0; | 213 | int ret = 0; |
221 | struct iwl_rxon_assoc_cmd rxon_assoc; | 214 | struct iwl_rxon_assoc_cmd rxon_assoc; |
@@ -427,10 +420,10 @@ static int iwl_set_tx_power(struct iwl_priv *priv, s8 tx_power, bool force) | |||
427 | return -EINVAL; | 420 | return -EINVAL; |
428 | } | 421 | } |
429 | 422 | ||
430 | if (tx_power > priv->tx_power_device_lmt) { | 423 | if (tx_power > DIV_ROUND_UP(priv->eeprom_data->max_tx_pwr_half_dbm, 2)) { |
431 | IWL_WARN(priv, | 424 | IWL_WARN(priv, |
432 | "Requested user TXPOWER %d above upper limit %d.\n", | 425 | "Requested user TXPOWER %d above upper limit %d.\n", |
433 | tx_power, priv->tx_power_device_lmt); | 426 | tx_power, priv->eeprom_data->max_tx_pwr_half_dbm); |
434 | return -EINVAL; | 427 | return -EINVAL; |
435 | } | 428 | } |
436 | 429 | ||
@@ -863,8 +856,8 @@ static int iwl_check_rxon_cmd(struct iwl_priv *priv, | |||
863 | * or is clearing the RXON_FILTER_ASSOC_MSK, then return 1 to indicate that | 856 | * or is clearing the RXON_FILTER_ASSOC_MSK, then return 1 to indicate that |
864 | * a new tune (full RXON command, rather than RXON_ASSOC cmd) is required. | 857 | * a new tune (full RXON command, rather than RXON_ASSOC cmd) is required. |
865 | */ | 858 | */ |
866 | int iwl_full_rxon_required(struct iwl_priv *priv, | 859 | static int iwl_full_rxon_required(struct iwl_priv *priv, |
867 | struct iwl_rxon_context *ctx) | 860 | struct iwl_rxon_context *ctx) |
868 | { | 861 | { |
869 | const struct iwl_rxon_cmd *staging = &ctx->staging; | 862 | const struct iwl_rxon_cmd *staging = &ctx->staging; |
870 | const struct iwl_rxon_cmd *active = &ctx->active; | 863 | const struct iwl_rxon_cmd *active = &ctx->active; |
@@ -1189,7 +1182,6 @@ int iwlagn_mac_config(struct ieee80211_hw *hw, u32 changed) | |||
1189 | struct iwl_rxon_context *ctx; | 1182 | struct iwl_rxon_context *ctx; |
1190 | struct ieee80211_conf *conf = &hw->conf; | 1183 | struct ieee80211_conf *conf = &hw->conf; |
1191 | struct ieee80211_channel *channel = conf->channel; | 1184 | struct ieee80211_channel *channel = conf->channel; |
1192 | const struct iwl_channel_info *ch_info; | ||
1193 | int ret = 0; | 1185 | int ret = 0; |
1194 | 1186 | ||
1195 | IWL_DEBUG_MAC80211(priv, "enter: changed %#x\n", changed); | 1187 | IWL_DEBUG_MAC80211(priv, "enter: changed %#x\n", changed); |
@@ -1223,14 +1215,6 @@ int iwlagn_mac_config(struct ieee80211_hw *hw, u32 changed) | |||
1223 | } | 1215 | } |
1224 | 1216 | ||
1225 | if (changed & IEEE80211_CONF_CHANGE_CHANNEL) { | 1217 | if (changed & IEEE80211_CONF_CHANGE_CHANNEL) { |
1226 | ch_info = iwl_get_channel_info(priv, channel->band, | ||
1227 | channel->hw_value); | ||
1228 | if (!is_channel_valid(ch_info)) { | ||
1229 | IWL_DEBUG_MAC80211(priv, "leave - invalid channel\n"); | ||
1230 | ret = -EINVAL; | ||
1231 | goto out; | ||
1232 | } | ||
1233 | |||
1234 | for_each_context(priv, ctx) { | 1218 | for_each_context(priv, ctx) { |
1235 | /* Configure HT40 channels */ | 1219 | /* Configure HT40 channels */ |
1236 | if (ctx->ht.enabled != conf_is_ht(conf)) | 1220 | if (ctx->ht.enabled != conf_is_ht(conf)) |
@@ -1294,9 +1278,9 @@ int iwlagn_mac_config(struct ieee80211_hw *hw, u32 changed) | |||
1294 | return ret; | 1278 | return ret; |
1295 | } | 1279 | } |
1296 | 1280 | ||
1297 | void iwlagn_check_needed_chains(struct iwl_priv *priv, | 1281 | static void iwlagn_check_needed_chains(struct iwl_priv *priv, |
1298 | struct iwl_rxon_context *ctx, | 1282 | struct iwl_rxon_context *ctx, |
1299 | struct ieee80211_bss_conf *bss_conf) | 1283 | struct ieee80211_bss_conf *bss_conf) |
1300 | { | 1284 | { |
1301 | struct ieee80211_vif *vif = ctx->vif; | 1285 | struct ieee80211_vif *vif = ctx->vif; |
1302 | struct iwl_rxon_context *tmp; | 1286 | struct iwl_rxon_context *tmp; |
@@ -1388,7 +1372,7 @@ void iwlagn_check_needed_chains(struct iwl_priv *priv, | |||
1388 | ht_conf->single_chain_sufficient = !need_multiple; | 1372 | ht_conf->single_chain_sufficient = !need_multiple; |
1389 | } | 1373 | } |
1390 | 1374 | ||
1391 | void iwlagn_chain_noise_reset(struct iwl_priv *priv) | 1375 | static void iwlagn_chain_noise_reset(struct iwl_priv *priv) |
1392 | { | 1376 | { |
1393 | struct iwl_chain_noise_data *data = &priv->chain_noise_data; | 1377 | struct iwl_chain_noise_data *data = &priv->chain_noise_data; |
1394 | int ret; | 1378 | int ret; |
diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/dvm/scan.c index 031d8e21f82f..2f271c96ed39 100644 --- a/drivers/net/wireless/iwlwifi/iwl-scan.c +++ b/drivers/net/wireless/iwlwifi/dvm/scan.c | |||
@@ -30,11 +30,8 @@ | |||
30 | #include <linux/etherdevice.h> | 30 | #include <linux/etherdevice.h> |
31 | #include <net/mac80211.h> | 31 | #include <net/mac80211.h> |
32 | 32 | ||
33 | #include "iwl-eeprom.h" | 33 | #include "dev.h" |
34 | #include "iwl-dev.h" | 34 | #include "agn.h" |
35 | #include "iwl-io.h" | ||
36 | #include "iwl-agn.h" | ||
37 | #include "iwl-trans.h" | ||
38 | 35 | ||
39 | /* For active scan, listen ACTIVE_DWELL_TIME (msec) on each channel after | 36 | /* For active scan, listen ACTIVE_DWELL_TIME (msec) on each channel after |
40 | * sending probe req. This should be set long enough to hear probe responses | 37 | * sending probe req. This should be set long enough to hear probe responses |
@@ -67,7 +64,6 @@ static int iwl_send_scan_abort(struct iwl_priv *priv) | |||
67 | * to receive scan abort command or it does not perform | 64 | * to receive scan abort command or it does not perform |
68 | * hardware scan currently */ | 65 | * hardware scan currently */ |
69 | if (!test_bit(STATUS_READY, &priv->status) || | 66 | if (!test_bit(STATUS_READY, &priv->status) || |
70 | !test_bit(STATUS_GEO_CONFIGURED, &priv->status) || | ||
71 | !test_bit(STATUS_SCAN_HW, &priv->status) || | 67 | !test_bit(STATUS_SCAN_HW, &priv->status) || |
72 | test_bit(STATUS_FW_ERROR, &priv->status)) | 68 | test_bit(STATUS_FW_ERROR, &priv->status)) |
73 | return -EIO; | 69 | return -EIO; |
@@ -101,11 +97,8 @@ static void iwl_complete_scan(struct iwl_priv *priv, bool aborted) | |||
101 | ieee80211_scan_completed(priv->hw, aborted); | 97 | ieee80211_scan_completed(priv->hw, aborted); |
102 | } | 98 | } |
103 | 99 | ||
104 | if (priv->scan_type == IWL_SCAN_ROC) { | 100 | if (priv->scan_type == IWL_SCAN_ROC) |
105 | ieee80211_remain_on_channel_expired(priv->hw); | 101 | iwl_scan_roc_expired(priv); |
106 | priv->hw_roc_channel = NULL; | ||
107 | schedule_delayed_work(&priv->hw_roc_disable_work, 10 * HZ); | ||
108 | } | ||
109 | 102 | ||
110 | priv->scan_type = IWL_SCAN_NORMAL; | 103 | priv->scan_type = IWL_SCAN_NORMAL; |
111 | priv->scan_vif = NULL; | 104 | priv->scan_vif = NULL; |
@@ -134,11 +127,8 @@ static void iwl_process_scan_complete(struct iwl_priv *priv) | |||
134 | goto out_settings; | 127 | goto out_settings; |
135 | } | 128 | } |
136 | 129 | ||
137 | if (priv->scan_type == IWL_SCAN_ROC) { | 130 | if (priv->scan_type == IWL_SCAN_ROC) |
138 | ieee80211_remain_on_channel_expired(priv->hw); | 131 | iwl_scan_roc_expired(priv); |
139 | priv->hw_roc_channel = NULL; | ||
140 | schedule_delayed_work(&priv->hw_roc_disable_work, 10 * HZ); | ||
141 | } | ||
142 | 132 | ||
143 | if (priv->scan_type != IWL_SCAN_NORMAL && !aborted) { | 133 | if (priv->scan_type != IWL_SCAN_NORMAL && !aborted) { |
144 | int err; | 134 | int err; |
@@ -453,27 +443,17 @@ static u16 iwl_get_passive_dwell_time(struct iwl_priv *priv, | |||
453 | 443 | ||
454 | /* Return valid, unused, channel for a passive scan to reset the RF */ | 444 | /* Return valid, unused, channel for a passive scan to reset the RF */ |
455 | static u8 iwl_get_single_channel_number(struct iwl_priv *priv, | 445 | static u8 iwl_get_single_channel_number(struct iwl_priv *priv, |
456 | enum ieee80211_band band) | 446 | enum ieee80211_band band) |
457 | { | 447 | { |
458 | const struct iwl_channel_info *ch_info; | 448 | struct ieee80211_supported_band *sband = priv->hw->wiphy->bands[band]; |
459 | int i; | ||
460 | u8 channel = 0; | ||
461 | u8 min, max; | ||
462 | struct iwl_rxon_context *ctx; | 449 | struct iwl_rxon_context *ctx; |
450 | int i; | ||
463 | 451 | ||
464 | if (band == IEEE80211_BAND_5GHZ) { | 452 | for (i = 0; i < sband->n_channels; i++) { |
465 | min = 14; | ||
466 | max = priv->channel_count; | ||
467 | } else { | ||
468 | min = 0; | ||
469 | max = 14; | ||
470 | } | ||
471 | |||
472 | for (i = min; i < max; i++) { | ||
473 | bool busy = false; | 453 | bool busy = false; |
474 | 454 | ||
475 | for_each_context(priv, ctx) { | 455 | for_each_context(priv, ctx) { |
476 | busy = priv->channel_info[i].channel == | 456 | busy = sband->channels[i].hw_value == |
477 | le16_to_cpu(ctx->staging.channel); | 457 | le16_to_cpu(ctx->staging.channel); |
478 | if (busy) | 458 | if (busy) |
479 | break; | 459 | break; |
@@ -482,13 +462,11 @@ static u8 iwl_get_single_channel_number(struct iwl_priv *priv, | |||
482 | if (busy) | 462 | if (busy) |
483 | continue; | 463 | continue; |
484 | 464 | ||
485 | channel = priv->channel_info[i].channel; | 465 | if (!(sband->channels[i].flags & IEEE80211_CHAN_DISABLED)) |
486 | ch_info = iwl_get_channel_info(priv, band, channel); | 466 | return sband->channels[i].hw_value; |
487 | if (is_channel_valid(ch_info)) | ||
488 | break; | ||
489 | } | 467 | } |
490 | 468 | ||
491 | return channel; | 469 | return 0; |
492 | } | 470 | } |
493 | 471 | ||
494 | static int iwl_get_single_channel_for_scan(struct iwl_priv *priv, | 472 | static int iwl_get_single_channel_for_scan(struct iwl_priv *priv, |
@@ -540,7 +518,6 @@ static int iwl_get_channels_for_scan(struct iwl_priv *priv, | |||
540 | { | 518 | { |
541 | struct ieee80211_channel *chan; | 519 | struct ieee80211_channel *chan; |
542 | const struct ieee80211_supported_band *sband; | 520 | const struct ieee80211_supported_band *sband; |
543 | const struct iwl_channel_info *ch_info; | ||
544 | u16 passive_dwell = 0; | 521 | u16 passive_dwell = 0; |
545 | u16 active_dwell = 0; | 522 | u16 active_dwell = 0; |
546 | int added, i; | 523 | int added, i; |
@@ -565,16 +542,7 @@ static int iwl_get_channels_for_scan(struct iwl_priv *priv, | |||
565 | channel = chan->hw_value; | 542 | channel = chan->hw_value; |
566 | scan_ch->channel = cpu_to_le16(channel); | 543 | scan_ch->channel = cpu_to_le16(channel); |
567 | 544 | ||
568 | ch_info = iwl_get_channel_info(priv, band, channel); | 545 | if (!is_active || (chan->flags & IEEE80211_CHAN_PASSIVE_SCAN)) |
569 | if (!is_channel_valid(ch_info)) { | ||
570 | IWL_DEBUG_SCAN(priv, | ||
571 | "Channel %d is INVALID for this band.\n", | ||
572 | channel); | ||
573 | continue; | ||
574 | } | ||
575 | |||
576 | if (!is_active || is_channel_passive(ch_info) || | ||
577 | (chan->flags & IEEE80211_CHAN_PASSIVE_SCAN)) | ||
578 | scan_ch->type = SCAN_CHANNEL_TYPE_PASSIVE; | 546 | scan_ch->type = SCAN_CHANNEL_TYPE_PASSIVE; |
579 | else | 547 | else |
580 | scan_ch->type = SCAN_CHANNEL_TYPE_ACTIVE; | 548 | scan_ch->type = SCAN_CHANNEL_TYPE_ACTIVE; |
@@ -678,12 +646,12 @@ static int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) | |||
678 | u16 rx_chain = 0; | 646 | u16 rx_chain = 0; |
679 | enum ieee80211_band band; | 647 | enum ieee80211_band band; |
680 | u8 n_probes = 0; | 648 | u8 n_probes = 0; |
681 | u8 rx_ant = priv->hw_params.valid_rx_ant; | 649 | u8 rx_ant = priv->eeprom_data->valid_rx_ant; |
682 | u8 rate; | 650 | u8 rate; |
683 | bool is_active = false; | 651 | bool is_active = false; |
684 | int chan_mod; | 652 | int chan_mod; |
685 | u8 active_chains; | 653 | u8 active_chains; |
686 | u8 scan_tx_antennas = priv->hw_params.valid_tx_ant; | 654 | u8 scan_tx_antennas = priv->eeprom_data->valid_tx_ant; |
687 | int ret; | 655 | int ret; |
688 | int scan_cmd_size = sizeof(struct iwl_scan_cmd) + | 656 | int scan_cmd_size = sizeof(struct iwl_scan_cmd) + |
689 | MAX_SCAN_CHANNEL * sizeof(struct iwl_scan_channel) + | 657 | MAX_SCAN_CHANNEL * sizeof(struct iwl_scan_channel) + |
@@ -893,7 +861,7 @@ static int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) | |||
893 | 861 | ||
894 | /* MIMO is not used here, but value is required */ | 862 | /* MIMO is not used here, but value is required */ |
895 | rx_chain |= | 863 | rx_chain |= |
896 | priv->hw_params.valid_rx_ant << RXON_RX_CHAIN_VALID_POS; | 864 | priv->eeprom_data->valid_rx_ant << RXON_RX_CHAIN_VALID_POS; |
897 | rx_chain |= rx_ant << RXON_RX_CHAIN_FORCE_MIMO_SEL_POS; | 865 | rx_chain |= rx_ant << RXON_RX_CHAIN_FORCE_MIMO_SEL_POS; |
898 | rx_chain |= rx_ant << RXON_RX_CHAIN_FORCE_SEL_POS; | 866 | rx_chain |= rx_ant << RXON_RX_CHAIN_FORCE_SEL_POS; |
899 | rx_chain |= 0x1 << RXON_RX_CHAIN_DRIVER_FORCE_POS; | 867 | rx_chain |= 0x1 << RXON_RX_CHAIN_DRIVER_FORCE_POS; |
@@ -994,8 +962,10 @@ static int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) | |||
994 | set_bit(STATUS_SCAN_HW, &priv->status); | 962 | set_bit(STATUS_SCAN_HW, &priv->status); |
995 | 963 | ||
996 | ret = iwlagn_set_pan_params(priv); | 964 | ret = iwlagn_set_pan_params(priv); |
997 | if (ret) | 965 | if (ret) { |
966 | clear_bit(STATUS_SCAN_HW, &priv->status); | ||
998 | return ret; | 967 | return ret; |
968 | } | ||
999 | 969 | ||
1000 | ret = iwl_dvm_send_cmd(priv, &cmd); | 970 | ret = iwl_dvm_send_cmd(priv, &cmd); |
1001 | if (ret) { | 971 | if (ret) { |
@@ -1008,7 +978,7 @@ static int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) | |||
1008 | 978 | ||
1009 | void iwl_init_scan_params(struct iwl_priv *priv) | 979 | void iwl_init_scan_params(struct iwl_priv *priv) |
1010 | { | 980 | { |
1011 | u8 ant_idx = fls(priv->hw_params.valid_tx_ant) - 1; | 981 | u8 ant_idx = fls(priv->eeprom_data->valid_tx_ant) - 1; |
1012 | if (!priv->scan_tx_ant[IEEE80211_BAND_5GHZ]) | 982 | if (!priv->scan_tx_ant[IEEE80211_BAND_5GHZ]) |
1013 | priv->scan_tx_ant[IEEE80211_BAND_5GHZ] = ant_idx; | 983 | priv->scan_tx_ant[IEEE80211_BAND_5GHZ] = ant_idx; |
1014 | if (!priv->scan_tx_ant[IEEE80211_BAND_2GHZ]) | 984 | if (!priv->scan_tx_ant[IEEE80211_BAND_2GHZ]) |
@@ -1158,3 +1128,40 @@ void iwl_cancel_scan_deferred_work(struct iwl_priv *priv) | |||
1158 | mutex_unlock(&priv->mutex); | 1128 | mutex_unlock(&priv->mutex); |
1159 | } | 1129 | } |
1160 | } | 1130 | } |
1131 | |||
1132 | void iwl_scan_roc_expired(struct iwl_priv *priv) | ||
1133 | { | ||
1134 | /* | ||
1135 | * The status bit should be set here, to prevent a race | ||
1136 | * where the atomic_read returns 1, but before the execution continues | ||
1137 | * iwl_scan_offchannel_skb_status() checks if the status bit is set | ||
1138 | */ | ||
1139 | set_bit(STATUS_SCAN_ROC_EXPIRED, &priv->status); | ||
1140 | |||
1141 | if (atomic_read(&priv->num_aux_in_flight) == 0) { | ||
1142 | ieee80211_remain_on_channel_expired(priv->hw); | ||
1143 | priv->hw_roc_channel = NULL; | ||
1144 | schedule_delayed_work(&priv->hw_roc_disable_work, | ||
1145 | 10 * HZ); | ||
1146 | |||
1147 | clear_bit(STATUS_SCAN_ROC_EXPIRED, &priv->status); | ||
1148 | } else { | ||
1149 | IWL_DEBUG_SCAN(priv, "ROC done with %d frames in aux\n", | ||
1150 | atomic_read(&priv->num_aux_in_flight)); | ||
1151 | } | ||
1152 | } | ||
1153 | |||
1154 | void iwl_scan_offchannel_skb(struct iwl_priv *priv) | ||
1155 | { | ||
1156 | WARN_ON(!priv->hw_roc_start_notified); | ||
1157 | atomic_inc(&priv->num_aux_in_flight); | ||
1158 | } | ||
1159 | |||
1160 | void iwl_scan_offchannel_skb_status(struct iwl_priv *priv) | ||
1161 | { | ||
1162 | if (atomic_dec_return(&priv->num_aux_in_flight) == 0 && | ||
1163 | test_bit(STATUS_SCAN_ROC_EXPIRED, &priv->status)) { | ||
1164 | IWL_DEBUG_SCAN(priv, "0 aux frames. Calling ROC expired\n"); | ||
1165 | iwl_scan_roc_expired(priv); | ||
1166 | } | ||
1167 | } | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-sta.c b/drivers/net/wireless/iwlwifi/dvm/sta.c index 36055ed1c069..286ce4e18068 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-sta.c +++ b/drivers/net/wireless/iwlwifi/dvm/sta.c | |||
@@ -28,10 +28,9 @@ | |||
28 | *****************************************************************************/ | 28 | *****************************************************************************/ |
29 | #include <linux/etherdevice.h> | 29 | #include <linux/etherdevice.h> |
30 | #include <net/mac80211.h> | 30 | #include <net/mac80211.h> |
31 | |||
32 | #include "iwl-dev.h" | ||
33 | #include "iwl-agn.h" | ||
34 | #include "iwl-trans.h" | 31 | #include "iwl-trans.h" |
32 | #include "dev.h" | ||
33 | #include "agn.h" | ||
35 | 34 | ||
36 | const u8 iwl_bcast_addr[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; | 35 | const u8 iwl_bcast_addr[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; |
37 | 36 | ||
@@ -171,26 +170,6 @@ int iwl_send_add_sta(struct iwl_priv *priv, | |||
171 | return cmd.handler_status; | 170 | return cmd.handler_status; |
172 | } | 171 | } |
173 | 172 | ||
174 | static bool iwl_is_channel_extension(struct iwl_priv *priv, | ||
175 | enum ieee80211_band band, | ||
176 | u16 channel, u8 extension_chan_offset) | ||
177 | { | ||
178 | const struct iwl_channel_info *ch_info; | ||
179 | |||
180 | ch_info = iwl_get_channel_info(priv, band, channel); | ||
181 | if (!is_channel_valid(ch_info)) | ||
182 | return false; | ||
183 | |||
184 | if (extension_chan_offset == IEEE80211_HT_PARAM_CHA_SEC_ABOVE) | ||
185 | return !(ch_info->ht40_extension_channel & | ||
186 | IEEE80211_CHAN_NO_HT40PLUS); | ||
187 | else if (extension_chan_offset == IEEE80211_HT_PARAM_CHA_SEC_BELOW) | ||
188 | return !(ch_info->ht40_extension_channel & | ||
189 | IEEE80211_CHAN_NO_HT40MINUS); | ||
190 | |||
191 | return false; | ||
192 | } | ||
193 | |||
194 | bool iwl_is_ht40_tx_allowed(struct iwl_priv *priv, | 173 | bool iwl_is_ht40_tx_allowed(struct iwl_priv *priv, |
195 | struct iwl_rxon_context *ctx, | 174 | struct iwl_rxon_context *ctx, |
196 | struct ieee80211_sta_ht_cap *ht_cap) | 175 | struct ieee80211_sta_ht_cap *ht_cap) |
@@ -198,21 +177,25 @@ bool iwl_is_ht40_tx_allowed(struct iwl_priv *priv, | |||
198 | if (!ctx->ht.enabled || !ctx->ht.is_40mhz) | 177 | if (!ctx->ht.enabled || !ctx->ht.is_40mhz) |
199 | return false; | 178 | return false; |
200 | 179 | ||
180 | #ifdef CONFIG_IWLWIFI_DEBUGFS | ||
181 | if (priv->disable_ht40) | ||
182 | return false; | ||
183 | #endif | ||
184 | |||
201 | /* | 185 | /* |
202 | * We do not check for IEEE80211_HT_CAP_SUP_WIDTH_20_40 | 186 | * Remainder of this function checks ht_cap, but if it's |
203 | * the bit will not set if it is pure 40MHz case | 187 | * NULL then we can do HT40 (special case for RXON) |
204 | */ | 188 | */ |
205 | if (ht_cap && !ht_cap->ht_supported) | 189 | if (!ht_cap) |
190 | return true; | ||
191 | |||
192 | if (!ht_cap->ht_supported) | ||
206 | return false; | 193 | return false; |
207 | 194 | ||
208 | #ifdef CONFIG_IWLWIFI_DEBUGFS | 195 | if (!(ht_cap->cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40)) |
209 | if (priv->disable_ht40) | ||
210 | return false; | 196 | return false; |
211 | #endif | ||
212 | 197 | ||
213 | return iwl_is_channel_extension(priv, priv->band, | 198 | return true; |
214 | le16_to_cpu(ctx->staging.channel), | ||
215 | ctx->ht.extension_chan_offset); | ||
216 | } | 199 | } |
217 | 200 | ||
218 | static void iwl_sta_calc_ht_flags(struct iwl_priv *priv, | 201 | static void iwl_sta_calc_ht_flags(struct iwl_priv *priv, |
@@ -650,23 +633,23 @@ static void iwl_sta_fill_lq(struct iwl_priv *priv, struct iwl_rxon_context *ctx, | |||
650 | if (r >= IWL_FIRST_CCK_RATE && r <= IWL_LAST_CCK_RATE) | 633 | if (r >= IWL_FIRST_CCK_RATE && r <= IWL_LAST_CCK_RATE) |
651 | rate_flags |= RATE_MCS_CCK_MSK; | 634 | rate_flags |= RATE_MCS_CCK_MSK; |
652 | 635 | ||
653 | rate_flags |= first_antenna(priv->hw_params.valid_tx_ant) << | 636 | rate_flags |= first_antenna(priv->eeprom_data->valid_tx_ant) << |
654 | RATE_MCS_ANT_POS; | 637 | RATE_MCS_ANT_POS; |
655 | rate_n_flags = iwl_hw_set_rate_n_flags(iwl_rates[r].plcp, rate_flags); | 638 | rate_n_flags = iwl_hw_set_rate_n_flags(iwl_rates[r].plcp, rate_flags); |
656 | for (i = 0; i < LINK_QUAL_MAX_RETRY_NUM; i++) | 639 | for (i = 0; i < LINK_QUAL_MAX_RETRY_NUM; i++) |
657 | link_cmd->rs_table[i].rate_n_flags = rate_n_flags; | 640 | link_cmd->rs_table[i].rate_n_flags = rate_n_flags; |
658 | 641 | ||
659 | link_cmd->general_params.single_stream_ant_msk = | 642 | link_cmd->general_params.single_stream_ant_msk = |
660 | first_antenna(priv->hw_params.valid_tx_ant); | 643 | first_antenna(priv->eeprom_data->valid_tx_ant); |
661 | 644 | ||
662 | link_cmd->general_params.dual_stream_ant_msk = | 645 | link_cmd->general_params.dual_stream_ant_msk = |
663 | priv->hw_params.valid_tx_ant & | 646 | priv->eeprom_data->valid_tx_ant & |
664 | ~first_antenna(priv->hw_params.valid_tx_ant); | 647 | ~first_antenna(priv->eeprom_data->valid_tx_ant); |
665 | if (!link_cmd->general_params.dual_stream_ant_msk) { | 648 | if (!link_cmd->general_params.dual_stream_ant_msk) { |
666 | link_cmd->general_params.dual_stream_ant_msk = ANT_AB; | 649 | link_cmd->general_params.dual_stream_ant_msk = ANT_AB; |
667 | } else if (num_of_ant(priv->hw_params.valid_tx_ant) == 2) { | 650 | } else if (num_of_ant(priv->eeprom_data->valid_tx_ant) == 2) { |
668 | link_cmd->general_params.dual_stream_ant_msk = | 651 | link_cmd->general_params.dual_stream_ant_msk = |
669 | priv->hw_params.valid_tx_ant; | 652 | priv->eeprom_data->valid_tx_ant; |
670 | } | 653 | } |
671 | 654 | ||
672 | link_cmd->agg_params.agg_dis_start_th = | 655 | link_cmd->agg_params.agg_dis_start_th = |
diff --git a/drivers/net/wireless/iwlwifi/iwl-testmode.c b/drivers/net/wireless/iwlwifi/dvm/testmode.c index 060aac3e22f1..a7b59590bb53 100644 --- a/drivers/net/wireless/iwlwifi/iwl-testmode.c +++ b/drivers/net/wireless/iwlwifi/dvm/testmode.c | |||
@@ -69,15 +69,14 @@ | |||
69 | #include <net/cfg80211.h> | 69 | #include <net/cfg80211.h> |
70 | #include <net/mac80211.h> | 70 | #include <net/mac80211.h> |
71 | #include <net/netlink.h> | 71 | #include <net/netlink.h> |
72 | |||
73 | #include "iwl-dev.h" | ||
74 | #include "iwl-debug.h" | 72 | #include "iwl-debug.h" |
75 | #include "iwl-io.h" | 73 | #include "iwl-io.h" |
76 | #include "iwl-agn.h" | ||
77 | #include "iwl-testmode.h" | ||
78 | #include "iwl-trans.h" | 74 | #include "iwl-trans.h" |
79 | #include "iwl-fh.h" | 75 | #include "iwl-fh.h" |
80 | #include "iwl-prph.h" | 76 | #include "iwl-prph.h" |
77 | #include "dev.h" | ||
78 | #include "agn.h" | ||
79 | #include "testmode.h" | ||
81 | 80 | ||
82 | 81 | ||
83 | /* Periphery registers absolute lower bound. This is used in order to | 82 | /* Periphery registers absolute lower bound. This is used in order to |
@@ -89,7 +88,7 @@ | |||
89 | /* The TLVs used in the gnl message policy between the kernel module and | 88 | /* The TLVs used in the gnl message policy between the kernel module and |
90 | * user space application. iwl_testmode_gnl_msg_policy is to be carried | 89 | * user space application. iwl_testmode_gnl_msg_policy is to be carried |
91 | * through the NL80211_CMD_TESTMODE channel regulated by nl80211. | 90 | * through the NL80211_CMD_TESTMODE channel regulated by nl80211. |
92 | * See iwl-testmode.h | 91 | * See testmode.h |
93 | */ | 92 | */ |
94 | static | 93 | static |
95 | struct nla_policy iwl_testmode_gnl_msg_policy[IWL_TM_ATTR_MAX] = { | 94 | struct nla_policy iwl_testmode_gnl_msg_policy[IWL_TM_ATTR_MAX] = { |
@@ -129,7 +128,7 @@ struct nla_policy iwl_testmode_gnl_msg_policy[IWL_TM_ATTR_MAX] = { | |||
129 | }; | 128 | }; |
130 | 129 | ||
131 | /* | 130 | /* |
132 | * See the struct iwl_rx_packet in iwl-commands.h for the format of the | 131 | * See the struct iwl_rx_packet in commands.h for the format of the |
133 | * received events from the device | 132 | * received events from the device |
134 | */ | 133 | */ |
135 | static inline int get_event_length(struct iwl_rx_cmd_buffer *rxb) | 134 | static inline int get_event_length(struct iwl_rx_cmd_buffer *rxb) |
@@ -535,9 +534,9 @@ static int iwl_testmode_driver(struct ieee80211_hw *hw, struct nlattr **tb) | |||
535 | break; | 534 | break; |
536 | 535 | ||
537 | case IWL_TM_CMD_APP2DEV_GET_EEPROM: | 536 | case IWL_TM_CMD_APP2DEV_GET_EEPROM: |
538 | if (priv->eeprom) { | 537 | if (priv->eeprom_blob) { |
539 | skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy, | 538 | skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy, |
540 | priv->cfg->base_params->eeprom_size + 20); | 539 | priv->eeprom_blob_size + 20); |
541 | if (!skb) { | 540 | if (!skb) { |
542 | IWL_ERR(priv, "Memory allocation fail\n"); | 541 | IWL_ERR(priv, "Memory allocation fail\n"); |
543 | return -ENOMEM; | 542 | return -ENOMEM; |
@@ -545,15 +544,15 @@ static int iwl_testmode_driver(struct ieee80211_hw *hw, struct nlattr **tb) | |||
545 | if (nla_put_u32(skb, IWL_TM_ATTR_COMMAND, | 544 | if (nla_put_u32(skb, IWL_TM_ATTR_COMMAND, |
546 | IWL_TM_CMD_DEV2APP_EEPROM_RSP) || | 545 | IWL_TM_CMD_DEV2APP_EEPROM_RSP) || |
547 | nla_put(skb, IWL_TM_ATTR_EEPROM, | 546 | nla_put(skb, IWL_TM_ATTR_EEPROM, |
548 | priv->cfg->base_params->eeprom_size, | 547 | priv->eeprom_blob_size, |
549 | priv->eeprom)) | 548 | priv->eeprom_blob)) |
550 | goto nla_put_failure; | 549 | goto nla_put_failure; |
551 | status = cfg80211_testmode_reply(skb); | 550 | status = cfg80211_testmode_reply(skb); |
552 | if (status < 0) | 551 | if (status < 0) |
553 | IWL_ERR(priv, "Error sending msg : %d\n", | 552 | IWL_ERR(priv, "Error sending msg : %d\n", |
554 | status); | 553 | status); |
555 | } else | 554 | } else |
556 | return -EFAULT; | 555 | return -ENODATA; |
557 | break; | 556 | break; |
558 | 557 | ||
559 | case IWL_TM_CMD_APP2DEV_FIXRATE_REQ: | 558 | case IWL_TM_CMD_APP2DEV_FIXRATE_REQ: |
diff --git a/drivers/net/wireless/iwlwifi/iwl-testmode.h b/drivers/net/wireless/iwlwifi/dvm/testmode.h index 6ba211b09426..6ba211b09426 100644 --- a/drivers/net/wireless/iwlwifi/iwl-testmode.h +++ b/drivers/net/wireless/iwlwifi/dvm/testmode.h | |||
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tt.c b/drivers/net/wireless/iwlwifi/dvm/tt.c index a5cfe0aceedb..eb864433e59d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-tt.c +++ b/drivers/net/wireless/iwlwifi/dvm/tt.c | |||
@@ -31,17 +31,14 @@ | |||
31 | #include <linux/module.h> | 31 | #include <linux/module.h> |
32 | #include <linux/slab.h> | 32 | #include <linux/slab.h> |
33 | #include <linux/init.h> | 33 | #include <linux/init.h> |
34 | |||
35 | #include <net/mac80211.h> | 34 | #include <net/mac80211.h> |
36 | |||
37 | #include "iwl-agn.h" | ||
38 | #include "iwl-eeprom.h" | ||
39 | #include "iwl-dev.h" | ||
40 | #include "iwl-io.h" | 35 | #include "iwl-io.h" |
41 | #include "iwl-commands.h" | ||
42 | #include "iwl-debug.h" | ||
43 | #include "iwl-agn-tt.h" | ||
44 | #include "iwl-modparams.h" | 36 | #include "iwl-modparams.h" |
37 | #include "iwl-debug.h" | ||
38 | #include "agn.h" | ||
39 | #include "dev.h" | ||
40 | #include "commands.h" | ||
41 | #include "tt.h" | ||
45 | 42 | ||
46 | /* default Thermal Throttling transaction table | 43 | /* default Thermal Throttling transaction table |
47 | * Current state | Throttling Down | Throttling Up | 44 | * Current state | Throttling Down | Throttling Up |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tt.h b/drivers/net/wireless/iwlwifi/dvm/tt.h index 86bbf47501c1..44c7c8f30a2d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-tt.h +++ b/drivers/net/wireless/iwlwifi/dvm/tt.h | |||
@@ -28,7 +28,7 @@ | |||
28 | #ifndef __iwl_tt_setting_h__ | 28 | #ifndef __iwl_tt_setting_h__ |
29 | #define __iwl_tt_setting_h__ | 29 | #define __iwl_tt_setting_h__ |
30 | 30 | ||
31 | #include "iwl-commands.h" | 31 | #include "commands.h" |
32 | 32 | ||
33 | #define IWL_ABSOLUTE_ZERO 0 | 33 | #define IWL_ABSOLUTE_ZERO 0 |
34 | #define IWL_ABSOLUTE_MAX 0xFFFFFFFF | 34 | #define IWL_ABSOLUTE_MAX 0xFFFFFFFF |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c b/drivers/net/wireless/iwlwifi/dvm/tx.c index 3366e2e2f00f..0dfaf649b257 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c +++ b/drivers/net/wireless/iwlwifi/dvm/tx.c | |||
@@ -32,12 +32,11 @@ | |||
32 | #include <linux/init.h> | 32 | #include <linux/init.h> |
33 | #include <linux/sched.h> | 33 | #include <linux/sched.h> |
34 | #include <linux/ieee80211.h> | 34 | #include <linux/ieee80211.h> |
35 | |||
36 | #include "iwl-dev.h" | ||
37 | #include "iwl-io.h" | 35 | #include "iwl-io.h" |
38 | #include "iwl-agn-hw.h" | ||
39 | #include "iwl-agn.h" | ||
40 | #include "iwl-trans.h" | 36 | #include "iwl-trans.h" |
37 | #include "iwl-agn-hw.h" | ||
38 | #include "dev.h" | ||
39 | #include "agn.h" | ||
41 | 40 | ||
42 | static const u8 tid_to_ac[] = { | 41 | static const u8 tid_to_ac[] = { |
43 | IEEE80211_AC_BE, | 42 | IEEE80211_AC_BE, |
@@ -187,7 +186,8 @@ static void iwlagn_tx_cmd_build_rate(struct iwl_priv *priv, | |||
187 | rate_idx = info->control.rates[0].idx; | 186 | rate_idx = info->control.rates[0].idx; |
188 | if (info->control.rates[0].flags & IEEE80211_TX_RC_MCS || | 187 | if (info->control.rates[0].flags & IEEE80211_TX_RC_MCS || |
189 | (rate_idx < 0) || (rate_idx > IWL_RATE_COUNT_LEGACY)) | 188 | (rate_idx < 0) || (rate_idx > IWL_RATE_COUNT_LEGACY)) |
190 | rate_idx = rate_lowest_index(&priv->bands[info->band], | 189 | rate_idx = rate_lowest_index( |
190 | &priv->eeprom_data->bands[info->band], | ||
191 | info->control.sta); | 191 | info->control.sta); |
192 | /* For 5 GHZ band, remap mac80211 rate indices into driver indices */ | 192 | /* For 5 GHZ band, remap mac80211 rate indices into driver indices */ |
193 | if (info->band == IEEE80211_BAND_5GHZ) | 193 | if (info->band == IEEE80211_BAND_5GHZ) |
@@ -207,10 +207,11 @@ static void iwlagn_tx_cmd_build_rate(struct iwl_priv *priv, | |||
207 | priv->bt_full_concurrent) { | 207 | priv->bt_full_concurrent) { |
208 | /* operated as 1x1 in full concurrency mode */ | 208 | /* operated as 1x1 in full concurrency mode */ |
209 | priv->mgmt_tx_ant = iwl_toggle_tx_ant(priv, priv->mgmt_tx_ant, | 209 | priv->mgmt_tx_ant = iwl_toggle_tx_ant(priv, priv->mgmt_tx_ant, |
210 | first_antenna(priv->hw_params.valid_tx_ant)); | 210 | first_antenna(priv->eeprom_data->valid_tx_ant)); |
211 | } else | 211 | } else |
212 | priv->mgmt_tx_ant = iwl_toggle_tx_ant(priv, priv->mgmt_tx_ant, | 212 | priv->mgmt_tx_ant = iwl_toggle_tx_ant( |
213 | priv->hw_params.valid_tx_ant); | 213 | priv, priv->mgmt_tx_ant, |
214 | priv->eeprom_data->valid_tx_ant); | ||
214 | rate_flags |= iwl_ant_idx_to_flags(priv->mgmt_tx_ant); | 215 | rate_flags |= iwl_ant_idx_to_flags(priv->mgmt_tx_ant); |
215 | 216 | ||
216 | /* Set the rate in the TX cmd */ | 217 | /* Set the rate in the TX cmd */ |
@@ -296,7 +297,7 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) | |||
296 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | 297 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); |
297 | struct iwl_station_priv *sta_priv = NULL; | 298 | struct iwl_station_priv *sta_priv = NULL; |
298 | struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; | 299 | struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; |
299 | struct iwl_device_cmd *dev_cmd = NULL; | 300 | struct iwl_device_cmd *dev_cmd; |
300 | struct iwl_tx_cmd *tx_cmd; | 301 | struct iwl_tx_cmd *tx_cmd; |
301 | __le16 fc; | 302 | __le16 fc; |
302 | u8 hdr_len; | 303 | u8 hdr_len; |
@@ -378,7 +379,7 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) | |||
378 | if (info->flags & IEEE80211_TX_CTL_AMPDU) | 379 | if (info->flags & IEEE80211_TX_CTL_AMPDU) |
379 | is_agg = true; | 380 | is_agg = true; |
380 | 381 | ||
381 | dev_cmd = kmem_cache_alloc(iwl_tx_cmd_pool, GFP_ATOMIC); | 382 | dev_cmd = iwl_trans_alloc_tx_cmd(priv->trans); |
382 | 383 | ||
383 | if (unlikely(!dev_cmd)) | 384 | if (unlikely(!dev_cmd)) |
384 | goto drop_unlock_priv; | 385 | goto drop_unlock_priv; |
@@ -486,11 +487,14 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) | |||
486 | if (sta_priv && sta_priv->client && !is_agg) | 487 | if (sta_priv && sta_priv->client && !is_agg) |
487 | atomic_inc(&sta_priv->pending_frames); | 488 | atomic_inc(&sta_priv->pending_frames); |
488 | 489 | ||
490 | if (info->flags & IEEE80211_TX_CTL_TX_OFFCHAN) | ||
491 | iwl_scan_offchannel_skb(priv); | ||
492 | |||
489 | return 0; | 493 | return 0; |
490 | 494 | ||
491 | drop_unlock_sta: | 495 | drop_unlock_sta: |
492 | if (dev_cmd) | 496 | if (dev_cmd) |
493 | kmem_cache_free(iwl_tx_cmd_pool, dev_cmd); | 497 | iwl_trans_free_tx_cmd(priv->trans, dev_cmd); |
494 | spin_unlock(&priv->sta_lock); | 498 | spin_unlock(&priv->sta_lock); |
495 | drop_unlock_priv: | 499 | drop_unlock_priv: |
496 | return -1; | 500 | return -1; |
@@ -597,7 +601,7 @@ turn_off: | |||
597 | * time, or we hadn't time to drain the AC queues. | 601 | * time, or we hadn't time to drain the AC queues. |
598 | */ | 602 | */ |
599 | if (agg_state == IWL_AGG_ON) | 603 | if (agg_state == IWL_AGG_ON) |
600 | iwl_trans_tx_agg_disable(priv->trans, txq_id); | 604 | iwl_trans_txq_disable(priv->trans, txq_id); |
601 | else | 605 | else |
602 | IWL_DEBUG_TX_QUEUES(priv, "Don't disable tx agg: %d\n", | 606 | IWL_DEBUG_TX_QUEUES(priv, "Don't disable tx agg: %d\n", |
603 | agg_state); | 607 | agg_state); |
@@ -686,9 +690,8 @@ int iwlagn_tx_agg_oper(struct iwl_priv *priv, struct ieee80211_vif *vif, | |||
686 | 690 | ||
687 | fifo = ctx->ac_to_fifo[tid_to_ac[tid]]; | 691 | fifo = ctx->ac_to_fifo[tid_to_ac[tid]]; |
688 | 692 | ||
689 | iwl_trans_tx_agg_setup(priv->trans, q, fifo, | 693 | iwl_trans_txq_enable(priv->trans, q, fifo, sta_priv->sta_id, tid, |
690 | sta_priv->sta_id, tid, | 694 | buf_size, ssn); |
691 | buf_size, ssn); | ||
692 | 695 | ||
693 | /* | 696 | /* |
694 | * If the limit is 0, then it wasn't initialised yet, | 697 | * If the limit is 0, then it wasn't initialised yet, |
@@ -753,8 +756,8 @@ static void iwlagn_check_ratid_empty(struct iwl_priv *priv, int sta_id, u8 tid) | |||
753 | IWL_DEBUG_TX_QUEUES(priv, | 756 | IWL_DEBUG_TX_QUEUES(priv, |
754 | "Can continue DELBA flow ssn = next_recl =" | 757 | "Can continue DELBA flow ssn = next_recl =" |
755 | " %d", tid_data->next_reclaimed); | 758 | " %d", tid_data->next_reclaimed); |
756 | iwl_trans_tx_agg_disable(priv->trans, | 759 | iwl_trans_txq_disable(priv->trans, |
757 | tid_data->agg.txq_id); | 760 | tid_data->agg.txq_id); |
758 | iwlagn_dealloc_agg_txq(priv, tid_data->agg.txq_id); | 761 | iwlagn_dealloc_agg_txq(priv, tid_data->agg.txq_id); |
759 | tid_data->agg.state = IWL_AGG_OFF; | 762 | tid_data->agg.state = IWL_AGG_OFF; |
760 | ieee80211_stop_tx_ba_cb_irqsafe(vif, addr, tid); | 763 | ieee80211_stop_tx_ba_cb_irqsafe(vif, addr, tid); |
@@ -1136,6 +1139,7 @@ int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_cmd_buffer *rxb, | |||
1136 | struct sk_buff *skb; | 1139 | struct sk_buff *skb; |
1137 | struct iwl_rxon_context *ctx; | 1140 | struct iwl_rxon_context *ctx; |
1138 | bool is_agg = (txq_id >= IWLAGN_FIRST_AMPDU_QUEUE); | 1141 | bool is_agg = (txq_id >= IWLAGN_FIRST_AMPDU_QUEUE); |
1142 | bool is_offchannel_skb; | ||
1139 | 1143 | ||
1140 | tid = (tx_resp->ra_tid & IWLAGN_TX_RES_TID_MSK) >> | 1144 | tid = (tx_resp->ra_tid & IWLAGN_TX_RES_TID_MSK) >> |
1141 | IWLAGN_TX_RES_TID_POS; | 1145 | IWLAGN_TX_RES_TID_POS; |
@@ -1149,6 +1153,8 @@ int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_cmd_buffer *rxb, | |||
1149 | 1153 | ||
1150 | __skb_queue_head_init(&skbs); | 1154 | __skb_queue_head_init(&skbs); |
1151 | 1155 | ||
1156 | is_offchannel_skb = false; | ||
1157 | |||
1152 | if (tx_resp->frame_count == 1) { | 1158 | if (tx_resp->frame_count == 1) { |
1153 | u16 next_reclaimed = le16_to_cpu(tx_resp->seq_ctl); | 1159 | u16 next_reclaimed = le16_to_cpu(tx_resp->seq_ctl); |
1154 | next_reclaimed = SEQ_TO_SN(next_reclaimed + 0x10); | 1160 | next_reclaimed = SEQ_TO_SN(next_reclaimed + 0x10); |
@@ -1189,8 +1195,8 @@ int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_cmd_buffer *rxb, | |||
1189 | 1195 | ||
1190 | info = IEEE80211_SKB_CB(skb); | 1196 | info = IEEE80211_SKB_CB(skb); |
1191 | ctx = info->driver_data[0]; | 1197 | ctx = info->driver_data[0]; |
1192 | kmem_cache_free(iwl_tx_cmd_pool, | 1198 | iwl_trans_free_tx_cmd(priv->trans, |
1193 | (info->driver_data[1])); | 1199 | info->driver_data[1]); |
1194 | 1200 | ||
1195 | memset(&info->status, 0, sizeof(info->status)); | 1201 | memset(&info->status, 0, sizeof(info->status)); |
1196 | 1202 | ||
@@ -1225,10 +1231,19 @@ int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_cmd_buffer *rxb, | |||
1225 | if (!is_agg) | 1231 | if (!is_agg) |
1226 | iwlagn_non_agg_tx_status(priv, ctx, hdr->addr1); | 1232 | iwlagn_non_agg_tx_status(priv, ctx, hdr->addr1); |
1227 | 1233 | ||
1234 | is_offchannel_skb = | ||
1235 | (info->flags & IEEE80211_TX_CTL_TX_OFFCHAN); | ||
1228 | freed++; | 1236 | freed++; |
1229 | } | 1237 | } |
1230 | 1238 | ||
1231 | WARN_ON(!is_agg && freed != 1); | 1239 | WARN_ON(!is_agg && freed != 1); |
1240 | |||
1241 | /* | ||
1242 | * An offchannel frame can be send only on the AUX queue, where | ||
1243 | * there is no aggregation (and reordering) so it only is single | ||
1244 | * skb is expected to be processed. | ||
1245 | */ | ||
1246 | WARN_ON(is_offchannel_skb && freed != 1); | ||
1232 | } | 1247 | } |
1233 | 1248 | ||
1234 | iwl_check_abort_status(priv, tx_resp->frame_count, status); | 1249 | iwl_check_abort_status(priv, tx_resp->frame_count, status); |
@@ -1239,6 +1254,9 @@ int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_cmd_buffer *rxb, | |||
1239 | ieee80211_tx_status(priv->hw, skb); | 1254 | ieee80211_tx_status(priv->hw, skb); |
1240 | } | 1255 | } |
1241 | 1256 | ||
1257 | if (is_offchannel_skb) | ||
1258 | iwl_scan_offchannel_skb_status(priv); | ||
1259 | |||
1242 | return 0; | 1260 | return 0; |
1243 | } | 1261 | } |
1244 | 1262 | ||
@@ -1341,7 +1359,7 @@ int iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv, | |||
1341 | WARN_ON_ONCE(1); | 1359 | WARN_ON_ONCE(1); |
1342 | 1360 | ||
1343 | info = IEEE80211_SKB_CB(skb); | 1361 | info = IEEE80211_SKB_CB(skb); |
1344 | kmem_cache_free(iwl_tx_cmd_pool, (info->driver_data[1])); | 1362 | iwl_trans_free_tx_cmd(priv->trans, info->driver_data[1]); |
1345 | 1363 | ||
1346 | if (freed == 1) { | 1364 | if (freed == 1) { |
1347 | /* this is the first skb we deliver in this batch */ | 1365 | /* this is the first skb we deliver in this batch */ |
diff --git a/drivers/net/wireless/iwlwifi/iwl-ucode.c b/drivers/net/wireless/iwlwifi/dvm/ucode.c index bc40dc68b0f4..b3a314ba48c7 100644 --- a/drivers/net/wireless/iwlwifi/iwl-ucode.c +++ b/drivers/net/wireless/iwlwifi/dvm/ucode.c | |||
@@ -30,15 +30,16 @@ | |||
30 | #include <linux/kernel.h> | 30 | #include <linux/kernel.h> |
31 | #include <linux/init.h> | 31 | #include <linux/init.h> |
32 | 32 | ||
33 | #include "iwl-dev.h" | ||
34 | #include "iwl-io.h" | 33 | #include "iwl-io.h" |
35 | #include "iwl-agn-hw.h" | 34 | #include "iwl-agn-hw.h" |
36 | #include "iwl-agn.h" | ||
37 | #include "iwl-agn-calib.h" | ||
38 | #include "iwl-trans.h" | 35 | #include "iwl-trans.h" |
39 | #include "iwl-fh.h" | 36 | #include "iwl-fh.h" |
40 | #include "iwl-op-mode.h" | 37 | #include "iwl-op-mode.h" |
41 | 38 | ||
39 | #include "dev.h" | ||
40 | #include "agn.h" | ||
41 | #include "calib.h" | ||
42 | |||
42 | /****************************************************************************** | 43 | /****************************************************************************** |
43 | * | 44 | * |
44 | * uCode download functions | 45 | * uCode download functions |
@@ -60,8 +61,7 @@ iwl_get_ucode_image(struct iwl_priv *priv, enum iwl_ucode_type ucode_type) | |||
60 | static int iwl_set_Xtal_calib(struct iwl_priv *priv) | 61 | static int iwl_set_Xtal_calib(struct iwl_priv *priv) |
61 | { | 62 | { |
62 | struct iwl_calib_xtal_freq_cmd cmd; | 63 | struct iwl_calib_xtal_freq_cmd cmd; |
63 | __le16 *xtal_calib = | 64 | __le16 *xtal_calib = priv->eeprom_data->xtal_calib; |
64 | (__le16 *)iwl_eeprom_query_addr(priv, EEPROM_XTAL); | ||
65 | 65 | ||
66 | iwl_set_calib_hdr(&cmd.hdr, IWL_PHY_CALIBRATE_CRYSTAL_FRQ_CMD); | 66 | iwl_set_calib_hdr(&cmd.hdr, IWL_PHY_CALIBRATE_CRYSTAL_FRQ_CMD); |
67 | cmd.cap_pin1 = le16_to_cpu(xtal_calib[0]); | 67 | cmd.cap_pin1 = le16_to_cpu(xtal_calib[0]); |
@@ -72,12 +72,10 @@ static int iwl_set_Xtal_calib(struct iwl_priv *priv) | |||
72 | static int iwl_set_temperature_offset_calib(struct iwl_priv *priv) | 72 | static int iwl_set_temperature_offset_calib(struct iwl_priv *priv) |
73 | { | 73 | { |
74 | struct iwl_calib_temperature_offset_cmd cmd; | 74 | struct iwl_calib_temperature_offset_cmd cmd; |
75 | __le16 *offset_calib = | ||
76 | (__le16 *)iwl_eeprom_query_addr(priv, EEPROM_RAW_TEMPERATURE); | ||
77 | 75 | ||
78 | memset(&cmd, 0, sizeof(cmd)); | 76 | memset(&cmd, 0, sizeof(cmd)); |
79 | iwl_set_calib_hdr(&cmd.hdr, IWL_PHY_CALIBRATE_TEMP_OFFSET_CMD); | 77 | iwl_set_calib_hdr(&cmd.hdr, IWL_PHY_CALIBRATE_TEMP_OFFSET_CMD); |
80 | memcpy(&cmd.radio_sensor_offset, offset_calib, sizeof(*offset_calib)); | 78 | cmd.radio_sensor_offset = priv->eeprom_data->raw_temperature; |
81 | if (!(cmd.radio_sensor_offset)) | 79 | if (!(cmd.radio_sensor_offset)) |
82 | cmd.radio_sensor_offset = DEFAULT_RADIO_SENSOR_OFFSET; | 80 | cmd.radio_sensor_offset = DEFAULT_RADIO_SENSOR_OFFSET; |
83 | 81 | ||
@@ -89,27 +87,17 @@ static int iwl_set_temperature_offset_calib(struct iwl_priv *priv) | |||
89 | static int iwl_set_temperature_offset_calib_v2(struct iwl_priv *priv) | 87 | static int iwl_set_temperature_offset_calib_v2(struct iwl_priv *priv) |
90 | { | 88 | { |
91 | struct iwl_calib_temperature_offset_v2_cmd cmd; | 89 | struct iwl_calib_temperature_offset_v2_cmd cmd; |
92 | __le16 *offset_calib_high = (__le16 *)iwl_eeprom_query_addr(priv, | ||
93 | EEPROM_KELVIN_TEMPERATURE); | ||
94 | __le16 *offset_calib_low = | ||
95 | (__le16 *)iwl_eeprom_query_addr(priv, EEPROM_RAW_TEMPERATURE); | ||
96 | struct iwl_eeprom_calib_hdr *hdr; | ||
97 | 90 | ||
98 | memset(&cmd, 0, sizeof(cmd)); | 91 | memset(&cmd, 0, sizeof(cmd)); |
99 | iwl_set_calib_hdr(&cmd.hdr, IWL_PHY_CALIBRATE_TEMP_OFFSET_CMD); | 92 | iwl_set_calib_hdr(&cmd.hdr, IWL_PHY_CALIBRATE_TEMP_OFFSET_CMD); |
100 | hdr = (struct iwl_eeprom_calib_hdr *)iwl_eeprom_query_addr(priv, | 93 | cmd.radio_sensor_offset_high = priv->eeprom_data->kelvin_temperature; |
101 | EEPROM_CALIB_ALL); | 94 | cmd.radio_sensor_offset_low = priv->eeprom_data->raw_temperature; |
102 | memcpy(&cmd.radio_sensor_offset_high, offset_calib_high, | 95 | if (!cmd.radio_sensor_offset_low) { |
103 | sizeof(*offset_calib_high)); | ||
104 | memcpy(&cmd.radio_sensor_offset_low, offset_calib_low, | ||
105 | sizeof(*offset_calib_low)); | ||
106 | if (!(cmd.radio_sensor_offset_low)) { | ||
107 | IWL_DEBUG_CALIB(priv, "no info in EEPROM, use default\n"); | 96 | IWL_DEBUG_CALIB(priv, "no info in EEPROM, use default\n"); |
108 | cmd.radio_sensor_offset_low = DEFAULT_RADIO_SENSOR_OFFSET; | 97 | cmd.radio_sensor_offset_low = DEFAULT_RADIO_SENSOR_OFFSET; |
109 | cmd.radio_sensor_offset_high = DEFAULT_RADIO_SENSOR_OFFSET; | 98 | cmd.radio_sensor_offset_high = DEFAULT_RADIO_SENSOR_OFFSET; |
110 | } | 99 | } |
111 | memcpy(&cmd.burntVoltageRef, &hdr->voltage, | 100 | cmd.burntVoltageRef = priv->eeprom_data->calib_voltage; |
112 | sizeof(hdr->voltage)); | ||
113 | 101 | ||
114 | IWL_DEBUG_CALIB(priv, "Radio sensor offset high: %d\n", | 102 | IWL_DEBUG_CALIB(priv, "Radio sensor offset high: %d\n", |
115 | le16_to_cpu(cmd.radio_sensor_offset_high)); | 103 | le16_to_cpu(cmd.radio_sensor_offset_high)); |
@@ -177,7 +165,7 @@ int iwl_init_alive_start(struct iwl_priv *priv) | |||
177 | return 0; | 165 | return 0; |
178 | } | 166 | } |
179 | 167 | ||
180 | int iwl_send_wimax_coex(struct iwl_priv *priv) | 168 | static int iwl_send_wimax_coex(struct iwl_priv *priv) |
181 | { | 169 | { |
182 | struct iwl_wimax_coex_cmd coex_cmd; | 170 | struct iwl_wimax_coex_cmd coex_cmd; |
183 | 171 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-config.h b/drivers/net/wireless/iwlwifi/iwl-config.h index a52818bbfe98..10e47938b635 100644 --- a/drivers/net/wireless/iwlwifi/iwl-config.h +++ b/drivers/net/wireless/iwlwifi/iwl-config.h | |||
@@ -113,7 +113,7 @@ enum iwl_led_mode { | |||
113 | #define IWL_MAX_PLCP_ERR_THRESHOLD_DISABLE 0 | 113 | #define IWL_MAX_PLCP_ERR_THRESHOLD_DISABLE 0 |
114 | 114 | ||
115 | /* TX queue watchdog timeouts in mSecs */ | 115 | /* TX queue watchdog timeouts in mSecs */ |
116 | #define IWL_WATCHHDOG_DISABLED 0 | 116 | #define IWL_WATCHDOG_DISABLED 0 |
117 | #define IWL_DEF_WD_TIMEOUT 2000 | 117 | #define IWL_DEF_WD_TIMEOUT 2000 |
118 | #define IWL_LONG_WD_TIMEOUT 10000 | 118 | #define IWL_LONG_WD_TIMEOUT 10000 |
119 | #define IWL_MAX_WD_TIMEOUT 120000 | 119 | #define IWL_MAX_WD_TIMEOUT 120000 |
@@ -182,13 +182,34 @@ struct iwl_bt_params { | |||
182 | bool bt_sco_disable; | 182 | bool bt_sco_disable; |
183 | bool bt_session_2; | 183 | bool bt_session_2; |
184 | }; | 184 | }; |
185 | |||
185 | /* | 186 | /* |
186 | * @use_rts_for_aggregation: use rts/cts protection for HT traffic | 187 | * @use_rts_for_aggregation: use rts/cts protection for HT traffic |
188 | * @ht40_bands: bitmap of bands (using %IEEE80211_BAND_*) that support HT40 | ||
187 | */ | 189 | */ |
188 | struct iwl_ht_params { | 190 | struct iwl_ht_params { |
191 | enum ieee80211_smps_mode smps_mode; | ||
189 | const bool ht_greenfield_support; /* if used set to true */ | 192 | const bool ht_greenfield_support; /* if used set to true */ |
190 | bool use_rts_for_aggregation; | 193 | bool use_rts_for_aggregation; |
191 | enum ieee80211_smps_mode smps_mode; | 194 | u8 ht40_bands; |
195 | }; | ||
196 | |||
197 | /* | ||
198 | * information on how to parse the EEPROM | ||
199 | */ | ||
200 | #define EEPROM_REG_BAND_1_CHANNELS 0x08 | ||
201 | #define EEPROM_REG_BAND_2_CHANNELS 0x26 | ||
202 | #define EEPROM_REG_BAND_3_CHANNELS 0x42 | ||
203 | #define EEPROM_REG_BAND_4_CHANNELS 0x5C | ||
204 | #define EEPROM_REG_BAND_5_CHANNELS 0x74 | ||
205 | #define EEPROM_REG_BAND_24_HT40_CHANNELS 0x82 | ||
206 | #define EEPROM_REG_BAND_52_HT40_CHANNELS 0x92 | ||
207 | #define EEPROM_6000_REG_BAND_24_HT40_CHANNELS 0x80 | ||
208 | #define EEPROM_REGULATORY_BAND_NO_HT40 0 | ||
209 | |||
210 | struct iwl_eeprom_params { | ||
211 | const u8 regulatory_bands[7]; | ||
212 | bool enhanced_txpower; | ||
192 | }; | 213 | }; |
193 | 214 | ||
194 | /** | 215 | /** |
@@ -243,6 +264,7 @@ struct iwl_cfg { | |||
243 | /* params likely to change within a device family */ | 264 | /* params likely to change within a device family */ |
244 | const struct iwl_ht_params *ht_params; | 265 | const struct iwl_ht_params *ht_params; |
245 | const struct iwl_bt_params *bt_params; | 266 | const struct iwl_bt_params *bt_params; |
267 | const struct iwl_eeprom_params *eeprom_params; | ||
246 | const bool need_temp_offset_calib; /* if used set to true */ | 268 | const bool need_temp_offset_calib; /* if used set to true */ |
247 | const bool no_xtal_calib; | 269 | const bool no_xtal_calib; |
248 | enum iwl_led_mode led_mode; | 270 | enum iwl_led_mode led_mode; |
diff --git a/drivers/net/wireless/iwlwifi/iwl-csr.h b/drivers/net/wireless/iwlwifi/iwl-csr.h index 59750543fce7..34a5287dfc2f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-csr.h +++ b/drivers/net/wireless/iwlwifi/iwl-csr.h | |||
@@ -97,13 +97,10 @@ | |||
97 | /* | 97 | /* |
98 | * Hardware revision info | 98 | * Hardware revision info |
99 | * Bit fields: | 99 | * Bit fields: |
100 | * 31-8: Reserved | 100 | * 31-16: Reserved |
101 | * 7-4: Type of device: see CSR_HW_REV_TYPE_xxx definitions | 101 | * 15-4: Type of device: see CSR_HW_REV_TYPE_xxx definitions |
102 | * 3-2: Revision step: 0 = A, 1 = B, 2 = C, 3 = D | 102 | * 3-2: Revision step: 0 = A, 1 = B, 2 = C, 3 = D |
103 | * 1-0: "Dash" (-) value, as in A-1, etc. | 103 | * 1-0: "Dash" (-) value, as in A-1, etc. |
104 | * | ||
105 | * NOTE: Revision step affects calculation of CCK txpower for 4965. | ||
106 | * NOTE: See also CSR_HW_REV_WA_REG (work-around for bug in 4965). | ||
107 | */ | 104 | */ |
108 | #define CSR_HW_REV (CSR_BASE+0x028) | 105 | #define CSR_HW_REV (CSR_BASE+0x028) |
109 | 106 | ||
@@ -155,9 +152,21 @@ | |||
155 | #define CSR_DBG_LINK_PWR_MGMT_REG (CSR_BASE+0x250) | 152 | #define CSR_DBG_LINK_PWR_MGMT_REG (CSR_BASE+0x250) |
156 | 153 | ||
157 | /* Bits for CSR_HW_IF_CONFIG_REG */ | 154 | /* Bits for CSR_HW_IF_CONFIG_REG */ |
158 | #define CSR_HW_IF_CONFIG_REG_MSK_BOARD_VER (0x00000C00) | 155 | #define CSR_HW_IF_CONFIG_REG_MSK_MAC_DASH (0x00000003) |
159 | #define CSR_HW_IF_CONFIG_REG_BIT_MAC_SI (0x00000100) | 156 | #define CSR_HW_IF_CONFIG_REG_MSK_MAC_STEP (0x0000000C) |
157 | #define CSR_HW_IF_CONFIG_REG_MSK_BOARD_VER (0x000000C0) | ||
158 | #define CSR_HW_IF_CONFIG_REG_BIT_MAC_SI (0x00000100) | ||
160 | #define CSR_HW_IF_CONFIG_REG_BIT_RADIO_SI (0x00000200) | 159 | #define CSR_HW_IF_CONFIG_REG_BIT_RADIO_SI (0x00000200) |
160 | #define CSR_HW_IF_CONFIG_REG_MSK_PHY_TYPE (0x00000C00) | ||
161 | #define CSR_HW_IF_CONFIG_REG_MSK_PHY_DASH (0x00003000) | ||
162 | #define CSR_HW_IF_CONFIG_REG_MSK_PHY_STEP (0x0000C000) | ||
163 | |||
164 | #define CSR_HW_IF_CONFIG_REG_POS_MAC_DASH (0) | ||
165 | #define CSR_HW_IF_CONFIG_REG_POS_MAC_STEP (2) | ||
166 | #define CSR_HW_IF_CONFIG_REG_POS_BOARD_VER (6) | ||
167 | #define CSR_HW_IF_CONFIG_REG_POS_PHY_TYPE (10) | ||
168 | #define CSR_HW_IF_CONFIG_REG_POS_PHY_DASH (12) | ||
169 | #define CSR_HW_IF_CONFIG_REG_POS_PHY_STEP (14) | ||
161 | 170 | ||
162 | #define CSR_HW_IF_CONFIG_REG_BIT_HAP_WAKE_L1A (0x00080000) | 171 | #define CSR_HW_IF_CONFIG_REG_BIT_HAP_WAKE_L1A (0x00080000) |
163 | #define CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM (0x00200000) | 172 | #define CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM (0x00200000) |
@@ -270,7 +279,10 @@ | |||
270 | 279 | ||
271 | 280 | ||
272 | /* HW REV */ | 281 | /* HW REV */ |
273 | #define CSR_HW_REV_TYPE_MSK (0x00001F0) | 282 | #define CSR_HW_REV_DASH(_val) (((_val) & 0x0000003) >> 0) |
283 | #define CSR_HW_REV_STEP(_val) (((_val) & 0x000000C) >> 2) | ||
284 | |||
285 | #define CSR_HW_REV_TYPE_MSK (0x000FFF0) | ||
274 | #define CSR_HW_REV_TYPE_5300 (0x0000020) | 286 | #define CSR_HW_REV_TYPE_5300 (0x0000020) |
275 | #define CSR_HW_REV_TYPE_5350 (0x0000030) | 287 | #define CSR_HW_REV_TYPE_5350 (0x0000030) |
276 | #define CSR_HW_REV_TYPE_5100 (0x0000050) | 288 | #define CSR_HW_REV_TYPE_5100 (0x0000050) |
diff --git a/drivers/net/wireless/iwlwifi/iwl-debug.h b/drivers/net/wireless/iwlwifi/iwl-debug.h index f6bf91c8f773..42b20b0e83bc 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debug.h +++ b/drivers/net/wireless/iwlwifi/iwl-debug.h | |||
@@ -45,6 +45,7 @@ void __iwl_crit(struct device *dev, const char *fmt, ...) __printf(2, 3); | |||
45 | 45 | ||
46 | /* No matter what is m (priv, bus, trans), this will work */ | 46 | /* No matter what is m (priv, bus, trans), this will work */ |
47 | #define IWL_ERR(m, f, a...) __iwl_err((m)->dev, false, false, f, ## a) | 47 | #define IWL_ERR(m, f, a...) __iwl_err((m)->dev, false, false, f, ## a) |
48 | #define IWL_ERR_DEV(d, f, a...) __iwl_err((d), false, false, f, ## a) | ||
48 | #define IWL_WARN(m, f, a...) __iwl_warn((m)->dev, f, ## a) | 49 | #define IWL_WARN(m, f, a...) __iwl_warn((m)->dev, f, ## a) |
49 | #define IWL_INFO(m, f, a...) __iwl_info((m)->dev, f, ## a) | 50 | #define IWL_INFO(m, f, a...) __iwl_info((m)->dev, f, ## a) |
50 | #define IWL_CRIT(m, f, a...) __iwl_crit((m)->dev, f, ## a) | 51 | #define IWL_CRIT(m, f, a...) __iwl_crit((m)->dev, f, ## a) |
@@ -69,6 +70,8 @@ do { \ | |||
69 | 70 | ||
70 | #define IWL_DEBUG(m, level, fmt, args...) \ | 71 | #define IWL_DEBUG(m, level, fmt, args...) \ |
71 | __iwl_dbg((m)->dev, level, false, __func__, fmt, ##args) | 72 | __iwl_dbg((m)->dev, level, false, __func__, fmt, ##args) |
73 | #define IWL_DEBUG_DEV(dev, level, fmt, args...) \ | ||
74 | __iwl_dbg((dev), level, false, __func__, fmt, ##args) | ||
72 | #define IWL_DEBUG_LIMIT(m, level, fmt, args...) \ | 75 | #define IWL_DEBUG_LIMIT(m, level, fmt, args...) \ |
73 | __iwl_dbg((m)->dev, level, true, __func__, fmt, ##args) | 76 | __iwl_dbg((m)->dev, level, true, __func__, fmt, ##args) |
74 | 77 | ||
@@ -153,7 +156,7 @@ do { \ | |||
153 | #define IWL_DEBUG_LED(p, f, a...) IWL_DEBUG(p, IWL_DL_LED, f, ## a) | 156 | #define IWL_DEBUG_LED(p, f, a...) IWL_DEBUG(p, IWL_DL_LED, f, ## a) |
154 | #define IWL_DEBUG_WEP(p, f, a...) IWL_DEBUG(p, IWL_DL_WEP, f, ## a) | 157 | #define IWL_DEBUG_WEP(p, f, a...) IWL_DEBUG(p, IWL_DL_WEP, f, ## a) |
155 | #define IWL_DEBUG_HC(p, f, a...) IWL_DEBUG(p, IWL_DL_HCMD, f, ## a) | 158 | #define IWL_DEBUG_HC(p, f, a...) IWL_DEBUG(p, IWL_DL_HCMD, f, ## a) |
156 | #define IWL_DEBUG_EEPROM(p, f, a...) IWL_DEBUG(p, IWL_DL_EEPROM, f, ## a) | 159 | #define IWL_DEBUG_EEPROM(d, f, a...) IWL_DEBUG_DEV(d, IWL_DL_EEPROM, f, ## a) |
157 | #define IWL_DEBUG_CALIB(p, f, a...) IWL_DEBUG(p, IWL_DL_CALIB, f, ## a) | 160 | #define IWL_DEBUG_CALIB(p, f, a...) IWL_DEBUG(p, IWL_DL_CALIB, f, ## a) |
158 | #define IWL_DEBUG_FW(p, f, a...) IWL_DEBUG(p, IWL_DL_FW, f, ## a) | 161 | #define IWL_DEBUG_FW(p, f, a...) IWL_DEBUG(p, IWL_DL_FW, f, ## a) |
159 | #define IWL_DEBUG_RF_KILL(p, f, a...) IWL_DEBUG(p, IWL_DL_RF_KILL, f, ## a) | 162 | #define IWL_DEBUG_RF_KILL(p, f, a...) IWL_DEBUG(p, IWL_DL_RF_KILL, f, ## a) |
diff --git a/drivers/net/wireless/iwlwifi/iwl-devtrace.h b/drivers/net/wireless/iwlwifi/iwl-devtrace.h index 06203d6a1d86..65364793021f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-devtrace.h +++ b/drivers/net/wireless/iwlwifi/iwl-devtrace.h | |||
@@ -28,6 +28,7 @@ | |||
28 | #define __IWLWIFI_DEVICE_TRACE | 28 | #define __IWLWIFI_DEVICE_TRACE |
29 | 29 | ||
30 | #include <linux/tracepoint.h> | 30 | #include <linux/tracepoint.h> |
31 | #include <linux/device.h> | ||
31 | 32 | ||
32 | 33 | ||
33 | #if !defined(CONFIG_IWLWIFI_DEVICE_TRACING) || defined(__CHECKER__) | 34 | #if !defined(CONFIG_IWLWIFI_DEVICE_TRACING) || defined(__CHECKER__) |
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.c b/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.c new file mode 100644 index 000000000000..c87a05cbec12 --- /dev/null +++ b/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.c | |||
@@ -0,0 +1,900 @@ | |||
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 - 2012 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 - 2012 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 | #include <linux/types.h> | ||
63 | #include <linux/slab.h> | ||
64 | #include <linux/export.h> | ||
65 | #include "iwl-modparams.h" | ||
66 | #include "iwl-eeprom-parse.h" | ||
67 | |||
68 | /* EEPROM offset definitions */ | ||
69 | |||
70 | /* indirect access definitions */ | ||
71 | #define ADDRESS_MSK 0x0000FFFF | ||
72 | #define INDIRECT_TYPE_MSK 0x000F0000 | ||
73 | #define INDIRECT_HOST 0x00010000 | ||
74 | #define INDIRECT_GENERAL 0x00020000 | ||
75 | #define INDIRECT_REGULATORY 0x00030000 | ||
76 | #define INDIRECT_CALIBRATION 0x00040000 | ||
77 | #define INDIRECT_PROCESS_ADJST 0x00050000 | ||
78 | #define INDIRECT_OTHERS 0x00060000 | ||
79 | #define INDIRECT_TXP_LIMIT 0x00070000 | ||
80 | #define INDIRECT_TXP_LIMIT_SIZE 0x00080000 | ||
81 | #define INDIRECT_ADDRESS 0x00100000 | ||
82 | |||
83 | /* corresponding link offsets in EEPROM */ | ||
84 | #define EEPROM_LINK_HOST (2*0x64) | ||
85 | #define EEPROM_LINK_GENERAL (2*0x65) | ||
86 | #define EEPROM_LINK_REGULATORY (2*0x66) | ||
87 | #define EEPROM_LINK_CALIBRATION (2*0x67) | ||
88 | #define EEPROM_LINK_PROCESS_ADJST (2*0x68) | ||
89 | #define EEPROM_LINK_OTHERS (2*0x69) | ||
90 | #define EEPROM_LINK_TXP_LIMIT (2*0x6a) | ||
91 | #define EEPROM_LINK_TXP_LIMIT_SIZE (2*0x6b) | ||
92 | |||
93 | /* General */ | ||
94 | #define EEPROM_DEVICE_ID (2*0x08) /* 2 bytes */ | ||
95 | #define EEPROM_SUBSYSTEM_ID (2*0x0A) /* 2 bytes */ | ||
96 | #define EEPROM_MAC_ADDRESS (2*0x15) /* 6 bytes */ | ||
97 | #define EEPROM_BOARD_REVISION (2*0x35) /* 2 bytes */ | ||
98 | #define EEPROM_BOARD_PBA_NUMBER (2*0x3B+1) /* 9 bytes */ | ||
99 | #define EEPROM_VERSION (2*0x44) /* 2 bytes */ | ||
100 | #define EEPROM_SKU_CAP (2*0x45) /* 2 bytes */ | ||
101 | #define EEPROM_OEM_MODE (2*0x46) /* 2 bytes */ | ||
102 | #define EEPROM_RADIO_CONFIG (2*0x48) /* 2 bytes */ | ||
103 | #define EEPROM_NUM_MAC_ADDRESS (2*0x4C) /* 2 bytes */ | ||
104 | |||
105 | /* calibration */ | ||
106 | struct iwl_eeprom_calib_hdr { | ||
107 | u8 version; | ||
108 | u8 pa_type; | ||
109 | __le16 voltage; | ||
110 | } __packed; | ||
111 | |||
112 | #define EEPROM_CALIB_ALL (INDIRECT_ADDRESS | INDIRECT_CALIBRATION) | ||
113 | #define EEPROM_XTAL ((2*0x128) | EEPROM_CALIB_ALL) | ||
114 | |||
115 | /* temperature */ | ||
116 | #define EEPROM_KELVIN_TEMPERATURE ((2*0x12A) | EEPROM_CALIB_ALL) | ||
117 | #define EEPROM_RAW_TEMPERATURE ((2*0x12B) | EEPROM_CALIB_ALL) | ||
118 | |||
119 | /* | ||
120 | * EEPROM bands | ||
121 | * These are the channel numbers from each band in the order | ||
122 | * that they are stored in the EEPROM band information. Note | ||
123 | * that EEPROM bands aren't the same as mac80211 bands, and | ||
124 | * there are even special "ht40 bands" in the EEPROM. | ||
125 | */ | ||
126 | static const u8 iwl_eeprom_band_1[14] = { /* 2.4 GHz */ | ||
127 | 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 | ||
128 | }; | ||
129 | |||
130 | static const u8 iwl_eeprom_band_2[] = { /* 4915-5080MHz */ | ||
131 | 183, 184, 185, 187, 188, 189, 192, 196, 7, 8, 11, 12, 16 | ||
132 | }; | ||
133 | |||
134 | static const u8 iwl_eeprom_band_3[] = { /* 5170-5320MHz */ | ||
135 | 34, 36, 38, 40, 42, 44, 46, 48, 52, 56, 60, 64 | ||
136 | }; | ||
137 | |||
138 | static const u8 iwl_eeprom_band_4[] = { /* 5500-5700MHz */ | ||
139 | 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140 | ||
140 | }; | ||
141 | |||
142 | static const u8 iwl_eeprom_band_5[] = { /* 5725-5825MHz */ | ||
143 | 145, 149, 153, 157, 161, 165 | ||
144 | }; | ||
145 | |||
146 | static const u8 iwl_eeprom_band_6[] = { /* 2.4 ht40 channel */ | ||
147 | 1, 2, 3, 4, 5, 6, 7 | ||
148 | }; | ||
149 | |||
150 | static const u8 iwl_eeprom_band_7[] = { /* 5.2 ht40 channel */ | ||
151 | 36, 44, 52, 60, 100, 108, 116, 124, 132, 149, 157 | ||
152 | }; | ||
153 | |||
154 | #define IWL_NUM_CHANNELS (ARRAY_SIZE(iwl_eeprom_band_1) + \ | ||
155 | ARRAY_SIZE(iwl_eeprom_band_2) + \ | ||
156 | ARRAY_SIZE(iwl_eeprom_band_3) + \ | ||
157 | ARRAY_SIZE(iwl_eeprom_band_4) + \ | ||
158 | ARRAY_SIZE(iwl_eeprom_band_5)) | ||
159 | |||
160 | /* rate data (static) */ | ||
161 | static struct ieee80211_rate iwl_cfg80211_rates[] = { | ||
162 | { .bitrate = 1 * 10, .hw_value = 0, .hw_value_short = 0, }, | ||
163 | { .bitrate = 2 * 10, .hw_value = 1, .hw_value_short = 1, | ||
164 | .flags = IEEE80211_RATE_SHORT_PREAMBLE, }, | ||
165 | { .bitrate = 5.5 * 10, .hw_value = 2, .hw_value_short = 2, | ||
166 | .flags = IEEE80211_RATE_SHORT_PREAMBLE, }, | ||
167 | { .bitrate = 11 * 10, .hw_value = 3, .hw_value_short = 3, | ||
168 | .flags = IEEE80211_RATE_SHORT_PREAMBLE, }, | ||
169 | { .bitrate = 6 * 10, .hw_value = 4, .hw_value_short = 4, }, | ||
170 | { .bitrate = 9 * 10, .hw_value = 5, .hw_value_short = 5, }, | ||
171 | { .bitrate = 12 * 10, .hw_value = 6, .hw_value_short = 6, }, | ||
172 | { .bitrate = 18 * 10, .hw_value = 7, .hw_value_short = 7, }, | ||
173 | { .bitrate = 24 * 10, .hw_value = 8, .hw_value_short = 8, }, | ||
174 | { .bitrate = 36 * 10, .hw_value = 9, .hw_value_short = 9, }, | ||
175 | { .bitrate = 48 * 10, .hw_value = 10, .hw_value_short = 10, }, | ||
176 | { .bitrate = 54 * 10, .hw_value = 11, .hw_value_short = 11, }, | ||
177 | }; | ||
178 | #define RATES_24_OFFS 0 | ||
179 | #define N_RATES_24 ARRAY_SIZE(iwl_cfg80211_rates) | ||
180 | #define RATES_52_OFFS 4 | ||
181 | #define N_RATES_52 (N_RATES_24 - RATES_52_OFFS) | ||
182 | |||
183 | /* EEPROM reading functions */ | ||
184 | |||
185 | static u16 iwl_eeprom_query16(const u8 *eeprom, size_t eeprom_size, int offset) | ||
186 | { | ||
187 | if (WARN_ON(offset + sizeof(u16) > eeprom_size)) | ||
188 | return 0; | ||
189 | return le16_to_cpup((__le16 *)(eeprom + offset)); | ||
190 | } | ||
191 | |||
192 | static u32 eeprom_indirect_address(const u8 *eeprom, size_t eeprom_size, | ||
193 | u32 address) | ||
194 | { | ||
195 | u16 offset = 0; | ||
196 | |||
197 | if ((address & INDIRECT_ADDRESS) == 0) | ||
198 | return address; | ||
199 | |||
200 | switch (address & INDIRECT_TYPE_MSK) { | ||
201 | case INDIRECT_HOST: | ||
202 | offset = iwl_eeprom_query16(eeprom, eeprom_size, | ||
203 | EEPROM_LINK_HOST); | ||
204 | break; | ||
205 | case INDIRECT_GENERAL: | ||
206 | offset = iwl_eeprom_query16(eeprom, eeprom_size, | ||
207 | EEPROM_LINK_GENERAL); | ||
208 | break; | ||
209 | case INDIRECT_REGULATORY: | ||
210 | offset = iwl_eeprom_query16(eeprom, eeprom_size, | ||
211 | EEPROM_LINK_REGULATORY); | ||
212 | break; | ||
213 | case INDIRECT_TXP_LIMIT: | ||
214 | offset = iwl_eeprom_query16(eeprom, eeprom_size, | ||
215 | EEPROM_LINK_TXP_LIMIT); | ||
216 | break; | ||
217 | case INDIRECT_TXP_LIMIT_SIZE: | ||
218 | offset = iwl_eeprom_query16(eeprom, eeprom_size, | ||
219 | EEPROM_LINK_TXP_LIMIT_SIZE); | ||
220 | break; | ||
221 | case INDIRECT_CALIBRATION: | ||
222 | offset = iwl_eeprom_query16(eeprom, eeprom_size, | ||
223 | EEPROM_LINK_CALIBRATION); | ||
224 | break; | ||
225 | case INDIRECT_PROCESS_ADJST: | ||
226 | offset = iwl_eeprom_query16(eeprom, eeprom_size, | ||
227 | EEPROM_LINK_PROCESS_ADJST); | ||
228 | break; | ||
229 | case INDIRECT_OTHERS: | ||
230 | offset = iwl_eeprom_query16(eeprom, eeprom_size, | ||
231 | EEPROM_LINK_OTHERS); | ||
232 | break; | ||
233 | default: | ||
234 | WARN_ON(1); | ||
235 | break; | ||
236 | } | ||
237 | |||
238 | /* translate the offset from words to byte */ | ||
239 | return (address & ADDRESS_MSK) + (offset << 1); | ||
240 | } | ||
241 | |||
242 | static const u8 *iwl_eeprom_query_addr(const u8 *eeprom, size_t eeprom_size, | ||
243 | u32 offset) | ||
244 | { | ||
245 | u32 address = eeprom_indirect_address(eeprom, eeprom_size, offset); | ||
246 | |||
247 | if (WARN_ON(address >= eeprom_size)) | ||
248 | return NULL; | ||
249 | |||
250 | return &eeprom[address]; | ||
251 | } | ||
252 | |||
253 | static int iwl_eeprom_read_calib(const u8 *eeprom, size_t eeprom_size, | ||
254 | struct iwl_eeprom_data *data) | ||
255 | { | ||
256 | struct iwl_eeprom_calib_hdr *hdr; | ||
257 | |||
258 | hdr = (void *)iwl_eeprom_query_addr(eeprom, eeprom_size, | ||
259 | EEPROM_CALIB_ALL); | ||
260 | if (!hdr) | ||
261 | return -ENODATA; | ||
262 | data->calib_version = hdr->version; | ||
263 | data->calib_voltage = hdr->voltage; | ||
264 | |||
265 | return 0; | ||
266 | } | ||
267 | |||
268 | /** | ||
269 | * enum iwl_eeprom_channel_flags - channel flags in EEPROM | ||
270 | * @EEPROM_CHANNEL_VALID: channel is usable for this SKU/geo | ||
271 | * @EEPROM_CHANNEL_IBSS: usable as an IBSS channel | ||
272 | * @EEPROM_CHANNEL_ACTIVE: active scanning allowed | ||
273 | * @EEPROM_CHANNEL_RADAR: radar detection required | ||
274 | * @EEPROM_CHANNEL_WIDE: 20 MHz channel okay (?) | ||
275 | * @EEPROM_CHANNEL_DFS: dynamic freq selection candidate | ||
276 | */ | ||
277 | enum iwl_eeprom_channel_flags { | ||
278 | EEPROM_CHANNEL_VALID = BIT(0), | ||
279 | EEPROM_CHANNEL_IBSS = BIT(1), | ||
280 | EEPROM_CHANNEL_ACTIVE = BIT(3), | ||
281 | EEPROM_CHANNEL_RADAR = BIT(4), | ||
282 | EEPROM_CHANNEL_WIDE = BIT(5), | ||
283 | EEPROM_CHANNEL_DFS = BIT(7), | ||
284 | }; | ||
285 | |||
286 | /** | ||
287 | * struct iwl_eeprom_channel - EEPROM channel data | ||
288 | * @flags: %EEPROM_CHANNEL_* flags | ||
289 | * @max_power_avg: max power (in dBm) on this channel, at most 31 dBm | ||
290 | */ | ||
291 | struct iwl_eeprom_channel { | ||
292 | u8 flags; | ||
293 | s8 max_power_avg; | ||
294 | } __packed; | ||
295 | |||
296 | |||
297 | enum iwl_eeprom_enhanced_txpwr_flags { | ||
298 | IWL_EEPROM_ENH_TXP_FL_VALID = BIT(0), | ||
299 | IWL_EEPROM_ENH_TXP_FL_BAND_52G = BIT(1), | ||
300 | IWL_EEPROM_ENH_TXP_FL_OFDM = BIT(2), | ||
301 | IWL_EEPROM_ENH_TXP_FL_40MHZ = BIT(3), | ||
302 | IWL_EEPROM_ENH_TXP_FL_HT_AP = BIT(4), | ||
303 | IWL_EEPROM_ENH_TXP_FL_RES1 = BIT(5), | ||
304 | IWL_EEPROM_ENH_TXP_FL_RES2 = BIT(6), | ||
305 | IWL_EEPROM_ENH_TXP_FL_COMMON_TYPE = BIT(7), | ||
306 | }; | ||
307 | |||
308 | /** | ||
309 | * iwl_eeprom_enhanced_txpwr structure | ||
310 | * @flags: entry flags | ||
311 | * @channel: channel number | ||
312 | * @chain_a_max_pwr: chain a max power in 1/2 dBm | ||
313 | * @chain_b_max_pwr: chain b max power in 1/2 dBm | ||
314 | * @chain_c_max_pwr: chain c max power in 1/2 dBm | ||
315 | * @delta_20_in_40: 20-in-40 deltas (hi/lo) | ||
316 | * @mimo2_max_pwr: mimo2 max power in 1/2 dBm | ||
317 | * @mimo3_max_pwr: mimo3 max power in 1/2 dBm | ||
318 | * | ||
319 | * This structure presents the enhanced regulatory tx power limit layout | ||
320 | * in an EEPROM image. | ||
321 | */ | ||
322 | struct iwl_eeprom_enhanced_txpwr { | ||
323 | u8 flags; | ||
324 | u8 channel; | ||
325 | s8 chain_a_max; | ||
326 | s8 chain_b_max; | ||
327 | s8 chain_c_max; | ||
328 | u8 delta_20_in_40; | ||
329 | s8 mimo2_max; | ||
330 | s8 mimo3_max; | ||
331 | } __packed; | ||
332 | |||
333 | static s8 iwl_get_max_txpwr_half_dbm(const struct iwl_eeprom_data *data, | ||
334 | struct iwl_eeprom_enhanced_txpwr *txp) | ||
335 | { | ||
336 | s8 result = 0; /* (.5 dBm) */ | ||
337 | |||
338 | /* Take the highest tx power from any valid chains */ | ||
339 | if (data->valid_tx_ant & ANT_A && txp->chain_a_max > result) | ||
340 | result = txp->chain_a_max; | ||
341 | |||
342 | if (data->valid_tx_ant & ANT_B && txp->chain_b_max > result) | ||
343 | result = txp->chain_b_max; | ||
344 | |||
345 | if (data->valid_tx_ant & ANT_C && txp->chain_c_max > result) | ||
346 | result = txp->chain_c_max; | ||
347 | |||
348 | if ((data->valid_tx_ant == ANT_AB || | ||
349 | data->valid_tx_ant == ANT_BC || | ||
350 | data->valid_tx_ant == ANT_AC) && txp->mimo2_max > result) | ||
351 | result = txp->mimo2_max; | ||
352 | |||
353 | if (data->valid_tx_ant == ANT_ABC && txp->mimo3_max > result) | ||
354 | result = txp->mimo3_max; | ||
355 | |||
356 | return result; | ||
357 | } | ||
358 | |||
359 | #define EEPROM_TXP_OFFS (0x00 | INDIRECT_ADDRESS | INDIRECT_TXP_LIMIT) | ||
360 | #define EEPROM_TXP_ENTRY_LEN sizeof(struct iwl_eeprom_enhanced_txpwr) | ||
361 | #define EEPROM_TXP_SZ_OFFS (0x00 | INDIRECT_ADDRESS | INDIRECT_TXP_LIMIT_SIZE) | ||
362 | |||
363 | #define TXP_CHECK_AND_PRINT(x) \ | ||
364 | ((txp->flags & IWL_EEPROM_ENH_TXP_FL_##x) ? # x " " : "") | ||
365 | |||
366 | static void | ||
367 | iwl_eeprom_enh_txp_read_element(struct iwl_eeprom_data *data, | ||
368 | struct iwl_eeprom_enhanced_txpwr *txp, | ||
369 | int n_channels, s8 max_txpower_avg) | ||
370 | { | ||
371 | int ch_idx; | ||
372 | enum ieee80211_band band; | ||
373 | |||
374 | band = txp->flags & IWL_EEPROM_ENH_TXP_FL_BAND_52G ? | ||
375 | IEEE80211_BAND_5GHZ : IEEE80211_BAND_2GHZ; | ||
376 | |||
377 | for (ch_idx = 0; ch_idx < n_channels; ch_idx++) { | ||
378 | struct ieee80211_channel *chan = &data->channels[ch_idx]; | ||
379 | |||
380 | /* update matching channel or from common data only */ | ||
381 | if (txp->channel != 0 && chan->hw_value != txp->channel) | ||
382 | continue; | ||
383 | |||
384 | /* update matching band only */ | ||
385 | if (band != chan->band) | ||
386 | continue; | ||
387 | |||
388 | if (chan->max_power < max_txpower_avg && | ||
389 | !(txp->flags & IWL_EEPROM_ENH_TXP_FL_40MHZ)) | ||
390 | chan->max_power = max_txpower_avg; | ||
391 | } | ||
392 | } | ||
393 | |||
394 | static void iwl_eeprom_enhanced_txpower(struct device *dev, | ||
395 | struct iwl_eeprom_data *data, | ||
396 | const u8 *eeprom, size_t eeprom_size, | ||
397 | int n_channels) | ||
398 | { | ||
399 | struct iwl_eeprom_enhanced_txpwr *txp_array, *txp; | ||
400 | int idx, entries; | ||
401 | __le16 *txp_len; | ||
402 | s8 max_txp_avg_halfdbm; | ||
403 | |||
404 | BUILD_BUG_ON(sizeof(struct iwl_eeprom_enhanced_txpwr) != 8); | ||
405 | |||
406 | /* the length is in 16-bit words, but we want entries */ | ||
407 | txp_len = (__le16 *)iwl_eeprom_query_addr(eeprom, eeprom_size, | ||
408 | EEPROM_TXP_SZ_OFFS); | ||
409 | entries = le16_to_cpup(txp_len) * 2 / EEPROM_TXP_ENTRY_LEN; | ||
410 | |||
411 | txp_array = (void *)iwl_eeprom_query_addr(eeprom, eeprom_size, | ||
412 | EEPROM_TXP_OFFS); | ||
413 | |||
414 | for (idx = 0; idx < entries; idx++) { | ||
415 | txp = &txp_array[idx]; | ||
416 | /* skip invalid entries */ | ||
417 | if (!(txp->flags & IWL_EEPROM_ENH_TXP_FL_VALID)) | ||
418 | continue; | ||
419 | |||
420 | IWL_DEBUG_EEPROM(dev, "%s %d:\t %s%s%s%s%s%s%s%s (0x%02x)\n", | ||
421 | (txp->channel && (txp->flags & | ||
422 | IWL_EEPROM_ENH_TXP_FL_COMMON_TYPE)) ? | ||
423 | "Common " : (txp->channel) ? | ||
424 | "Channel" : "Common", | ||
425 | (txp->channel), | ||
426 | TXP_CHECK_AND_PRINT(VALID), | ||
427 | TXP_CHECK_AND_PRINT(BAND_52G), | ||
428 | TXP_CHECK_AND_PRINT(OFDM), | ||
429 | TXP_CHECK_AND_PRINT(40MHZ), | ||
430 | TXP_CHECK_AND_PRINT(HT_AP), | ||
431 | TXP_CHECK_AND_PRINT(RES1), | ||
432 | TXP_CHECK_AND_PRINT(RES2), | ||
433 | TXP_CHECK_AND_PRINT(COMMON_TYPE), | ||
434 | txp->flags); | ||
435 | IWL_DEBUG_EEPROM(dev, | ||
436 | "\t\t chain_A: 0x%02x chain_B: 0X%02x chain_C: 0X%02x\n", | ||
437 | txp->chain_a_max, txp->chain_b_max, | ||
438 | txp->chain_c_max); | ||
439 | IWL_DEBUG_EEPROM(dev, | ||
440 | "\t\t MIMO2: 0x%02x MIMO3: 0x%02x High 20_on_40: 0x%02x Low 20_on_40: 0x%02x\n", | ||
441 | txp->mimo2_max, txp->mimo3_max, | ||
442 | ((txp->delta_20_in_40 & 0xf0) >> 4), | ||
443 | (txp->delta_20_in_40 & 0x0f)); | ||
444 | |||
445 | max_txp_avg_halfdbm = iwl_get_max_txpwr_half_dbm(data, txp); | ||
446 | |||
447 | iwl_eeprom_enh_txp_read_element(data, txp, n_channels, | ||
448 | DIV_ROUND_UP(max_txp_avg_halfdbm, 2)); | ||
449 | |||
450 | if (max_txp_avg_halfdbm > data->max_tx_pwr_half_dbm) | ||
451 | data->max_tx_pwr_half_dbm = max_txp_avg_halfdbm; | ||
452 | } | ||
453 | } | ||
454 | |||
455 | static void iwl_init_band_reference(const struct iwl_cfg *cfg, | ||
456 | const u8 *eeprom, size_t eeprom_size, | ||
457 | int eeprom_band, int *eeprom_ch_count, | ||
458 | const struct iwl_eeprom_channel **ch_info, | ||
459 | const u8 **eeprom_ch_array) | ||
460 | { | ||
461 | u32 offset = cfg->eeprom_params->regulatory_bands[eeprom_band - 1]; | ||
462 | |||
463 | offset |= INDIRECT_ADDRESS | INDIRECT_REGULATORY; | ||
464 | |||
465 | *ch_info = (void *)iwl_eeprom_query_addr(eeprom, eeprom_size, offset); | ||
466 | |||
467 | switch (eeprom_band) { | ||
468 | case 1: /* 2.4GHz band */ | ||
469 | *eeprom_ch_count = ARRAY_SIZE(iwl_eeprom_band_1); | ||
470 | *eeprom_ch_array = iwl_eeprom_band_1; | ||
471 | break; | ||
472 | case 2: /* 4.9GHz band */ | ||
473 | *eeprom_ch_count = ARRAY_SIZE(iwl_eeprom_band_2); | ||
474 | *eeprom_ch_array = iwl_eeprom_band_2; | ||
475 | break; | ||
476 | case 3: /* 5.2GHz band */ | ||
477 | *eeprom_ch_count = ARRAY_SIZE(iwl_eeprom_band_3); | ||
478 | *eeprom_ch_array = iwl_eeprom_band_3; | ||
479 | break; | ||
480 | case 4: /* 5.5GHz band */ | ||
481 | *eeprom_ch_count = ARRAY_SIZE(iwl_eeprom_band_4); | ||
482 | *eeprom_ch_array = iwl_eeprom_band_4; | ||
483 | break; | ||
484 | case 5: /* 5.7GHz band */ | ||
485 | *eeprom_ch_count = ARRAY_SIZE(iwl_eeprom_band_5); | ||
486 | *eeprom_ch_array = iwl_eeprom_band_5; | ||
487 | break; | ||
488 | case 6: /* 2.4GHz ht40 channels */ | ||
489 | *eeprom_ch_count = ARRAY_SIZE(iwl_eeprom_band_6); | ||
490 | *eeprom_ch_array = iwl_eeprom_band_6; | ||
491 | break; | ||
492 | case 7: /* 5 GHz ht40 channels */ | ||
493 | *eeprom_ch_count = ARRAY_SIZE(iwl_eeprom_band_7); | ||
494 | *eeprom_ch_array = iwl_eeprom_band_7; | ||
495 | break; | ||
496 | default: | ||
497 | *eeprom_ch_count = 0; | ||
498 | *eeprom_ch_array = NULL; | ||
499 | WARN_ON(1); | ||
500 | } | ||
501 | } | ||
502 | |||
503 | #define CHECK_AND_PRINT(x) \ | ||
504 | ((eeprom_ch->flags & EEPROM_CHANNEL_##x) ? # x " " : "") | ||
505 | |||
506 | static void iwl_mod_ht40_chan_info(struct device *dev, | ||
507 | struct iwl_eeprom_data *data, int n_channels, | ||
508 | enum ieee80211_band band, u16 channel, | ||
509 | const struct iwl_eeprom_channel *eeprom_ch, | ||
510 | u8 clear_ht40_extension_channel) | ||
511 | { | ||
512 | struct ieee80211_channel *chan = NULL; | ||
513 | int i; | ||
514 | |||
515 | for (i = 0; i < n_channels; i++) { | ||
516 | if (data->channels[i].band != band) | ||
517 | continue; | ||
518 | if (data->channels[i].hw_value != channel) | ||
519 | continue; | ||
520 | chan = &data->channels[i]; | ||
521 | break; | ||
522 | } | ||
523 | |||
524 | if (!chan) | ||
525 | return; | ||
526 | |||
527 | IWL_DEBUG_EEPROM(dev, | ||
528 | "HT40 Ch. %d [%sGHz] %s%s%s%s%s(0x%02x %ddBm): Ad-Hoc %ssupported\n", | ||
529 | channel, | ||
530 | band == IEEE80211_BAND_5GHZ ? "5.2" : "2.4", | ||
531 | CHECK_AND_PRINT(IBSS), | ||
532 | CHECK_AND_PRINT(ACTIVE), | ||
533 | CHECK_AND_PRINT(RADAR), | ||
534 | CHECK_AND_PRINT(WIDE), | ||
535 | CHECK_AND_PRINT(DFS), | ||
536 | eeprom_ch->flags, | ||
537 | eeprom_ch->max_power_avg, | ||
538 | ((eeprom_ch->flags & EEPROM_CHANNEL_IBSS) && | ||
539 | !(eeprom_ch->flags & EEPROM_CHANNEL_RADAR)) ? "" | ||
540 | : "not "); | ||
541 | |||
542 | if (eeprom_ch->flags & EEPROM_CHANNEL_VALID) | ||
543 | chan->flags &= ~clear_ht40_extension_channel; | ||
544 | } | ||
545 | |||
546 | #define CHECK_AND_PRINT_I(x) \ | ||
547 | ((eeprom_ch_info[ch_idx].flags & EEPROM_CHANNEL_##x) ? # x " " : "") | ||
548 | |||
549 | static int iwl_init_channel_map(struct device *dev, const struct iwl_cfg *cfg, | ||
550 | struct iwl_eeprom_data *data, | ||
551 | const u8 *eeprom, size_t eeprom_size) | ||
552 | { | ||
553 | int band, ch_idx; | ||
554 | const struct iwl_eeprom_channel *eeprom_ch_info; | ||
555 | const u8 *eeprom_ch_array; | ||
556 | int eeprom_ch_count; | ||
557 | int n_channels = 0; | ||
558 | |||
559 | /* | ||
560 | * Loop through the 5 EEPROM bands and add them to the parse list | ||
561 | */ | ||
562 | for (band = 1; band <= 5; band++) { | ||
563 | struct ieee80211_channel *channel; | ||
564 | |||
565 | iwl_init_band_reference(cfg, eeprom, eeprom_size, band, | ||
566 | &eeprom_ch_count, &eeprom_ch_info, | ||
567 | &eeprom_ch_array); | ||
568 | |||
569 | /* Loop through each band adding each of the channels */ | ||
570 | for (ch_idx = 0; ch_idx < eeprom_ch_count; ch_idx++) { | ||
571 | const struct iwl_eeprom_channel *eeprom_ch; | ||
572 | |||
573 | eeprom_ch = &eeprom_ch_info[ch_idx]; | ||
574 | |||
575 | if (!(eeprom_ch->flags & EEPROM_CHANNEL_VALID)) { | ||
576 | IWL_DEBUG_EEPROM(dev, | ||
577 | "Ch. %d Flags %x [%sGHz] - No traffic\n", | ||
578 | eeprom_ch_array[ch_idx], | ||
579 | eeprom_ch_info[ch_idx].flags, | ||
580 | (band != 1) ? "5.2" : "2.4"); | ||
581 | continue; | ||
582 | } | ||
583 | |||
584 | channel = &data->channels[n_channels]; | ||
585 | n_channels++; | ||
586 | |||
587 | channel->hw_value = eeprom_ch_array[ch_idx]; | ||
588 | channel->band = (band == 1) ? IEEE80211_BAND_2GHZ | ||
589 | : IEEE80211_BAND_5GHZ; | ||
590 | channel->center_freq = | ||
591 | ieee80211_channel_to_frequency( | ||
592 | channel->hw_value, channel->band); | ||
593 | |||
594 | /* set no-HT40, will enable as appropriate later */ | ||
595 | channel->flags = IEEE80211_CHAN_NO_HT40; | ||
596 | |||
597 | if (!(eeprom_ch->flags & EEPROM_CHANNEL_IBSS)) | ||
598 | channel->flags |= IEEE80211_CHAN_NO_IBSS; | ||
599 | |||
600 | if (!(eeprom_ch->flags & EEPROM_CHANNEL_ACTIVE)) | ||
601 | channel->flags |= IEEE80211_CHAN_PASSIVE_SCAN; | ||
602 | |||
603 | if (eeprom_ch->flags & EEPROM_CHANNEL_RADAR) | ||
604 | channel->flags |= IEEE80211_CHAN_RADAR; | ||
605 | |||
606 | /* Initialize regulatory-based run-time data */ | ||
607 | channel->max_power = | ||
608 | eeprom_ch_info[ch_idx].max_power_avg; | ||
609 | IWL_DEBUG_EEPROM(dev, | ||
610 | "Ch. %d [%sGHz] %s%s%s%s%s%s(0x%02x %ddBm): Ad-Hoc %ssupported\n", | ||
611 | channel->hw_value, | ||
612 | (band != 1) ? "5.2" : "2.4", | ||
613 | CHECK_AND_PRINT_I(VALID), | ||
614 | CHECK_AND_PRINT_I(IBSS), | ||
615 | CHECK_AND_PRINT_I(ACTIVE), | ||
616 | CHECK_AND_PRINT_I(RADAR), | ||
617 | CHECK_AND_PRINT_I(WIDE), | ||
618 | CHECK_AND_PRINT_I(DFS), | ||
619 | eeprom_ch_info[ch_idx].flags, | ||
620 | eeprom_ch_info[ch_idx].max_power_avg, | ||
621 | ((eeprom_ch_info[ch_idx].flags & | ||
622 | EEPROM_CHANNEL_IBSS) && | ||
623 | !(eeprom_ch_info[ch_idx].flags & | ||
624 | EEPROM_CHANNEL_RADAR)) | ||
625 | ? "" : "not "); | ||
626 | } | ||
627 | } | ||
628 | |||
629 | if (cfg->eeprom_params->enhanced_txpower) { | ||
630 | /* | ||
631 | * for newer device (6000 series and up) | ||
632 | * EEPROM contain enhanced tx power information | ||
633 | * driver need to process addition information | ||
634 | * to determine the max channel tx power limits | ||
635 | */ | ||
636 | iwl_eeprom_enhanced_txpower(dev, data, eeprom, eeprom_size, | ||
637 | n_channels); | ||
638 | } else { | ||
639 | /* All others use data from channel map */ | ||
640 | int i; | ||
641 | |||
642 | data->max_tx_pwr_half_dbm = -128; | ||
643 | |||
644 | for (i = 0; i < n_channels; i++) | ||
645 | data->max_tx_pwr_half_dbm = | ||
646 | max_t(s8, data->max_tx_pwr_half_dbm, | ||
647 | data->channels[i].max_power * 2); | ||
648 | } | ||
649 | |||
650 | /* Check if we do have HT40 channels */ | ||
651 | if (cfg->eeprom_params->regulatory_bands[5] == | ||
652 | EEPROM_REGULATORY_BAND_NO_HT40 && | ||
653 | cfg->eeprom_params->regulatory_bands[6] == | ||
654 | EEPROM_REGULATORY_BAND_NO_HT40) | ||
655 | return n_channels; | ||
656 | |||
657 | /* Two additional EEPROM bands for 2.4 and 5 GHz HT40 channels */ | ||
658 | for (band = 6; band <= 7; band++) { | ||
659 | enum ieee80211_band ieeeband; | ||
660 | |||
661 | iwl_init_band_reference(cfg, eeprom, eeprom_size, band, | ||
662 | &eeprom_ch_count, &eeprom_ch_info, | ||
663 | &eeprom_ch_array); | ||
664 | |||
665 | /* EEPROM band 6 is 2.4, band 7 is 5 GHz */ | ||
666 | ieeeband = (band == 6) ? IEEE80211_BAND_2GHZ | ||
667 | : IEEE80211_BAND_5GHZ; | ||
668 | |||
669 | /* Loop through each band adding each of the channels */ | ||
670 | for (ch_idx = 0; ch_idx < eeprom_ch_count; ch_idx++) { | ||
671 | /* Set up driver's info for lower half */ | ||
672 | iwl_mod_ht40_chan_info(dev, data, n_channels, ieeeband, | ||
673 | eeprom_ch_array[ch_idx], | ||
674 | &eeprom_ch_info[ch_idx], | ||
675 | IEEE80211_CHAN_NO_HT40PLUS); | ||
676 | |||
677 | /* Set up driver's info for upper half */ | ||
678 | iwl_mod_ht40_chan_info(dev, data, n_channels, ieeeband, | ||
679 | eeprom_ch_array[ch_idx] + 4, | ||
680 | &eeprom_ch_info[ch_idx], | ||
681 | IEEE80211_CHAN_NO_HT40MINUS); | ||
682 | } | ||
683 | } | ||
684 | |||
685 | return n_channels; | ||
686 | } | ||
687 | |||
688 | static int iwl_init_sband_channels(struct iwl_eeprom_data *data, | ||
689 | struct ieee80211_supported_band *sband, | ||
690 | int n_channels, enum ieee80211_band band) | ||
691 | { | ||
692 | struct ieee80211_channel *chan = &data->channels[0]; | ||
693 | int n = 0, idx = 0; | ||
694 | |||
695 | while (chan->band != band && idx < n_channels) | ||
696 | chan = &data->channels[++idx]; | ||
697 | |||
698 | sband->channels = &data->channels[idx]; | ||
699 | |||
700 | while (chan->band == band && idx < n_channels) { | ||
701 | chan = &data->channels[++idx]; | ||
702 | n++; | ||
703 | } | ||
704 | |||
705 | sband->n_channels = n; | ||
706 | |||
707 | return n; | ||
708 | } | ||
709 | |||
710 | #define MAX_BIT_RATE_40_MHZ 150 /* Mbps */ | ||
711 | #define MAX_BIT_RATE_20_MHZ 72 /* Mbps */ | ||
712 | |||
713 | static void iwl_init_ht_hw_capab(const struct iwl_cfg *cfg, | ||
714 | struct iwl_eeprom_data *data, | ||
715 | struct ieee80211_sta_ht_cap *ht_info, | ||
716 | enum ieee80211_band band) | ||
717 | { | ||
718 | int max_bit_rate = 0; | ||
719 | u8 rx_chains; | ||
720 | u8 tx_chains; | ||
721 | |||
722 | tx_chains = hweight8(data->valid_tx_ant); | ||
723 | if (cfg->rx_with_siso_diversity) | ||
724 | rx_chains = 1; | ||
725 | else | ||
726 | rx_chains = hweight8(data->valid_rx_ant); | ||
727 | |||
728 | if (!(data->sku & EEPROM_SKU_CAP_11N_ENABLE) || !cfg->ht_params) { | ||
729 | ht_info->ht_supported = false; | ||
730 | return; | ||
731 | } | ||
732 | |||
733 | ht_info->ht_supported = true; | ||
734 | ht_info->cap = 0; | ||
735 | |||
736 | if (iwlwifi_mod_params.amsdu_size_8K) | ||
737 | ht_info->cap |= IEEE80211_HT_CAP_MAX_AMSDU; | ||
738 | |||
739 | ht_info->ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K; | ||
740 | ht_info->ampdu_density = IEEE80211_HT_MPDU_DENSITY_4; | ||
741 | |||
742 | ht_info->mcs.rx_mask[0] = 0xFF; | ||
743 | if (rx_chains >= 2) | ||
744 | ht_info->mcs.rx_mask[1] = 0xFF; | ||
745 | if (rx_chains >= 3) | ||
746 | ht_info->mcs.rx_mask[2] = 0xFF; | ||
747 | |||
748 | if (cfg->ht_params->ht_greenfield_support) | ||
749 | ht_info->cap |= IEEE80211_HT_CAP_GRN_FLD; | ||
750 | ht_info->cap |= IEEE80211_HT_CAP_SGI_20; | ||
751 | |||
752 | max_bit_rate = MAX_BIT_RATE_20_MHZ; | ||
753 | |||
754 | if (cfg->ht_params->ht40_bands & BIT(band)) { | ||
755 | ht_info->cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40; | ||
756 | ht_info->cap |= IEEE80211_HT_CAP_SGI_40; | ||
757 | ht_info->mcs.rx_mask[4] = 0x01; | ||
758 | max_bit_rate = MAX_BIT_RATE_40_MHZ; | ||
759 | } | ||
760 | |||
761 | /* Highest supported Rx data rate */ | ||
762 | max_bit_rate *= rx_chains; | ||
763 | WARN_ON(max_bit_rate & ~IEEE80211_HT_MCS_RX_HIGHEST_MASK); | ||
764 | ht_info->mcs.rx_highest = cpu_to_le16(max_bit_rate); | ||
765 | |||
766 | /* Tx MCS capabilities */ | ||
767 | ht_info->mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED; | ||
768 | if (tx_chains != rx_chains) { | ||
769 | ht_info->mcs.tx_params |= IEEE80211_HT_MCS_TX_RX_DIFF; | ||
770 | ht_info->mcs.tx_params |= ((tx_chains - 1) << | ||
771 | IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT); | ||
772 | } | ||
773 | } | ||
774 | |||
775 | static void iwl_init_sbands(struct device *dev, const struct iwl_cfg *cfg, | ||
776 | struct iwl_eeprom_data *data, | ||
777 | const u8 *eeprom, size_t eeprom_size) | ||
778 | { | ||
779 | int n_channels = iwl_init_channel_map(dev, cfg, data, | ||
780 | eeprom, eeprom_size); | ||
781 | int n_used = 0; | ||
782 | struct ieee80211_supported_band *sband; | ||
783 | |||
784 | sband = &data->bands[IEEE80211_BAND_2GHZ]; | ||
785 | sband->band = IEEE80211_BAND_2GHZ; | ||
786 | sband->bitrates = &iwl_cfg80211_rates[RATES_24_OFFS]; | ||
787 | sband->n_bitrates = N_RATES_24; | ||
788 | n_used += iwl_init_sband_channels(data, sband, n_channels, | ||
789 | IEEE80211_BAND_2GHZ); | ||
790 | iwl_init_ht_hw_capab(cfg, data, &sband->ht_cap, IEEE80211_BAND_2GHZ); | ||
791 | |||
792 | sband = &data->bands[IEEE80211_BAND_5GHZ]; | ||
793 | sband->band = IEEE80211_BAND_5GHZ; | ||
794 | sband->bitrates = &iwl_cfg80211_rates[RATES_52_OFFS]; | ||
795 | sband->n_bitrates = N_RATES_52; | ||
796 | n_used += iwl_init_sband_channels(data, sband, n_channels, | ||
797 | IEEE80211_BAND_5GHZ); | ||
798 | iwl_init_ht_hw_capab(cfg, data, &sband->ht_cap, IEEE80211_BAND_5GHZ); | ||
799 | |||
800 | if (n_channels != n_used) | ||
801 | IWL_ERR_DEV(dev, "EEPROM: used only %d of %d channels\n", | ||
802 | n_used, n_channels); | ||
803 | } | ||
804 | |||
805 | /* EEPROM data functions */ | ||
806 | |||
807 | struct iwl_eeprom_data * | ||
808 | iwl_parse_eeprom_data(struct device *dev, const struct iwl_cfg *cfg, | ||
809 | const u8 *eeprom, size_t eeprom_size) | ||
810 | { | ||
811 | struct iwl_eeprom_data *data; | ||
812 | const void *tmp; | ||
813 | |||
814 | if (WARN_ON(!cfg || !cfg->eeprom_params)) | ||
815 | return NULL; | ||
816 | |||
817 | data = kzalloc(sizeof(*data) + | ||
818 | sizeof(struct ieee80211_channel) * IWL_NUM_CHANNELS, | ||
819 | GFP_KERNEL); | ||
820 | if (!data) | ||
821 | return NULL; | ||
822 | |||
823 | /* get MAC address(es) */ | ||
824 | tmp = iwl_eeprom_query_addr(eeprom, eeprom_size, EEPROM_MAC_ADDRESS); | ||
825 | if (!tmp) | ||
826 | goto err_free; | ||
827 | memcpy(data->hw_addr, tmp, ETH_ALEN); | ||
828 | data->n_hw_addrs = iwl_eeprom_query16(eeprom, eeprom_size, | ||
829 | EEPROM_NUM_MAC_ADDRESS); | ||
830 | |||
831 | if (iwl_eeprom_read_calib(eeprom, eeprom_size, data)) | ||
832 | goto err_free; | ||
833 | |||
834 | tmp = iwl_eeprom_query_addr(eeprom, eeprom_size, EEPROM_XTAL); | ||
835 | if (!tmp) | ||
836 | goto err_free; | ||
837 | memcpy(data->xtal_calib, tmp, sizeof(data->xtal_calib)); | ||
838 | |||
839 | tmp = iwl_eeprom_query_addr(eeprom, eeprom_size, | ||
840 | EEPROM_RAW_TEMPERATURE); | ||
841 | if (!tmp) | ||
842 | goto err_free; | ||
843 | data->raw_temperature = *(__le16 *)tmp; | ||
844 | |||
845 | tmp = iwl_eeprom_query_addr(eeprom, eeprom_size, | ||
846 | EEPROM_KELVIN_TEMPERATURE); | ||
847 | if (!tmp) | ||
848 | goto err_free; | ||
849 | data->kelvin_temperature = *(__le16 *)tmp; | ||
850 | data->kelvin_voltage = *((__le16 *)tmp + 1); | ||
851 | |||
852 | data->radio_cfg = iwl_eeprom_query16(eeprom, eeprom_size, | ||
853 | EEPROM_RADIO_CONFIG); | ||
854 | data->sku = iwl_eeprom_query16(eeprom, eeprom_size, | ||
855 | EEPROM_SKU_CAP); | ||
856 | data->eeprom_version = iwl_eeprom_query16(eeprom, eeprom_size, | ||
857 | EEPROM_VERSION); | ||
858 | |||
859 | data->valid_tx_ant = EEPROM_RF_CFG_TX_ANT_MSK(data->radio_cfg); | ||
860 | data->valid_rx_ant = EEPROM_RF_CFG_RX_ANT_MSK(data->radio_cfg); | ||
861 | |||
862 | /* check overrides (some devices have wrong EEPROM) */ | ||
863 | if (cfg->valid_tx_ant) | ||
864 | data->valid_tx_ant = cfg->valid_tx_ant; | ||
865 | if (cfg->valid_rx_ant) | ||
866 | data->valid_rx_ant = cfg->valid_rx_ant; | ||
867 | |||
868 | if (!data->valid_tx_ant || !data->valid_rx_ant) { | ||
869 | IWL_ERR_DEV(dev, "invalid antennas (0x%x, 0x%x)\n", | ||
870 | data->valid_tx_ant, data->valid_rx_ant); | ||
871 | goto err_free; | ||
872 | } | ||
873 | |||
874 | iwl_init_sbands(dev, cfg, data, eeprom, eeprom_size); | ||
875 | |||
876 | return data; | ||
877 | err_free: | ||
878 | kfree(data); | ||
879 | return NULL; | ||
880 | } | ||
881 | EXPORT_SYMBOL_GPL(iwl_parse_eeprom_data); | ||
882 | |||
883 | /* helper functions */ | ||
884 | int iwl_eeprom_check_version(struct iwl_eeprom_data *data, | ||
885 | struct iwl_trans *trans) | ||
886 | { | ||
887 | if (data->eeprom_version >= trans->cfg->eeprom_ver || | ||
888 | data->calib_version >= trans->cfg->eeprom_calib_ver) { | ||
889 | IWL_INFO(trans, "device EEPROM VER=0x%x, CALIB=0x%x\n", | ||
890 | data->eeprom_version, data->calib_version); | ||
891 | return 0; | ||
892 | } | ||
893 | |||
894 | IWL_ERR(trans, | ||
895 | "Unsupported (too old) EEPROM VER=0x%x < 0x%x CALIB=0x%x < 0x%x\n", | ||
896 | data->eeprom_version, trans->cfg->eeprom_ver, | ||
897 | data->calib_version, trans->cfg->eeprom_calib_ver); | ||
898 | return -EINVAL; | ||
899 | } | ||
900 | EXPORT_SYMBOL_GPL(iwl_eeprom_check_version); | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.h b/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.h new file mode 100644 index 000000000000..9c07c670a1ce --- /dev/null +++ b/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.h | |||
@@ -0,0 +1,138 @@ | |||
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 - 2012 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 - 2012 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 | #ifndef __iwl_eeprom_parse_h__ | ||
63 | #define __iwl_eeprom_parse_h__ | ||
64 | |||
65 | #include <linux/types.h> | ||
66 | #include <linux/if_ether.h> | ||
67 | #include "iwl-trans.h" | ||
68 | |||
69 | /* SKU Capabilities (actual values from EEPROM definition) */ | ||
70 | #define EEPROM_SKU_CAP_BAND_24GHZ (1 << 4) | ||
71 | #define EEPROM_SKU_CAP_BAND_52GHZ (1 << 5) | ||
72 | #define EEPROM_SKU_CAP_11N_ENABLE (1 << 6) | ||
73 | #define EEPROM_SKU_CAP_AMT_ENABLE (1 << 7) | ||
74 | #define EEPROM_SKU_CAP_IPAN_ENABLE (1 << 8) | ||
75 | |||
76 | /* radio config bits (actual values from EEPROM definition) */ | ||
77 | #define EEPROM_RF_CFG_TYPE_MSK(x) (x & 0x3) /* bits 0-1 */ | ||
78 | #define EEPROM_RF_CFG_STEP_MSK(x) ((x >> 2) & 0x3) /* bits 2-3 */ | ||
79 | #define EEPROM_RF_CFG_DASH_MSK(x) ((x >> 4) & 0x3) /* bits 4-5 */ | ||
80 | #define EEPROM_RF_CFG_PNUM_MSK(x) ((x >> 6) & 0x3) /* bits 6-7 */ | ||
81 | #define EEPROM_RF_CFG_TX_ANT_MSK(x) ((x >> 8) & 0xF) /* bits 8-11 */ | ||
82 | #define EEPROM_RF_CFG_RX_ANT_MSK(x) ((x >> 12) & 0xF) /* bits 12-15 */ | ||
83 | |||
84 | struct iwl_eeprom_data { | ||
85 | int n_hw_addrs; | ||
86 | u8 hw_addr[ETH_ALEN]; | ||
87 | |||
88 | u16 radio_config; | ||
89 | |||
90 | u8 calib_version; | ||
91 | __le16 calib_voltage; | ||
92 | |||
93 | __le16 raw_temperature; | ||
94 | __le16 kelvin_temperature; | ||
95 | __le16 kelvin_voltage; | ||
96 | __le16 xtal_calib[2]; | ||
97 | |||
98 | u16 sku; | ||
99 | u16 radio_cfg; | ||
100 | u16 eeprom_version; | ||
101 | s8 max_tx_pwr_half_dbm; | ||
102 | |||
103 | u8 valid_tx_ant, valid_rx_ant; | ||
104 | |||
105 | struct ieee80211_supported_band bands[IEEE80211_NUM_BANDS]; | ||
106 | struct ieee80211_channel channels[]; | ||
107 | }; | ||
108 | |||
109 | /** | ||
110 | * iwl_parse_eeprom_data - parse EEPROM data and return values | ||
111 | * | ||
112 | * @dev: device pointer we're parsing for, for debug only | ||
113 | * @cfg: device configuration for parsing and overrides | ||
114 | * @eeprom: the EEPROM data | ||
115 | * @eeprom_size: length of the EEPROM data | ||
116 | * | ||
117 | * This function parses all EEPROM values we need and then | ||
118 | * returns a (newly allocated) struct containing all the | ||
119 | * relevant values for driver use. The struct must be freed | ||
120 | * later with iwl_free_eeprom_data(). | ||
121 | */ | ||
122 | struct iwl_eeprom_data * | ||
123 | iwl_parse_eeprom_data(struct device *dev, const struct iwl_cfg *cfg, | ||
124 | const u8 *eeprom, size_t eeprom_size); | ||
125 | |||
126 | /** | ||
127 | * iwl_free_eeprom_data - free EEPROM data | ||
128 | * @data: the data to free | ||
129 | */ | ||
130 | static inline void iwl_free_eeprom_data(struct iwl_eeprom_data *data) | ||
131 | { | ||
132 | kfree(data); | ||
133 | } | ||
134 | |||
135 | int iwl_eeprom_check_version(struct iwl_eeprom_data *data, | ||
136 | struct iwl_trans *trans); | ||
137 | |||
138 | #endif /* __iwl_eeprom_parse_h__ */ | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom-read.c b/drivers/net/wireless/iwlwifi/iwl-eeprom-read.c new file mode 100644 index 000000000000..27c7da3c6ed1 --- /dev/null +++ b/drivers/net/wireless/iwlwifi/iwl-eeprom-read.c | |||
@@ -0,0 +1,463 @@ | |||
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 - 2012 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 - 2012 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 | #include <linux/types.h> | ||
63 | #include <linux/slab.h> | ||
64 | #include <linux/export.h> | ||
65 | |||
66 | #include "iwl-debug.h" | ||
67 | #include "iwl-eeprom-read.h" | ||
68 | #include "iwl-io.h" | ||
69 | #include "iwl-prph.h" | ||
70 | #include "iwl-csr.h" | ||
71 | |||
72 | /* | ||
73 | * EEPROM access time values: | ||
74 | * | ||
75 | * Driver initiates EEPROM read by writing byte address << 1 to CSR_EEPROM_REG. | ||
76 | * Driver then polls CSR_EEPROM_REG for CSR_EEPROM_REG_READ_VALID_MSK (0x1). | ||
77 | * When polling, wait 10 uSec between polling loops, up to a maximum 5000 uSec. | ||
78 | * Driver reads 16-bit value from bits 31-16 of CSR_EEPROM_REG. | ||
79 | */ | ||
80 | #define IWL_EEPROM_ACCESS_TIMEOUT 5000 /* uSec */ | ||
81 | |||
82 | #define IWL_EEPROM_SEM_TIMEOUT 10 /* microseconds */ | ||
83 | #define IWL_EEPROM_SEM_RETRY_LIMIT 1000 /* number of attempts (not time) */ | ||
84 | |||
85 | |||
86 | /* | ||
87 | * The device's EEPROM semaphore prevents conflicts between driver and uCode | ||
88 | * when accessing the EEPROM; each access is a series of pulses to/from the | ||
89 | * EEPROM chip, not a single event, so even reads could conflict if they | ||
90 | * weren't arbitrated by the semaphore. | ||
91 | */ | ||
92 | |||
93 | #define EEPROM_SEM_TIMEOUT 10 /* milliseconds */ | ||
94 | #define EEPROM_SEM_RETRY_LIMIT 1000 /* number of attempts (not time) */ | ||
95 | |||
96 | static int iwl_eeprom_acquire_semaphore(struct iwl_trans *trans) | ||
97 | { | ||
98 | u16 count; | ||
99 | int ret; | ||
100 | |||
101 | for (count = 0; count < EEPROM_SEM_RETRY_LIMIT; count++) { | ||
102 | /* Request semaphore */ | ||
103 | iwl_set_bit(trans, CSR_HW_IF_CONFIG_REG, | ||
104 | CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM); | ||
105 | |||
106 | /* See if we got it */ | ||
107 | ret = iwl_poll_bit(trans, CSR_HW_IF_CONFIG_REG, | ||
108 | CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM, | ||
109 | CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM, | ||
110 | EEPROM_SEM_TIMEOUT); | ||
111 | if (ret >= 0) { | ||
112 | IWL_DEBUG_EEPROM(trans->dev, | ||
113 | "Acquired semaphore after %d tries.\n", | ||
114 | count+1); | ||
115 | return ret; | ||
116 | } | ||
117 | } | ||
118 | |||
119 | return ret; | ||
120 | } | ||
121 | |||
122 | static void iwl_eeprom_release_semaphore(struct iwl_trans *trans) | ||
123 | { | ||
124 | iwl_clear_bit(trans, CSR_HW_IF_CONFIG_REG, | ||
125 | CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM); | ||
126 | } | ||
127 | |||
128 | static int iwl_eeprom_verify_signature(struct iwl_trans *trans, bool nvm_is_otp) | ||
129 | { | ||
130 | u32 gp = iwl_read32(trans, CSR_EEPROM_GP) & CSR_EEPROM_GP_VALID_MSK; | ||
131 | |||
132 | IWL_DEBUG_EEPROM(trans->dev, "EEPROM signature=0x%08x\n", gp); | ||
133 | |||
134 | switch (gp) { | ||
135 | case CSR_EEPROM_GP_BAD_SIG_EEP_GOOD_SIG_OTP: | ||
136 | if (!nvm_is_otp) { | ||
137 | IWL_ERR(trans, "EEPROM with bad signature: 0x%08x\n", | ||
138 | gp); | ||
139 | return -ENOENT; | ||
140 | } | ||
141 | return 0; | ||
142 | case CSR_EEPROM_GP_GOOD_SIG_EEP_LESS_THAN_4K: | ||
143 | case CSR_EEPROM_GP_GOOD_SIG_EEP_MORE_THAN_4K: | ||
144 | if (nvm_is_otp) { | ||
145 | IWL_ERR(trans, "OTP with bad signature: 0x%08x\n", gp); | ||
146 | return -ENOENT; | ||
147 | } | ||
148 | return 0; | ||
149 | case CSR_EEPROM_GP_BAD_SIGNATURE_BOTH_EEP_AND_OTP: | ||
150 | default: | ||
151 | IWL_ERR(trans, | ||
152 | "bad EEPROM/OTP signature, type=%s, EEPROM_GP=0x%08x\n", | ||
153 | nvm_is_otp ? "OTP" : "EEPROM", gp); | ||
154 | return -ENOENT; | ||
155 | } | ||
156 | } | ||
157 | |||
158 | /****************************************************************************** | ||
159 | * | ||
160 | * OTP related functions | ||
161 | * | ||
162 | ******************************************************************************/ | ||
163 | |||
164 | static void iwl_set_otp_access_absolute(struct iwl_trans *trans) | ||
165 | { | ||
166 | iwl_read32(trans, CSR_OTP_GP_REG); | ||
167 | |||
168 | iwl_clear_bit(trans, CSR_OTP_GP_REG, | ||
169 | CSR_OTP_GP_REG_OTP_ACCESS_MODE); | ||
170 | } | ||
171 | |||
172 | static int iwl_nvm_is_otp(struct iwl_trans *trans) | ||
173 | { | ||
174 | u32 otpgp; | ||
175 | |||
176 | /* OTP only valid for CP/PP and after */ | ||
177 | switch (trans->hw_rev & CSR_HW_REV_TYPE_MSK) { | ||
178 | case CSR_HW_REV_TYPE_NONE: | ||
179 | IWL_ERR(trans, "Unknown hardware type\n"); | ||
180 | return -EIO; | ||
181 | case CSR_HW_REV_TYPE_5300: | ||
182 | case CSR_HW_REV_TYPE_5350: | ||
183 | case CSR_HW_REV_TYPE_5100: | ||
184 | case CSR_HW_REV_TYPE_5150: | ||
185 | return 0; | ||
186 | default: | ||
187 | otpgp = iwl_read32(trans, CSR_OTP_GP_REG); | ||
188 | if (otpgp & CSR_OTP_GP_REG_DEVICE_SELECT) | ||
189 | return 1; | ||
190 | return 0; | ||
191 | } | ||
192 | } | ||
193 | |||
194 | static int iwl_init_otp_access(struct iwl_trans *trans) | ||
195 | { | ||
196 | int ret; | ||
197 | |||
198 | /* Enable 40MHz radio clock */ | ||
199 | iwl_write32(trans, CSR_GP_CNTRL, | ||
200 | iwl_read32(trans, CSR_GP_CNTRL) | | ||
201 | CSR_GP_CNTRL_REG_FLAG_INIT_DONE); | ||
202 | |||
203 | /* wait for clock to be ready */ | ||
204 | ret = iwl_poll_bit(trans, CSR_GP_CNTRL, | ||
205 | CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, | ||
206 | CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, | ||
207 | 25000); | ||
208 | if (ret < 0) { | ||
209 | IWL_ERR(trans, "Time out access OTP\n"); | ||
210 | } else { | ||
211 | iwl_set_bits_prph(trans, APMG_PS_CTRL_REG, | ||
212 | APMG_PS_CTRL_VAL_RESET_REQ); | ||
213 | udelay(5); | ||
214 | iwl_clear_bits_prph(trans, APMG_PS_CTRL_REG, | ||
215 | APMG_PS_CTRL_VAL_RESET_REQ); | ||
216 | |||
217 | /* | ||
218 | * CSR auto clock gate disable bit - | ||
219 | * this is only applicable for HW with OTP shadow RAM | ||
220 | */ | ||
221 | if (trans->cfg->base_params->shadow_ram_support) | ||
222 | iwl_set_bit(trans, CSR_DBG_LINK_PWR_MGMT_REG, | ||
223 | CSR_RESET_LINK_PWR_MGMT_DISABLED); | ||
224 | } | ||
225 | return ret; | ||
226 | } | ||
227 | |||
228 | static int iwl_read_otp_word(struct iwl_trans *trans, u16 addr, | ||
229 | __le16 *eeprom_data) | ||
230 | { | ||
231 | int ret = 0; | ||
232 | u32 r; | ||
233 | u32 otpgp; | ||
234 | |||
235 | iwl_write32(trans, CSR_EEPROM_REG, | ||
236 | CSR_EEPROM_REG_MSK_ADDR & (addr << 1)); | ||
237 | ret = iwl_poll_bit(trans, CSR_EEPROM_REG, | ||
238 | CSR_EEPROM_REG_READ_VALID_MSK, | ||
239 | CSR_EEPROM_REG_READ_VALID_MSK, | ||
240 | IWL_EEPROM_ACCESS_TIMEOUT); | ||
241 | if (ret < 0) { | ||
242 | IWL_ERR(trans, "Time out reading OTP[%d]\n", addr); | ||
243 | return ret; | ||
244 | } | ||
245 | r = iwl_read32(trans, CSR_EEPROM_REG); | ||
246 | /* check for ECC errors: */ | ||
247 | otpgp = iwl_read32(trans, CSR_OTP_GP_REG); | ||
248 | if (otpgp & CSR_OTP_GP_REG_ECC_UNCORR_STATUS_MSK) { | ||
249 | /* stop in this case */ | ||
250 | /* set the uncorrectable OTP ECC bit for acknowledgement */ | ||
251 | iwl_set_bit(trans, CSR_OTP_GP_REG, | ||
252 | CSR_OTP_GP_REG_ECC_UNCORR_STATUS_MSK); | ||
253 | IWL_ERR(trans, "Uncorrectable OTP ECC error, abort OTP read\n"); | ||
254 | return -EINVAL; | ||
255 | } | ||
256 | if (otpgp & CSR_OTP_GP_REG_ECC_CORR_STATUS_MSK) { | ||
257 | /* continue in this case */ | ||
258 | /* set the correctable OTP ECC bit for acknowledgement */ | ||
259 | iwl_set_bit(trans, CSR_OTP_GP_REG, | ||
260 | CSR_OTP_GP_REG_ECC_CORR_STATUS_MSK); | ||
261 | IWL_ERR(trans, "Correctable OTP ECC error, continue read\n"); | ||
262 | } | ||
263 | *eeprom_data = cpu_to_le16(r >> 16); | ||
264 | return 0; | ||
265 | } | ||
266 | |||
267 | /* | ||
268 | * iwl_is_otp_empty: check for empty OTP | ||
269 | */ | ||
270 | static bool iwl_is_otp_empty(struct iwl_trans *trans) | ||
271 | { | ||
272 | u16 next_link_addr = 0; | ||
273 | __le16 link_value; | ||
274 | bool is_empty = false; | ||
275 | |||
276 | /* locate the beginning of OTP link list */ | ||
277 | if (!iwl_read_otp_word(trans, next_link_addr, &link_value)) { | ||
278 | if (!link_value) { | ||
279 | IWL_ERR(trans, "OTP is empty\n"); | ||
280 | is_empty = true; | ||
281 | } | ||
282 | } else { | ||
283 | IWL_ERR(trans, "Unable to read first block of OTP list.\n"); | ||
284 | is_empty = true; | ||
285 | } | ||
286 | |||
287 | return is_empty; | ||
288 | } | ||
289 | |||
290 | |||
291 | /* | ||
292 | * iwl_find_otp_image: find EEPROM image in OTP | ||
293 | * finding the OTP block that contains the EEPROM image. | ||
294 | * the last valid block on the link list (the block _before_ the last block) | ||
295 | * is the block we should read and used to configure the device. | ||
296 | * If all the available OTP blocks are full, the last block will be the block | ||
297 | * we should read and used to configure the device. | ||
298 | * only perform this operation if shadow RAM is disabled | ||
299 | */ | ||
300 | static int iwl_find_otp_image(struct iwl_trans *trans, | ||
301 | u16 *validblockaddr) | ||
302 | { | ||
303 | u16 next_link_addr = 0, valid_addr; | ||
304 | __le16 link_value = 0; | ||
305 | int usedblocks = 0; | ||
306 | |||
307 | /* set addressing mode to absolute to traverse the link list */ | ||
308 | iwl_set_otp_access_absolute(trans); | ||
309 | |||
310 | /* checking for empty OTP or error */ | ||
311 | if (iwl_is_otp_empty(trans)) | ||
312 | return -EINVAL; | ||
313 | |||
314 | /* | ||
315 | * start traverse link list | ||
316 | * until reach the max number of OTP blocks | ||
317 | * different devices have different number of OTP blocks | ||
318 | */ | ||
319 | do { | ||
320 | /* save current valid block address | ||
321 | * check for more block on the link list | ||
322 | */ | ||
323 | valid_addr = next_link_addr; | ||
324 | next_link_addr = le16_to_cpu(link_value) * sizeof(u16); | ||
325 | IWL_DEBUG_EEPROM(trans->dev, "OTP blocks %d addr 0x%x\n", | ||
326 | usedblocks, next_link_addr); | ||
327 | if (iwl_read_otp_word(trans, next_link_addr, &link_value)) | ||
328 | return -EINVAL; | ||
329 | if (!link_value) { | ||
330 | /* | ||
331 | * reach the end of link list, return success and | ||
332 | * set address point to the starting address | ||
333 | * of the image | ||
334 | */ | ||
335 | *validblockaddr = valid_addr; | ||
336 | /* skip first 2 bytes (link list pointer) */ | ||
337 | *validblockaddr += 2; | ||
338 | return 0; | ||
339 | } | ||
340 | /* more in the link list, continue */ | ||
341 | usedblocks++; | ||
342 | } while (usedblocks <= trans->cfg->base_params->max_ll_items); | ||
343 | |||
344 | /* OTP has no valid blocks */ | ||
345 | IWL_DEBUG_EEPROM(trans->dev, "OTP has no valid blocks\n"); | ||
346 | return -EINVAL; | ||
347 | } | ||
348 | |||
349 | /** | ||
350 | * iwl_read_eeprom - read EEPROM contents | ||
351 | * | ||
352 | * Load the EEPROM contents from adapter and return it | ||
353 | * and its size. | ||
354 | * | ||
355 | * NOTE: This routine uses the non-debug IO access functions. | ||
356 | */ | ||
357 | int iwl_read_eeprom(struct iwl_trans *trans, u8 **eeprom, size_t *eeprom_size) | ||
358 | { | ||
359 | __le16 *e; | ||
360 | u32 gp = iwl_read32(trans, CSR_EEPROM_GP); | ||
361 | int sz; | ||
362 | int ret; | ||
363 | u16 addr; | ||
364 | u16 validblockaddr = 0; | ||
365 | u16 cache_addr = 0; | ||
366 | int nvm_is_otp; | ||
367 | |||
368 | if (!eeprom || !eeprom_size) | ||
369 | return -EINVAL; | ||
370 | |||
371 | nvm_is_otp = iwl_nvm_is_otp(trans); | ||
372 | if (nvm_is_otp < 0) | ||
373 | return nvm_is_otp; | ||
374 | |||
375 | sz = trans->cfg->base_params->eeprom_size; | ||
376 | IWL_DEBUG_EEPROM(trans->dev, "NVM size = %d\n", sz); | ||
377 | |||
378 | e = kmalloc(sz, GFP_KERNEL); | ||
379 | if (!e) | ||
380 | return -ENOMEM; | ||
381 | |||
382 | ret = iwl_eeprom_verify_signature(trans, nvm_is_otp); | ||
383 | if (ret < 0) { | ||
384 | IWL_ERR(trans, "EEPROM not found, EEPROM_GP=0x%08x\n", gp); | ||
385 | goto err_free; | ||
386 | } | ||
387 | |||
388 | /* Make sure driver (instead of uCode) is allowed to read EEPROM */ | ||
389 | ret = iwl_eeprom_acquire_semaphore(trans); | ||
390 | if (ret < 0) { | ||
391 | IWL_ERR(trans, "Failed to acquire EEPROM semaphore.\n"); | ||
392 | goto err_free; | ||
393 | } | ||
394 | |||
395 | if (nvm_is_otp) { | ||
396 | ret = iwl_init_otp_access(trans); | ||
397 | if (ret) { | ||
398 | IWL_ERR(trans, "Failed to initialize OTP access.\n"); | ||
399 | goto err_unlock; | ||
400 | } | ||
401 | |||
402 | iwl_write32(trans, CSR_EEPROM_GP, | ||
403 | iwl_read32(trans, CSR_EEPROM_GP) & | ||
404 | ~CSR_EEPROM_GP_IF_OWNER_MSK); | ||
405 | |||
406 | iwl_set_bit(trans, CSR_OTP_GP_REG, | ||
407 | CSR_OTP_GP_REG_ECC_CORR_STATUS_MSK | | ||
408 | CSR_OTP_GP_REG_ECC_UNCORR_STATUS_MSK); | ||
409 | /* traversing the linked list if no shadow ram supported */ | ||
410 | if (!trans->cfg->base_params->shadow_ram_support) { | ||
411 | ret = iwl_find_otp_image(trans, &validblockaddr); | ||
412 | if (ret) | ||
413 | goto err_unlock; | ||
414 | } | ||
415 | for (addr = validblockaddr; addr < validblockaddr + sz; | ||
416 | addr += sizeof(u16)) { | ||
417 | __le16 eeprom_data; | ||
418 | |||
419 | ret = iwl_read_otp_word(trans, addr, &eeprom_data); | ||
420 | if (ret) | ||
421 | goto err_unlock; | ||
422 | e[cache_addr / 2] = eeprom_data; | ||
423 | cache_addr += sizeof(u16); | ||
424 | } | ||
425 | } else { | ||
426 | /* eeprom is an array of 16bit values */ | ||
427 | for (addr = 0; addr < sz; addr += sizeof(u16)) { | ||
428 | u32 r; | ||
429 | |||
430 | iwl_write32(trans, CSR_EEPROM_REG, | ||
431 | CSR_EEPROM_REG_MSK_ADDR & (addr << 1)); | ||
432 | |||
433 | ret = iwl_poll_bit(trans, CSR_EEPROM_REG, | ||
434 | CSR_EEPROM_REG_READ_VALID_MSK, | ||
435 | CSR_EEPROM_REG_READ_VALID_MSK, | ||
436 | IWL_EEPROM_ACCESS_TIMEOUT); | ||
437 | if (ret < 0) { | ||
438 | IWL_ERR(trans, | ||
439 | "Time out reading EEPROM[%d]\n", addr); | ||
440 | goto err_unlock; | ||
441 | } | ||
442 | r = iwl_read32(trans, CSR_EEPROM_REG); | ||
443 | e[addr / 2] = cpu_to_le16(r >> 16); | ||
444 | } | ||
445 | } | ||
446 | |||
447 | IWL_DEBUG_EEPROM(trans->dev, "NVM Type: %s\n", | ||
448 | nvm_is_otp ? "OTP" : "EEPROM"); | ||
449 | |||
450 | iwl_eeprom_release_semaphore(trans); | ||
451 | |||
452 | *eeprom_size = sz; | ||
453 | *eeprom = (u8 *)e; | ||
454 | return 0; | ||
455 | |||
456 | err_unlock: | ||
457 | iwl_eeprom_release_semaphore(trans); | ||
458 | err_free: | ||
459 | kfree(e); | ||
460 | |||
461 | return ret; | ||
462 | } | ||
463 | EXPORT_SYMBOL_GPL(iwl_read_eeprom); | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom-read.h b/drivers/net/wireless/iwlwifi/iwl-eeprom-read.h new file mode 100644 index 000000000000..1337c9d36fee --- /dev/null +++ b/drivers/net/wireless/iwlwifi/iwl-eeprom-read.h | |||
@@ -0,0 +1,70 @@ | |||
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 - 2012 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 - 2012 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_eeprom_h__ | ||
64 | #define __iwl_eeprom_h__ | ||
65 | |||
66 | #include "iwl-trans.h" | ||
67 | |||
68 | int iwl_read_eeprom(struct iwl_trans *trans, u8 **eeprom, size_t *eeprom_size); | ||
69 | |||
70 | #endif /* __iwl_eeprom_h__ */ | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.c b/drivers/net/wireless/iwlwifi/iwl-eeprom.c deleted file mode 100644 index b8e2b223ac36..000000000000 --- a/drivers/net/wireless/iwlwifi/iwl-eeprom.c +++ /dev/null | |||
@@ -1,1148 +0,0 @@ | |||
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 - 2012 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 - 2012 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 | |||
64 | #include <linux/kernel.h> | ||
65 | #include <linux/module.h> | ||
66 | #include <linux/slab.h> | ||
67 | #include <linux/init.h> | ||
68 | |||
69 | #include <net/mac80211.h> | ||
70 | |||
71 | #include "iwl-dev.h" | ||
72 | #include "iwl-debug.h" | ||
73 | #include "iwl-agn.h" | ||
74 | #include "iwl-eeprom.h" | ||
75 | #include "iwl-io.h" | ||
76 | #include "iwl-prph.h" | ||
77 | |||
78 | /************************** EEPROM BANDS **************************** | ||
79 | * | ||
80 | * The iwl_eeprom_band definitions below provide the mapping from the | ||
81 | * EEPROM contents to the specific channel number supported for each | ||
82 | * band. | ||
83 | * | ||
84 | * For example, iwl_priv->eeprom.band_3_channels[4] from the band_3 | ||
85 | * definition below maps to physical channel 42 in the 5.2GHz spectrum. | ||
86 | * The specific geography and calibration information for that channel | ||
87 | * is contained in the eeprom map itself. | ||
88 | * | ||
89 | * During init, we copy the eeprom information and channel map | ||
90 | * information into priv->channel_info_24/52 and priv->channel_map_24/52 | ||
91 | * | ||
92 | * channel_map_24/52 provides the index in the channel_info array for a | ||
93 | * given channel. We have to have two separate maps as there is channel | ||
94 | * overlap with the 2.4GHz and 5.2GHz spectrum as seen in band_1 and | ||
95 | * band_2 | ||
96 | * | ||
97 | * A value of 0xff stored in the channel_map indicates that the channel | ||
98 | * is not supported by the hardware at all. | ||
99 | * | ||
100 | * A value of 0xfe in the channel_map indicates that the channel is not | ||
101 | * valid for Tx with the current hardware. This means that | ||
102 | * while the system can tune and receive on a given channel, it may not | ||
103 | * be able to associate or transmit any frames on that | ||
104 | * channel. There is no corresponding channel information for that | ||
105 | * entry. | ||
106 | * | ||
107 | *********************************************************************/ | ||
108 | |||
109 | /* 2.4 GHz */ | ||
110 | const u8 iwl_eeprom_band_1[14] = { | ||
111 | 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 | ||
112 | }; | ||
113 | |||
114 | /* 5.2 GHz bands */ | ||
115 | static const u8 iwl_eeprom_band_2[] = { /* 4915-5080MHz */ | ||
116 | 183, 184, 185, 187, 188, 189, 192, 196, 7, 8, 11, 12, 16 | ||
117 | }; | ||
118 | |||
119 | static const u8 iwl_eeprom_band_3[] = { /* 5170-5320MHz */ | ||
120 | 34, 36, 38, 40, 42, 44, 46, 48, 52, 56, 60, 64 | ||
121 | }; | ||
122 | |||
123 | static const u8 iwl_eeprom_band_4[] = { /* 5500-5700MHz */ | ||
124 | 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140 | ||
125 | }; | ||
126 | |||
127 | static const u8 iwl_eeprom_band_5[] = { /* 5725-5825MHz */ | ||
128 | 145, 149, 153, 157, 161, 165 | ||
129 | }; | ||
130 | |||
131 | static const u8 iwl_eeprom_band_6[] = { /* 2.4 ht40 channel */ | ||
132 | 1, 2, 3, 4, 5, 6, 7 | ||
133 | }; | ||
134 | |||
135 | static const u8 iwl_eeprom_band_7[] = { /* 5.2 ht40 channel */ | ||
136 | 36, 44, 52, 60, 100, 108, 116, 124, 132, 149, 157 | ||
137 | }; | ||
138 | |||
139 | /****************************************************************************** | ||
140 | * | ||
141 | * generic NVM functions | ||
142 | * | ||
143 | ******************************************************************************/ | ||
144 | |||
145 | /* | ||
146 | * The device's EEPROM semaphore prevents conflicts between driver and uCode | ||
147 | * when accessing the EEPROM; each access is a series of pulses to/from the | ||
148 | * EEPROM chip, not a single event, so even reads could conflict if they | ||
149 | * weren't arbitrated by the semaphore. | ||
150 | */ | ||
151 | |||
152 | #define EEPROM_SEM_TIMEOUT 10 /* milliseconds */ | ||
153 | #define EEPROM_SEM_RETRY_LIMIT 1000 /* number of attempts (not time) */ | ||
154 | |||
155 | static int iwl_eeprom_acquire_semaphore(struct iwl_trans *trans) | ||
156 | { | ||
157 | u16 count; | ||
158 | int ret; | ||
159 | |||
160 | for (count = 0; count < EEPROM_SEM_RETRY_LIMIT; count++) { | ||
161 | /* Request semaphore */ | ||
162 | iwl_set_bit(trans, CSR_HW_IF_CONFIG_REG, | ||
163 | CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM); | ||
164 | |||
165 | /* See if we got it */ | ||
166 | ret = iwl_poll_bit(trans, CSR_HW_IF_CONFIG_REG, | ||
167 | CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM, | ||
168 | CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM, | ||
169 | EEPROM_SEM_TIMEOUT); | ||
170 | if (ret >= 0) { | ||
171 | IWL_DEBUG_EEPROM(trans, | ||
172 | "Acquired semaphore after %d tries.\n", | ||
173 | count+1); | ||
174 | return ret; | ||
175 | } | ||
176 | } | ||
177 | |||
178 | return ret; | ||
179 | } | ||
180 | |||
181 | static void iwl_eeprom_release_semaphore(struct iwl_trans *trans) | ||
182 | { | ||
183 | iwl_clear_bit(trans, CSR_HW_IF_CONFIG_REG, | ||
184 | CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM); | ||
185 | |||
186 | } | ||
187 | |||
188 | static int iwl_eeprom_verify_signature(struct iwl_priv *priv) | ||
189 | { | ||
190 | u32 gp = iwl_read32(priv->trans, CSR_EEPROM_GP) & | ||
191 | CSR_EEPROM_GP_VALID_MSK; | ||
192 | int ret = 0; | ||
193 | |||
194 | IWL_DEBUG_EEPROM(priv, "EEPROM signature=0x%08x\n", gp); | ||
195 | switch (gp) { | ||
196 | case CSR_EEPROM_GP_BAD_SIG_EEP_GOOD_SIG_OTP: | ||
197 | if (priv->nvm_device_type != NVM_DEVICE_TYPE_OTP) { | ||
198 | IWL_ERR(priv, "EEPROM with bad signature: 0x%08x\n", | ||
199 | gp); | ||
200 | ret = -ENOENT; | ||
201 | } | ||
202 | break; | ||
203 | case CSR_EEPROM_GP_GOOD_SIG_EEP_LESS_THAN_4K: | ||
204 | case CSR_EEPROM_GP_GOOD_SIG_EEP_MORE_THAN_4K: | ||
205 | if (priv->nvm_device_type != NVM_DEVICE_TYPE_EEPROM) { | ||
206 | IWL_ERR(priv, "OTP with bad signature: 0x%08x\n", gp); | ||
207 | ret = -ENOENT; | ||
208 | } | ||
209 | break; | ||
210 | case CSR_EEPROM_GP_BAD_SIGNATURE_BOTH_EEP_AND_OTP: | ||
211 | default: | ||
212 | IWL_ERR(priv, "bad EEPROM/OTP signature, type=%s, " | ||
213 | "EEPROM_GP=0x%08x\n", | ||
214 | (priv->nvm_device_type == NVM_DEVICE_TYPE_OTP) | ||
215 | ? "OTP" : "EEPROM", gp); | ||
216 | ret = -ENOENT; | ||
217 | break; | ||
218 | } | ||
219 | return ret; | ||
220 | } | ||
221 | |||
222 | u16 iwl_eeprom_query16(struct iwl_priv *priv, size_t offset) | ||
223 | { | ||
224 | if (!priv->eeprom) | ||
225 | return 0; | ||
226 | return (u16)priv->eeprom[offset] | ((u16)priv->eeprom[offset + 1] << 8); | ||
227 | } | ||
228 | |||
229 | int iwl_eeprom_check_version(struct iwl_priv *priv) | ||
230 | { | ||
231 | u16 eeprom_ver; | ||
232 | u16 calib_ver; | ||
233 | |||
234 | eeprom_ver = iwl_eeprom_query16(priv, EEPROM_VERSION); | ||
235 | calib_ver = iwl_eeprom_calib_version(priv); | ||
236 | |||
237 | if (eeprom_ver < priv->cfg->eeprom_ver || | ||
238 | calib_ver < priv->cfg->eeprom_calib_ver) | ||
239 | goto err; | ||
240 | |||
241 | IWL_INFO(priv, "device EEPROM VER=0x%x, CALIB=0x%x\n", | ||
242 | eeprom_ver, calib_ver); | ||
243 | |||
244 | return 0; | ||
245 | err: | ||
246 | IWL_ERR(priv, "Unsupported (too old) EEPROM VER=0x%x < 0x%x " | ||
247 | "CALIB=0x%x < 0x%x\n", | ||
248 | eeprom_ver, priv->cfg->eeprom_ver, | ||
249 | calib_ver, priv->cfg->eeprom_calib_ver); | ||
250 | return -EINVAL; | ||
251 | |||
252 | } | ||
253 | |||
254 | int iwl_eeprom_init_hw_params(struct iwl_priv *priv) | ||
255 | { | ||
256 | u16 radio_cfg; | ||
257 | |||
258 | priv->hw_params.sku = iwl_eeprom_query16(priv, EEPROM_SKU_CAP); | ||
259 | if (priv->hw_params.sku & EEPROM_SKU_CAP_11N_ENABLE && | ||
260 | !priv->cfg->ht_params) { | ||
261 | IWL_ERR(priv, "Invalid 11n configuration\n"); | ||
262 | return -EINVAL; | ||
263 | } | ||
264 | |||
265 | if (!priv->hw_params.sku) { | ||
266 | IWL_ERR(priv, "Invalid device sku\n"); | ||
267 | return -EINVAL; | ||
268 | } | ||
269 | |||
270 | IWL_INFO(priv, "Device SKU: 0x%X\n", priv->hw_params.sku); | ||
271 | |||
272 | radio_cfg = iwl_eeprom_query16(priv, EEPROM_RADIO_CONFIG); | ||
273 | |||
274 | priv->hw_params.valid_tx_ant = EEPROM_RF_CFG_TX_ANT_MSK(radio_cfg); | ||
275 | priv->hw_params.valid_rx_ant = EEPROM_RF_CFG_RX_ANT_MSK(radio_cfg); | ||
276 | |||
277 | /* check overrides (some devices have wrong EEPROM) */ | ||
278 | if (priv->cfg->valid_tx_ant) | ||
279 | priv->hw_params.valid_tx_ant = priv->cfg->valid_tx_ant; | ||
280 | if (priv->cfg->valid_rx_ant) | ||
281 | priv->hw_params.valid_rx_ant = priv->cfg->valid_rx_ant; | ||
282 | |||
283 | if (!priv->hw_params.valid_tx_ant || !priv->hw_params.valid_rx_ant) { | ||
284 | IWL_ERR(priv, "Invalid chain (0x%X, 0x%X)\n", | ||
285 | priv->hw_params.valid_tx_ant, | ||
286 | priv->hw_params.valid_rx_ant); | ||
287 | return -EINVAL; | ||
288 | } | ||
289 | |||
290 | IWL_INFO(priv, "Valid Tx ant: 0x%X, Valid Rx ant: 0x%X\n", | ||
291 | priv->hw_params.valid_tx_ant, priv->hw_params.valid_rx_ant); | ||
292 | |||
293 | return 0; | ||
294 | } | ||
295 | |||
296 | u16 iwl_eeprom_calib_version(struct iwl_priv *priv) | ||
297 | { | ||
298 | struct iwl_eeprom_calib_hdr *hdr; | ||
299 | |||
300 | hdr = (struct iwl_eeprom_calib_hdr *)iwl_eeprom_query_addr(priv, | ||
301 | EEPROM_CALIB_ALL); | ||
302 | return hdr->version; | ||
303 | } | ||
304 | |||
305 | static u32 eeprom_indirect_address(struct iwl_priv *priv, u32 address) | ||
306 | { | ||
307 | u16 offset = 0; | ||
308 | |||
309 | if ((address & INDIRECT_ADDRESS) == 0) | ||
310 | return address; | ||
311 | |||
312 | switch (address & INDIRECT_TYPE_MSK) { | ||
313 | case INDIRECT_HOST: | ||
314 | offset = iwl_eeprom_query16(priv, EEPROM_LINK_HOST); | ||
315 | break; | ||
316 | case INDIRECT_GENERAL: | ||
317 | offset = iwl_eeprom_query16(priv, EEPROM_LINK_GENERAL); | ||
318 | break; | ||
319 | case INDIRECT_REGULATORY: | ||
320 | offset = iwl_eeprom_query16(priv, EEPROM_LINK_REGULATORY); | ||
321 | break; | ||
322 | case INDIRECT_TXP_LIMIT: | ||
323 | offset = iwl_eeprom_query16(priv, EEPROM_LINK_TXP_LIMIT); | ||
324 | break; | ||
325 | case INDIRECT_TXP_LIMIT_SIZE: | ||
326 | offset = iwl_eeprom_query16(priv, EEPROM_LINK_TXP_LIMIT_SIZE); | ||
327 | break; | ||
328 | case INDIRECT_CALIBRATION: | ||
329 | offset = iwl_eeprom_query16(priv, EEPROM_LINK_CALIBRATION); | ||
330 | break; | ||
331 | case INDIRECT_PROCESS_ADJST: | ||
332 | offset = iwl_eeprom_query16(priv, EEPROM_LINK_PROCESS_ADJST); | ||
333 | break; | ||
334 | case INDIRECT_OTHERS: | ||
335 | offset = iwl_eeprom_query16(priv, EEPROM_LINK_OTHERS); | ||
336 | break; | ||
337 | default: | ||
338 | IWL_ERR(priv, "illegal indirect type: 0x%X\n", | ||
339 | address & INDIRECT_TYPE_MSK); | ||
340 | break; | ||
341 | } | ||
342 | |||
343 | /* translate the offset from words to byte */ | ||
344 | return (address & ADDRESS_MSK) + (offset << 1); | ||
345 | } | ||
346 | |||
347 | const u8 *iwl_eeprom_query_addr(struct iwl_priv *priv, size_t offset) | ||
348 | { | ||
349 | u32 address = eeprom_indirect_address(priv, offset); | ||
350 | BUG_ON(address >= priv->cfg->base_params->eeprom_size); | ||
351 | return &priv->eeprom[address]; | ||
352 | } | ||
353 | |||
354 | void iwl_eeprom_get_mac(struct iwl_priv *priv, u8 *mac) | ||
355 | { | ||
356 | const u8 *addr = iwl_eeprom_query_addr(priv, | ||
357 | EEPROM_MAC_ADDRESS); | ||
358 | memcpy(mac, addr, ETH_ALEN); | ||
359 | } | ||
360 | |||
361 | /****************************************************************************** | ||
362 | * | ||
363 | * OTP related functions | ||
364 | * | ||
365 | ******************************************************************************/ | ||
366 | |||
367 | static void iwl_set_otp_access(struct iwl_trans *trans, | ||
368 | enum iwl_access_mode mode) | ||
369 | { | ||
370 | iwl_read32(trans, CSR_OTP_GP_REG); | ||
371 | |||
372 | if (mode == IWL_OTP_ACCESS_ABSOLUTE) | ||
373 | iwl_clear_bit(trans, CSR_OTP_GP_REG, | ||
374 | CSR_OTP_GP_REG_OTP_ACCESS_MODE); | ||
375 | else | ||
376 | iwl_set_bit(trans, CSR_OTP_GP_REG, | ||
377 | CSR_OTP_GP_REG_OTP_ACCESS_MODE); | ||
378 | } | ||
379 | |||
380 | static int iwl_get_nvm_type(struct iwl_trans *trans, u32 hw_rev) | ||
381 | { | ||
382 | u32 otpgp; | ||
383 | int nvm_type; | ||
384 | |||
385 | /* OTP only valid for CP/PP and after */ | ||
386 | switch (hw_rev & CSR_HW_REV_TYPE_MSK) { | ||
387 | case CSR_HW_REV_TYPE_NONE: | ||
388 | IWL_ERR(trans, "Unknown hardware type\n"); | ||
389 | return -ENOENT; | ||
390 | case CSR_HW_REV_TYPE_5300: | ||
391 | case CSR_HW_REV_TYPE_5350: | ||
392 | case CSR_HW_REV_TYPE_5100: | ||
393 | case CSR_HW_REV_TYPE_5150: | ||
394 | nvm_type = NVM_DEVICE_TYPE_EEPROM; | ||
395 | break; | ||
396 | default: | ||
397 | otpgp = iwl_read32(trans, CSR_OTP_GP_REG); | ||
398 | if (otpgp & CSR_OTP_GP_REG_DEVICE_SELECT) | ||
399 | nvm_type = NVM_DEVICE_TYPE_OTP; | ||
400 | else | ||
401 | nvm_type = NVM_DEVICE_TYPE_EEPROM; | ||
402 | break; | ||
403 | } | ||
404 | return nvm_type; | ||
405 | } | ||
406 | |||
407 | static int iwl_init_otp_access(struct iwl_trans *trans) | ||
408 | { | ||
409 | int ret; | ||
410 | |||
411 | /* Enable 40MHz radio clock */ | ||
412 | iwl_write32(trans, CSR_GP_CNTRL, | ||
413 | iwl_read32(trans, CSR_GP_CNTRL) | | ||
414 | CSR_GP_CNTRL_REG_FLAG_INIT_DONE); | ||
415 | |||
416 | /* wait for clock to be ready */ | ||
417 | ret = iwl_poll_bit(trans, CSR_GP_CNTRL, | ||
418 | CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, | ||
419 | CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, | ||
420 | 25000); | ||
421 | if (ret < 0) | ||
422 | IWL_ERR(trans, "Time out access OTP\n"); | ||
423 | else { | ||
424 | iwl_set_bits_prph(trans, APMG_PS_CTRL_REG, | ||
425 | APMG_PS_CTRL_VAL_RESET_REQ); | ||
426 | udelay(5); | ||
427 | iwl_clear_bits_prph(trans, APMG_PS_CTRL_REG, | ||
428 | APMG_PS_CTRL_VAL_RESET_REQ); | ||
429 | |||
430 | /* | ||
431 | * CSR auto clock gate disable bit - | ||
432 | * this is only applicable for HW with OTP shadow RAM | ||
433 | */ | ||
434 | if (trans->cfg->base_params->shadow_ram_support) | ||
435 | iwl_set_bit(trans, CSR_DBG_LINK_PWR_MGMT_REG, | ||
436 | CSR_RESET_LINK_PWR_MGMT_DISABLED); | ||
437 | } | ||
438 | return ret; | ||
439 | } | ||
440 | |||
441 | static int iwl_read_otp_word(struct iwl_trans *trans, u16 addr, | ||
442 | __le16 *eeprom_data) | ||
443 | { | ||
444 | int ret = 0; | ||
445 | u32 r; | ||
446 | u32 otpgp; | ||
447 | |||
448 | iwl_write32(trans, CSR_EEPROM_REG, | ||
449 | CSR_EEPROM_REG_MSK_ADDR & (addr << 1)); | ||
450 | ret = iwl_poll_bit(trans, CSR_EEPROM_REG, | ||
451 | CSR_EEPROM_REG_READ_VALID_MSK, | ||
452 | CSR_EEPROM_REG_READ_VALID_MSK, | ||
453 | IWL_EEPROM_ACCESS_TIMEOUT); | ||
454 | if (ret < 0) { | ||
455 | IWL_ERR(trans, "Time out reading OTP[%d]\n", addr); | ||
456 | return ret; | ||
457 | } | ||
458 | r = iwl_read32(trans, CSR_EEPROM_REG); | ||
459 | /* check for ECC errors: */ | ||
460 | otpgp = iwl_read32(trans, CSR_OTP_GP_REG); | ||
461 | if (otpgp & CSR_OTP_GP_REG_ECC_UNCORR_STATUS_MSK) { | ||
462 | /* stop in this case */ | ||
463 | /* set the uncorrectable OTP ECC bit for acknowledgement */ | ||
464 | iwl_set_bit(trans, CSR_OTP_GP_REG, | ||
465 | CSR_OTP_GP_REG_ECC_UNCORR_STATUS_MSK); | ||
466 | IWL_ERR(trans, "Uncorrectable OTP ECC error, abort OTP read\n"); | ||
467 | return -EINVAL; | ||
468 | } | ||
469 | if (otpgp & CSR_OTP_GP_REG_ECC_CORR_STATUS_MSK) { | ||
470 | /* continue in this case */ | ||
471 | /* set the correctable OTP ECC bit for acknowledgement */ | ||
472 | iwl_set_bit(trans, CSR_OTP_GP_REG, | ||
473 | CSR_OTP_GP_REG_ECC_CORR_STATUS_MSK); | ||
474 | IWL_ERR(trans, "Correctable OTP ECC error, continue read\n"); | ||
475 | } | ||
476 | *eeprom_data = cpu_to_le16(r >> 16); | ||
477 | return 0; | ||
478 | } | ||
479 | |||
480 | /* | ||
481 | * iwl_is_otp_empty: check for empty OTP | ||
482 | */ | ||
483 | static bool iwl_is_otp_empty(struct iwl_trans *trans) | ||
484 | { | ||
485 | u16 next_link_addr = 0; | ||
486 | __le16 link_value; | ||
487 | bool is_empty = false; | ||
488 | |||
489 | /* locate the beginning of OTP link list */ | ||
490 | if (!iwl_read_otp_word(trans, next_link_addr, &link_value)) { | ||
491 | if (!link_value) { | ||
492 | IWL_ERR(trans, "OTP is empty\n"); | ||
493 | is_empty = true; | ||
494 | } | ||
495 | } else { | ||
496 | IWL_ERR(trans, "Unable to read first block of OTP list.\n"); | ||
497 | is_empty = true; | ||
498 | } | ||
499 | |||
500 | return is_empty; | ||
501 | } | ||
502 | |||
503 | |||
504 | /* | ||
505 | * iwl_find_otp_image: find EEPROM image in OTP | ||
506 | * finding the OTP block that contains the EEPROM image. | ||
507 | * the last valid block on the link list (the block _before_ the last block) | ||
508 | * is the block we should read and used to configure the device. | ||
509 | * If all the available OTP blocks are full, the last block will be the block | ||
510 | * we should read and used to configure the device. | ||
511 | * only perform this operation if shadow RAM is disabled | ||
512 | */ | ||
513 | static int iwl_find_otp_image(struct iwl_trans *trans, | ||
514 | u16 *validblockaddr) | ||
515 | { | ||
516 | u16 next_link_addr = 0, valid_addr; | ||
517 | __le16 link_value = 0; | ||
518 | int usedblocks = 0; | ||
519 | |||
520 | /* set addressing mode to absolute to traverse the link list */ | ||
521 | iwl_set_otp_access(trans, IWL_OTP_ACCESS_ABSOLUTE); | ||
522 | |||
523 | /* checking for empty OTP or error */ | ||
524 | if (iwl_is_otp_empty(trans)) | ||
525 | return -EINVAL; | ||
526 | |||
527 | /* | ||
528 | * start traverse link list | ||
529 | * until reach the max number of OTP blocks | ||
530 | * different devices have different number of OTP blocks | ||
531 | */ | ||
532 | do { | ||
533 | /* save current valid block address | ||
534 | * check for more block on the link list | ||
535 | */ | ||
536 | valid_addr = next_link_addr; | ||
537 | next_link_addr = le16_to_cpu(link_value) * sizeof(u16); | ||
538 | IWL_DEBUG_EEPROM(trans, "OTP blocks %d addr 0x%x\n", | ||
539 | usedblocks, next_link_addr); | ||
540 | if (iwl_read_otp_word(trans, next_link_addr, &link_value)) | ||
541 | return -EINVAL; | ||
542 | if (!link_value) { | ||
543 | /* | ||
544 | * reach the end of link list, return success and | ||
545 | * set address point to the starting address | ||
546 | * of the image | ||
547 | */ | ||
548 | *validblockaddr = valid_addr; | ||
549 | /* skip first 2 bytes (link list pointer) */ | ||
550 | *validblockaddr += 2; | ||
551 | return 0; | ||
552 | } | ||
553 | /* more in the link list, continue */ | ||
554 | usedblocks++; | ||
555 | } while (usedblocks <= trans->cfg->base_params->max_ll_items); | ||
556 | |||
557 | /* OTP has no valid blocks */ | ||
558 | IWL_DEBUG_EEPROM(trans, "OTP has no valid blocks\n"); | ||
559 | return -EINVAL; | ||
560 | } | ||
561 | |||
562 | /****************************************************************************** | ||
563 | * | ||
564 | * Tx Power related functions | ||
565 | * | ||
566 | ******************************************************************************/ | ||
567 | /** | ||
568 | * iwl_get_max_txpower_avg - get the highest tx power from all chains. | ||
569 | * find the highest tx power from all chains for the channel | ||
570 | */ | ||
571 | static s8 iwl_get_max_txpower_avg(struct iwl_priv *priv, | ||
572 | struct iwl_eeprom_enhanced_txpwr *enhanced_txpower, | ||
573 | int element, s8 *max_txpower_in_half_dbm) | ||
574 | { | ||
575 | s8 max_txpower_avg = 0; /* (dBm) */ | ||
576 | |||
577 | /* Take the highest tx power from any valid chains */ | ||
578 | if ((priv->hw_params.valid_tx_ant & ANT_A) && | ||
579 | (enhanced_txpower[element].chain_a_max > max_txpower_avg)) | ||
580 | max_txpower_avg = enhanced_txpower[element].chain_a_max; | ||
581 | if ((priv->hw_params.valid_tx_ant & ANT_B) && | ||
582 | (enhanced_txpower[element].chain_b_max > max_txpower_avg)) | ||
583 | max_txpower_avg = enhanced_txpower[element].chain_b_max; | ||
584 | if ((priv->hw_params.valid_tx_ant & ANT_C) && | ||
585 | (enhanced_txpower[element].chain_c_max > max_txpower_avg)) | ||
586 | max_txpower_avg = enhanced_txpower[element].chain_c_max; | ||
587 | if (((priv->hw_params.valid_tx_ant == ANT_AB) | | ||
588 | (priv->hw_params.valid_tx_ant == ANT_BC) | | ||
589 | (priv->hw_params.valid_tx_ant == ANT_AC)) && | ||
590 | (enhanced_txpower[element].mimo2_max > max_txpower_avg)) | ||
591 | max_txpower_avg = enhanced_txpower[element].mimo2_max; | ||
592 | if ((priv->hw_params.valid_tx_ant == ANT_ABC) && | ||
593 | (enhanced_txpower[element].mimo3_max > max_txpower_avg)) | ||
594 | max_txpower_avg = enhanced_txpower[element].mimo3_max; | ||
595 | |||
596 | /* | ||
597 | * max. tx power in EEPROM is in 1/2 dBm format | ||
598 | * convert from 1/2 dBm to dBm (round-up convert) | ||
599 | * but we also do not want to loss 1/2 dBm resolution which | ||
600 | * will impact performance | ||
601 | */ | ||
602 | *max_txpower_in_half_dbm = max_txpower_avg; | ||
603 | return (max_txpower_avg & 0x01) + (max_txpower_avg >> 1); | ||
604 | } | ||
605 | |||
606 | static void | ||
607 | iwl_eeprom_enh_txp_read_element(struct iwl_priv *priv, | ||
608 | struct iwl_eeprom_enhanced_txpwr *txp, | ||
609 | s8 max_txpower_avg) | ||
610 | { | ||
611 | int ch_idx; | ||
612 | bool is_ht40 = txp->flags & IWL_EEPROM_ENH_TXP_FL_40MHZ; | ||
613 | enum ieee80211_band band; | ||
614 | |||
615 | band = txp->flags & IWL_EEPROM_ENH_TXP_FL_BAND_52G ? | ||
616 | IEEE80211_BAND_5GHZ : IEEE80211_BAND_2GHZ; | ||
617 | |||
618 | for (ch_idx = 0; ch_idx < priv->channel_count; ch_idx++) { | ||
619 | struct iwl_channel_info *ch_info = &priv->channel_info[ch_idx]; | ||
620 | |||
621 | /* update matching channel or from common data only */ | ||
622 | if (txp->channel != 0 && ch_info->channel != txp->channel) | ||
623 | continue; | ||
624 | |||
625 | /* update matching band only */ | ||
626 | if (band != ch_info->band) | ||
627 | continue; | ||
628 | |||
629 | if (ch_info->max_power_avg < max_txpower_avg && !is_ht40) { | ||
630 | ch_info->max_power_avg = max_txpower_avg; | ||
631 | ch_info->curr_txpow = max_txpower_avg; | ||
632 | ch_info->scan_power = max_txpower_avg; | ||
633 | } | ||
634 | |||
635 | if (is_ht40 && ch_info->ht40_max_power_avg < max_txpower_avg) | ||
636 | ch_info->ht40_max_power_avg = max_txpower_avg; | ||
637 | } | ||
638 | } | ||
639 | |||
640 | #define EEPROM_TXP_OFFS (0x00 | INDIRECT_ADDRESS | INDIRECT_TXP_LIMIT) | ||
641 | #define EEPROM_TXP_ENTRY_LEN sizeof(struct iwl_eeprom_enhanced_txpwr) | ||
642 | #define EEPROM_TXP_SZ_OFFS (0x00 | INDIRECT_ADDRESS | INDIRECT_TXP_LIMIT_SIZE) | ||
643 | |||
644 | #define TXP_CHECK_AND_PRINT(x) ((txp->flags & IWL_EEPROM_ENH_TXP_FL_##x) \ | ||
645 | ? # x " " : "") | ||
646 | |||
647 | static void iwl_eeprom_enhanced_txpower(struct iwl_priv *priv) | ||
648 | { | ||
649 | struct iwl_eeprom_enhanced_txpwr *txp_array, *txp; | ||
650 | int idx, entries; | ||
651 | __le16 *txp_len; | ||
652 | s8 max_txp_avg, max_txp_avg_halfdbm; | ||
653 | |||
654 | BUILD_BUG_ON(sizeof(struct iwl_eeprom_enhanced_txpwr) != 8); | ||
655 | |||
656 | /* the length is in 16-bit words, but we want entries */ | ||
657 | txp_len = (__le16 *) iwl_eeprom_query_addr(priv, EEPROM_TXP_SZ_OFFS); | ||
658 | entries = le16_to_cpup(txp_len) * 2 / EEPROM_TXP_ENTRY_LEN; | ||
659 | |||
660 | txp_array = (void *) iwl_eeprom_query_addr(priv, EEPROM_TXP_OFFS); | ||
661 | |||
662 | for (idx = 0; idx < entries; idx++) { | ||
663 | txp = &txp_array[idx]; | ||
664 | /* skip invalid entries */ | ||
665 | if (!(txp->flags & IWL_EEPROM_ENH_TXP_FL_VALID)) | ||
666 | continue; | ||
667 | |||
668 | IWL_DEBUG_EEPROM(priv, "%s %d:\t %s%s%s%s%s%s%s%s (0x%02x)\n", | ||
669 | (txp->channel && (txp->flags & | ||
670 | IWL_EEPROM_ENH_TXP_FL_COMMON_TYPE)) ? | ||
671 | "Common " : (txp->channel) ? | ||
672 | "Channel" : "Common", | ||
673 | (txp->channel), | ||
674 | TXP_CHECK_AND_PRINT(VALID), | ||
675 | TXP_CHECK_AND_PRINT(BAND_52G), | ||
676 | TXP_CHECK_AND_PRINT(OFDM), | ||
677 | TXP_CHECK_AND_PRINT(40MHZ), | ||
678 | TXP_CHECK_AND_PRINT(HT_AP), | ||
679 | TXP_CHECK_AND_PRINT(RES1), | ||
680 | TXP_CHECK_AND_PRINT(RES2), | ||
681 | TXP_CHECK_AND_PRINT(COMMON_TYPE), | ||
682 | txp->flags); | ||
683 | IWL_DEBUG_EEPROM(priv, "\t\t chain_A: 0x%02x " | ||
684 | "chain_B: 0X%02x chain_C: 0X%02x\n", | ||
685 | txp->chain_a_max, txp->chain_b_max, | ||
686 | txp->chain_c_max); | ||
687 | IWL_DEBUG_EEPROM(priv, "\t\t MIMO2: 0x%02x " | ||
688 | "MIMO3: 0x%02x High 20_on_40: 0x%02x " | ||
689 | "Low 20_on_40: 0x%02x\n", | ||
690 | txp->mimo2_max, txp->mimo3_max, | ||
691 | ((txp->delta_20_in_40 & 0xf0) >> 4), | ||
692 | (txp->delta_20_in_40 & 0x0f)); | ||
693 | |||
694 | max_txp_avg = iwl_get_max_txpower_avg(priv, txp_array, idx, | ||
695 | &max_txp_avg_halfdbm); | ||
696 | |||
697 | /* | ||
698 | * Update the user limit values values to the highest | ||
699 | * power supported by any channel | ||
700 | */ | ||
701 | if (max_txp_avg > priv->tx_power_user_lmt) | ||
702 | priv->tx_power_user_lmt = max_txp_avg; | ||
703 | if (max_txp_avg_halfdbm > priv->tx_power_lmt_in_half_dbm) | ||
704 | priv->tx_power_lmt_in_half_dbm = max_txp_avg_halfdbm; | ||
705 | |||
706 | iwl_eeprom_enh_txp_read_element(priv, txp, max_txp_avg); | ||
707 | } | ||
708 | } | ||
709 | |||
710 | /** | ||
711 | * iwl_eeprom_init - read EEPROM contents | ||
712 | * | ||
713 | * Load the EEPROM contents from adapter into priv->eeprom | ||
714 | * | ||
715 | * NOTE: This routine uses the non-debug IO access functions. | ||
716 | */ | ||
717 | int iwl_eeprom_init(struct iwl_priv *priv, u32 hw_rev) | ||
718 | { | ||
719 | __le16 *e; | ||
720 | u32 gp = iwl_read32(priv->trans, CSR_EEPROM_GP); | ||
721 | int sz; | ||
722 | int ret; | ||
723 | u16 addr; | ||
724 | u16 validblockaddr = 0; | ||
725 | u16 cache_addr = 0; | ||
726 | |||
727 | priv->nvm_device_type = iwl_get_nvm_type(priv->trans, hw_rev); | ||
728 | if (priv->nvm_device_type == -ENOENT) | ||
729 | return -ENOENT; | ||
730 | /* allocate eeprom */ | ||
731 | sz = priv->cfg->base_params->eeprom_size; | ||
732 | IWL_DEBUG_EEPROM(priv, "NVM size = %d\n", sz); | ||
733 | priv->eeprom = kzalloc(sz, GFP_KERNEL); | ||
734 | if (!priv->eeprom) { | ||
735 | ret = -ENOMEM; | ||
736 | goto alloc_err; | ||
737 | } | ||
738 | e = (__le16 *)priv->eeprom; | ||
739 | |||
740 | ret = iwl_eeprom_verify_signature(priv); | ||
741 | if (ret < 0) { | ||
742 | IWL_ERR(priv, "EEPROM not found, EEPROM_GP=0x%08x\n", gp); | ||
743 | ret = -ENOENT; | ||
744 | goto err; | ||
745 | } | ||
746 | |||
747 | /* Make sure driver (instead of uCode) is allowed to read EEPROM */ | ||
748 | ret = iwl_eeprom_acquire_semaphore(priv->trans); | ||
749 | if (ret < 0) { | ||
750 | IWL_ERR(priv, "Failed to acquire EEPROM semaphore.\n"); | ||
751 | ret = -ENOENT; | ||
752 | goto err; | ||
753 | } | ||
754 | |||
755 | if (priv->nvm_device_type == NVM_DEVICE_TYPE_OTP) { | ||
756 | |||
757 | ret = iwl_init_otp_access(priv->trans); | ||
758 | if (ret) { | ||
759 | IWL_ERR(priv, "Failed to initialize OTP access.\n"); | ||
760 | ret = -ENOENT; | ||
761 | goto done; | ||
762 | } | ||
763 | iwl_write32(priv->trans, CSR_EEPROM_GP, | ||
764 | iwl_read32(priv->trans, CSR_EEPROM_GP) & | ||
765 | ~CSR_EEPROM_GP_IF_OWNER_MSK); | ||
766 | |||
767 | iwl_set_bit(priv->trans, CSR_OTP_GP_REG, | ||
768 | CSR_OTP_GP_REG_ECC_CORR_STATUS_MSK | | ||
769 | CSR_OTP_GP_REG_ECC_UNCORR_STATUS_MSK); | ||
770 | /* traversing the linked list if no shadow ram supported */ | ||
771 | if (!priv->cfg->base_params->shadow_ram_support) { | ||
772 | if (iwl_find_otp_image(priv->trans, &validblockaddr)) { | ||
773 | ret = -ENOENT; | ||
774 | goto done; | ||
775 | } | ||
776 | } | ||
777 | for (addr = validblockaddr; addr < validblockaddr + sz; | ||
778 | addr += sizeof(u16)) { | ||
779 | __le16 eeprom_data; | ||
780 | |||
781 | ret = iwl_read_otp_word(priv->trans, addr, | ||
782 | &eeprom_data); | ||
783 | if (ret) | ||
784 | goto done; | ||
785 | e[cache_addr / 2] = eeprom_data; | ||
786 | cache_addr += sizeof(u16); | ||
787 | } | ||
788 | } else { | ||
789 | /* eeprom is an array of 16bit values */ | ||
790 | for (addr = 0; addr < sz; addr += sizeof(u16)) { | ||
791 | u32 r; | ||
792 | |||
793 | iwl_write32(priv->trans, CSR_EEPROM_REG, | ||
794 | CSR_EEPROM_REG_MSK_ADDR & (addr << 1)); | ||
795 | |||
796 | ret = iwl_poll_bit(priv->trans, CSR_EEPROM_REG, | ||
797 | CSR_EEPROM_REG_READ_VALID_MSK, | ||
798 | CSR_EEPROM_REG_READ_VALID_MSK, | ||
799 | IWL_EEPROM_ACCESS_TIMEOUT); | ||
800 | if (ret < 0) { | ||
801 | IWL_ERR(priv, | ||
802 | "Time out reading EEPROM[%d]\n", addr); | ||
803 | goto done; | ||
804 | } | ||
805 | r = iwl_read32(priv->trans, CSR_EEPROM_REG); | ||
806 | e[addr / 2] = cpu_to_le16(r >> 16); | ||
807 | } | ||
808 | } | ||
809 | |||
810 | IWL_DEBUG_EEPROM(priv, "NVM Type: %s, version: 0x%x\n", | ||
811 | (priv->nvm_device_type == NVM_DEVICE_TYPE_OTP) | ||
812 | ? "OTP" : "EEPROM", | ||
813 | iwl_eeprom_query16(priv, EEPROM_VERSION)); | ||
814 | |||
815 | ret = 0; | ||
816 | done: | ||
817 | iwl_eeprom_release_semaphore(priv->trans); | ||
818 | |||
819 | err: | ||
820 | if (ret) | ||
821 | iwl_eeprom_free(priv); | ||
822 | alloc_err: | ||
823 | return ret; | ||
824 | } | ||
825 | |||
826 | void iwl_eeprom_free(struct iwl_priv *priv) | ||
827 | { | ||
828 | kfree(priv->eeprom); | ||
829 | priv->eeprom = NULL; | ||
830 | } | ||
831 | |||
832 | static void iwl_init_band_reference(struct iwl_priv *priv, | ||
833 | int eep_band, int *eeprom_ch_count, | ||
834 | const struct iwl_eeprom_channel **eeprom_ch_info, | ||
835 | const u8 **eeprom_ch_index) | ||
836 | { | ||
837 | u32 offset = priv->lib-> | ||
838 | eeprom_ops.regulatory_bands[eep_band - 1]; | ||
839 | switch (eep_band) { | ||
840 | case 1: /* 2.4GHz band */ | ||
841 | *eeprom_ch_count = ARRAY_SIZE(iwl_eeprom_band_1); | ||
842 | *eeprom_ch_info = (struct iwl_eeprom_channel *) | ||
843 | iwl_eeprom_query_addr(priv, offset); | ||
844 | *eeprom_ch_index = iwl_eeprom_band_1; | ||
845 | break; | ||
846 | case 2: /* 4.9GHz band */ | ||
847 | *eeprom_ch_count = ARRAY_SIZE(iwl_eeprom_band_2); | ||
848 | *eeprom_ch_info = (struct iwl_eeprom_channel *) | ||
849 | iwl_eeprom_query_addr(priv, offset); | ||
850 | *eeprom_ch_index = iwl_eeprom_band_2; | ||
851 | break; | ||
852 | case 3: /* 5.2GHz band */ | ||
853 | *eeprom_ch_count = ARRAY_SIZE(iwl_eeprom_band_3); | ||
854 | *eeprom_ch_info = (struct iwl_eeprom_channel *) | ||
855 | iwl_eeprom_query_addr(priv, offset); | ||
856 | *eeprom_ch_index = iwl_eeprom_band_3; | ||
857 | break; | ||
858 | case 4: /* 5.5GHz band */ | ||
859 | *eeprom_ch_count = ARRAY_SIZE(iwl_eeprom_band_4); | ||
860 | *eeprom_ch_info = (struct iwl_eeprom_channel *) | ||
861 | iwl_eeprom_query_addr(priv, offset); | ||
862 | *eeprom_ch_index = iwl_eeprom_band_4; | ||
863 | break; | ||
864 | case 5: /* 5.7GHz band */ | ||
865 | *eeprom_ch_count = ARRAY_SIZE(iwl_eeprom_band_5); | ||
866 | *eeprom_ch_info = (struct iwl_eeprom_channel *) | ||
867 | iwl_eeprom_query_addr(priv, offset); | ||
868 | *eeprom_ch_index = iwl_eeprom_band_5; | ||
869 | break; | ||
870 | case 6: /* 2.4GHz ht40 channels */ | ||
871 | *eeprom_ch_count = ARRAY_SIZE(iwl_eeprom_band_6); | ||
872 | *eeprom_ch_info = (struct iwl_eeprom_channel *) | ||
873 | iwl_eeprom_query_addr(priv, offset); | ||
874 | *eeprom_ch_index = iwl_eeprom_band_6; | ||
875 | break; | ||
876 | case 7: /* 5 GHz ht40 channels */ | ||
877 | *eeprom_ch_count = ARRAY_SIZE(iwl_eeprom_band_7); | ||
878 | *eeprom_ch_info = (struct iwl_eeprom_channel *) | ||
879 | iwl_eeprom_query_addr(priv, offset); | ||
880 | *eeprom_ch_index = iwl_eeprom_band_7; | ||
881 | break; | ||
882 | default: | ||
883 | BUG(); | ||
884 | return; | ||
885 | } | ||
886 | } | ||
887 | |||
888 | #define CHECK_AND_PRINT(x) ((eeprom_ch->flags & EEPROM_CHANNEL_##x) \ | ||
889 | ? # x " " : "") | ||
890 | /** | ||
891 | * iwl_mod_ht40_chan_info - Copy ht40 channel info into driver's priv. | ||
892 | * | ||
893 | * Does not set up a command, or touch hardware. | ||
894 | */ | ||
895 | static int iwl_mod_ht40_chan_info(struct iwl_priv *priv, | ||
896 | enum ieee80211_band band, u16 channel, | ||
897 | const struct iwl_eeprom_channel *eeprom_ch, | ||
898 | u8 clear_ht40_extension_channel) | ||
899 | { | ||
900 | struct iwl_channel_info *ch_info; | ||
901 | |||
902 | ch_info = (struct iwl_channel_info *) | ||
903 | iwl_get_channel_info(priv, band, channel); | ||
904 | |||
905 | if (!is_channel_valid(ch_info)) | ||
906 | return -1; | ||
907 | |||
908 | IWL_DEBUG_EEPROM(priv, "HT40 Ch. %d [%sGHz] %s%s%s%s%s(0x%02x %ddBm):" | ||
909 | " Ad-Hoc %ssupported\n", | ||
910 | ch_info->channel, | ||
911 | is_channel_a_band(ch_info) ? | ||
912 | "5.2" : "2.4", | ||
913 | CHECK_AND_PRINT(IBSS), | ||
914 | CHECK_AND_PRINT(ACTIVE), | ||
915 | CHECK_AND_PRINT(RADAR), | ||
916 | CHECK_AND_PRINT(WIDE), | ||
917 | CHECK_AND_PRINT(DFS), | ||
918 | eeprom_ch->flags, | ||
919 | eeprom_ch->max_power_avg, | ||
920 | ((eeprom_ch->flags & EEPROM_CHANNEL_IBSS) | ||
921 | && !(eeprom_ch->flags & EEPROM_CHANNEL_RADAR)) ? | ||
922 | "" : "not "); | ||
923 | |||
924 | ch_info->ht40_eeprom = *eeprom_ch; | ||
925 | ch_info->ht40_max_power_avg = eeprom_ch->max_power_avg; | ||
926 | ch_info->ht40_flags = eeprom_ch->flags; | ||
927 | if (eeprom_ch->flags & EEPROM_CHANNEL_VALID) | ||
928 | ch_info->ht40_extension_channel &= ~clear_ht40_extension_channel; | ||
929 | |||
930 | return 0; | ||
931 | } | ||
932 | |||
933 | #define CHECK_AND_PRINT_I(x) ((eeprom_ch_info[ch].flags & EEPROM_CHANNEL_##x) \ | ||
934 | ? # x " " : "") | ||
935 | |||
936 | /** | ||
937 | * iwl_init_channel_map - Set up driver's info for all possible channels | ||
938 | */ | ||
939 | int iwl_init_channel_map(struct iwl_priv *priv) | ||
940 | { | ||
941 | int eeprom_ch_count = 0; | ||
942 | const u8 *eeprom_ch_index = NULL; | ||
943 | const struct iwl_eeprom_channel *eeprom_ch_info = NULL; | ||
944 | int band, ch; | ||
945 | struct iwl_channel_info *ch_info; | ||
946 | |||
947 | if (priv->channel_count) { | ||
948 | IWL_DEBUG_EEPROM(priv, "Channel map already initialized.\n"); | ||
949 | return 0; | ||
950 | } | ||
951 | |||
952 | IWL_DEBUG_EEPROM(priv, "Initializing regulatory info from EEPROM\n"); | ||
953 | |||
954 | priv->channel_count = | ||
955 | ARRAY_SIZE(iwl_eeprom_band_1) + | ||
956 | ARRAY_SIZE(iwl_eeprom_band_2) + | ||
957 | ARRAY_SIZE(iwl_eeprom_band_3) + | ||
958 | ARRAY_SIZE(iwl_eeprom_band_4) + | ||
959 | ARRAY_SIZE(iwl_eeprom_band_5); | ||
960 | |||
961 | IWL_DEBUG_EEPROM(priv, "Parsing data for %d channels.\n", | ||
962 | priv->channel_count); | ||
963 | |||
964 | priv->channel_info = kcalloc(priv->channel_count, | ||
965 | sizeof(struct iwl_channel_info), | ||
966 | GFP_KERNEL); | ||
967 | if (!priv->channel_info) { | ||
968 | IWL_ERR(priv, "Could not allocate channel_info\n"); | ||
969 | priv->channel_count = 0; | ||
970 | return -ENOMEM; | ||
971 | } | ||
972 | |||
973 | ch_info = priv->channel_info; | ||
974 | |||
975 | /* Loop through the 5 EEPROM bands adding them in order to the | ||
976 | * channel map we maintain (that contains additional information than | ||
977 | * what just in the EEPROM) */ | ||
978 | for (band = 1; band <= 5; band++) { | ||
979 | |||
980 | iwl_init_band_reference(priv, band, &eeprom_ch_count, | ||
981 | &eeprom_ch_info, &eeprom_ch_index); | ||
982 | |||
983 | /* Loop through each band adding each of the channels */ | ||
984 | for (ch = 0; ch < eeprom_ch_count; ch++) { | ||
985 | ch_info->channel = eeprom_ch_index[ch]; | ||
986 | ch_info->band = (band == 1) ? IEEE80211_BAND_2GHZ : | ||
987 | IEEE80211_BAND_5GHZ; | ||
988 | |||
989 | /* permanently store EEPROM's channel regulatory flags | ||
990 | * and max power in channel info database. */ | ||
991 | ch_info->eeprom = eeprom_ch_info[ch]; | ||
992 | |||
993 | /* Copy the run-time flags so they are there even on | ||
994 | * invalid channels */ | ||
995 | ch_info->flags = eeprom_ch_info[ch].flags; | ||
996 | /* First write that ht40 is not enabled, and then enable | ||
997 | * one by one */ | ||
998 | ch_info->ht40_extension_channel = | ||
999 | IEEE80211_CHAN_NO_HT40; | ||
1000 | |||
1001 | if (!(is_channel_valid(ch_info))) { | ||
1002 | IWL_DEBUG_EEPROM(priv, | ||
1003 | "Ch. %d Flags %x [%sGHz] - " | ||
1004 | "No traffic\n", | ||
1005 | ch_info->channel, | ||
1006 | ch_info->flags, | ||
1007 | is_channel_a_band(ch_info) ? | ||
1008 | "5.2" : "2.4"); | ||
1009 | ch_info++; | ||
1010 | continue; | ||
1011 | } | ||
1012 | |||
1013 | /* Initialize regulatory-based run-time data */ | ||
1014 | ch_info->max_power_avg = ch_info->curr_txpow = | ||
1015 | eeprom_ch_info[ch].max_power_avg; | ||
1016 | ch_info->scan_power = eeprom_ch_info[ch].max_power_avg; | ||
1017 | ch_info->min_power = 0; | ||
1018 | |||
1019 | IWL_DEBUG_EEPROM(priv, "Ch. %d [%sGHz] " | ||
1020 | "%s%s%s%s%s%s(0x%02x %ddBm):" | ||
1021 | " Ad-Hoc %ssupported\n", | ||
1022 | ch_info->channel, | ||
1023 | is_channel_a_band(ch_info) ? | ||
1024 | "5.2" : "2.4", | ||
1025 | CHECK_AND_PRINT_I(VALID), | ||
1026 | CHECK_AND_PRINT_I(IBSS), | ||
1027 | CHECK_AND_PRINT_I(ACTIVE), | ||
1028 | CHECK_AND_PRINT_I(RADAR), | ||
1029 | CHECK_AND_PRINT_I(WIDE), | ||
1030 | CHECK_AND_PRINT_I(DFS), | ||
1031 | eeprom_ch_info[ch].flags, | ||
1032 | eeprom_ch_info[ch].max_power_avg, | ||
1033 | ((eeprom_ch_info[ch]. | ||
1034 | flags & EEPROM_CHANNEL_IBSS) | ||
1035 | && !(eeprom_ch_info[ch]. | ||
1036 | flags & EEPROM_CHANNEL_RADAR)) | ||
1037 | ? "" : "not "); | ||
1038 | |||
1039 | ch_info++; | ||
1040 | } | ||
1041 | } | ||
1042 | |||
1043 | /* Check if we do have HT40 channels */ | ||
1044 | if (priv->lib->eeprom_ops.regulatory_bands[5] == | ||
1045 | EEPROM_REGULATORY_BAND_NO_HT40 && | ||
1046 | priv->lib->eeprom_ops.regulatory_bands[6] == | ||
1047 | EEPROM_REGULATORY_BAND_NO_HT40) | ||
1048 | return 0; | ||
1049 | |||
1050 | /* Two additional EEPROM bands for 2.4 and 5 GHz HT40 channels */ | ||
1051 | for (band = 6; band <= 7; band++) { | ||
1052 | enum ieee80211_band ieeeband; | ||
1053 | |||
1054 | iwl_init_band_reference(priv, band, &eeprom_ch_count, | ||
1055 | &eeprom_ch_info, &eeprom_ch_index); | ||
1056 | |||
1057 | /* EEPROM band 6 is 2.4, band 7 is 5 GHz */ | ||
1058 | ieeeband = | ||
1059 | (band == 6) ? IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ; | ||
1060 | |||
1061 | /* Loop through each band adding each of the channels */ | ||
1062 | for (ch = 0; ch < eeprom_ch_count; ch++) { | ||
1063 | /* Set up driver's info for lower half */ | ||
1064 | iwl_mod_ht40_chan_info(priv, ieeeband, | ||
1065 | eeprom_ch_index[ch], | ||
1066 | &eeprom_ch_info[ch], | ||
1067 | IEEE80211_CHAN_NO_HT40PLUS); | ||
1068 | |||
1069 | /* Set up driver's info for upper half */ | ||
1070 | iwl_mod_ht40_chan_info(priv, ieeeband, | ||
1071 | eeprom_ch_index[ch] + 4, | ||
1072 | &eeprom_ch_info[ch], | ||
1073 | IEEE80211_CHAN_NO_HT40MINUS); | ||
1074 | } | ||
1075 | } | ||
1076 | |||
1077 | /* for newer device (6000 series and up) | ||
1078 | * EEPROM contain enhanced tx power information | ||
1079 | * driver need to process addition information | ||
1080 | * to determine the max channel tx power limits | ||
1081 | */ | ||
1082 | if (priv->lib->eeprom_ops.enhanced_txpower) | ||
1083 | iwl_eeprom_enhanced_txpower(priv); | ||
1084 | |||
1085 | return 0; | ||
1086 | } | ||
1087 | |||
1088 | /* | ||
1089 | * iwl_free_channel_map - undo allocations in iwl_init_channel_map | ||
1090 | */ | ||
1091 | void iwl_free_channel_map(struct iwl_priv *priv) | ||
1092 | { | ||
1093 | kfree(priv->channel_info); | ||
1094 | priv->channel_count = 0; | ||
1095 | } | ||
1096 | |||
1097 | /** | ||
1098 | * iwl_get_channel_info - Find driver's private channel info | ||
1099 | * | ||
1100 | * Based on band and channel number. | ||
1101 | */ | ||
1102 | const struct iwl_channel_info *iwl_get_channel_info(const struct iwl_priv *priv, | ||
1103 | enum ieee80211_band band, u16 channel) | ||
1104 | { | ||
1105 | int i; | ||
1106 | |||
1107 | switch (band) { | ||
1108 | case IEEE80211_BAND_5GHZ: | ||
1109 | for (i = 14; i < priv->channel_count; i++) { | ||
1110 | if (priv->channel_info[i].channel == channel) | ||
1111 | return &priv->channel_info[i]; | ||
1112 | } | ||
1113 | break; | ||
1114 | case IEEE80211_BAND_2GHZ: | ||
1115 | if (channel >= 1 && channel <= 14) | ||
1116 | return &priv->channel_info[channel - 1]; | ||
1117 | break; | ||
1118 | default: | ||
1119 | BUG(); | ||
1120 | } | ||
1121 | |||
1122 | return NULL; | ||
1123 | } | ||
1124 | |||
1125 | void iwl_rf_config(struct iwl_priv *priv) | ||
1126 | { | ||
1127 | u16 radio_cfg; | ||
1128 | |||
1129 | radio_cfg = iwl_eeprom_query16(priv, EEPROM_RADIO_CONFIG); | ||
1130 | |||
1131 | /* write radio config values to register */ | ||
1132 | if (EEPROM_RF_CFG_TYPE_MSK(radio_cfg) <= EEPROM_RF_CONFIG_TYPE_MAX) { | ||
1133 | iwl_set_bit(priv->trans, CSR_HW_IF_CONFIG_REG, | ||
1134 | EEPROM_RF_CFG_TYPE_MSK(radio_cfg) | | ||
1135 | EEPROM_RF_CFG_STEP_MSK(radio_cfg) | | ||
1136 | EEPROM_RF_CFG_DASH_MSK(radio_cfg)); | ||
1137 | IWL_INFO(priv, "Radio type=0x%x-0x%x-0x%x\n", | ||
1138 | EEPROM_RF_CFG_TYPE_MSK(radio_cfg), | ||
1139 | EEPROM_RF_CFG_STEP_MSK(radio_cfg), | ||
1140 | EEPROM_RF_CFG_DASH_MSK(radio_cfg)); | ||
1141 | } else | ||
1142 | WARN_ON(1); | ||
1143 | |||
1144 | /* set CSR_HW_CONFIG_REG for uCode use */ | ||
1145 | iwl_set_bit(priv->trans, CSR_HW_IF_CONFIG_REG, | ||
1146 | CSR_HW_IF_CONFIG_REG_BIT_RADIO_SI | | ||
1147 | CSR_HW_IF_CONFIG_REG_BIT_MAC_SI); | ||
1148 | } | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.h b/drivers/net/wireless/iwlwifi/iwl-eeprom.h deleted file mode 100644 index 64bfd947caeb..000000000000 --- a/drivers/net/wireless/iwlwifi/iwl-eeprom.h +++ /dev/null | |||
@@ -1,269 +0,0 @@ | |||
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 - 2012 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 - 2012 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_eeprom_h__ | ||
64 | #define __iwl_eeprom_h__ | ||
65 | |||
66 | #include <net/mac80211.h> | ||
67 | |||
68 | struct iwl_priv; | ||
69 | |||
70 | /* | ||
71 | * EEPROM access time values: | ||
72 | * | ||
73 | * Driver initiates EEPROM read by writing byte address << 1 to CSR_EEPROM_REG. | ||
74 | * Driver then polls CSR_EEPROM_REG for CSR_EEPROM_REG_READ_VALID_MSK (0x1). | ||
75 | * When polling, wait 10 uSec between polling loops, up to a maximum 5000 uSec. | ||
76 | * Driver reads 16-bit value from bits 31-16 of CSR_EEPROM_REG. | ||
77 | */ | ||
78 | #define IWL_EEPROM_ACCESS_TIMEOUT 5000 /* uSec */ | ||
79 | |||
80 | #define IWL_EEPROM_SEM_TIMEOUT 10 /* microseconds */ | ||
81 | #define IWL_EEPROM_SEM_RETRY_LIMIT 1000 /* number of attempts (not time) */ | ||
82 | |||
83 | |||
84 | /* | ||
85 | * Regulatory channel usage flags in EEPROM struct iwl4965_eeprom_channel.flags. | ||
86 | * | ||
87 | * IBSS and/or AP operation is allowed *only* on those channels with | ||
88 | * (VALID && IBSS && ACTIVE && !RADAR). This restriction is in place because | ||
89 | * RADAR detection is not supported by the 4965 driver, but is a | ||
90 | * requirement for establishing a new network for legal operation on channels | ||
91 | * requiring RADAR detection or restricting ACTIVE scanning. | ||
92 | * | ||
93 | * NOTE: "WIDE" flag does not indicate anything about "HT40" 40 MHz channels. | ||
94 | * It only indicates that 20 MHz channel use is supported; HT40 channel | ||
95 | * usage is indicated by a separate set of regulatory flags for each | ||
96 | * HT40 channel pair. | ||
97 | * | ||
98 | * NOTE: Using a channel inappropriately will result in a uCode error! | ||
99 | */ | ||
100 | #define IWL_NUM_TX_CALIB_GROUPS 5 | ||
101 | enum { | ||
102 | EEPROM_CHANNEL_VALID = (1 << 0), /* usable for this SKU/geo */ | ||
103 | EEPROM_CHANNEL_IBSS = (1 << 1), /* usable as an IBSS channel */ | ||
104 | /* Bit 2 Reserved */ | ||
105 | EEPROM_CHANNEL_ACTIVE = (1 << 3), /* active scanning allowed */ | ||
106 | EEPROM_CHANNEL_RADAR = (1 << 4), /* radar detection required */ | ||
107 | EEPROM_CHANNEL_WIDE = (1 << 5), /* 20 MHz channel okay */ | ||
108 | /* Bit 6 Reserved (was Narrow Channel) */ | ||
109 | EEPROM_CHANNEL_DFS = (1 << 7), /* dynamic freq selection candidate */ | ||
110 | }; | ||
111 | |||
112 | /* SKU Capabilities */ | ||
113 | #define EEPROM_SKU_CAP_BAND_24GHZ (1 << 4) | ||
114 | #define EEPROM_SKU_CAP_BAND_52GHZ (1 << 5) | ||
115 | #define EEPROM_SKU_CAP_11N_ENABLE (1 << 6) | ||
116 | #define EEPROM_SKU_CAP_AMT_ENABLE (1 << 7) | ||
117 | #define EEPROM_SKU_CAP_IPAN_ENABLE (1 << 8) | ||
118 | |||
119 | /* *regulatory* channel data format in eeprom, one for each channel. | ||
120 | * There are separate entries for HT40 (40 MHz) vs. normal (20 MHz) channels. */ | ||
121 | struct iwl_eeprom_channel { | ||
122 | u8 flags; /* EEPROM_CHANNEL_* flags copied from EEPROM */ | ||
123 | s8 max_power_avg; /* max power (dBm) on this chnl, limit 31 */ | ||
124 | } __packed; | ||
125 | |||
126 | enum iwl_eeprom_enhanced_txpwr_flags { | ||
127 | IWL_EEPROM_ENH_TXP_FL_VALID = BIT(0), | ||
128 | IWL_EEPROM_ENH_TXP_FL_BAND_52G = BIT(1), | ||
129 | IWL_EEPROM_ENH_TXP_FL_OFDM = BIT(2), | ||
130 | IWL_EEPROM_ENH_TXP_FL_40MHZ = BIT(3), | ||
131 | IWL_EEPROM_ENH_TXP_FL_HT_AP = BIT(4), | ||
132 | IWL_EEPROM_ENH_TXP_FL_RES1 = BIT(5), | ||
133 | IWL_EEPROM_ENH_TXP_FL_RES2 = BIT(6), | ||
134 | IWL_EEPROM_ENH_TXP_FL_COMMON_TYPE = BIT(7), | ||
135 | }; | ||
136 | |||
137 | /** | ||
138 | * iwl_eeprom_enhanced_txpwr structure | ||
139 | * This structure presents the enhanced regulatory tx power limit layout | ||
140 | * in eeprom image | ||
141 | * Enhanced regulatory tx power portion of eeprom image can be broken down | ||
142 | * into individual structures; each one is 8 bytes in size and contain the | ||
143 | * following information | ||
144 | * @flags: entry flags | ||
145 | * @channel: channel number | ||
146 | * @chain_a_max_pwr: chain a max power in 1/2 dBm | ||
147 | * @chain_b_max_pwr: chain b max power in 1/2 dBm | ||
148 | * @chain_c_max_pwr: chain c max power in 1/2 dBm | ||
149 | * @delta_20_in_40: 20-in-40 deltas (hi/lo) | ||
150 | * @mimo2_max_pwr: mimo2 max power in 1/2 dBm | ||
151 | * @mimo3_max_pwr: mimo3 max power in 1/2 dBm | ||
152 | * | ||
153 | */ | ||
154 | struct iwl_eeprom_enhanced_txpwr { | ||
155 | u8 flags; | ||
156 | u8 channel; | ||
157 | s8 chain_a_max; | ||
158 | s8 chain_b_max; | ||
159 | s8 chain_c_max; | ||
160 | u8 delta_20_in_40; | ||
161 | s8 mimo2_max; | ||
162 | s8 mimo3_max; | ||
163 | } __packed; | ||
164 | |||
165 | /* calibration */ | ||
166 | struct iwl_eeprom_calib_hdr { | ||
167 | u8 version; | ||
168 | u8 pa_type; | ||
169 | __le16 voltage; | ||
170 | } __packed; | ||
171 | |||
172 | #define EEPROM_CALIB_ALL (INDIRECT_ADDRESS | INDIRECT_CALIBRATION) | ||
173 | #define EEPROM_XTAL ((2*0x128) | EEPROM_CALIB_ALL) | ||
174 | |||
175 | /* temperature */ | ||
176 | #define EEPROM_KELVIN_TEMPERATURE ((2*0x12A) | EEPROM_CALIB_ALL) | ||
177 | #define EEPROM_RAW_TEMPERATURE ((2*0x12B) | EEPROM_CALIB_ALL) | ||
178 | |||
179 | |||
180 | /* agn links */ | ||
181 | #define EEPROM_LINK_HOST (2*0x64) | ||
182 | #define EEPROM_LINK_GENERAL (2*0x65) | ||
183 | #define EEPROM_LINK_REGULATORY (2*0x66) | ||
184 | #define EEPROM_LINK_CALIBRATION (2*0x67) | ||
185 | #define EEPROM_LINK_PROCESS_ADJST (2*0x68) | ||
186 | #define EEPROM_LINK_OTHERS (2*0x69) | ||
187 | #define EEPROM_LINK_TXP_LIMIT (2*0x6a) | ||
188 | #define EEPROM_LINK_TXP_LIMIT_SIZE (2*0x6b) | ||
189 | |||
190 | /* agn regulatory - indirect access */ | ||
191 | #define EEPROM_REG_BAND_1_CHANNELS ((0x08)\ | ||
192 | | INDIRECT_ADDRESS | INDIRECT_REGULATORY) /* 28 bytes */ | ||
193 | #define EEPROM_REG_BAND_2_CHANNELS ((0x26)\ | ||
194 | | INDIRECT_ADDRESS | INDIRECT_REGULATORY) /* 26 bytes */ | ||
195 | #define EEPROM_REG_BAND_3_CHANNELS ((0x42)\ | ||
196 | | INDIRECT_ADDRESS | INDIRECT_REGULATORY) /* 24 bytes */ | ||
197 | #define EEPROM_REG_BAND_4_CHANNELS ((0x5C)\ | ||
198 | | INDIRECT_ADDRESS | INDIRECT_REGULATORY) /* 22 bytes */ | ||
199 | #define EEPROM_REG_BAND_5_CHANNELS ((0x74)\ | ||
200 | | INDIRECT_ADDRESS | INDIRECT_REGULATORY) /* 12 bytes */ | ||
201 | #define EEPROM_REG_BAND_24_HT40_CHANNELS ((0x82)\ | ||
202 | | INDIRECT_ADDRESS | INDIRECT_REGULATORY) /* 14 bytes */ | ||
203 | #define EEPROM_REG_BAND_52_HT40_CHANNELS ((0x92)\ | ||
204 | | INDIRECT_ADDRESS | INDIRECT_REGULATORY) /* 22 bytes */ | ||
205 | |||
206 | /* 6000 regulatory - indirect access */ | ||
207 | #define EEPROM_6000_REG_BAND_24_HT40_CHANNELS ((0x80)\ | ||
208 | | INDIRECT_ADDRESS | INDIRECT_REGULATORY) /* 14 bytes */ | ||
209 | /* 2.4 GHz */ | ||
210 | extern const u8 iwl_eeprom_band_1[14]; | ||
211 | |||
212 | #define ADDRESS_MSK 0x0000FFFF | ||
213 | #define INDIRECT_TYPE_MSK 0x000F0000 | ||
214 | #define INDIRECT_HOST 0x00010000 | ||
215 | #define INDIRECT_GENERAL 0x00020000 | ||
216 | #define INDIRECT_REGULATORY 0x00030000 | ||
217 | #define INDIRECT_CALIBRATION 0x00040000 | ||
218 | #define INDIRECT_PROCESS_ADJST 0x00050000 | ||
219 | #define INDIRECT_OTHERS 0x00060000 | ||
220 | #define INDIRECT_TXP_LIMIT 0x00070000 | ||
221 | #define INDIRECT_TXP_LIMIT_SIZE 0x00080000 | ||
222 | #define INDIRECT_ADDRESS 0x00100000 | ||
223 | |||
224 | /* General */ | ||
225 | #define EEPROM_DEVICE_ID (2*0x08) /* 2 bytes */ | ||
226 | #define EEPROM_SUBSYSTEM_ID (2*0x0A) /* 2 bytes */ | ||
227 | #define EEPROM_MAC_ADDRESS (2*0x15) /* 6 bytes */ | ||
228 | #define EEPROM_BOARD_REVISION (2*0x35) /* 2 bytes */ | ||
229 | #define EEPROM_BOARD_PBA_NUMBER (2*0x3B+1) /* 9 bytes */ | ||
230 | #define EEPROM_VERSION (2*0x44) /* 2 bytes */ | ||
231 | #define EEPROM_SKU_CAP (2*0x45) /* 2 bytes */ | ||
232 | #define EEPROM_OEM_MODE (2*0x46) /* 2 bytes */ | ||
233 | #define EEPROM_RADIO_CONFIG (2*0x48) /* 2 bytes */ | ||
234 | #define EEPROM_NUM_MAC_ADDRESS (2*0x4C) /* 2 bytes */ | ||
235 | |||
236 | /* The following masks are to be applied on EEPROM_RADIO_CONFIG */ | ||
237 | #define EEPROM_RF_CFG_TYPE_MSK(x) (x & 0x3) /* bits 0-1 */ | ||
238 | #define EEPROM_RF_CFG_STEP_MSK(x) ((x >> 2) & 0x3) /* bits 2-3 */ | ||
239 | #define EEPROM_RF_CFG_DASH_MSK(x) ((x >> 4) & 0x3) /* bits 4-5 */ | ||
240 | #define EEPROM_RF_CFG_PNUM_MSK(x) ((x >> 6) & 0x3) /* bits 6-7 */ | ||
241 | #define EEPROM_RF_CFG_TX_ANT_MSK(x) ((x >> 8) & 0xF) /* bits 8-11 */ | ||
242 | #define EEPROM_RF_CFG_RX_ANT_MSK(x) ((x >> 12) & 0xF) /* bits 12-15 */ | ||
243 | |||
244 | #define EEPROM_RF_CONFIG_TYPE_MAX 0x3 | ||
245 | |||
246 | #define EEPROM_REGULATORY_BAND_NO_HT40 (0) | ||
247 | |||
248 | struct iwl_eeprom_ops { | ||
249 | const u32 regulatory_bands[7]; | ||
250 | bool enhanced_txpower; | ||
251 | }; | ||
252 | |||
253 | |||
254 | int iwl_eeprom_init(struct iwl_priv *priv, u32 hw_rev); | ||
255 | void iwl_eeprom_free(struct iwl_priv *priv); | ||
256 | int iwl_eeprom_check_version(struct iwl_priv *priv); | ||
257 | int iwl_eeprom_init_hw_params(struct iwl_priv *priv); | ||
258 | u16 iwl_eeprom_calib_version(struct iwl_priv *priv); | ||
259 | const u8 *iwl_eeprom_query_addr(struct iwl_priv *priv, size_t offset); | ||
260 | u16 iwl_eeprom_query16(struct iwl_priv *priv, size_t offset); | ||
261 | void iwl_eeprom_get_mac(struct iwl_priv *priv, u8 *mac); | ||
262 | int iwl_init_channel_map(struct iwl_priv *priv); | ||
263 | void iwl_free_channel_map(struct iwl_priv *priv); | ||
264 | const struct iwl_channel_info *iwl_get_channel_info( | ||
265 | const struct iwl_priv *priv, | ||
266 | enum ieee80211_band band, u16 channel); | ||
267 | void iwl_rf_config(struct iwl_priv *priv); | ||
268 | |||
269 | #endif /* __iwl_eeprom_h__ */ | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-io.c b/drivers/net/wireless/iwlwifi/iwl-io.c index ee93274214d6..5f2df70b73c1 100644 --- a/drivers/net/wireless/iwlwifi/iwl-io.c +++ b/drivers/net/wireless/iwlwifi/iwl-io.c | |||
@@ -65,6 +65,24 @@ void iwl_clear_bit(struct iwl_trans *trans, u32 reg, u32 mask) | |||
65 | } | 65 | } |
66 | EXPORT_SYMBOL_GPL(iwl_clear_bit); | 66 | EXPORT_SYMBOL_GPL(iwl_clear_bit); |
67 | 67 | ||
68 | void iwl_set_bits_mask(struct iwl_trans *trans, u32 reg, u32 mask, u32 value) | ||
69 | { | ||
70 | unsigned long flags; | ||
71 | u32 v; | ||
72 | |||
73 | #ifdef CONFIG_IWLWIFI_DEBUG | ||
74 | WARN_ON_ONCE(value & ~mask); | ||
75 | #endif | ||
76 | |||
77 | spin_lock_irqsave(&trans->reg_lock, flags); | ||
78 | v = iwl_read32(trans, reg); | ||
79 | v &= ~mask; | ||
80 | v |= value; | ||
81 | iwl_write32(trans, reg, v); | ||
82 | spin_unlock_irqrestore(&trans->reg_lock, flags); | ||
83 | } | ||
84 | EXPORT_SYMBOL_GPL(iwl_set_bits_mask); | ||
85 | |||
68 | int iwl_poll_bit(struct iwl_trans *trans, u32 addr, | 86 | int iwl_poll_bit(struct iwl_trans *trans, u32 addr, |
69 | u32 bits, u32 mask, int timeout) | 87 | u32 bits, u32 mask, int timeout) |
70 | { | 88 | { |
diff --git a/drivers/net/wireless/iwlwifi/iwl-io.h b/drivers/net/wireless/iwlwifi/iwl-io.h index abb3250164ba..4a9a45f771ed 100644 --- a/drivers/net/wireless/iwlwifi/iwl-io.h +++ b/drivers/net/wireless/iwlwifi/iwl-io.h | |||
@@ -54,6 +54,8 @@ static inline u32 iwl_read32(struct iwl_trans *trans, u32 ofs) | |||
54 | void iwl_set_bit(struct iwl_trans *trans, u32 reg, u32 mask); | 54 | void iwl_set_bit(struct iwl_trans *trans, u32 reg, u32 mask); |
55 | void iwl_clear_bit(struct iwl_trans *trans, u32 reg, u32 mask); | 55 | void iwl_clear_bit(struct iwl_trans *trans, u32 reg, u32 mask); |
56 | 56 | ||
57 | void iwl_set_bits_mask(struct iwl_trans *trans, u32 reg, u32 mask, u32 value); | ||
58 | |||
57 | int iwl_poll_bit(struct iwl_trans *trans, u32 addr, | 59 | int iwl_poll_bit(struct iwl_trans *trans, u32 addr, |
58 | u32 bits, u32 mask, int timeout); | 60 | u32 bits, u32 mask, int timeout); |
59 | int iwl_poll_direct_bit(struct iwl_trans *trans, u32 addr, u32 mask, | 61 | int iwl_poll_direct_bit(struct iwl_trans *trans, u32 addr, u32 mask, |
diff --git a/drivers/net/wireless/iwlwifi/iwl-op-mode.h b/drivers/net/wireless/iwlwifi/iwl-op-mode.h index cec133c87ad8..cd9ef114d3a3 100644 --- a/drivers/net/wireless/iwlwifi/iwl-op-mode.h +++ b/drivers/net/wireless/iwlwifi/iwl-op-mode.h | |||
@@ -221,9 +221,4 @@ static inline void iwl_op_mode_wimax_active(struct iwl_op_mode *op_mode) | |||
221 | op_mode->ops->wimax_active(op_mode); | 221 | op_mode->ops->wimax_active(op_mode); |
222 | } | 222 | } |
223 | 223 | ||
224 | /***************************************************** | ||
225 | * Op mode layers implementations | ||
226 | ******************************************************/ | ||
227 | extern const struct iwl_op_mode_ops iwl_dvm_ops; | ||
228 | |||
229 | #endif /* __iwl_op_mode_h__ */ | 224 | #endif /* __iwl_op_mode_h__ */ |
diff --git a/drivers/net/wireless/iwlwifi/iwl-prph.h b/drivers/net/wireless/iwlwifi/iwl-prph.h index 3b1069290fa9..a9f0415916c7 100644 --- a/drivers/net/wireless/iwlwifi/iwl-prph.h +++ b/drivers/net/wireless/iwlwifi/iwl-prph.h | |||
@@ -187,7 +187,7 @@ | |||
187 | #define SCD_QUEUE_STTS_REG_POS_ACTIVE (3) | 187 | #define SCD_QUEUE_STTS_REG_POS_ACTIVE (3) |
188 | #define SCD_QUEUE_STTS_REG_POS_WSL (4) | 188 | #define SCD_QUEUE_STTS_REG_POS_WSL (4) |
189 | #define SCD_QUEUE_STTS_REG_POS_SCD_ACT_EN (19) | 189 | #define SCD_QUEUE_STTS_REG_POS_SCD_ACT_EN (19) |
190 | #define SCD_QUEUE_STTS_REG_MSK (0x00FF0000) | 190 | #define SCD_QUEUE_STTS_REG_MSK (0x017F0000) |
191 | 191 | ||
192 | #define SCD_QUEUE_CTX_REG1_CREDIT_POS (8) | 192 | #define SCD_QUEUE_CTX_REG1_CREDIT_POS (8) |
193 | #define SCD_QUEUE_CTX_REG1_CREDIT_MSK (0x00FFFF00) | 193 | #define SCD_QUEUE_CTX_REG1_CREDIT_MSK (0x00FFFF00) |
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.h b/drivers/net/wireless/iwlwifi/iwl-trans.h index 0aeeb7ce91c7..00efde8e5536 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans.h +++ b/drivers/net/wireless/iwlwifi/iwl-trans.h | |||
@@ -355,10 +355,10 @@ struct iwl_trans; | |||
355 | * Must be atomic | 355 | * Must be atomic |
356 | * @reclaim: free packet until ssn. Returns a list of freed packets. | 356 | * @reclaim: free packet until ssn. Returns a list of freed packets. |
357 | * Must be atomic | 357 | * Must be atomic |
358 | * @tx_agg_setup: setup a tx queue for AMPDU - will be called once the HW is | 358 | * @txq_enable: setup a tx queue for AMPDU - will be called once the HW is |
359 | * ready and a successful ADDBA response has been received. | 359 | * ready and a successful ADDBA response has been received. |
360 | * May sleep | 360 | * May sleep |
361 | * @tx_agg_disable: de-configure a Tx queue to send AMPDUs | 361 | * @txq_disable: de-configure a Tx queue to send AMPDUs |
362 | * Must be atomic | 362 | * Must be atomic |
363 | * @wait_tx_queue_empty: wait until all tx queues are empty | 363 | * @wait_tx_queue_empty: wait until all tx queues are empty |
364 | * May sleep | 364 | * May sleep |
@@ -391,9 +391,9 @@ struct iwl_trans_ops { | |||
391 | void (*reclaim)(struct iwl_trans *trans, int queue, int ssn, | 391 | void (*reclaim)(struct iwl_trans *trans, int queue, int ssn, |
392 | struct sk_buff_head *skbs); | 392 | struct sk_buff_head *skbs); |
393 | 393 | ||
394 | void (*tx_agg_setup)(struct iwl_trans *trans, int queue, int fifo, | 394 | void (*txq_enable)(struct iwl_trans *trans, int queue, int fifo, |
395 | int sta_id, int tid, int frame_limit, u16 ssn); | 395 | int sta_id, int tid, int frame_limit, u16 ssn); |
396 | void (*tx_agg_disable)(struct iwl_trans *trans, int queue); | 396 | void (*txq_disable)(struct iwl_trans *trans, int queue); |
397 | 397 | ||
398 | int (*dbgfs_register)(struct iwl_trans *trans, struct dentry* dir); | 398 | int (*dbgfs_register)(struct iwl_trans *trans, struct dentry* dir); |
399 | int (*wait_tx_queue_empty)(struct iwl_trans *trans); | 399 | int (*wait_tx_queue_empty)(struct iwl_trans *trans); |
@@ -433,6 +433,11 @@ enum iwl_trans_state { | |||
433 | * @hw_id_str: a string with info about HW ID. Set during transport allocation. | 433 | * @hw_id_str: a string with info about HW ID. Set during transport allocation. |
434 | * @pm_support: set to true in start_hw if link pm is supported | 434 | * @pm_support: set to true in start_hw if link pm is supported |
435 | * @wait_command_queue: the wait_queue for SYNC host commands | 435 | * @wait_command_queue: the wait_queue for SYNC host commands |
436 | * @dev_cmd_pool: pool for Tx cmd allocation - for internal use only. | ||
437 | * The user should use iwl_trans_{alloc,free}_tx_cmd. | ||
438 | * @dev_cmd_headroom: room needed for the transport's private use before the | ||
439 | * device_cmd for Tx - for internal use only | ||
440 | * The user should use iwl_trans_{alloc,free}_tx_cmd. | ||
436 | */ | 441 | */ |
437 | struct iwl_trans { | 442 | struct iwl_trans { |
438 | const struct iwl_trans_ops *ops; | 443 | const struct iwl_trans_ops *ops; |
@@ -450,6 +455,10 @@ struct iwl_trans { | |||
450 | 455 | ||
451 | wait_queue_head_t wait_command_queue; | 456 | wait_queue_head_t wait_command_queue; |
452 | 457 | ||
458 | /* The following fields are internal only */ | ||
459 | struct kmem_cache *dev_cmd_pool; | ||
460 | size_t dev_cmd_headroom; | ||
461 | |||
453 | /* pointer to trans specific struct */ | 462 | /* pointer to trans specific struct */ |
454 | /*Ensure that this pointer will always be aligned to sizeof pointer */ | 463 | /*Ensure that this pointer will always be aligned to sizeof pointer */ |
455 | char trans_specific[0] __aligned(sizeof(void *)); | 464 | char trans_specific[0] __aligned(sizeof(void *)); |
@@ -525,6 +534,26 @@ static inline int iwl_trans_send_cmd(struct iwl_trans *trans, | |||
525 | return trans->ops->send_cmd(trans, cmd); | 534 | return trans->ops->send_cmd(trans, cmd); |
526 | } | 535 | } |
527 | 536 | ||
537 | static inline struct iwl_device_cmd * | ||
538 | iwl_trans_alloc_tx_cmd(struct iwl_trans *trans) | ||
539 | { | ||
540 | u8 *dev_cmd_ptr = kmem_cache_alloc(trans->dev_cmd_pool, GFP_ATOMIC); | ||
541 | |||
542 | if (unlikely(dev_cmd_ptr == NULL)) | ||
543 | return NULL; | ||
544 | |||
545 | return (struct iwl_device_cmd *) | ||
546 | (dev_cmd_ptr + trans->dev_cmd_headroom); | ||
547 | } | ||
548 | |||
549 | static inline void iwl_trans_free_tx_cmd(struct iwl_trans *trans, | ||
550 | struct iwl_device_cmd *dev_cmd) | ||
551 | { | ||
552 | u8 *dev_cmd_ptr = (u8 *)dev_cmd - trans->dev_cmd_headroom; | ||
553 | |||
554 | kmem_cache_free(trans->dev_cmd_pool, dev_cmd_ptr); | ||
555 | } | ||
556 | |||
528 | static inline int iwl_trans_tx(struct iwl_trans *trans, struct sk_buff *skb, | 557 | static inline int iwl_trans_tx(struct iwl_trans *trans, struct sk_buff *skb, |
529 | struct iwl_device_cmd *dev_cmd, int queue) | 558 | struct iwl_device_cmd *dev_cmd, int queue) |
530 | { | 559 | { |
@@ -543,24 +572,24 @@ static inline void iwl_trans_reclaim(struct iwl_trans *trans, int queue, | |||
543 | trans->ops->reclaim(trans, queue, ssn, skbs); | 572 | trans->ops->reclaim(trans, queue, ssn, skbs); |
544 | } | 573 | } |
545 | 574 | ||
546 | static inline void iwl_trans_tx_agg_disable(struct iwl_trans *trans, int queue) | 575 | static inline void iwl_trans_txq_disable(struct iwl_trans *trans, int queue) |
547 | { | 576 | { |
548 | WARN_ONCE(trans->state != IWL_TRANS_FW_ALIVE, | 577 | WARN_ONCE(trans->state != IWL_TRANS_FW_ALIVE, |
549 | "%s bad state = %d", __func__, trans->state); | 578 | "%s bad state = %d", __func__, trans->state); |
550 | 579 | ||
551 | trans->ops->tx_agg_disable(trans, queue); | 580 | trans->ops->txq_disable(trans, queue); |
552 | } | 581 | } |
553 | 582 | ||
554 | static inline void iwl_trans_tx_agg_setup(struct iwl_trans *trans, int queue, | 583 | static inline void iwl_trans_txq_enable(struct iwl_trans *trans, int queue, |
555 | int fifo, int sta_id, int tid, | 584 | int fifo, int sta_id, int tid, |
556 | int frame_limit, u16 ssn) | 585 | int frame_limit, u16 ssn) |
557 | { | 586 | { |
558 | might_sleep(); | 587 | might_sleep(); |
559 | 588 | ||
560 | WARN_ONCE(trans->state != IWL_TRANS_FW_ALIVE, | 589 | WARN_ONCE(trans->state != IWL_TRANS_FW_ALIVE, |
561 | "%s bad state = %d", __func__, trans->state); | 590 | "%s bad state = %d", __func__, trans->state); |
562 | 591 | ||
563 | trans->ops->tx_agg_setup(trans, queue, fifo, sta_id, tid, | 592 | trans->ops->txq_enable(trans, queue, fifo, sta_id, tid, |
564 | frame_limit, ssn); | 593 | frame_limit, ssn); |
565 | } | 594 | } |
566 | 595 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/pcie/1000.c index 2629a6602dfa..81b83f484f08 100644 --- a/drivers/net/wireless/iwlwifi/iwl-1000.c +++ b/drivers/net/wireless/iwlwifi/pcie/1000.c | |||
@@ -27,9 +27,9 @@ | |||
27 | #include <linux/module.h> | 27 | #include <linux/module.h> |
28 | #include <linux/stringify.h> | 28 | #include <linux/stringify.h> |
29 | #include "iwl-config.h" | 29 | #include "iwl-config.h" |
30 | #include "iwl-cfg.h" | ||
31 | #include "iwl-csr.h" | 30 | #include "iwl-csr.h" |
32 | #include "iwl-agn-hw.h" | 31 | #include "iwl-agn-hw.h" |
32 | #include "cfg.h" | ||
33 | 33 | ||
34 | /* Highest firmware API version supported */ | 34 | /* Highest firmware API version supported */ |
35 | #define IWL1000_UCODE_API_MAX 5 | 35 | #define IWL1000_UCODE_API_MAX 5 |
@@ -64,13 +64,26 @@ static const struct iwl_base_params iwl1000_base_params = { | |||
64 | .support_ct_kill_exit = true, | 64 | .support_ct_kill_exit = true, |
65 | .plcp_delta_threshold = IWL_MAX_PLCP_ERR_EXT_LONG_THRESHOLD_DEF, | 65 | .plcp_delta_threshold = IWL_MAX_PLCP_ERR_EXT_LONG_THRESHOLD_DEF, |
66 | .chain_noise_scale = 1000, | 66 | .chain_noise_scale = 1000, |
67 | .wd_timeout = IWL_WATCHHDOG_DISABLED, | 67 | .wd_timeout = IWL_WATCHDOG_DISABLED, |
68 | .max_event_log_size = 128, | 68 | .max_event_log_size = 128, |
69 | }; | 69 | }; |
70 | 70 | ||
71 | static const struct iwl_ht_params iwl1000_ht_params = { | 71 | static const struct iwl_ht_params iwl1000_ht_params = { |
72 | .ht_greenfield_support = true, | 72 | .ht_greenfield_support = true, |
73 | .use_rts_for_aggregation = true, /* use rts/cts protection */ | 73 | .use_rts_for_aggregation = true, /* use rts/cts protection */ |
74 | .ht40_bands = BIT(IEEE80211_BAND_2GHZ), | ||
75 | }; | ||
76 | |||
77 | static const struct iwl_eeprom_params iwl1000_eeprom_params = { | ||
78 | .regulatory_bands = { | ||
79 | EEPROM_REG_BAND_1_CHANNELS, | ||
80 | EEPROM_REG_BAND_2_CHANNELS, | ||
81 | EEPROM_REG_BAND_3_CHANNELS, | ||
82 | EEPROM_REG_BAND_4_CHANNELS, | ||
83 | EEPROM_REG_BAND_5_CHANNELS, | ||
84 | EEPROM_REG_BAND_24_HT40_CHANNELS, | ||
85 | EEPROM_REGULATORY_BAND_NO_HT40, | ||
86 | } | ||
74 | }; | 87 | }; |
75 | 88 | ||
76 | #define IWL_DEVICE_1000 \ | 89 | #define IWL_DEVICE_1000 \ |
@@ -84,6 +97,7 @@ static const struct iwl_ht_params iwl1000_ht_params = { | |||
84 | .eeprom_ver = EEPROM_1000_EEPROM_VERSION, \ | 97 | .eeprom_ver = EEPROM_1000_EEPROM_VERSION, \ |
85 | .eeprom_calib_ver = EEPROM_1000_TX_POWER_VERSION, \ | 98 | .eeprom_calib_ver = EEPROM_1000_TX_POWER_VERSION, \ |
86 | .base_params = &iwl1000_base_params, \ | 99 | .base_params = &iwl1000_base_params, \ |
100 | .eeprom_params = &iwl1000_eeprom_params, \ | ||
87 | .led_mode = IWL_LED_BLINK | 101 | .led_mode = IWL_LED_BLINK |
88 | 102 | ||
89 | const struct iwl_cfg iwl1000_bgn_cfg = { | 103 | const struct iwl_cfg iwl1000_bgn_cfg = { |
@@ -108,6 +122,7 @@ const struct iwl_cfg iwl1000_bg_cfg = { | |||
108 | .eeprom_ver = EEPROM_1000_EEPROM_VERSION, \ | 122 | .eeprom_ver = EEPROM_1000_EEPROM_VERSION, \ |
109 | .eeprom_calib_ver = EEPROM_1000_TX_POWER_VERSION, \ | 123 | .eeprom_calib_ver = EEPROM_1000_TX_POWER_VERSION, \ |
110 | .base_params = &iwl1000_base_params, \ | 124 | .base_params = &iwl1000_base_params, \ |
125 | .eeprom_params = &iwl1000_eeprom_params, \ | ||
111 | .led_mode = IWL_LED_RF_STATE, \ | 126 | .led_mode = IWL_LED_RF_STATE, \ |
112 | .rx_with_siso_diversity = true | 127 | .rx_with_siso_diversity = true |
113 | 128 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-2000.c b/drivers/net/wireless/iwlwifi/pcie/2000.c index 8133105ac645..fd4e78f56fa6 100644 --- a/drivers/net/wireless/iwlwifi/iwl-2000.c +++ b/drivers/net/wireless/iwlwifi/pcie/2000.c | |||
@@ -27,9 +27,9 @@ | |||
27 | #include <linux/module.h> | 27 | #include <linux/module.h> |
28 | #include <linux/stringify.h> | 28 | #include <linux/stringify.h> |
29 | #include "iwl-config.h" | 29 | #include "iwl-config.h" |
30 | #include "iwl-cfg.h" | ||
31 | #include "iwl-agn-hw.h" | 30 | #include "iwl-agn-hw.h" |
32 | #include "iwl-commands.h" /* needed for BT for now */ | 31 | #include "cfg.h" |
32 | #include "dvm/commands.h" /* needed for BT for now */ | ||
33 | 33 | ||
34 | /* Highest firmware API version supported */ | 34 | /* Highest firmware API version supported */ |
35 | #define IWL2030_UCODE_API_MAX 6 | 35 | #define IWL2030_UCODE_API_MAX 6 |
@@ -104,6 +104,7 @@ static const struct iwl_base_params iwl2030_base_params = { | |||
104 | static const struct iwl_ht_params iwl2000_ht_params = { | 104 | static const struct iwl_ht_params iwl2000_ht_params = { |
105 | .ht_greenfield_support = true, | 105 | .ht_greenfield_support = true, |
106 | .use_rts_for_aggregation = true, /* use rts/cts protection */ | 106 | .use_rts_for_aggregation = true, /* use rts/cts protection */ |
107 | .ht40_bands = BIT(IEEE80211_BAND_2GHZ), | ||
107 | }; | 108 | }; |
108 | 109 | ||
109 | static const struct iwl_bt_params iwl2030_bt_params = { | 110 | static const struct iwl_bt_params iwl2030_bt_params = { |
@@ -116,6 +117,19 @@ static const struct iwl_bt_params iwl2030_bt_params = { | |||
116 | .bt_session_2 = true, | 117 | .bt_session_2 = true, |
117 | }; | 118 | }; |
118 | 119 | ||
120 | static const struct iwl_eeprom_params iwl20x0_eeprom_params = { | ||
121 | .regulatory_bands = { | ||
122 | EEPROM_REG_BAND_1_CHANNELS, | ||
123 | EEPROM_REG_BAND_2_CHANNELS, | ||
124 | EEPROM_REG_BAND_3_CHANNELS, | ||
125 | EEPROM_REG_BAND_4_CHANNELS, | ||
126 | EEPROM_REG_BAND_5_CHANNELS, | ||
127 | EEPROM_6000_REG_BAND_24_HT40_CHANNELS, | ||
128 | EEPROM_REGULATORY_BAND_NO_HT40, | ||
129 | }, | ||
130 | .enhanced_txpower = true, | ||
131 | }; | ||
132 | |||
119 | #define IWL_DEVICE_2000 \ | 133 | #define IWL_DEVICE_2000 \ |
120 | .fw_name_pre = IWL2000_FW_PRE, \ | 134 | .fw_name_pre = IWL2000_FW_PRE, \ |
121 | .ucode_api_max = IWL2000_UCODE_API_MAX, \ | 135 | .ucode_api_max = IWL2000_UCODE_API_MAX, \ |
@@ -127,6 +141,7 @@ static const struct iwl_bt_params iwl2030_bt_params = { | |||
127 | .eeprom_ver = EEPROM_2000_EEPROM_VERSION, \ | 141 | .eeprom_ver = EEPROM_2000_EEPROM_VERSION, \ |
128 | .eeprom_calib_ver = EEPROM_2000_TX_POWER_VERSION, \ | 142 | .eeprom_calib_ver = EEPROM_2000_TX_POWER_VERSION, \ |
129 | .base_params = &iwl2000_base_params, \ | 143 | .base_params = &iwl2000_base_params, \ |
144 | .eeprom_params = &iwl20x0_eeprom_params, \ | ||
130 | .need_temp_offset_calib = true, \ | 145 | .need_temp_offset_calib = true, \ |
131 | .temp_offset_v2 = true, \ | 146 | .temp_offset_v2 = true, \ |
132 | .led_mode = IWL_LED_RF_STATE | 147 | .led_mode = IWL_LED_RF_STATE |
@@ -155,6 +170,7 @@ const struct iwl_cfg iwl2000_2bgn_d_cfg = { | |||
155 | .eeprom_calib_ver = EEPROM_2000_TX_POWER_VERSION, \ | 170 | .eeprom_calib_ver = EEPROM_2000_TX_POWER_VERSION, \ |
156 | .base_params = &iwl2030_base_params, \ | 171 | .base_params = &iwl2030_base_params, \ |
157 | .bt_params = &iwl2030_bt_params, \ | 172 | .bt_params = &iwl2030_bt_params, \ |
173 | .eeprom_params = &iwl20x0_eeprom_params, \ | ||
158 | .need_temp_offset_calib = true, \ | 174 | .need_temp_offset_calib = true, \ |
159 | .temp_offset_v2 = true, \ | 175 | .temp_offset_v2 = true, \ |
160 | .led_mode = IWL_LED_RF_STATE, \ | 176 | .led_mode = IWL_LED_RF_STATE, \ |
@@ -177,6 +193,7 @@ const struct iwl_cfg iwl2030_2bgn_cfg = { | |||
177 | .eeprom_ver = EEPROM_2000_EEPROM_VERSION, \ | 193 | .eeprom_ver = EEPROM_2000_EEPROM_VERSION, \ |
178 | .eeprom_calib_ver = EEPROM_2000_TX_POWER_VERSION, \ | 194 | .eeprom_calib_ver = EEPROM_2000_TX_POWER_VERSION, \ |
179 | .base_params = &iwl2000_base_params, \ | 195 | .base_params = &iwl2000_base_params, \ |
196 | .eeprom_params = &iwl20x0_eeprom_params, \ | ||
180 | .need_temp_offset_calib = true, \ | 197 | .need_temp_offset_calib = true, \ |
181 | .temp_offset_v2 = true, \ | 198 | .temp_offset_v2 = true, \ |
182 | .led_mode = IWL_LED_RF_STATE, \ | 199 | .led_mode = IWL_LED_RF_STATE, \ |
@@ -207,6 +224,7 @@ const struct iwl_cfg iwl105_bgn_d_cfg = { | |||
207 | .eeprom_calib_ver = EEPROM_2000_TX_POWER_VERSION, \ | 224 | .eeprom_calib_ver = EEPROM_2000_TX_POWER_VERSION, \ |
208 | .base_params = &iwl2030_base_params, \ | 225 | .base_params = &iwl2030_base_params, \ |
209 | .bt_params = &iwl2030_bt_params, \ | 226 | .bt_params = &iwl2030_bt_params, \ |
227 | .eeprom_params = &iwl20x0_eeprom_params, \ | ||
210 | .need_temp_offset_calib = true, \ | 228 | .need_temp_offset_calib = true, \ |
211 | .temp_offset_v2 = true, \ | 229 | .temp_offset_v2 = true, \ |
212 | .led_mode = IWL_LED_RF_STATE, \ | 230 | .led_mode = IWL_LED_RF_STATE, \ |
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/pcie/5000.c index 8e26bc825f23..d1665fa6d15a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/drivers/net/wireless/iwlwifi/pcie/5000.c | |||
@@ -27,9 +27,9 @@ | |||
27 | #include <linux/module.h> | 27 | #include <linux/module.h> |
28 | #include <linux/stringify.h> | 28 | #include <linux/stringify.h> |
29 | #include "iwl-config.h" | 29 | #include "iwl-config.h" |
30 | #include "iwl-cfg.h" | ||
31 | #include "iwl-agn-hw.h" | 30 | #include "iwl-agn-hw.h" |
32 | #include "iwl-csr.h" | 31 | #include "iwl-csr.h" |
32 | #include "cfg.h" | ||
33 | 33 | ||
34 | /* Highest firmware API version supported */ | 34 | /* Highest firmware API version supported */ |
35 | #define IWL5000_UCODE_API_MAX 5 | 35 | #define IWL5000_UCODE_API_MAX 5 |
@@ -62,13 +62,26 @@ static const struct iwl_base_params iwl5000_base_params = { | |||
62 | .led_compensation = 51, | 62 | .led_compensation = 51, |
63 | .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF, | 63 | .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF, |
64 | .chain_noise_scale = 1000, | 64 | .chain_noise_scale = 1000, |
65 | .wd_timeout = IWL_WATCHHDOG_DISABLED, | 65 | .wd_timeout = IWL_WATCHDOG_DISABLED, |
66 | .max_event_log_size = 512, | 66 | .max_event_log_size = 512, |
67 | .no_idle_support = true, | 67 | .no_idle_support = true, |
68 | }; | 68 | }; |
69 | 69 | ||
70 | static const struct iwl_ht_params iwl5000_ht_params = { | 70 | static const struct iwl_ht_params iwl5000_ht_params = { |
71 | .ht_greenfield_support = true, | 71 | .ht_greenfield_support = true, |
72 | .ht40_bands = BIT(IEEE80211_BAND_2GHZ) | BIT(IEEE80211_BAND_5GHZ), | ||
73 | }; | ||
74 | |||
75 | static const struct iwl_eeprom_params iwl5000_eeprom_params = { | ||
76 | .regulatory_bands = { | ||
77 | EEPROM_REG_BAND_1_CHANNELS, | ||
78 | EEPROM_REG_BAND_2_CHANNELS, | ||
79 | EEPROM_REG_BAND_3_CHANNELS, | ||
80 | EEPROM_REG_BAND_4_CHANNELS, | ||
81 | EEPROM_REG_BAND_5_CHANNELS, | ||
82 | EEPROM_REG_BAND_24_HT40_CHANNELS, | ||
83 | EEPROM_REG_BAND_52_HT40_CHANNELS | ||
84 | }, | ||
72 | }; | 85 | }; |
73 | 86 | ||
74 | #define IWL_DEVICE_5000 \ | 87 | #define IWL_DEVICE_5000 \ |
@@ -82,6 +95,7 @@ static const struct iwl_ht_params iwl5000_ht_params = { | |||
82 | .eeprom_ver = EEPROM_5000_EEPROM_VERSION, \ | 95 | .eeprom_ver = EEPROM_5000_EEPROM_VERSION, \ |
83 | .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION, \ | 96 | .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION, \ |
84 | .base_params = &iwl5000_base_params, \ | 97 | .base_params = &iwl5000_base_params, \ |
98 | .eeprom_params = &iwl5000_eeprom_params, \ | ||
85 | .led_mode = IWL_LED_BLINK | 99 | .led_mode = IWL_LED_BLINK |
86 | 100 | ||
87 | const struct iwl_cfg iwl5300_agn_cfg = { | 101 | const struct iwl_cfg iwl5300_agn_cfg = { |
@@ -128,6 +142,7 @@ const struct iwl_cfg iwl5350_agn_cfg = { | |||
128 | .eeprom_ver = EEPROM_5050_EEPROM_VERSION, | 142 | .eeprom_ver = EEPROM_5050_EEPROM_VERSION, |
129 | .eeprom_calib_ver = EEPROM_5050_TX_POWER_VERSION, | 143 | .eeprom_calib_ver = EEPROM_5050_TX_POWER_VERSION, |
130 | .base_params = &iwl5000_base_params, | 144 | .base_params = &iwl5000_base_params, |
145 | .eeprom_params = &iwl5000_eeprom_params, | ||
131 | .ht_params = &iwl5000_ht_params, | 146 | .ht_params = &iwl5000_ht_params, |
132 | .led_mode = IWL_LED_BLINK, | 147 | .led_mode = IWL_LED_BLINK, |
133 | .internal_wimax_coex = true, | 148 | .internal_wimax_coex = true, |
@@ -144,6 +159,7 @@ const struct iwl_cfg iwl5350_agn_cfg = { | |||
144 | .eeprom_ver = EEPROM_5050_EEPROM_VERSION, \ | 159 | .eeprom_ver = EEPROM_5050_EEPROM_VERSION, \ |
145 | .eeprom_calib_ver = EEPROM_5050_TX_POWER_VERSION, \ | 160 | .eeprom_calib_ver = EEPROM_5050_TX_POWER_VERSION, \ |
146 | .base_params = &iwl5000_base_params, \ | 161 | .base_params = &iwl5000_base_params, \ |
162 | .eeprom_params = &iwl5000_eeprom_params, \ | ||
147 | .no_xtal_calib = true, \ | 163 | .no_xtal_calib = true, \ |
148 | .led_mode = IWL_LED_BLINK, \ | 164 | .led_mode = IWL_LED_BLINK, \ |
149 | .internal_wimax_coex = true | 165 | .internal_wimax_coex = true |
diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/pcie/6000.c index 19f7ee84ae89..8dd8a6fe61e8 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/pcie/6000.c | |||
@@ -27,9 +27,9 @@ | |||
27 | #include <linux/module.h> | 27 | #include <linux/module.h> |
28 | #include <linux/stringify.h> | 28 | #include <linux/stringify.h> |
29 | #include "iwl-config.h" | 29 | #include "iwl-config.h" |
30 | #include "iwl-cfg.h" | ||
31 | #include "iwl-agn-hw.h" | 30 | #include "iwl-agn-hw.h" |
32 | #include "iwl-commands.h" /* needed for BT for now */ | 31 | #include "cfg.h" |
32 | #include "dvm/commands.h" /* needed for BT for now */ | ||
33 | 33 | ||
34 | /* Highest firmware API version supported */ | 34 | /* Highest firmware API version supported */ |
35 | #define IWL6000_UCODE_API_MAX 6 | 35 | #define IWL6000_UCODE_API_MAX 6 |
@@ -124,6 +124,7 @@ static const struct iwl_base_params iwl6000_g2_base_params = { | |||
124 | static const struct iwl_ht_params iwl6000_ht_params = { | 124 | static const struct iwl_ht_params iwl6000_ht_params = { |
125 | .ht_greenfield_support = true, | 125 | .ht_greenfield_support = true, |
126 | .use_rts_for_aggregation = true, /* use rts/cts protection */ | 126 | .use_rts_for_aggregation = true, /* use rts/cts protection */ |
127 | .ht40_bands = BIT(IEEE80211_BAND_2GHZ) | BIT(IEEE80211_BAND_5GHZ), | ||
127 | }; | 128 | }; |
128 | 129 | ||
129 | static const struct iwl_bt_params iwl6000_bt_params = { | 130 | static const struct iwl_bt_params iwl6000_bt_params = { |
@@ -135,6 +136,19 @@ static const struct iwl_bt_params iwl6000_bt_params = { | |||
135 | .bt_sco_disable = true, | 136 | .bt_sco_disable = true, |
136 | }; | 137 | }; |
137 | 138 | ||
139 | static const struct iwl_eeprom_params iwl6000_eeprom_params = { | ||
140 | .regulatory_bands = { | ||
141 | EEPROM_REG_BAND_1_CHANNELS, | ||
142 | EEPROM_REG_BAND_2_CHANNELS, | ||
143 | EEPROM_REG_BAND_3_CHANNELS, | ||
144 | EEPROM_REG_BAND_4_CHANNELS, | ||
145 | EEPROM_REG_BAND_5_CHANNELS, | ||
146 | EEPROM_6000_REG_BAND_24_HT40_CHANNELS, | ||
147 | EEPROM_REG_BAND_52_HT40_CHANNELS | ||
148 | }, | ||
149 | .enhanced_txpower = true, | ||
150 | }; | ||
151 | |||
138 | #define IWL_DEVICE_6005 \ | 152 | #define IWL_DEVICE_6005 \ |
139 | .fw_name_pre = IWL6005_FW_PRE, \ | 153 | .fw_name_pre = IWL6005_FW_PRE, \ |
140 | .ucode_api_max = IWL6000G2_UCODE_API_MAX, \ | 154 | .ucode_api_max = IWL6000G2_UCODE_API_MAX, \ |
@@ -146,6 +160,7 @@ static const struct iwl_bt_params iwl6000_bt_params = { | |||
146 | .eeprom_ver = EEPROM_6005_EEPROM_VERSION, \ | 160 | .eeprom_ver = EEPROM_6005_EEPROM_VERSION, \ |
147 | .eeprom_calib_ver = EEPROM_6005_TX_POWER_VERSION, \ | 161 | .eeprom_calib_ver = EEPROM_6005_TX_POWER_VERSION, \ |
148 | .base_params = &iwl6000_g2_base_params, \ | 162 | .base_params = &iwl6000_g2_base_params, \ |
163 | .eeprom_params = &iwl6000_eeprom_params, \ | ||
149 | .need_temp_offset_calib = true, \ | 164 | .need_temp_offset_calib = true, \ |
150 | .led_mode = IWL_LED_RF_STATE | 165 | .led_mode = IWL_LED_RF_STATE |
151 | 166 | ||
@@ -201,6 +216,7 @@ const struct iwl_cfg iwl6005_2agn_mow2_cfg = { | |||
201 | .eeprom_calib_ver = EEPROM_6030_TX_POWER_VERSION, \ | 216 | .eeprom_calib_ver = EEPROM_6030_TX_POWER_VERSION, \ |
202 | .base_params = &iwl6000_g2_base_params, \ | 217 | .base_params = &iwl6000_g2_base_params, \ |
203 | .bt_params = &iwl6000_bt_params, \ | 218 | .bt_params = &iwl6000_bt_params, \ |
219 | .eeprom_params = &iwl6000_eeprom_params, \ | ||
204 | .need_temp_offset_calib = true, \ | 220 | .need_temp_offset_calib = true, \ |
205 | .led_mode = IWL_LED_RF_STATE, \ | 221 | .led_mode = IWL_LED_RF_STATE, \ |
206 | .adv_pm = true \ | 222 | .adv_pm = true \ |
@@ -273,6 +289,7 @@ const struct iwl_cfg iwl130_bg_cfg = { | |||
273 | .eeprom_ver = EEPROM_6000_EEPROM_VERSION, \ | 289 | .eeprom_ver = EEPROM_6000_EEPROM_VERSION, \ |
274 | .eeprom_calib_ver = EEPROM_6000_TX_POWER_VERSION, \ | 290 | .eeprom_calib_ver = EEPROM_6000_TX_POWER_VERSION, \ |
275 | .base_params = &iwl6000_base_params, \ | 291 | .base_params = &iwl6000_base_params, \ |
292 | .eeprom_params = &iwl6000_eeprom_params, \ | ||
276 | .led_mode = IWL_LED_BLINK | 293 | .led_mode = IWL_LED_BLINK |
277 | 294 | ||
278 | const struct iwl_cfg iwl6000i_2agn_cfg = { | 295 | const struct iwl_cfg iwl6000i_2agn_cfg = { |
@@ -303,6 +320,7 @@ const struct iwl_cfg iwl6000i_2bg_cfg = { | |||
303 | .eeprom_ver = EEPROM_6050_EEPROM_VERSION, \ | 320 | .eeprom_ver = EEPROM_6050_EEPROM_VERSION, \ |
304 | .eeprom_calib_ver = EEPROM_6050_TX_POWER_VERSION, \ | 321 | .eeprom_calib_ver = EEPROM_6050_TX_POWER_VERSION, \ |
305 | .base_params = &iwl6050_base_params, \ | 322 | .base_params = &iwl6050_base_params, \ |
323 | .eeprom_params = &iwl6000_eeprom_params, \ | ||
306 | .led_mode = IWL_LED_BLINK, \ | 324 | .led_mode = IWL_LED_BLINK, \ |
307 | .internal_wimax_coex = true | 325 | .internal_wimax_coex = true |
308 | 326 | ||
@@ -327,6 +345,7 @@ const struct iwl_cfg iwl6050_2abg_cfg = { | |||
327 | .eeprom_ver = EEPROM_6150_EEPROM_VERSION, \ | 345 | .eeprom_ver = EEPROM_6150_EEPROM_VERSION, \ |
328 | .eeprom_calib_ver = EEPROM_6150_TX_POWER_VERSION, \ | 346 | .eeprom_calib_ver = EEPROM_6150_TX_POWER_VERSION, \ |
329 | .base_params = &iwl6050_base_params, \ | 347 | .base_params = &iwl6050_base_params, \ |
348 | .eeprom_params = &iwl6000_eeprom_params, \ | ||
330 | .led_mode = IWL_LED_BLINK, \ | 349 | .led_mode = IWL_LED_BLINK, \ |
331 | .internal_wimax_coex = true | 350 | .internal_wimax_coex = true |
332 | 351 | ||
@@ -353,6 +372,7 @@ const struct iwl_cfg iwl6000_3agn_cfg = { | |||
353 | .eeprom_ver = EEPROM_6000_EEPROM_VERSION, | 372 | .eeprom_ver = EEPROM_6000_EEPROM_VERSION, |
354 | .eeprom_calib_ver = EEPROM_6000_TX_POWER_VERSION, | 373 | .eeprom_calib_ver = EEPROM_6000_TX_POWER_VERSION, |
355 | .base_params = &iwl6000_base_params, | 374 | .base_params = &iwl6000_base_params, |
375 | .eeprom_params = &iwl6000_eeprom_params, | ||
356 | .ht_params = &iwl6000_ht_params, | 376 | .ht_params = &iwl6000_ht_params, |
357 | .led_mode = IWL_LED_BLINK, | 377 | .led_mode = IWL_LED_BLINK, |
358 | }; | 378 | }; |
diff --git a/drivers/net/wireless/iwlwifi/iwl-cfg.h b/drivers/net/wireless/iwlwifi/pcie/cfg.h index 82152311d73b..82152311d73b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-cfg.h +++ b/drivers/net/wireless/iwlwifi/pcie/cfg.h | |||
diff --git a/drivers/net/wireless/iwlwifi/iwl-pci.c b/drivers/net/wireless/iwlwifi/pcie/drv.c index 0c8a1c2d8847..f4c3500b68c6 100644 --- a/drivers/net/wireless/iwlwifi/iwl-pci.c +++ b/drivers/net/wireless/iwlwifi/pcie/drv.c | |||
@@ -68,10 +68,11 @@ | |||
68 | #include <linux/pci-aspm.h> | 68 | #include <linux/pci-aspm.h> |
69 | 69 | ||
70 | #include "iwl-trans.h" | 70 | #include "iwl-trans.h" |
71 | #include "iwl-cfg.h" | ||
72 | #include "iwl-drv.h" | 71 | #include "iwl-drv.h" |
73 | #include "iwl-trans.h" | 72 | #include "iwl-trans.h" |
74 | #include "iwl-trans-pcie-int.h" | 73 | |
74 | #include "cfg.h" | ||
75 | #include "internal.h" | ||
75 | 76 | ||
76 | #define IWL_PCI_DEVICE(dev, subdev, cfg) \ | 77 | #define IWL_PCI_DEVICE(dev, subdev, cfg) \ |
77 | .vendor = PCI_VENDOR_ID_INTEL, .device = (dev), \ | 78 | .vendor = PCI_VENDOR_ID_INTEL, .device = (dev), \ |
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h b/drivers/net/wireless/iwlwifi/pcie/internal.h index f027769933d9..94201c4d6227 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h +++ b/drivers/net/wireless/iwlwifi/pcie/internal.h | |||
@@ -339,13 +339,16 @@ void iwl_tx_cmd_complete(struct iwl_trans *trans, | |||
339 | void iwl_trans_txq_update_byte_cnt_tbl(struct iwl_trans *trans, | 339 | void iwl_trans_txq_update_byte_cnt_tbl(struct iwl_trans *trans, |
340 | struct iwl_tx_queue *txq, | 340 | struct iwl_tx_queue *txq, |
341 | u16 byte_cnt); | 341 | u16 byte_cnt); |
342 | void iwl_trans_pcie_tx_agg_disable(struct iwl_trans *trans, int queue); | 342 | void iwl_trans_pcie_txq_disable(struct iwl_trans *trans, int queue); |
343 | void iwl_trans_set_wr_ptrs(struct iwl_trans *trans, int txq_id, u32 index); | 343 | void iwl_trans_set_wr_ptrs(struct iwl_trans *trans, int txq_id, u32 index); |
344 | void iwl_trans_tx_queue_set_status(struct iwl_trans *trans, | 344 | void iwl_trans_tx_queue_set_status(struct iwl_trans *trans, |
345 | struct iwl_tx_queue *txq, | 345 | struct iwl_tx_queue *txq, |
346 | int tx_fifo_id, bool active); | 346 | int tx_fifo_id, bool active); |
347 | void iwl_trans_pcie_tx_agg_setup(struct iwl_trans *trans, int queue, int fifo, | 347 | void __iwl_trans_pcie_txq_enable(struct iwl_trans *trans, int txq_id, |
348 | int sta_id, int tid, int frame_limit, u16 ssn); | 348 | int fifo, int sta_id, int tid, |
349 | int frame_limit, u16 ssn); | ||
350 | void iwl_trans_pcie_txq_enable(struct iwl_trans *trans, int txq_id, int fifo, | ||
351 | int sta_id, int tid, int frame_limit, u16 ssn); | ||
349 | void iwl_txq_free_tfd(struct iwl_trans *trans, struct iwl_tx_queue *txq, | 352 | void iwl_txq_free_tfd(struct iwl_trans *trans, struct iwl_tx_queue *txq, |
350 | enum dma_data_direction dma_dir); | 353 | enum dma_data_direction dma_dir); |
351 | int iwl_tx_queue_reclaim(struct iwl_trans *trans, int txq_id, int index, | 354 | int iwl_tx_queue_reclaim(struct iwl_trans *trans, int txq_id, int index, |
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c b/drivers/net/wireless/iwlwifi/pcie/rx.c index 98605fc7ad37..d6860c070c16 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c +++ b/drivers/net/wireless/iwlwifi/pcie/rx.c | |||
@@ -32,7 +32,7 @@ | |||
32 | 32 | ||
33 | #include "iwl-prph.h" | 33 | #include "iwl-prph.h" |
34 | #include "iwl-io.h" | 34 | #include "iwl-io.h" |
35 | #include "iwl-trans-pcie-int.h" | 35 | #include "internal.h" |
36 | #include "iwl-op-mode.h" | 36 | #include "iwl-op-mode.h" |
37 | 37 | ||
38 | #ifdef CONFIG_IWLWIFI_IDI | 38 | #ifdef CONFIG_IWLWIFI_IDI |
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c b/drivers/net/wireless/iwlwifi/pcie/trans.c index 1e50401023e0..1eabb834e32a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c +++ b/drivers/net/wireless/iwlwifi/pcie/trans.c | |||
@@ -70,13 +70,12 @@ | |||
70 | 70 | ||
71 | #include "iwl-drv.h" | 71 | #include "iwl-drv.h" |
72 | #include "iwl-trans.h" | 72 | #include "iwl-trans.h" |
73 | #include "iwl-trans-pcie-int.h" | ||
74 | #include "iwl-csr.h" | 73 | #include "iwl-csr.h" |
75 | #include "iwl-prph.h" | 74 | #include "iwl-prph.h" |
76 | #include "iwl-eeprom.h" | ||
77 | #include "iwl-agn-hw.h" | 75 | #include "iwl-agn-hw.h" |
76 | #include "internal.h" | ||
78 | /* FIXME: need to abstract out TX command (once we know what it looks like) */ | 77 | /* FIXME: need to abstract out TX command (once we know what it looks like) */ |
79 | #include "iwl-commands.h" | 78 | #include "dvm/commands.h" |
80 | 79 | ||
81 | #define SCD_QUEUECHAIN_SEL_ALL(trans, trans_pcie) \ | 80 | #define SCD_QUEUECHAIN_SEL_ALL(trans, trans_pcie) \ |
82 | (((1<<trans->cfg->base_params->num_of_queues) - 1) &\ | 81 | (((1<<trans->cfg->base_params->num_of_queues) - 1) &\ |
@@ -1031,6 +1030,10 @@ static void iwl_tx_start(struct iwl_trans *trans) | |||
1031 | 1030 | ||
1032 | spin_lock_irqsave(&trans_pcie->irq_lock, flags); | 1031 | spin_lock_irqsave(&trans_pcie->irq_lock, flags); |
1033 | 1032 | ||
1033 | /* make sure all queue are not stopped/used */ | ||
1034 | memset(trans_pcie->queue_stopped, 0, sizeof(trans_pcie->queue_stopped)); | ||
1035 | memset(trans_pcie->queue_used, 0, sizeof(trans_pcie->queue_used)); | ||
1036 | |||
1034 | trans_pcie->scd_base_addr = | 1037 | trans_pcie->scd_base_addr = |
1035 | iwl_read_prph(trans, SCD_SRAM_BASE_ADDR); | 1038 | iwl_read_prph(trans, SCD_SRAM_BASE_ADDR); |
1036 | a = trans_pcie->scd_base_addr + SCD_CONTEXT_MEM_LOWER_BOUND; | 1039 | a = trans_pcie->scd_base_addr + SCD_CONTEXT_MEM_LOWER_BOUND; |
@@ -1051,59 +1054,28 @@ static void iwl_tx_start(struct iwl_trans *trans) | |||
1051 | iwl_write_prph(trans, SCD_DRAM_BASE_ADDR, | 1054 | iwl_write_prph(trans, SCD_DRAM_BASE_ADDR, |
1052 | trans_pcie->scd_bc_tbls.dma >> 10); | 1055 | trans_pcie->scd_bc_tbls.dma >> 10); |
1053 | 1056 | ||
1057 | for (i = 0; i < trans_pcie->n_q_to_fifo; i++) { | ||
1058 | int fifo = trans_pcie->setup_q_to_fifo[i]; | ||
1059 | |||
1060 | __iwl_trans_pcie_txq_enable(trans, i, fifo, IWL_INVALID_STATION, | ||
1061 | IWL_TID_NON_QOS, | ||
1062 | SCD_FRAME_LIMIT, 0); | ||
1063 | } | ||
1064 | |||
1065 | /* Activate all Tx DMA/FIFO channels */ | ||
1066 | iwl_trans_txq_set_sched(trans, IWL_MASK(0, 7)); | ||
1067 | |||
1054 | /* Enable DMA channel */ | 1068 | /* Enable DMA channel */ |
1055 | for (chan = 0; chan < FH_TCSR_CHNL_NUM ; chan++) | 1069 | for (chan = 0; chan < FH_TCSR_CHNL_NUM ; chan++) |
1056 | iwl_write_direct32(trans, FH_TCSR_CHNL_TX_CONFIG_REG(chan), | 1070 | iwl_write_direct32(trans, FH_TCSR_CHNL_TX_CONFIG_REG(chan), |
1057 | FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_ENABLE | | 1071 | FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_ENABLE | |
1058 | FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_ENABLE); | 1072 | FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_ENABLE); |
1059 | 1073 | ||
1060 | /* Update FH chicken bits */ | 1074 | /* Update FH chicken bits */ |
1061 | reg_val = iwl_read_direct32(trans, FH_TX_CHICKEN_BITS_REG); | 1075 | reg_val = iwl_read_direct32(trans, FH_TX_CHICKEN_BITS_REG); |
1062 | iwl_write_direct32(trans, FH_TX_CHICKEN_BITS_REG, | 1076 | iwl_write_direct32(trans, FH_TX_CHICKEN_BITS_REG, |
1063 | reg_val | FH_TX_CHICKEN_BITS_SCD_AUTO_RETRY_EN); | 1077 | reg_val | FH_TX_CHICKEN_BITS_SCD_AUTO_RETRY_EN); |
1064 | 1078 | ||
1065 | iwl_write_prph(trans, SCD_QUEUECHAIN_SEL, | ||
1066 | SCD_QUEUECHAIN_SEL_ALL(trans, trans_pcie)); | ||
1067 | iwl_write_prph(trans, SCD_AGGR_SEL, 0); | ||
1068 | |||
1069 | /* initiate the queues */ | ||
1070 | for (i = 0; i < trans->cfg->base_params->num_of_queues; i++) { | ||
1071 | iwl_write_prph(trans, SCD_QUEUE_RDPTR(i), 0); | ||
1072 | iwl_write_direct32(trans, HBUS_TARG_WRPTR, 0 | (i << 8)); | ||
1073 | iwl_write_targ_mem(trans, trans_pcie->scd_base_addr + | ||
1074 | SCD_CONTEXT_QUEUE_OFFSET(i), 0); | ||
1075 | iwl_write_targ_mem(trans, trans_pcie->scd_base_addr + | ||
1076 | SCD_CONTEXT_QUEUE_OFFSET(i) + | ||
1077 | sizeof(u32), | ||
1078 | ((SCD_WIN_SIZE << | ||
1079 | SCD_QUEUE_CTX_REG2_WIN_SIZE_POS) & | ||
1080 | SCD_QUEUE_CTX_REG2_WIN_SIZE_MSK) | | ||
1081 | ((SCD_FRAME_LIMIT << | ||
1082 | SCD_QUEUE_CTX_REG2_FRAME_LIMIT_POS) & | ||
1083 | SCD_QUEUE_CTX_REG2_FRAME_LIMIT_MSK)); | ||
1084 | } | ||
1085 | |||
1086 | iwl_write_prph(trans, SCD_INTERRUPT_MASK, | ||
1087 | IWL_MASK(0, trans->cfg->base_params->num_of_queues)); | ||
1088 | |||
1089 | /* Activate all Tx DMA/FIFO channels */ | ||
1090 | iwl_trans_txq_set_sched(trans, IWL_MASK(0, 7)); | ||
1091 | |||
1092 | iwl_trans_set_wr_ptrs(trans, trans_pcie->cmd_queue, 0); | ||
1093 | |||
1094 | /* make sure all queue are not stopped/used */ | ||
1095 | memset(trans_pcie->queue_stopped, 0, sizeof(trans_pcie->queue_stopped)); | ||
1096 | memset(trans_pcie->queue_used, 0, sizeof(trans_pcie->queue_used)); | ||
1097 | |||
1098 | for (i = 0; i < trans_pcie->n_q_to_fifo; i++) { | ||
1099 | int fifo = trans_pcie->setup_q_to_fifo[i]; | ||
1100 | |||
1101 | set_bit(i, trans_pcie->queue_used); | ||
1102 | |||
1103 | iwl_trans_tx_queue_set_status(trans, &trans_pcie->txq[i], | ||
1104 | fifo, true); | ||
1105 | } | ||
1106 | |||
1107 | spin_unlock_irqrestore(&trans_pcie->irq_lock, flags); | 1079 | spin_unlock_irqrestore(&trans_pcie->irq_lock, flags); |
1108 | 1080 | ||
1109 | /* Enable L1-Active */ | 1081 | /* Enable L1-Active */ |
@@ -1556,6 +1528,7 @@ void iwl_trans_pcie_free(struct iwl_trans *trans) | |||
1556 | iounmap(trans_pcie->hw_base); | 1528 | iounmap(trans_pcie->hw_base); |
1557 | pci_release_regions(trans_pcie->pci_dev); | 1529 | pci_release_regions(trans_pcie->pci_dev); |
1558 | pci_disable_device(trans_pcie->pci_dev); | 1530 | pci_disable_device(trans_pcie->pci_dev); |
1531 | kmem_cache_destroy(trans->dev_cmd_pool); | ||
1559 | 1532 | ||
1560 | kfree(trans); | 1533 | kfree(trans); |
1561 | } | 1534 | } |
@@ -2046,8 +2019,8 @@ static const struct iwl_trans_ops trans_ops_pcie = { | |||
2046 | .tx = iwl_trans_pcie_tx, | 2019 | .tx = iwl_trans_pcie_tx, |
2047 | .reclaim = iwl_trans_pcie_reclaim, | 2020 | .reclaim = iwl_trans_pcie_reclaim, |
2048 | 2021 | ||
2049 | .tx_agg_disable = iwl_trans_pcie_tx_agg_disable, | 2022 | .txq_disable = iwl_trans_pcie_txq_disable, |
2050 | .tx_agg_setup = iwl_trans_pcie_tx_agg_setup, | 2023 | .txq_enable = iwl_trans_pcie_txq_enable, |
2051 | 2024 | ||
2052 | .dbgfs_register = iwl_trans_pcie_dbgfs_register, | 2025 | .dbgfs_register = iwl_trans_pcie_dbgfs_register, |
2053 | 2026 | ||
@@ -2070,6 +2043,7 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev, | |||
2070 | { | 2043 | { |
2071 | struct iwl_trans_pcie *trans_pcie; | 2044 | struct iwl_trans_pcie *trans_pcie; |
2072 | struct iwl_trans *trans; | 2045 | struct iwl_trans *trans; |
2046 | char cmd_pool_name[100]; | ||
2073 | u16 pci_cmd; | 2047 | u16 pci_cmd; |
2074 | int err; | 2048 | int err; |
2075 | 2049 | ||
@@ -2166,8 +2140,25 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev, | |||
2166 | init_waitqueue_head(&trans->wait_command_queue); | 2140 | init_waitqueue_head(&trans->wait_command_queue); |
2167 | spin_lock_init(&trans->reg_lock); | 2141 | spin_lock_init(&trans->reg_lock); |
2168 | 2142 | ||
2143 | snprintf(cmd_pool_name, sizeof(cmd_pool_name), "iwl_cmd_pool:%s", | ||
2144 | dev_name(trans->dev)); | ||
2145 | |||
2146 | trans->dev_cmd_headroom = 0; | ||
2147 | trans->dev_cmd_pool = | ||
2148 | kmem_cache_create(cmd_pool_name, | ||
2149 | sizeof(struct iwl_device_cmd) | ||
2150 | + trans->dev_cmd_headroom, | ||
2151 | sizeof(void *), | ||
2152 | SLAB_HWCACHE_ALIGN, | ||
2153 | NULL); | ||
2154 | |||
2155 | if (!trans->dev_cmd_pool) | ||
2156 | goto out_pci_disable_msi; | ||
2157 | |||
2169 | return trans; | 2158 | return trans; |
2170 | 2159 | ||
2160 | out_pci_disable_msi: | ||
2161 | pci_disable_msi(pdev); | ||
2171 | out_pci_release_regions: | 2162 | out_pci_release_regions: |
2172 | pci_release_regions(pdev); | 2163 | pci_release_regions(pdev); |
2173 | out_pci_disable_device: | 2164 | out_pci_disable_device: |
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c b/drivers/net/wireless/iwlwifi/pcie/tx.c index 6f601cd05a94..35e82161ca43 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c +++ b/drivers/net/wireless/iwlwifi/pcie/tx.c | |||
@@ -34,11 +34,10 @@ | |||
34 | #include "iwl-csr.h" | 34 | #include "iwl-csr.h" |
35 | #include "iwl-prph.h" | 35 | #include "iwl-prph.h" |
36 | #include "iwl-io.h" | 36 | #include "iwl-io.h" |
37 | #include "iwl-agn-hw.h" | ||
38 | #include "iwl-op-mode.h" | 37 | #include "iwl-op-mode.h" |
39 | #include "iwl-trans-pcie-int.h" | 38 | #include "internal.h" |
40 | /* FIXME: need to abstract out TX command (once we know what it looks like) */ | 39 | /* FIXME: need to abstract out TX command (once we know what it looks like) */ |
41 | #include "iwl-commands.h" | 40 | #include "dvm/commands.h" |
42 | 41 | ||
43 | #define IWL_TX_CRC_SIZE 4 | 42 | #define IWL_TX_CRC_SIZE 4 |
44 | #define IWL_TX_DELIMITER_SIZE 4 | 43 | #define IWL_TX_DELIMITER_SIZE 4 |
@@ -443,29 +442,34 @@ void iwl_trans_tx_queue_set_status(struct iwl_trans *trans, | |||
443 | IWL_DEBUG_TX_QUEUES(trans, "Deactivate queue %d\n", txq_id); | 442 | IWL_DEBUG_TX_QUEUES(trans, "Deactivate queue %d\n", txq_id); |
444 | } | 443 | } |
445 | 444 | ||
446 | void iwl_trans_pcie_tx_agg_setup(struct iwl_trans *trans, int txq_id, int fifo, | 445 | void __iwl_trans_pcie_txq_enable(struct iwl_trans *trans, int txq_id, |
447 | int sta_id, int tid, int frame_limit, u16 ssn) | 446 | int fifo, int sta_id, int tid, |
447 | int frame_limit, u16 ssn) | ||
448 | { | 448 | { |
449 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | 449 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); |
450 | unsigned long flags; | 450 | |
451 | u16 ra_tid = BUILD_RAxTID(sta_id, tid); | 451 | lockdep_assert_held(&trans_pcie->irq_lock); |
452 | 452 | ||
453 | if (test_and_set_bit(txq_id, trans_pcie->queue_used)) | 453 | if (test_and_set_bit(txq_id, trans_pcie->queue_used)) |
454 | WARN_ONCE(1, "queue %d already used - expect issues", txq_id); | 454 | WARN_ONCE(1, "queue %d already used - expect issues", txq_id); |
455 | 455 | ||
456 | spin_lock_irqsave(&trans_pcie->irq_lock, flags); | ||
457 | |||
458 | /* Stop this Tx queue before configuring it */ | 456 | /* Stop this Tx queue before configuring it */ |
459 | iwlagn_tx_queue_stop_scheduler(trans, txq_id); | 457 | iwlagn_tx_queue_stop_scheduler(trans, txq_id); |
460 | 458 | ||
461 | /* Map receiver-address / traffic-ID to this queue */ | 459 | /* Set this queue as a chain-building queue unless it is CMD queue */ |
462 | iwlagn_tx_queue_set_q2ratid(trans, ra_tid, txq_id); | 460 | if (txq_id != trans_pcie->cmd_queue) |
461 | iwl_set_bits_prph(trans, SCD_QUEUECHAIN_SEL, BIT(txq_id)); | ||
463 | 462 | ||
464 | /* Set this queue as a chain-building queue */ | 463 | /* If this queue is mapped to a certain station: it is an AGG queue */ |
465 | iwl_set_bits_prph(trans, SCD_QUEUECHAIN_SEL, BIT(txq_id)); | 464 | if (sta_id != IWL_INVALID_STATION) { |
465 | u16 ra_tid = BUILD_RAxTID(sta_id, tid); | ||
466 | 466 | ||
467 | /* enable aggregations for the queue */ | 467 | /* Map receiver-address / traffic-ID to this queue */ |
468 | iwl_set_bits_prph(trans, SCD_AGGR_SEL, BIT(txq_id)); | 468 | iwlagn_tx_queue_set_q2ratid(trans, ra_tid, txq_id); |
469 | |||
470 | /* enable aggregations for the queue */ | ||
471 | iwl_set_bits_prph(trans, SCD_AGGR_SEL, BIT(txq_id)); | ||
472 | } | ||
469 | 473 | ||
470 | /* Place first TFD at index corresponding to start sequence number. | 474 | /* Place first TFD at index corresponding to start sequence number. |
471 | * Assumes that ssn_idx is valid (!= 0xFFF) */ | 475 | * Assumes that ssn_idx is valid (!= 0xFFF) */ |
@@ -475,22 +479,34 @@ void iwl_trans_pcie_tx_agg_setup(struct iwl_trans *trans, int txq_id, int fifo, | |||
475 | 479 | ||
476 | /* Set up Tx window size and frame limit for this queue */ | 480 | /* Set up Tx window size and frame limit for this queue */ |
477 | iwl_write_targ_mem(trans, trans_pcie->scd_base_addr + | 481 | iwl_write_targ_mem(trans, trans_pcie->scd_base_addr + |
482 | SCD_CONTEXT_QUEUE_OFFSET(txq_id), 0); | ||
483 | iwl_write_targ_mem(trans, trans_pcie->scd_base_addr + | ||
478 | SCD_CONTEXT_QUEUE_OFFSET(txq_id) + sizeof(u32), | 484 | SCD_CONTEXT_QUEUE_OFFSET(txq_id) + sizeof(u32), |
479 | ((frame_limit << SCD_QUEUE_CTX_REG2_WIN_SIZE_POS) & | 485 | ((frame_limit << SCD_QUEUE_CTX_REG2_WIN_SIZE_POS) & |
480 | SCD_QUEUE_CTX_REG2_WIN_SIZE_MSK) | | 486 | SCD_QUEUE_CTX_REG2_WIN_SIZE_MSK) | |
481 | ((frame_limit << SCD_QUEUE_CTX_REG2_FRAME_LIMIT_POS) & | 487 | ((frame_limit << SCD_QUEUE_CTX_REG2_FRAME_LIMIT_POS) & |
482 | SCD_QUEUE_CTX_REG2_FRAME_LIMIT_MSK)); | 488 | SCD_QUEUE_CTX_REG2_FRAME_LIMIT_MSK)); |
483 | 489 | ||
484 | iwl_set_bits_prph(trans, SCD_INTERRUPT_MASK, (1 << txq_id)); | ||
485 | |||
486 | /* Set up Status area in SRAM, map to Tx DMA/FIFO, activate the queue */ | 490 | /* Set up Status area in SRAM, map to Tx DMA/FIFO, activate the queue */ |
487 | iwl_trans_tx_queue_set_status(trans, &trans_pcie->txq[txq_id], | 491 | iwl_trans_tx_queue_set_status(trans, &trans_pcie->txq[txq_id], |
488 | fifo, true); | 492 | fifo, true); |
493 | } | ||
494 | |||
495 | void iwl_trans_pcie_txq_enable(struct iwl_trans *trans, int txq_id, int fifo, | ||
496 | int sta_id, int tid, int frame_limit, u16 ssn) | ||
497 | { | ||
498 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | ||
499 | unsigned long flags; | ||
500 | |||
501 | spin_lock_irqsave(&trans_pcie->irq_lock, flags); | ||
502 | |||
503 | __iwl_trans_pcie_txq_enable(trans, txq_id, fifo, sta_id, | ||
504 | tid, frame_limit, ssn); | ||
489 | 505 | ||
490 | spin_unlock_irqrestore(&trans_pcie->irq_lock, flags); | 506 | spin_unlock_irqrestore(&trans_pcie->irq_lock, flags); |
491 | } | 507 | } |
492 | 508 | ||
493 | void iwl_trans_pcie_tx_agg_disable(struct iwl_trans *trans, int txq_id) | 509 | void iwl_trans_pcie_txq_disable(struct iwl_trans *trans, int txq_id) |
494 | { | 510 | { |
495 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | 511 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); |
496 | 512 | ||
@@ -507,8 +523,6 @@ void iwl_trans_pcie_tx_agg_disable(struct iwl_trans *trans, int txq_id) | |||
507 | trans_pcie->txq[txq_id].q.write_ptr = 0; | 523 | trans_pcie->txq[txq_id].q.write_ptr = 0; |
508 | iwl_trans_set_wr_ptrs(trans, txq_id, 0); | 524 | iwl_trans_set_wr_ptrs(trans, txq_id, 0); |
509 | 525 | ||
510 | iwl_clear_bits_prph(trans, SCD_INTERRUPT_MASK, BIT(txq_id)); | ||
511 | |||
512 | iwl_trans_tx_queue_set_status(trans, &trans_pcie->txq[txq_id], | 526 | iwl_trans_tx_queue_set_status(trans, &trans_pcie->txq[txq_id], |
513 | 0, false); | 527 | 0, false); |
514 | } | 528 | } |