Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
linux
Commits
d896d463
Commit
d896d463
authored
Feb 27, 2012
by
John W. Linville
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'wireless-next' of
git://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi/iwlwifi
parents
0a8a721d
758f555f
Changes
35
Hide whitespace changes
Inline
Side-by-side
Showing
35 changed files
with
1112 additions
and
611 deletions
+1112
-611
drivers/net/wireless/iwlwifi/Makefile
drivers/net/wireless/iwlwifi/Makefile
+1
-1
drivers/net/wireless/iwlwifi/iwl-1000.c
drivers/net/wireless/iwlwifi/iwl-1000.c
+5
-5
drivers/net/wireless/iwlwifi/iwl-2000.c
drivers/net/wireless/iwlwifi/iwl-2000.c
+9
-5
drivers/net/wireless/iwlwifi/iwl-5000.c
drivers/net/wireless/iwlwifi/iwl-5000.c
+8
-10
drivers/net/wireless/iwlwifi/iwl-6000.c
drivers/net/wireless/iwlwifi/iwl-6000.c
+13
-4
drivers/net/wireless/iwlwifi/iwl-agn-calib.c
drivers/net/wireless/iwlwifi/iwl-agn-calib.c
+4
-2
drivers/net/wireless/iwlwifi/iwl-agn-lib.c
drivers/net/wireless/iwlwifi/iwl-agn-lib.c
+3
-3
drivers/net/wireless/iwlwifi/iwl-agn-rs.c
drivers/net/wireless/iwlwifi/iwl-agn-rs.c
+1
-1
drivers/net/wireless/iwlwifi/iwl-agn-rx.c
drivers/net/wireless/iwlwifi/iwl-agn-rx.c
+1
-1
drivers/net/wireless/iwlwifi/iwl-agn-rxon.c
drivers/net/wireless/iwlwifi/iwl-agn-rxon.c
+16
-0
drivers/net/wireless/iwlwifi/iwl-agn-tt.c
drivers/net/wireless/iwlwifi/iwl-agn-tt.c
+3
-3
drivers/net/wireless/iwlwifi/iwl-agn-tx.c
drivers/net/wireless/iwlwifi/iwl-agn-tx.c
+1
-1
drivers/net/wireless/iwlwifi/iwl-agn.c
drivers/net/wireless/iwlwifi/iwl-agn.c
+20
-33
drivers/net/wireless/iwlwifi/iwl-agn.h
drivers/net/wireless/iwlwifi/iwl-agn.h
+3
-7
drivers/net/wireless/iwlwifi/iwl-core.c
drivers/net/wireless/iwlwifi/iwl-core.c
+3
-4
drivers/net/wireless/iwlwifi/iwl-core.h
drivers/net/wireless/iwlwifi/iwl-core.h
+2
-2
drivers/net/wireless/iwlwifi/iwl-debug.c
drivers/net/wireless/iwlwifi/iwl-debug.c
+127
-0
drivers/net/wireless/iwlwifi/iwl-debug.h
drivers/net/wireless/iwlwifi/iwl-debug.h
+42
-41
drivers/net/wireless/iwlwifi/iwl-debugfs.c
drivers/net/wireless/iwlwifi/iwl-debugfs.c
+6
-5
drivers/net/wireless/iwlwifi/iwl-dev.h
drivers/net/wireless/iwlwifi/iwl-dev.h
+5
-16
drivers/net/wireless/iwlwifi/iwl-devtrace.h
drivers/net/wireless/iwlwifi/iwl-devtrace.h
+65
-0
drivers/net/wireless/iwlwifi/iwl-mac80211.c
drivers/net/wireless/iwlwifi/iwl-mac80211.c
+12
-8
drivers/net/wireless/iwlwifi/iwl-pci.c
drivers/net/wireless/iwlwifi/iwl-pci.c
+16
-2
drivers/net/wireless/iwlwifi/iwl-scan.c
drivers/net/wireless/iwlwifi/iwl-scan.c
+5
-5
drivers/net/wireless/iwlwifi/iwl-shared.h
drivers/net/wireless/iwlwifi/iwl-shared.h
+7
-6
drivers/net/wireless/iwlwifi/iwl-testmode.c
drivers/net/wireless/iwlwifi/iwl-testmode.c
+239
-172
drivers/net/wireless/iwlwifi/iwl-testmode.h
drivers/net/wireless/iwlwifi/iwl-testmode.h
+36
-28
drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h
drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h
+1
-0
drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c
drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c
+33
-37
drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c
drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c
+2
-2
drivers/net/wireless/iwlwifi/iwl-trans-pcie.c
drivers/net/wireless/iwlwifi/iwl-trans-pcie.c
+24
-15
drivers/net/wireless/iwlwifi/iwl-trans.h
drivers/net/wireless/iwlwifi/iwl-trans.h
+157
-33
drivers/net/wireless/iwlwifi/iwl-ucode.c
drivers/net/wireless/iwlwifi/iwl-ucode.c
+164
-157
drivers/net/wireless/iwlwifi/iwl-ucode.h
drivers/net/wireless/iwlwifi/iwl-ucode.h
+45
-2
drivers/net/wireless/iwlwifi/iwl-wifi.h
drivers/net/wireless/iwlwifi/iwl-wifi.h
+33
-0
No files found.
drivers/net/wireless/iwlwifi/Makefile
View file @
d896d463
# WIFI
obj-$(CONFIG_IWLWIFI)
+=
iwlwifi.o
iwlwifi-objs
:=
iwl-agn.o iwl-agn-rs.o iwl-mac80211.o
iwlwifi-objs
+=
iwl-ucode.o iwl-agn-tx.o
iwlwifi-objs
+=
iwl-ucode.o iwl-agn-tx.o
iwl-debug.o
iwlwifi-objs
+=
iwl-agn-lib.o iwl-agn-calib.o iwl-io.o
iwlwifi-objs
+=
iwl-agn-tt.o iwl-agn-sta.o iwl-agn-rx.o
...
...
drivers/net/wireless/iwlwifi/iwl-1000.c
View file @
d896d463
...
...
@@ -120,7 +120,7 @@ static struct iwl_sensitivity_ranges iwl1000_sensitivity = {
.
nrg_th_cca
=
62
,
};
static
int
iwl1000_hw_set_hw_params
(
struct
iwl_priv
*
priv
)
static
void
iwl1000_hw_set_hw_params
(
struct
iwl_priv
*
priv
)
{
if
(
iwlagn_mod_params
.
num_of_queues
>=
IWL_MIN_NUM_QUEUES
&&
iwlagn_mod_params
.
num_of_queues
<=
IWLAGN_NUM_QUEUES
)
...
...
@@ -128,8 +128,6 @@ static int iwl1000_hw_set_hw_params(struct iwl_priv *priv)
iwlagn_mod_params
.
num_of_queues
;
hw_params
(
priv
).
max_txq_num
=
cfg
(
priv
)
->
base_params
->
num_of_queues
;
hw_params
(
priv
).
max_data_size
=
IWLAGN_RTC_DATA_SIZE
;
hw_params
(
priv
).
max_inst_size
=
IWLAGN_RTC_INST_SIZE
;
hw_params
(
priv
).
ht40_channel
=
BIT
(
IEEE80211_BAND_2GHZ
);
...
...
@@ -146,8 +144,6 @@ static int iwl1000_hw_set_hw_params(struct iwl_priv *priv)
/* Set initial sensitivity parameters */
hw_params
(
priv
).
sens
=
&
iwl1000_sensitivity
;
return
0
;
}
static
struct
iwl_lib_ops
iwl1000_lib
=
{
...
...
@@ -193,6 +189,8 @@ static struct iwl_ht_params iwl1000_ht_params = {
.ucode_api_max = IWL1000_UCODE_API_MAX, \
.ucode_api_ok = IWL1000_UCODE_API_OK, \
.ucode_api_min = IWL1000_UCODE_API_MIN, \
.max_inst_size = IWLAGN_RTC_INST_SIZE, \
.max_data_size = IWLAGN_RTC_DATA_SIZE, \
.eeprom_ver = EEPROM_1000_EEPROM_VERSION, \
.eeprom_calib_ver = EEPROM_1000_TX_POWER_VERSION, \
.lib = &iwl1000_lib, \
...
...
@@ -215,6 +213,8 @@ struct iwl_cfg iwl1000_bg_cfg = {
.ucode_api_max = IWL100_UCODE_API_MAX, \
.ucode_api_ok = IWL100_UCODE_API_OK, \
.ucode_api_min = IWL100_UCODE_API_MIN, \
.max_inst_size = IWLAGN_RTC_INST_SIZE, \
.max_data_size = IWLAGN_RTC_DATA_SIZE, \
.eeprom_ver = EEPROM_1000_EEPROM_VERSION, \
.eeprom_calib_ver = EEPROM_1000_TX_POWER_VERSION, \
.lib = &iwl1000_lib, \
...
...
drivers/net/wireless/iwlwifi/iwl-2000.c
View file @
d896d463
...
...
@@ -116,7 +116,7 @@ static struct iwl_sensitivity_ranges iwl2000_sensitivity = {
.
nrg_th_cca
=
62
,
};
static
int
iwl2000_hw_set_hw_params
(
struct
iwl_priv
*
priv
)
static
void
iwl2000_hw_set_hw_params
(
struct
iwl_priv
*
priv
)
{
if
(
iwlagn_mod_params
.
num_of_queues
>=
IWL_MIN_NUM_QUEUES
&&
iwlagn_mod_params
.
num_of_queues
<=
IWLAGN_NUM_QUEUES
)
...
...
@@ -124,8 +124,6 @@ static int iwl2000_hw_set_hw_params(struct iwl_priv *priv)
iwlagn_mod_params
.
num_of_queues
;
hw_params
(
priv
).
max_txq_num
=
cfg
(
priv
)
->
base_params
->
num_of_queues
;
hw_params
(
priv
).
max_data_size
=
IWL60_RTC_DATA_SIZE
;
hw_params
(
priv
).
max_inst_size
=
IWL60_RTC_INST_SIZE
;
hw_params
(
priv
).
ht40_channel
=
BIT
(
IEEE80211_BAND_2GHZ
);
...
...
@@ -142,8 +140,6 @@ static int iwl2000_hw_set_hw_params(struct iwl_priv *priv)
/* Set initial sensitivity parameters */
hw_params
(
priv
).
sens
=
&
iwl2000_sensitivity
;
return
0
;
}
static
struct
iwl_lib_ops
iwl2000_lib
=
{
...
...
@@ -242,6 +238,8 @@ static struct iwl_bt_params iwl2030_bt_params = {
.ucode_api_max = IWL2000_UCODE_API_MAX, \
.ucode_api_ok = IWL2000_UCODE_API_OK, \
.ucode_api_min = IWL2000_UCODE_API_MIN, \
.max_inst_size = IWL60_RTC_INST_SIZE, \
.max_data_size = IWL60_RTC_DATA_SIZE, \
.eeprom_ver = EEPROM_2000_EEPROM_VERSION, \
.eeprom_calib_ver = EEPROM_2000_TX_POWER_VERSION, \
.lib = &iwl2000_lib, \
...
...
@@ -268,6 +266,8 @@ struct iwl_cfg iwl2000_2bgn_d_cfg = {
.ucode_api_max = IWL2030_UCODE_API_MAX, \
.ucode_api_ok = IWL2030_UCODE_API_OK, \
.ucode_api_min = IWL2030_UCODE_API_MIN, \
.max_inst_size = IWL60_RTC_INST_SIZE, \
.max_data_size = IWL60_RTC_DATA_SIZE, \
.eeprom_ver = EEPROM_2000_EEPROM_VERSION, \
.eeprom_calib_ver = EEPROM_2000_TX_POWER_VERSION, \
.lib = &iwl2030_lib, \
...
...
@@ -290,6 +290,8 @@ struct iwl_cfg iwl2030_2bgn_cfg = {
.ucode_api_max = IWL105_UCODE_API_MAX, \
.ucode_api_ok = IWL105_UCODE_API_OK, \
.ucode_api_min = IWL105_UCODE_API_MIN, \
.max_inst_size = IWL60_RTC_INST_SIZE, \
.max_data_size = IWL60_RTC_DATA_SIZE, \
.eeprom_ver = EEPROM_2000_EEPROM_VERSION, \
.eeprom_calib_ver = EEPROM_2000_TX_POWER_VERSION, \
.lib = &iwl2000_lib, \
...
...
@@ -318,6 +320,8 @@ struct iwl_cfg iwl105_bgn_d_cfg = {
.ucode_api_max = IWL135_UCODE_API_MAX, \
.ucode_api_ok = IWL135_UCODE_API_OK, \
.ucode_api_min = IWL135_UCODE_API_MIN, \
.max_inst_size = IWL60_RTC_INST_SIZE, \
.max_data_size = IWL60_RTC_DATA_SIZE, \
.eeprom_ver = EEPROM_2000_EEPROM_VERSION, \
.eeprom_calib_ver = EEPROM_2000_TX_POWER_VERSION, \
.lib = &iwl2030_lib, \
...
...
drivers/net/wireless/iwlwifi/iwl-5000.c
View file @
d896d463
...
...
@@ -162,7 +162,7 @@ static void iwl5000_set_ct_threshold(struct iwl_priv *priv)
hw_params
(
priv
).
ct_kill_threshold
=
CT_KILL_THRESHOLD_LEGACY
;
}
static
int
iwl5000_hw_set_hw_params
(
struct
iwl_priv
*
priv
)
static
void
iwl5000_hw_set_hw_params
(
struct
iwl_priv
*
priv
)
{
if
(
iwlagn_mod_params
.
num_of_queues
>=
IWL_MIN_NUM_QUEUES
&&
iwlagn_mod_params
.
num_of_queues
<=
IWLAGN_NUM_QUEUES
)
...
...
@@ -170,8 +170,6 @@ static int iwl5000_hw_set_hw_params(struct iwl_priv *priv)
iwlagn_mod_params
.
num_of_queues
;
hw_params
(
priv
).
max_txq_num
=
cfg
(
priv
)
->
base_params
->
num_of_queues
;
hw_params
(
priv
).
max_data_size
=
IWLAGN_RTC_DATA_SIZE
;
hw_params
(
priv
).
max_inst_size
=
IWLAGN_RTC_INST_SIZE
;
hw_params
(
priv
).
ht40_channel
=
BIT
(
IEEE80211_BAND_2GHZ
)
|
BIT
(
IEEE80211_BAND_5GHZ
);
...
...
@@ -185,11 +183,9 @@ static int iwl5000_hw_set_hw_params(struct iwl_priv *priv)
/* Set initial sensitivity parameters */
hw_params
(
priv
).
sens
=
&
iwl5000_sensitivity
;
return
0
;
}
static
int
iwl5150_hw_set_hw_params
(
struct
iwl_priv
*
priv
)
static
void
iwl5150_hw_set_hw_params
(
struct
iwl_priv
*
priv
)
{
if
(
iwlagn_mod_params
.
num_of_queues
>=
IWL_MIN_NUM_QUEUES
&&
iwlagn_mod_params
.
num_of_queues
<=
IWLAGN_NUM_QUEUES
)
...
...
@@ -197,8 +193,6 @@ static int iwl5150_hw_set_hw_params(struct iwl_priv *priv)
iwlagn_mod_params
.
num_of_queues
;
hw_params
(
priv
).
max_txq_num
=
cfg
(
priv
)
->
base_params
->
num_of_queues
;
hw_params
(
priv
).
max_data_size
=
IWLAGN_RTC_DATA_SIZE
;
hw_params
(
priv
).
max_inst_size
=
IWLAGN_RTC_INST_SIZE
;
hw_params
(
priv
).
ht40_channel
=
BIT
(
IEEE80211_BAND_2GHZ
)
|
BIT
(
IEEE80211_BAND_5GHZ
);
...
...
@@ -212,8 +206,6 @@ static int iwl5150_hw_set_hw_params(struct iwl_priv *priv)
/* Set initial sensitivity parameters */
hw_params
(
priv
).
sens
=
&
iwl5150_sensitivity
;
return
0
;
}
static
void
iwl5150_temperature
(
struct
iwl_priv
*
priv
)
...
...
@@ -356,6 +348,8 @@ static struct iwl_ht_params iwl5000_ht_params = {
.fw_name_pre = IWL5000_FW_PRE, \
.ucode_api_max = IWL5000_UCODE_API_MAX, \
.ucode_api_min = IWL5000_UCODE_API_MIN, \
.max_inst_size = IWLAGN_RTC_INST_SIZE, \
.max_data_size = IWLAGN_RTC_DATA_SIZE, \
.eeprom_ver = EEPROM_5000_EEPROM_VERSION, \
.eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION, \
.lib = &iwl5000_lib, \
...
...
@@ -399,6 +393,8 @@ struct iwl_cfg iwl5350_agn_cfg = {
.
fw_name_pre
=
IWL5000_FW_PRE
,
.
ucode_api_max
=
IWL5000_UCODE_API_MAX
,
.
ucode_api_min
=
IWL5000_UCODE_API_MIN
,
.
max_inst_size
=
IWLAGN_RTC_INST_SIZE
,
.
max_data_size
=
IWLAGN_RTC_DATA_SIZE
,
.
eeprom_ver
=
EEPROM_5050_EEPROM_VERSION
,
.
eeprom_calib_ver
=
EEPROM_5050_TX_POWER_VERSION
,
.
lib
=
&
iwl5000_lib
,
...
...
@@ -412,6 +408,8 @@ struct iwl_cfg iwl5350_agn_cfg = {
.fw_name_pre = IWL5150_FW_PRE, \
.ucode_api_max = IWL5150_UCODE_API_MAX, \
.ucode_api_min = IWL5150_UCODE_API_MIN, \
.max_inst_size = IWLAGN_RTC_INST_SIZE, \
.max_data_size = IWLAGN_RTC_DATA_SIZE, \
.eeprom_ver = EEPROM_5050_EEPROM_VERSION, \
.eeprom_calib_ver = EEPROM_5050_TX_POWER_VERSION, \
.lib = &iwl5150_lib, \
...
...
drivers/net/wireless/iwlwifi/iwl-6000.c
View file @
d896d463
...
...
@@ -137,7 +137,7 @@ static struct iwl_sensitivity_ranges iwl6000_sensitivity = {
.
nrg_th_cca
=
62
,
};
static
int
iwl6000_hw_set_hw_params
(
struct
iwl_priv
*
priv
)
static
void
iwl6000_hw_set_hw_params
(
struct
iwl_priv
*
priv
)
{
if
(
iwlagn_mod_params
.
num_of_queues
>=
IWL_MIN_NUM_QUEUES
&&
iwlagn_mod_params
.
num_of_queues
<=
IWLAGN_NUM_QUEUES
)
...
...
@@ -145,8 +145,6 @@ static int iwl6000_hw_set_hw_params(struct iwl_priv *priv)
iwlagn_mod_params
.
num_of_queues
;
hw_params
(
priv
).
max_txq_num
=
cfg
(
priv
)
->
base_params
->
num_of_queues
;
hw_params
(
priv
).
max_data_size
=
IWL60_RTC_DATA_SIZE
;
hw_params
(
priv
).
max_inst_size
=
IWL60_RTC_INST_SIZE
;
hw_params
(
priv
).
ht40_channel
=
BIT
(
IEEE80211_BAND_2GHZ
)
|
BIT
(
IEEE80211_BAND_5GHZ
);
...
...
@@ -165,7 +163,6 @@ static int iwl6000_hw_set_hw_params(struct iwl_priv *priv)
/* Set initial sensitivity parameters */
hw_params
(
priv
).
sens
=
&
iwl6000_sensitivity
;
return
0
;
}
static
int
iwl6000_hw_channel_switch
(
struct
iwl_priv
*
priv
,
...
...
@@ -349,6 +346,8 @@ static struct iwl_bt_params iwl6000_bt_params = {
.ucode_api_max = IWL6000G2_UCODE_API_MAX, \
.ucode_api_ok = IWL6000G2_UCODE_API_OK, \
.ucode_api_min = IWL6000G2_UCODE_API_MIN, \
.max_inst_size = IWL60_RTC_INST_SIZE, \
.max_data_size = IWL60_RTC_DATA_SIZE, \
.eeprom_ver = EEPROM_6005_EEPROM_VERSION, \
.eeprom_calib_ver = EEPROM_6005_TX_POWER_VERSION, \
.lib = &iwl6000_lib, \
...
...
@@ -389,6 +388,8 @@ struct iwl_cfg iwl6005_2agn_d_cfg = {
.ucode_api_max = IWL6000G2_UCODE_API_MAX, \
.ucode_api_ok = IWL6000G2_UCODE_API_OK, \
.ucode_api_min = IWL6000G2_UCODE_API_MIN, \
.max_inst_size = IWL60_RTC_INST_SIZE, \
.max_data_size = IWL60_RTC_DATA_SIZE, \
.eeprom_ver = EEPROM_6030_EEPROM_VERSION, \
.eeprom_calib_ver = EEPROM_6030_TX_POWER_VERSION, \
.lib = &iwl6030_lib, \
...
...
@@ -458,6 +459,8 @@ struct iwl_cfg iwl130_bg_cfg = {
.ucode_api_max = IWL6000_UCODE_API_MAX, \
.ucode_api_ok = IWL6000_UCODE_API_OK, \
.ucode_api_min = IWL6000_UCODE_API_MIN, \
.max_inst_size = IWL60_RTC_INST_SIZE, \
.max_data_size = IWL60_RTC_DATA_SIZE, \
.valid_tx_ant = ANT_BC,
/* .cfg overwrite */
\
.valid_rx_ant = ANT_BC,
/* .cfg overwrite */
\
.eeprom_ver = EEPROM_6000_EEPROM_VERSION, \
...
...
@@ -487,6 +490,8 @@ struct iwl_cfg iwl6000i_2bg_cfg = {
.fw_name_pre = IWL6050_FW_PRE, \
.ucode_api_max = IWL6050_UCODE_API_MAX, \
.ucode_api_min = IWL6050_UCODE_API_MIN, \
.max_inst_size = IWL60_RTC_INST_SIZE, \
.max_data_size = IWL60_RTC_DATA_SIZE, \
.valid_tx_ant = ANT_AB,
/* .cfg overwrite */
\
.valid_rx_ant = ANT_AB,
/* .cfg overwrite */
\
.lib = &iwl6000_lib, \
...
...
@@ -512,6 +517,8 @@ struct iwl_cfg iwl6050_2abg_cfg = {
.fw_name_pre = IWL6050_FW_PRE, \
.ucode_api_max = IWL6050_UCODE_API_MAX, \
.ucode_api_min = IWL6050_UCODE_API_MIN, \
.max_inst_size = IWL60_RTC_INST_SIZE, \
.max_data_size = IWL60_RTC_DATA_SIZE, \
.lib = &iwl6000_lib, \
.additional_nic_config = iwl6150_additional_nic_config, \
.eeprom_ver = EEPROM_6150_EEPROM_VERSION, \
...
...
@@ -537,6 +544,8 @@ struct iwl_cfg iwl6000_3agn_cfg = {
.
ucode_api_max
=
IWL6000_UCODE_API_MAX
,
.
ucode_api_ok
=
IWL6000_UCODE_API_OK
,
.
ucode_api_min
=
IWL6000_UCODE_API_MIN
,
.
max_inst_size
=
IWL60_RTC_INST_SIZE
,
.
max_data_size
=
IWL60_RTC_DATA_SIZE
,
.
eeprom_ver
=
EEPROM_6000_EEPROM_VERSION
,
.
eeprom_calib_ver
=
EEPROM_6000_TX_POWER_VERSION
,
.
lib
=
&
iwl6000_lib
,
...
...
drivers/net/wireless/iwlwifi/iwl-agn-calib.c
View file @
d896d463
...
...
@@ -68,6 +68,8 @@
#include "iwl-agn-calib.h"
#include "iwl-trans.h"
#include "iwl-agn.h"
#include "iwl-wifi.h"
#include "iwl-ucode.h"
/*****************************************************************************
* INIT calibrations framework
...
...
@@ -634,7 +636,7 @@ void iwl_init_sensitivity(struct iwl_priv *priv)
data
->
last_bad_plcp_cnt_cck
=
0
;
data
->
last_fa_cnt_cck
=
0
;
if
(
priv
->
enhance_sensitivity_table
)
if
(
nic
(
priv
)
->
fw
.
enhance_sensitivity_table
)
ret
|=
iwl_enhance_sensitivity_write
(
priv
);
else
ret
|=
iwl_sensitivity_write
(
priv
);
...
...
@@ -745,7 +747,7 @@ void iwl_sensitivity_calibration(struct iwl_priv *priv)
iwl_sens_auto_corr_ofdm
(
priv
,
norm_fa_ofdm
,
rx_enable_time
);
iwl_sens_energy_cck
(
priv
,
norm_fa_cck
,
rx_enable_time
,
&
statis
);
if
(
priv
->
enhance_sensitivity_table
)
if
(
nic
(
priv
)
->
fw
.
enhance_sensitivity_table
)
iwl_enhance_sensitivity_write
(
priv
);
else
iwl_sensitivity_write
(
priv
);
...
...
drivers/net/wireless/iwlwifi/iwl-agn-lib.c
View file @
d896d463
...
...
@@ -77,7 +77,7 @@ int iwlagn_send_tx_power(struct iwl_priv *priv)
tx_power_cmd
.
flags
=
IWLAGN_TX_POWER_NO_CLOSED
;
tx_power_cmd
.
srv_chan_lmt
=
IWLAGN_TX_POWER_AUTO
;
if
(
IWL_UCODE_API
(
priv
->
ucode_ver
)
==
1
)
if
(
IWL_UCODE_API
(
nic
(
priv
)
->
fw
.
ucode_ver
)
==
1
)
tx_ant_cfg_cmd
=
REPLY_TX_POWER_DBM_CMD_V1
;
else
tx_ant_cfg_cmd
=
REPLY_TX_POWER_DBM_CMD
;
...
...
@@ -700,7 +700,7 @@ static void iwlagn_set_kill_msk(struct iwl_priv *priv,
priv
->
kill_cts_mask
=
bt_kill_cts_msg
[
kill_msk
];
/* schedule to send runtime bt_config */
queue_work
(
priv
->
shrd
->
workqueue
,
&
priv
->
bt_runtime_config
);
queue_work
(
priv
->
workqueue
,
&
priv
->
bt_runtime_config
);
}
}
...
...
@@ -745,7 +745,7 @@ int iwlagn_bt_coex_profile_notif(struct iwl_priv *priv,
IWL_BT_COEX_TRAFFIC_LOAD_NONE
;
}
priv
->
bt_status
=
coex
->
bt_status
;
queue_work
(
priv
->
shrd
->
workqueue
,
queue_work
(
priv
->
workqueue
,
&
priv
->
bt_traffic_change_work
);
}
}
...
...
drivers/net/wireless/iwlwifi/iwl-agn-rs.c
View file @
d896d463
...
...
@@ -892,7 +892,7 @@ static void rs_bt_update_lq(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
rs_fill_link_cmd
(
priv
,
lq_sta
,
tbl
->
current_rate
);
iwl_send_lq_cmd
(
priv
,
ctx
,
&
lq_sta
->
lq
,
CMD_ASYNC
,
false
);
queue_work
(
priv
->
shrd
->
workqueue
,
&
priv
->
bt_full_concurrency
);
queue_work
(
priv
->
workqueue
,
&
priv
->
bt_full_concurrency
);
}
}
...
...
drivers/net/wireless/iwlwifi/iwl-agn-rx.c
View file @
d896d463
...
...
@@ -581,7 +581,7 @@ static int iwlagn_rx_statistics(struct iwl_priv *priv,
if
(
unlikely
(
!
test_bit
(
STATUS_SCANNING
,
&
priv
->
shrd
->
status
))
&&
(
pkt
->
hdr
.
cmd
==
STATISTICS_NOTIFICATION
))
{
iwlagn_rx_calc_noise
(
priv
);
queue_work
(
priv
->
shrd
->
workqueue
,
&
priv
->
run_time_calib_work
);
queue_work
(
priv
->
workqueue
,
&
priv
->
run_time_calib_work
);
}
if
(
cfg
(
priv
)
->
lib
->
temperature
&&
change
)
cfg
(
priv
)
->
lib
->
temperature
(
priv
);
...
...
drivers/net/wireless/iwlwifi/iwl-agn-rxon.c
View file @
d896d463
...
...
@@ -900,6 +900,22 @@ void iwlagn_bss_info_changed(struct ieee80211_hw *hw,
}
}
/*
* If the ucode decides to do beacon filtering before
* association, it will lose beacons that are needed
* before sending frames out on passive channels. This
* causes association failures on those channels. Enable
* receiving beacons in such cases.
*/
if
(
vif
->
type
==
NL80211_IFTYPE_STATION
)
{
if
(
!
bss_conf
->
assoc
)
ctx
->
staging
.
filter_flags
|=
RXON_FILTER_BCON_AWARE_MSK
;
else
ctx
->
staging
.
filter_flags
&=
~
RXON_FILTER_BCON_AWARE_MSK
;
}
if
(
force
||
memcmp
(
&
ctx
->
staging
,
&
ctx
->
active
,
sizeof
(
ctx
->
staging
)))
iwlagn_commit_rxon
(
priv
,
ctx
);
...
...
drivers/net/wireless/iwlwifi/iwl-agn-tt.c
View file @
d896d463
...
...
@@ -568,7 +568,7 @@ void iwl_tt_enter_ct_kill(struct iwl_priv *priv)
return
;
IWL_DEBUG_TEMP
(
priv
,
"Queueing critical temperature enter.
\n
"
);
queue_work
(
priv
->
shrd
->
workqueue
,
&
priv
->
ct_enter
);
queue_work
(
priv
->
workqueue
,
&
priv
->
ct_enter
);
}
void
iwl_tt_exit_ct_kill
(
struct
iwl_priv
*
priv
)
...
...
@@ -577,7 +577,7 @@ void iwl_tt_exit_ct_kill(struct iwl_priv *priv)
return
;
IWL_DEBUG_TEMP
(
priv
,
"Queueing critical temperature exit.
\n
"
);
queue_work
(
priv
->
shrd
->
workqueue
,
&
priv
->
ct_exit
);
queue_work
(
priv
->
workqueue
,
&
priv
->
ct_exit
);
}
static
void
iwl_bg_tt_work
(
struct
work_struct
*
work
)
...
...
@@ -600,7 +600,7 @@ void iwl_tt_handler(struct iwl_priv *priv)
return
;
IWL_DEBUG_TEMP
(
priv
,
"Queueing thermal throttling work.
\n
"
);
queue_work
(
priv
->
shrd
->
workqueue
,
&
priv
->
tt_work
);
queue_work
(
priv
->
workqueue
,
&
priv
->
tt_work
);
}
/* Thermal throttling initialization
...
...
drivers/net/wireless/iwlwifi/iwl-agn-tx.c
View file @
d896d463
...
...
@@ -983,7 +983,7 @@ static void iwl_check_abort_status(struct iwl_priv *priv,
if
(
frame_count
==
1
&&
status
==
TX_STATUS_FAIL_RFKILL_FLUSH
)
{
IWL_ERR
(
priv
,
"Tx flush command to flush out all frames
\n
"
);
if
(
!
test_bit
(
STATUS_EXIT_PENDING
,
&
priv
->
shrd
->
status
))
queue_work
(
priv
->
shrd
->
workqueue
,
&
priv
->
tx_flush
);
queue_work
(
priv
->
workqueue
,
&
priv
->
tx_flush
);
}
}
...
...
drivers/net/wireless/iwlwifi/iwl-agn.c
View file @
d896d463
...
...
@@ -618,7 +618,7 @@ static int iwlagn_send_tx_ant_config(struct iwl_priv *priv, u8 valid_tx_ant)
.
valid
=
cpu_to_le32
(
valid_tx_ant
),
};
if
(
IWL_UCODE_API
(
priv
->
ucode_ver
)
>
1
)
{
if
(
IWL_UCODE_API
(
nic
(
priv
)
->
fw
.
ucode_ver
)
>
1
)
{
IWL_DEBUG_HC
(
priv
,
"select valid tx ant: %u
\n
"
,
valid_tx_ant
);
return
iwl_trans_send_cmd_pdu
(
trans
(
priv
),
TX_ANT_CONFIGURATION_CMD
,
...
...
@@ -738,14 +738,14 @@ int iwl_alive_start(struct iwl_priv *priv)
return
iwl_power_update_mode
(
priv
,
true
);
}
static
void
iwl_cancel_deferred_work
(
struct
iwl_priv
*
priv
);
void
__iwl_down
(
struct
iwl_priv
*
priv
)
void
iwl_down
(
struct
iwl_priv
*
priv
)
{
int
exit_pending
;
IWL_DEBUG_INFO
(
priv
,
DRV_NAME
" is going down
\n
"
);
lockdep_assert_held
(
&
priv
->
shrd
->
mutex
);
iwl_scan_cancel_timeout
(
priv
,
200
);
/*
...
...
@@ -803,15 +803,6 @@ void __iwl_down(struct iwl_priv *priv)
priv
->
beacon_skb
=
NULL
;
}
void
iwl_down
(
struct
iwl_priv
*
priv
)
{
mutex_lock
(
&
priv
->
shrd
->
mutex
);
__iwl_down
(
priv
);
mutex_unlock
(
&
priv
->
shrd
->
mutex
);
iwl_cancel_deferred_work
(
priv
);
}
/*****************************************************************************
*
* Workqueue callbacks
...
...
@@ -869,7 +860,7 @@ void iwlagn_prepare_restart(struct iwl_priv *priv)
bt_status
=
priv
->
bt_status
;
bt_is_sco
=
priv
->
bt_is_sco
;
__
iwl_down
(
priv
);
iwl_down
(
priv
);
priv
->
bt_full_concurrent
=
bt_full_concurrent
;
priv
->
bt_ci_compliance
=
bt_ci_compliance
;
...
...
@@ -939,7 +930,7 @@ static void iwlagn_disable_roc_work(struct work_struct *work)
static
void
iwl_setup_deferred_work
(
struct
iwl_priv
*
priv
)
{
priv
->
shrd
->
workqueue
=
create_singlethread_workqueue
(
DRV_NAME
);
priv
->
workqueue
=
create_singlethread_workqueue
(
DRV_NAME
);
init_waitqueue_head
(
&
priv
->
shrd
->
wait_command_queue
);
...
...
@@ -970,7 +961,7 @@ static void iwl_setup_deferred_work(struct iwl_priv *priv)
priv
->
watchdog
.
function
=
iwl_bg_watchdog
;
}
static
void
iwl_cancel_deferred_work
(
struct
iwl_priv
*
priv
)
void
iwl_cancel_deferred_work
(
struct
iwl_priv
*
priv
)
{
if
(
cfg
(
priv
)
->
lib
->
cancel_deferred_work
)
cfg
(
priv
)
->
lib
->
cancel_deferred_work
(
priv
);
...
...
@@ -1091,7 +1082,7 @@ static void iwl_uninit_drv(struct iwl_priv *priv)
#define IWL_RX_BUF_SIZE_4K (4 * 1024)
#define IWL_RX_BUF_SIZE_8K (8 * 1024)
static
int
iwl_set_hw_params
(
struct
iwl_priv
*
priv
)
static
void
iwl_set_hw_params
(
struct
iwl_priv
*
priv
)
{
if
(
iwlagn_mod_params
.
amsdu_size_8K
)
hw_params
(
priv
).
rx_page_order
=
...
...
@@ -1111,7 +1102,7 @@ static int iwl_set_hw_params(struct iwl_priv *priv)
hw_params
(
priv
).
wd_timeout
=
cfg
(
priv
)
->
base_params
->
wd_timeout
;
/* Device-specific setup */
return
cfg
(
priv
)
->
lib
->
set_hw_params
(
priv
);
cfg
(
priv
)
->
lib
->
set_hw_params
(
priv
);
}
...
...
@@ -1248,11 +1239,7 @@ int iwl_probe(struct iwl_bus *bus, const struct iwl_trans_ops *trans_ops,
/************************
* 5. Setup HW constants
************************/
if
(
iwl_set_hw_params
(
priv
))
{
err
=
-
ENOENT
;
IWL_ERR
(
priv
,
"failed to set hw parameters
\n
"
);
goto
out_free_eeprom
;
}
iwl_set_hw_params
(
priv
);
/*******************
* 6. Setup priv
...
...
@@ -1273,17 +1260,17 @@ int iwl_probe(struct iwl_bus *bus, const struct iwl_trans_ops *trans_ops,
iwl_power_initialize
(
priv
);
iwl_tt_initialize
(
priv
);
init_completion
(
&
priv
->
firmware_loading
_complete
);
init_completion
(
&
nic
(
priv
)
->
request_firmware
_complete
);
err
=
iwl_request_firmware
(
priv
,
true
);
err
=
iwl_request_firmware
(
nic
(
priv
)
,
true
);
if
(
err
)
goto
out_destroy_workqueue
;
return
0
;
out_destroy_workqueue:
destroy_workqueue
(
priv
->
shrd
->
workqueue
);
priv
->
shrd
->
workqueue
=
NULL
;
destroy_workqueue
(
priv
->
workqueue
);
priv
->
workqueue
=
NULL
;
iwl_uninit_drv
(
priv
);
out_free_eeprom:
iwl_eeprom_free
(
priv
->
shrd
);
...
...
@@ -1296,7 +1283,7 @@ int iwl_probe(struct iwl_bus *bus, const struct iwl_trans_ops *trans_ops,
void
__devexit
iwl_remove
(
struct
iwl_priv
*
priv
)
{
wait_for_completion
(
&
priv
->
firmware_loading
_complete
);
wait_for_completion
(
&
nic
(
priv
)
->
request_firmware
_complete
);
IWL_DEBUG_INFO
(
priv
,
"*** UNLOAD DRIVER ***
\n
"
);
...
...
@@ -1316,18 +1303,18 @@ void __devexit iwl_remove(struct iwl_priv * priv)
/*This will stop the queues, move the device to low power state */
iwl_trans_stop_device
(
trans
(
priv
));
iwl_dealloc_ucode
(
trans
(
priv
));
iwl_dealloc_ucode
(
nic
(
priv
));
iwl_eeprom_free
(
priv
->
shrd
);
/*netif_stop_queue(dev); */
flush_workqueue
(
priv
->
shrd
->
workqueue
);
flush_workqueue
(
priv
->
workqueue
);
/* ieee80211_unregister_hw calls iwlagn_mac_stop, which flushes
* priv->
shrd->
workqueue... so we can't take down the workqueue
* priv->workqueue... so we can't take down the workqueue
* until now... */
destroy_workqueue
(
priv
->
shrd
->
workqueue
);
priv
->
shrd
->
workqueue
=
NULL
;
destroy_workqueue
(
priv
->
workqueue
);
priv
->
workqueue
=
NULL
;
iwl_free_traffic_mem
(
priv
);
iwl_uninit_drv
(
priv
);
...
...
drivers/net/wireless/iwlwifi/iwl-agn.h
View file @
d896d463
...
...
@@ -65,11 +65,7 @@
#include "iwl-dev.h"
struct
iwlagn_ucode_capabilities
{
u32
max_probe_length
;
u32
standard_phy_calibration_size
;
u32
flags
;
};
struct
iwl_ucode_capabilities
;
extern
struct
ieee80211_ops
iwlagn_hw_ops
;
...
...
@@ -81,14 +77,14 @@ static inline void iwl_set_calib_hdr(struct iwl_calib_hdr *hdr, u8 cmd)
hdr
->
data_valid
=
1
;
}
void
__iwl_down
(
struct
iwl_priv
*
priv
);
void
iwl_down
(
struct
iwl_priv
*
priv
);
void
iwl_cancel_deferred_work
(
struct
iwl_priv
*
priv
);
void
iwlagn_prepare_restart
(
struct
iwl_priv
*
priv
);
/* MAC80211 */
struct
ieee80211_hw
*
iwl_alloc_all
(
void
);
int
iwlagn_mac_setup_register
(
struct
iwl_priv
*
priv
,
struct
iwl
agn
_ucode_capabilities
*
capa
);
struct
iwl_ucode_capabilities
*
capa
);
void
iwlagn_mac_unregister
(
struct
iwl_priv
*
priv
);
/* RXON */
...
...
drivers/net/wireless/iwlwifi/iwl-core.c
View file @
d896d463
...
...
@@ -643,7 +643,7 @@ u8 iwl_get_single_channel_number(struct iwl_priv *priv,
* NOTE: Does not commit to the hardware; it sets appropriate bit fields
* in the staging RXON flag structure based on the ch->band
*/
int
iwl_set_rxon_channel
(
struct
iwl_priv
*
priv
,
struct
ieee80211_channel
*
ch
,
void
iwl_set_rxon_channel
(
struct
iwl_priv
*
priv
,
struct
ieee80211_channel
*
ch
,
struct
iwl_rxon_context
*
ctx
)
{
enum
ieee80211_band
band
=
ch
->
band
;
...
...
@@ -651,7 +651,7 @@ int iwl_set_rxon_channel(struct iwl_priv *priv, struct ieee80211_channel *ch,
if
((
le16_to_cpu
(
ctx
->
staging
.
channel
)
==
channel
)
&&
(
priv
->
band
==
band
))
return
0
;
return
;
ctx
->
staging
.
channel
=
cpu_to_le16
(
channel
);
if
(
band
==
IEEE80211_BAND_5GHZ
)
...
...
@@ -663,7 +663,6 @@ int iwl_set_rxon_channel(struct iwl_priv *priv, struct ieee80211_channel *ch,
IWL_DEBUG_INFO
(
priv
,
"Staging channel set to %d [%d]
\n
"
,
channel
,
band
);
return
0
;
}
void
iwl_set_flags_for_band
(
struct
iwl_priv
*
priv
,
...
...
@@ -875,7 +874,7 @@ void iwlagn_fw_error(struct iwl_priv *priv, bool ondemand)
if
(
iwlagn_mod_params
.
restart_fw
)
{
IWL_DEBUG_FW_ERRORS
(
priv
,
"Restarting adapter due to uCode error.
\n
"
);
queue_work
(
priv
->
shrd
->
workqueue
,
&
priv
->
restart
);
queue_work
(
priv
->
workqueue
,
&
priv
->
restart
);
}
else
IWL_DEBUG_FW_ERRORS
(
priv
,
"Detected FW error, but not restarting
\n
"
);
...
...
drivers/net/wireless/iwlwifi/iwl-core.h
View file @
d896d463
...
...
@@ -76,7 +76,7 @@ struct iwl_cmd;
struct
iwl_lib_ops
{
/* set hw dependent parameters */
int
(
*
set_hw_params
)(
struct
iwl_priv
*
priv
);
void
(
*
set_hw_params
)(
struct
iwl_priv
*
priv
);
/* setup BT Rx handler */
void
(
*
bt_rx_handler_setup
)(
struct
iwl_priv
*
priv
);
/* setup BT related deferred work */
...
...
@@ -169,7 +169,7 @@ void iwl_set_rxon_hwcrypto(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
int
hw_decrypt
);
int
iwl_check_rxon_cmd
(
struct
iwl_priv
*
priv
,
struct
iwl_rxon_context
*
ctx
);
int
iwl_full_rxon_required
(
struct
iwl_priv
*
priv
,
struct
iwl_rxon_context
*
ctx
);
int
iwl_set_rxon_channel
(
struct
iwl_priv
*
priv
,
struct
ieee80211_channel
*
ch
,
void
iwl_set_rxon_channel
(
struct
iwl_priv
*
priv
,
struct
ieee80211_channel
*
ch
,
struct
iwl_rxon_context
*
ctx
);
void
iwl_set_flags_for_band
(
struct
iwl_priv
*
priv
,
struct
iwl_rxon_context
*
ctx
,
...
...
drivers/net/wireless/iwlwifi/iwl-debug.c
0 → 100644
View file @
d896d463
/******************************************************************************
*
* This file is provided under a dual BSD/GPLv2 license. When using or
* redistributing this file, you may do so under either license.
*
* GPL LICENSE SUMMARY
*
* Copyright(c) 2007 - 2011 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
* USA
*
* The full GNU General Public License is included in this distribution
* in the file called LICENSE.GPL.
*
* Contact Information:
* Intel Linux Wireless <ilw@linux.intel.com>
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
*
* BSD LICENSE
*
* Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* * Neither the name Intel Corporation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*****************************************************************************/
#include <linux/interrupt.h>
#include "iwl-debug.h"
#define __iwl_fn(fn) \
void __iwl_ ##fn(struct device *dev, const char *fmt, ...) \
{ \
struct va_format vaf = { \
.fmt = fmt, \
}; \
va_list args; \
\
va_start(args, fmt); \
vaf.va = &args; \
dev_ ##fn(dev, "%pV", &vaf); \
trace_iwlwifi_ ##fn(&vaf); \
va_end(args); \
}
__iwl_fn
(
warn
)
__iwl_fn
(
info
)
__iwl_fn
(
crit
)
void
__iwl_err
(
struct
device
*
dev
,
bool
rfkill_prefix
,
bool
trace_only
,
const
char
*
fmt
,
...)
{
struct
va_format
vaf
=
{
.
fmt
=
fmt
,
};
va_list
args
;
va_start
(
args
,
fmt
);
vaf
.
va
=
&
args
;
if
(
!
trace_only
)
{
if
(
rfkill_prefix
)
dev_err
(
dev
,
"(RFKILL) %pV"
,
&
vaf
);
else
dev_err
(
dev
,
"%pV"
,
&
vaf
);
}
trace_iwlwifi_err
(
&
vaf
);
va_end
(
args
);
}
#if defined(CONFIG_IWLWIFI_DEBUG) || defined(CONFIG_IWLWIFI_DEVICE_TRACING)
void
__iwl_dbg
(
struct
iwl_shared
*
shared
,
struct
device
*
dev
,
u32
level
,
bool
limit
,
const
char
*
function
,
const
char
*
fmt
,
...)
{
struct
va_format
vaf
=
{
.
fmt
=
fmt
,
};
va_list
args
;
va_start
(
args
,
fmt
);
vaf
.
va
=
&
args
;
#ifdef CONFIG_IWLWIFI_DEBUG
if
(
iwl_get_debug_level
(
shared
)
&
level
&&
(
!
limit
||
net_ratelimit
()))
dev_err
(
dev
,
"%c %s %pV"
,
in_interrupt
()
?
'I'
:
'U'
,
function
,
&
vaf
);
#endif
trace_iwlwifi_dbg
(
level
,
in_interrupt
(),
function
,
&
vaf
);
va_end
(
args
);
}
#endif
drivers/net/wireless/iwlwifi/iwl-debug.h
View file @
d896d463
...
...
@@ -31,14 +31,33 @@
#include "iwl-bus.h"
#include "iwl-shared.h"
#include "iwl-devtrace.h"
struct
iwl_priv
;
/*No matter what is m (priv, bus, trans), this will work */
#define IWL_ERR(m, f, a...) dev_err(trans(m)->dev, f, ## a)
#define IWL_WARN(m, f, a...) dev_warn(trans(m)->dev, f, ## a)
#define IWL_INFO(m, f, a...) dev_info(trans(m)->dev, f, ## a)
#define IWL_CRIT(m, f, a...) dev_crit(trans(m)->dev, f, ## a)
void
__iwl_err
(
struct
device
*
dev
,
bool
rfkill_prefix
,
bool
only_trace
,
const
char
*
fmt
,
...);
void
__iwl_warn
(
struct
device
*
dev
,
const
char
*
fmt
,
...);
void
__iwl_info
(
struct
device
*
dev
,
const
char
*
fmt
,
...);
void
__iwl_crit
(
struct
device
*
dev
,
const
char
*
fmt
,
...);
/* No matter what is m (priv, bus, trans), this will work */
#define IWL_ERR(m, f, a...) __iwl_err(trans(m)->dev, false, false, f, ## a)
#define IWL_WARN(m, f, a...) __iwl_warn(trans(m)->dev, f, ## a)
#define IWL_INFO(m, f, a...) __iwl_info(trans(m)->dev, f, ## a)
#define IWL_CRIT(m, f, a...) __iwl_crit(trans(m)->dev, f, ## a)
#if defined(CONFIG_IWLWIFI_DEBUG) || defined(CONFIG_IWLWIFI_DEVICE_TRACING)
void
__iwl_dbg
(
struct
iwl_shared
*
shared
,
struct
device
*
dev
,
u32
level
,
bool
limit
,
const
char
*
function
,
const
char
*
fmt
,
...);
#else
static
inline
void
__iwl_dbg
(
struct
iwl_shared
*
shared
,
struct
device
*
dev
,
u32
level
,
bool
limit
,
const
char
*
function
,
const
char
*
fmt
,
...)
{}
#endif
#define iwl_print_hex_error(m, p, len) \
do { \
...
...
@@ -46,53 +65,35 @@ do { \
DUMP_PREFIX_OFFSET, 16, 1, p, len, 1); \
} while (0)
#ifdef CONFIG_IWLWIFI_DEBUG
#define IWL_DEBUG(m, level, fmt, ...) \
do { \
if (iwl_get_debug_level((m)->shrd) & (level)) \
dev_err(trans(m)->dev, "%c %s " fmt, \
in_interrupt() ? 'I' : 'U', __func__, \
##__VA_ARGS__); \
} while (0)
#define IWL_DEBUG_LIMIT(m, level, fmt, ...) \
do { \
if (iwl_get_debug_level((m)->shrd) & (level) && \
net_ratelimit()) \
dev_err(trans(m)->dev, "%c %s " fmt, \
in_interrupt() ? 'I' : 'U', __func__, \
##__VA_ARGS__); \
} while (0)
#define IWL_DEBUG(m, level, fmt, args...) \
__iwl_dbg((m)->shrd, trans(m)->dev, level, false, __func__, fmt, ##args)
#define IWL_DEBUG_LIMIT(m, level, fmt, args...) \
__iwl_dbg((m)->shrd, trans(m)->dev, level, true, __func__, fmt, ##args)
#ifdef CONFIG_IWLWIFI_DEBUG
#define iwl_print_hex_dump(m, level, p, len) \
do { \
if (iwl_get_debug_level((m)->shrd) & level) \
print_hex_dump(KERN_DEBUG, "iwl data: ", \
DUMP_PREFIX_OFFSET, 16, 1, p, len, 1); \
} while (0)
#define IWL_DEBUG_QUIET_RFKILL(p, fmt, ...) \
#define IWL_DEBUG_QUIET_RFKILL(m, fmt, args...) \
do { \
if (!iwl_is_rfkill(p->shrd)) \
dev_err(trans(p)->dev, "%s%c %s " fmt, \
"", \
in_interrupt() ? 'I' : 'U', __func__, \
##__VA_ARGS__); \
else if (iwl_get_debug_level(p->shrd) & IWL_DL_RADIO) \
dev_err(trans(p)->dev, "%s%c %s " fmt, \
"(RFKILL) ", \
in_interrupt() ? 'I' : 'U', __func__, \
##__VA_ARGS__); \
if (!iwl_is_rfkill((m)->shrd)) \
IWL_ERR(m, fmt, ##args); \
else \
__iwl_err(trans(m)->dev, true, \
!(iwl_get_debug_level((m)->shrd) & IWL_DL_RADIO),\
fmt, ##args); \
} while (0)
#else
#define IWL_DEBUG(m, level, fmt, args...)
#define IWL_DEBUG_LIMIT(m, level, fmt, args...)
#define iwl_print_hex_dump(m, level, p, len)
#define IWL_DEBUG_QUIET_RFKILL(p, fmt, args...) \
do { \
if (!iwl_is_rfkill(p->shrd)) \
IWL_ERR(p, fmt, ##args); \
#define IWL_DEBUG_QUIET_RFKILL(m, fmt, args...) \
do { \
if (!iwl_is_rfkill((m)->shrd)) \
IWL_ERR(m, fmt, ##args); \
else \
__iwl_err(trans(m)->dev, true, true, fmt, ##args); \
} while (0)
#endif
/* CONFIG_IWLWIFI_DEBUG */
...
...
drivers/net/wireless/iwlwifi/iwl-debugfs.c
View file @
d896d463
...
...
@@ -40,6 +40,7 @@
#include "iwl-core.h"
#include "iwl-io.h"
#include "iwl-agn.h"
#include "iwl-wifi.h"
/* create and remove of files */
#define DEBUGFS_ADD_FILE(name, parent, mode) do { \
...
...
@@ -234,12 +235,12 @@ static ssize_t iwl_dbgfs_sram_read(struct file *file,
/* default is to dump the entire data segment */
if
(
!
priv
->
dbgfs_sram_offset
&&
!
priv
->
dbgfs_sram_len
)
{
struct
iwl_
trans
*
trans
=
trans
(
priv
);
struct
iwl_
nic
*
nic
=
nic
(
priv
);
priv
->
dbgfs_sram_offset
=
0x800000
;
if
(
trans
->
shrd
->
ucode_type
==
IWL_UCODE_INIT
)
priv
->
dbgfs_sram_len
=
trans
->
ucode_init
.
data
.
len
;
if
(
nic
->
shrd
->
ucode_type
==
IWL_UCODE_INIT
)
priv
->
dbgfs_sram_len
=
nic
->
fw
.
ucode_init
.
data
.
len
;
else
priv
->
dbgfs_sram_len
=
trans
->
ucode_rt
.
data
.
len
;
priv
->
dbgfs_sram_len
=
nic
->
fw
.
ucode_rt
.
data
.
len
;
}
len
=
priv
->
dbgfs_sram_len
;
...
...
@@ -342,7 +343,7 @@ static ssize_t iwl_dbgfs_wowlan_sram_read(struct file *file,
return
simple_read_from_buffer
(
user_buf
,
count
,
ppos
,
priv
->
wowlan_sram
,
trans
(
priv
)
->
ucode_wowlan
.
data
.
len
);
nic
(
priv
)
->
fw
.
ucode_wowlan
.
data
.
len
);
}
static
ssize_t
iwl_dbgfs_stations_read
(
struct
file
*
file
,
char
__user
*
user_buf
,
size_t
count
,
loff_t
*
ppos
)
...
...
drivers/net/wireless/iwlwifi/iwl-dev.h
View file @
d896d463
...
...
@@ -696,11 +696,11 @@ struct iwl_testmode_trace {
dma_addr_t
dma_addr
;
bool
trace_enabled
;
};
struct
iwl_testmode_
sra
m
{
struct
iwl_testmode_
me
m
{
u32
buff_size
;
u32
num_chunks
;
u8
*
buff_addr
;
bool
sram_readed
;
bool
read_in_progress
;
};
#endif
...
...
@@ -721,6 +721,8 @@ struct iwl_priv {
struct
ieee80211_rate
*
ieee_rates
;
struct
kmem_cache
*
tx_cmd_pool
;
struct
workqueue_struct
*
workqueue
;
enum
ieee80211_band
band
;
void
(
*
pre_rx_handler
)(
struct
iwl_priv
*
priv
,
...
...
@@ -785,13 +787,6 @@ struct iwl_priv {
/* EEPROM MAC addresses */
struct
mac_address
addresses
[
2
];
/* uCode images, save to reload in case of failure */
int
fw_index
;
/* firmware we're trying to load */
u32
ucode_ver
;
/* version of ucode, copy of
iwl_ucode.ver */
char
firmware_name
[
25
];
struct
iwl_rxon_context
contexts
[
NUM_IWL_RXON_CTX
];
__le16
switch_channel
;
...
...
@@ -801,7 +796,6 @@ struct iwl_priv {
u8
start_calib
;
struct
iwl_sensitivity_data
sensitivity_data
;
struct
iwl_chain_noise_data
chain_noise_data
;
bool
enhance_sensitivity_table
;
__le16
sensitivity_tbl
[
HD_TABLE_SIZE
];
__le16
enhance_sensitivity_tbl
[
ENHANCE_HD_TABLE_ENTRIES
];
...
...
@@ -869,11 +863,6 @@ struct iwl_priv {
struct
iwl_rx_phy_res
last_phy_res
;
bool
last_phy_res_valid
;
struct
completion
firmware_loading_complete
;
u32
init_evtlog_ptr
,
init_evtlog_size
,
init_errlog_ptr
;
u32
inst_evtlog_ptr
,
inst_evtlog_size
,
inst_errlog_ptr
;
/*
* chain noise reset and gain commands are the
* two extra calibration commands follows the standard
...
...
@@ -964,7 +953,7 @@ struct iwl_priv {
bool
led_registered
;
#ifdef CONFIG_IWLWIFI_DEVICE_TESTMODE
struct
iwl_testmode_trace
testmode_trace
;
struct
iwl_testmode_
sram
testmode_sra
m
;
struct
iwl_testmode_
mem
testmode_me
m
;
u32
tm_fixed_rate
;
#endif
...
...
drivers/net/wireless/iwlwifi/iwl-devtrace.h
View file @
d896d463
...
...
@@ -34,6 +34,11 @@
#undef TRACE_EVENT
#define TRACE_EVENT(name, proto, ...) \
static inline void trace_ ## name(proto) {}
#undef DECLARE_EVENT_CLASS
#define DECLARE_EVENT_CLASS(...)
#undef DEFINE_EVENT
#define DEFINE_EVENT(evt_class, name, proto, ...) \
static inline void trace_ ## name(proto) {}
#endif
#define PRIV_ENTRY __field(void *, priv)
...
...
@@ -163,6 +168,66 @@ TRACE_EVENT(iwlwifi_dev_ucode_wrap_event,
__entry
->
p_entry
)
);
#undef TRACE_SYSTEM
#define TRACE_SYSTEM iwlwifi_msg
#define MAX_MSG_LEN 100
DECLARE_EVENT_CLASS
(
iwlwifi_msg_event
,
TP_PROTO
(
struct
va_format
*
vaf
),
TP_ARGS
(
vaf
),
TP_STRUCT__entry
(
__dynamic_array
(
char
,
msg
,
MAX_MSG_LEN
)
),
TP_fast_assign
(
WARN_ON_ONCE
(
vsnprintf
(
__get_dynamic_array
(
msg
),
MAX_MSG_LEN
,
vaf
->
fmt
,
*
vaf
->
va
)
>=
MAX_MSG_LEN
);
),
TP_printk
(
"%s"
,
(
char
*
)
__get_dynamic_array
(
msg
))
);
DEFINE_EVENT
(
iwlwifi_msg_event
,
iwlwifi_err
,
TP_PROTO
(
struct
va_format
*
vaf
),
TP_ARGS
(
vaf
)
);
DEFINE_EVENT
(
iwlwifi_msg_event
,
iwlwifi_warn
,
TP_PROTO
(
struct
va_format
*
vaf
),
TP_ARGS
(
vaf
)
);
DEFINE_EVENT
(
iwlwifi_msg_event
,
iwlwifi_info
,
TP_PROTO
(
struct
va_format
*
vaf
),
TP_ARGS
(
vaf
)
);
DEFINE_EVENT
(
iwlwifi_msg_event
,
iwlwifi_crit
,
TP_PROTO
(
struct
va_format
*
vaf
),
TP_ARGS
(
vaf
)
);
TRACE_EVENT
(
iwlwifi_dbg
,
TP_PROTO
(
u32
level
,
bool
in_interrupt
,
const
char
*
function
,
struct
va_format
*
vaf
),
TP_ARGS
(
level
,
in_interrupt
,
function
,
vaf
),
TP_STRUCT__entry
(
__field
(
u32
,
level
)
__field
(
u8
,
in_interrupt
)
__string
(
function
,
function
)
__dynamic_array
(
char
,
msg
,
MAX_MSG_LEN
)
),
TP_fast_assign
(
__entry
->
level
=
level
;
__entry
->
in_interrupt
=
in_interrupt
;
__assign_str
(
function
,
function
);
WARN_ON_ONCE
(
vsnprintf
(
__get_dynamic_array
(
msg
),
MAX_MSG_LEN
,
vaf
->
fmt
,
*
vaf
->
va
)
>=
MAX_MSG_LEN
);
),
TP_printk
(
"%s"
,
(
char
*
)
__get_dynamic_array
(
msg
))
);
#undef TRACE_SYSTEM
#define TRACE_SYSTEM iwlwifi
...
...
drivers/net/wireless/iwlwifi/iwl-mac80211.c
View file @
d896d463
...
...
@@ -136,7 +136,7 @@ iwlagn_iface_combinations_p2p[] = {
* other mac80211 functions grouped here.
*/
int
iwlagn_mac_setup_register
(
struct
iwl_priv
*
priv
,
struct
iwl
agn
_ucode_capabilities
*
capa
)
struct
iwl_ucode_capabilities
*
capa
)
{
int
ret
;
struct
ieee80211_hw
*
hw
=
priv
->
hw
;
...
...
@@ -195,7 +195,7 @@ int iwlagn_mac_setup_register(struct iwl_priv *priv,
WIPHY_FLAG_DISABLE_BEACON_HINTS
|
WIPHY_FLAG_IBSS_RSN
;
if
(
trans
(
priv
)
->
ucode_wowlan
.
code
.
len
&&
if
(
nic
(
priv
)
->
fw
.
ucode_wowlan
.
code
.
len
&&
device_can_wakeup
(
trans
(
priv
)
->
dev
))
{
hw
->
wiphy
->
wowlan
.
flags
=
WIPHY_WOWLAN_MAGIC_PKT
|
WIPHY_WOWLAN_DISCONNECT
|
...
...
@@ -296,7 +296,7 @@ static int __iwl_up(struct iwl_priv *priv)
error:
set_bit
(
STATUS_EXIT_PENDING
,
&
priv
->
shrd
->
status
);
__
iwl_down
(
priv
);
iwl_down
(
priv
);
clear_bit
(
STATUS_EXIT_PENDING
,
&
priv
->
shrd
->
status
);
IWL_ERR
(
priv
,
"Unable to initialize device.
\n
"
);
...
...
@@ -341,9 +341,13 @@ static void iwlagn_mac_stop(struct ieee80211_hw *hw)
priv
->
is_open
=
0
;
mutex_lock
(
&
priv
->
shrd
->
mutex
);
iwl_down
(
priv
);
mutex_unlock
(
&
priv
->
shrd
->
mutex
);
iwl_cancel_deferred_work
(
priv
);
flush_workqueue
(
priv
->
shrd
->
workqueue
);
flush_workqueue
(
priv
->
workqueue
);
/* User space software may expect getting rfkill changes
* even if interface is down, trans->down will leave the RF
...
...
@@ -453,17 +457,17 @@ static int iwlagn_mac_resume(struct ieee80211_hw *hw)
#ifdef CONFIG_IWLWIFI_DEBUGFS
if
(
ret
==
0
)
{
struct
iwl_
trans
*
trans
=
trans
(
priv
);
struct
iwl_
nic
*
nic
=
nic
(
priv
);
if
(
!
priv
->
wowlan_sram
)
priv
->
wowlan_sram
=
kzalloc
(
trans
->
ucode_wowlan
.
data
.
len
,
kzalloc
(
nic
->
fw
.
ucode_wowlan
.
data
.
len
,
GFP_KERNEL
);
if
(
priv
->
wowlan_sram
)
_iwl_read_targ_mem_words
(
trans
(
priv
),
0x800000
,
priv
->
wowlan_sram
,
trans
->
ucode_wowlan
.
data
.
len
/
4
);
nic
->
fw
.
ucode_wowlan
.
data
.
len
/
4
);
}
#endif
}
...
...
@@ -1117,7 +1121,7 @@ static int iwlagn_mac_set_tim(struct ieee80211_hw *hw,
{
struct
iwl_priv
*
priv
=
hw
->
priv
;
queue_work
(
priv
->
shrd
->
workqueue
,
&
priv
->
beacon_update
);
queue_work
(
priv
->
workqueue
,
&
priv
->
beacon_update
);
return
0
;
}
...
...
drivers/net/wireless/iwlwifi/iwl-pci.c
View file @
d896d463
...
...
@@ -70,6 +70,7 @@
#include "iwl-trans.h"
#include "iwl-csr.h"
#include "iwl-cfg.h"
#include "iwl-wifi.h"
#define IWL_PCI_DEVICE(dev, subdev, cfg) \
.vendor = PCI_VENDOR_ID_INTEL, .device = (dev), \
...
...
@@ -282,13 +283,23 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
bus
->
shrd
->
bus
=
bus
;
/* temporarily create this here */
bus
->
shrd
->
nic
=
kzalloc
(
sizeof
(
*
bus
->
shrd
->
nic
),
GFP_KERNEL
);
if
(
!
bus
->
shrd
->
nic
)
{
dev_printk
(
KERN_ERR
,
&
pdev
->
dev
,
"Couldn't allocate iwl_nic"
);
err
=
-
ENOMEM
;
goto
out_free_bus
;
}
/* and initialize it as well, temporarily */
bus
->
shrd
->
nic
->
shrd
=
bus
->
shrd
;
pci_set_drvdata
(
pdev
,
bus
);
#ifdef CONFIG_IWLWIFI_IDI
trans
(
bus
)
=
iwl_trans_idi_alloc
(
bus
->
shrd
,
pdev
,
ent
);
if
(
trans
(
bus
)
==
NULL
)
{
err
=
-
ENOMEM
;
goto
out_free_
bus
;
goto
out_free_
nic
;
}
err
=
iwl_probe
(
bus
,
&
trans_ops_idi
,
cfg
);
...
...
@@ -296,7 +307,7 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
trans
(
bus
)
=
iwl_trans_pcie_alloc
(
bus
->
shrd
,
pdev
,
ent
);
if
(
trans
(
bus
)
==
NULL
)
{
err
=
-
ENOMEM
;
goto
out_free_
bus
;
goto
out_free_
nic
;
}
err
=
iwl_probe
(
bus
,
&
trans_ops_pcie
,
cfg
);
...
...
@@ -309,6 +320,8 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
out_free_trans:
iwl_trans_free
(
trans
(
bus
));
pci_set_drvdata
(
pdev
,
NULL
);
out_free_nic:
kfree
(
bus
->
shrd
->
nic
);
out_free_bus:
kfree
(
bus
->
shrd
);
kfree
(
bus
);
...
...
@@ -325,6 +338,7 @@ static void __devexit iwl_pci_remove(struct pci_dev *pdev)
pci_set_drvdata
(
pdev
,
NULL
);
kfree
(
bus
->
shrd
->
nic
);
kfree
(
bus
->
shrd
);
kfree
(
bus
);
}
...
...
drivers/net/wireless/iwlwifi/iwl-scan.c
View file @
d896d463
...
...
@@ -218,7 +218,7 @@ static void iwl_do_scan_abort(struct iwl_priv *priv)
int
iwl_scan_cancel
(
struct
iwl_priv
*
priv
)
{
IWL_DEBUG_SCAN
(
priv
,
"Queuing abort scan
\n
"
);
queue_work
(
priv
->
shrd
->
workqueue
,
&
priv
->
abort_scan
);
queue_work
(
priv
->
workqueue
,
&
priv
->
abort_scan
);
return
0
;
}
...
...
@@ -354,7 +354,7 @@ static int iwl_rx_scan_complete_notif(struct iwl_priv *priv,
*/
set_bit
(
STATUS_SCAN_COMPLETE
,
&
priv
->
shrd
->
status
);
clear_bit
(
STATUS_SCAN_HW
,
&
priv
->
shrd
->
status
);
queue_work
(
priv
->
shrd
->
workqueue
,
&
priv
->
scan_completed
);
queue_work
(
priv
->
workqueue
,
&
priv
->
scan_completed
);
if
(
priv
->
iw_mode
!=
NL80211_IFTYPE_ADHOC
&&
iwl_advanced_bt_coexist
(
priv
)
&&
...
...
@@ -374,7 +374,7 @@ static int iwl_rx_scan_complete_notif(struct iwl_priv *priv,
IWL_BT_COEX_TRAFFIC_LOAD_NONE
;
}
priv
->
bt_status
=
scan_notif
->
bt_status
;
queue_work
(
priv
->
shrd
->
workqueue
,
queue_work
(
priv
->
workqueue
,
&
priv
->
bt_traffic_change_work
);
}
return
0
;
...
...
@@ -950,7 +950,7 @@ int __must_check iwl_scan_initiate(struct iwl_priv *priv,
return
ret
;
}
queue_delayed_work
(
priv
->
shrd
->
workqueue
,
&
priv
->
scan_check
,
queue_delayed_work
(
priv
->
workqueue
,
&
priv
->
scan_check
,
IWL_SCAN_CHECK_WATCHDOG
);
return
0
;
...
...
@@ -963,7 +963,7 @@ int __must_check iwl_scan_initiate(struct iwl_priv *priv,
*/
void
iwl_internal_short_hw_scan
(
struct
iwl_priv
*
priv
)
{
queue_work
(
priv
->
shrd
->
workqueue
,
&
priv
->
start_internal_scan
);
queue_work
(
priv
->
workqueue
,
&
priv
->
start_internal_scan
);
}
static
void
iwl_bg_start_internal_scan
(
struct
work_struct
*
work
)
...
...
drivers/net/wireless/iwlwifi/iwl-shared.h
View file @
d896d463
...
...
@@ -173,8 +173,6 @@ struct iwl_mod_params {
* @ht40_channel: is 40MHz width possible: BIT(IEEE80211_BAND_XXX)
* @sku: sku read from EEPROM
* @rx_page_order: Rx buffer page order
* @max_inst_size: for ucode use
* @max_data_size: for ucode use
* @ct_kill_threshold: temperature threshold - in hw dependent unit
* @ct_kill_exit_threshold: when to reeable the device - in hw dependent unit
* relevant for 1000, 6000 and up
...
...
@@ -192,8 +190,6 @@ struct iwl_hw_params {
bool
shadow_reg_enable
;
u16
sku
;
u32
rx_page_order
;
u32
max_inst_size
;
u32
max_data_size
;
u32
ct_kill_threshold
;
u32
ct_kill_exit_threshold
;
unsigned
int
wd_timeout
;
...
...
@@ -283,6 +279,8 @@ enum iwl_led_mode {
* @ucode_api_ok: oldest version of the uCode API that is OK to load
* without a warning, for use in transitions
* @ucode_api_min: Lowest version of uCode API supported by driver.
* @max_inst_size: The maximal length of the fw inst section
* @max_data_size: The maximal length of the fw data section
* @valid_tx_ant: valid transmit antenna
* @valid_rx_ant: valid receive antenna
* @sku: sku information from EEPROM
...
...
@@ -320,6 +318,8 @@ struct iwl_cfg {
const
unsigned
int
ucode_api_max
;
const
unsigned
int
ucode_api_ok
;
const
unsigned
int
ucode_api_min
;
const
u32
max_data_size
;
const
u32
max_inst_size
;
u8
valid_tx_ant
;
u8
valid_rx_ant
;
u16
sku
;
...
...
@@ -358,8 +358,8 @@ struct iwl_cfg {
* @cfg: see struct iwl_cfg
* @priv: pointer to the upper layer data
* @trans: pointer to the transport layer data
* @nic: pointer to the nic data
* @hw_params: see struct iwl_hw_params
* @workqueue: the workqueue used by all the layers of the driver
* @lock: protect general shared data
* @sta_lock: protects the station table.
* If lock and sta_lock are needed, lock must be acquired first.
...
...
@@ -389,9 +389,9 @@ struct iwl_shared {
struct
iwl_cfg
*
cfg
;
struct
iwl_priv
*
priv
;
struct
iwl_trans
*
trans
;
struct
iwl_nic
*
nic
;
struct
iwl_hw_params
hw_params
;
struct
workqueue_struct
*
workqueue
;
spinlock_t
lock
;
spinlock_t
sta_lock
;
struct
mutex
mutex
;
...
...
@@ -420,6 +420,7 @@ struct iwl_shared {
#define priv(_m) ((_m)->shrd->priv)
#define cfg(_m) ((_m)->shrd->cfg)
#define bus(_m) ((_m)->shrd->bus)
#define nic(_m) ((_m)->shrd->nic)
#define trans(_m) ((_m)->shrd->trans)
#define hw_params(_m) ((_m)->shrd->hw_params)
...
...
drivers/net/wireless/iwlwifi/iwl-testmode.c
View file @
d896d463
...
...
@@ -81,6 +81,13 @@
#include "iwl-bus.h"
#include "iwl-fh.h"
/* Periphery registers absolute lower bound. This is used in order to
* differentiate registery access through HBUS_TARG_PRPH_* and
* HBUS_TARG_MEM_* accesses.
*/
#define IWL_TM_ABS_PRPH_START (0xA00000)
/* The TLVs used in the gnl message policy between the kernel module and
* user space application. iwl_testmode_gnl_msg_policy is to be carried
* through the NL80211_CMD_TESTMODE channel regulated by nl80211.
...
...
@@ -110,9 +117,9 @@ struct nla_policy iwl_testmode_gnl_msg_policy[IWL_TM_ATTR_MAX] = {
[
IWL_TM_ATTR_UCODE_OWNER
]
=
{
.
type
=
NLA_U8
,
},
[
IWL_TM_ATTR_
SRA
M_ADDR
]
=
{
.
type
=
NLA_U32
,
},
[
IWL_TM_ATTR_
SRAM
_SIZE
]
=
{
.
type
=
NLA_U32
,
},
[
IWL_TM_ATTR_
SRAM
_DUMP
]
=
{
.
type
=
NLA_UNSPEC
,
},
[
IWL_TM_ATTR_
ME
M_ADDR
]
=
{
.
type
=
NLA_U32
,
},
[
IWL_TM_ATTR_
BUFFER
_SIZE
]
=
{
.
type
=
NLA_U32
,
},
[
IWL_TM_ATTR_
BUFFER
_DUMP
]
=
{
.
type
=
NLA_UNSPEC
,
},
[
IWL_TM_ATTR_FW_VERSION
]
=
{
.
type
=
NLA_U32
,
},
[
IWL_TM_ATTR_DEVICE_ID
]
=
{
.
type
=
NLA_U32
,
},
...
...
@@ -172,7 +179,7 @@ static void iwl_testmode_ucode_rx_pkt(struct iwl_priv *priv,
skb
=
cfg80211_testmode_alloc_event_skb
(
hw
->
wiphy
,
20
+
length
,
GFP_ATOMIC
);
if
(
skb
==
NULL
)
{
IWL_
DEBUG_INFO
(
priv
,
IWL_
ERR
(
priv
,
"Run out of memory for messages to user space ?
\n
"
);
return
;
}
...
...
@@ -183,24 +190,24 @@ static void iwl_testmode_ucode_rx_pkt(struct iwl_priv *priv,
nla_put_failure:
kfree_skb
(
skb
);
IWL_
DEBUG_INFO
(
priv
,
"Ouch, overran buffer, check allocation!
\n
"
);
IWL_
ERR
(
priv
,
"Ouch, overran buffer, check allocation!
\n
"
);
}
void
iwl_testmode_init
(
struct
iwl_priv
*
priv
)
{
priv
->
pre_rx_handler
=
iwl_testmode_ucode_rx_pkt
;
priv
->
testmode_trace
.
trace_enabled
=
false
;
priv
->
testmode_
sram
.
sram_readed
=
false
;
priv
->
testmode_
mem
.
read_in_progress
=
false
;
}
static
void
iwl_
sra
m_cleanup
(
struct
iwl_priv
*
priv
)
static
void
iwl_
me
m_cleanup
(
struct
iwl_priv
*
priv
)
{
if
(
priv
->
testmode_
sram
.
sram_readed
)
{
kfree
(
priv
->
testmode_
sra
m
.
buff_addr
);
priv
->
testmode_
sra
m
.
buff_addr
=
NULL
;
priv
->
testmode_
sra
m
.
buff_size
=
0
;
priv
->
testmode_
sra
m
.
num_chunks
=
0
;
priv
->
testmode_
sram
.
sram_readed
=
false
;
if
(
priv
->
testmode_
mem
.
read_in_progress
)
{
kfree
(
priv
->
testmode_
me
m
.
buff_addr
);
priv
->
testmode_
me
m
.
buff_addr
=
NULL
;
priv
->
testmode_
me
m
.
buff_size
=
0
;
priv
->
testmode_
me
m
.
num_chunks
=
0
;
priv
->
testmode_
mem
.
read_in_progress
=
false
;
}
}
...
...
@@ -226,9 +233,10 @@ static void iwl_trace_cleanup(struct iwl_priv *priv)
void
iwl_testmode_cleanup
(
struct
iwl_priv
*
priv
)
{
iwl_trace_cleanup
(
priv
);
iwl_
sra
m_cleanup
(
priv
);
iwl_
me
m_cleanup
(
priv
);
}
/*
* This function handles the user application commands to the ucode.
*
...
...
@@ -237,8 +245,10 @@ void iwl_testmode_cleanup(struct iwl_priv *priv)
* host command to the ucode.
*
* If any mandatory field is missing, -ENOMSG is replied to the user space
* application; otherwise, the actual execution result of the host command to
* ucode is replied.
* application; otherwise, waits for the host command to be sent and checks
* the return code. In case or error, it is returned, otherwise a reply is
* allocated and the reply RX packet
* is returned.
*
* @hw: ieee80211_hw object that represents the device
* @tb: gnl message fields from the user space
...
...
@@ -247,25 +257,68 @@ static int iwl_testmode_ucode(struct ieee80211_hw *hw, struct nlattr **tb)
{
struct
iwl_priv
*
priv
=
hw
->
priv
;
struct
iwl_host_cmd
cmd
;
struct
iwl_rx_packet
*
pkt
;
struct
sk_buff
*
skb
;
void
*
reply_buf
;
u32
reply_len
;
int
ret
;
bool
cmd_want_skb
;
memset
(
&
cmd
,
0
,
sizeof
(
struct
iwl_host_cmd
));
if
(
!
tb
[
IWL_TM_ATTR_UCODE_CMD_ID
]
||
!
tb
[
IWL_TM_ATTR_UCODE_CMD_DATA
])
{
IWL_DEBUG_INFO
(
priv
,
"Error finding ucode command mandatory fields
\n
"
);
IWL_ERR
(
priv
,
"Missing ucode command mandatory fields
\n
"
);
return
-
ENOMSG
;
}
cmd
.
flags
=
CMD_ON_DEMAND
;
cmd
.
flags
=
CMD_ON_DEMAND
|
CMD_SYNC
;
cmd_want_skb
=
nla_get_flag
(
tb
[
IWL_TM_ATTR_UCODE_CMD_SKB
]);
if
(
cmd_want_skb
)
cmd
.
flags
|=
CMD_WANT_SKB
;
cmd
.
id
=
nla_get_u8
(
tb
[
IWL_TM_ATTR_UCODE_CMD_ID
]);
cmd
.
data
[
0
]
=
nla_data
(
tb
[
IWL_TM_ATTR_UCODE_CMD_DATA
]);
cmd
.
len
[
0
]
=
nla_len
(
tb
[
IWL_TM_ATTR_UCODE_CMD_DATA
]);
cmd
.
dataflags
[
0
]
=
IWL_HCMD_DFL_NOCOPY
;
IWL_INFO
(
priv
,
"testmode ucode command ID 0x%x, flags 0x%x,"
IWL_
DEBUG_
INFO
(
priv
,
"testmode ucode command ID 0x%x, flags 0x%x,"
" len %d
\n
"
,
cmd
.
id
,
cmd
.
flags
,
cmd
.
len
[
0
]);
/* ok, let's submit the command to ucode */
return
iwl_trans_send_cmd
(
trans
(
priv
),
&
cmd
);
ret
=
iwl_trans_send_cmd
(
trans
(
priv
),
&
cmd
);
if
(
ret
)
{
IWL_ERR
(
priv
,
"Failed to send hcmd
\n
"
);
return
ret
;
}
if
(
!
cmd_want_skb
)
return
ret
;
/* Handling return of SKB to the user */
pkt
=
(
struct
iwl_rx_packet
*
)
cmd
.
reply_page
;
if
(
!
pkt
)
{
IWL_ERR
(
priv
,
"HCMD received a null response packet
\n
"
);
return
ret
;
}
reply_len
=
le32_to_cpu
(
pkt
->
len_n_flags
)
&
FH_RSCSR_FRAME_SIZE_MSK
;
skb
=
cfg80211_testmode_alloc_reply_skb
(
hw
->
wiphy
,
reply_len
+
20
);
reply_buf
=
kmalloc
(
reply_len
,
GFP_KERNEL
);
if
(
!
skb
||
!
reply_buf
)
{
kfree_skb
(
skb
);
kfree
(
reply_buf
);
return
-
ENOMEM
;
}
/* The reply is in a page, that we cannot send to user space. */
memcpy
(
reply_buf
,
&
(
pkt
->
hdr
),
reply_len
);
iwl_free_pages
(
priv
->
shrd
,
cmd
.
reply_page
);
NLA_PUT_U32
(
skb
,
IWL_TM_ATTR_COMMAND
,
IWL_TM_CMD_DEV2APP_UCODE_RX_PKT
);
NLA_PUT
(
skb
,
IWL_TM_ATTR_UCODE_RX_PKT
,
reply_len
,
reply_buf
);
return
cfg80211_testmode_reply
(
skb
);
nla_put_failure:
IWL_DEBUG_INFO
(
priv
,
"Failed creating NL attributes
\n
"
);
return
-
ENOMSG
;
}
...
...
@@ -295,7 +348,7 @@ static int iwl_testmode_reg(struct ieee80211_hw *hw, struct nlattr **tb)
int
status
=
0
;
if
(
!
tb
[
IWL_TM_ATTR_REG_OFFSET
])
{
IWL_
DEBUG_INFO
(
priv
,
"Error find
ing register offset
\n
"
);
IWL_
ERR
(
priv
,
"Miss
ing register offset
\n
"
);
return
-
ENOMSG
;
}
ofs
=
nla_get_u32
(
tb
[
IWL_TM_ATTR_REG_OFFSET
]);
...
...
@@ -309,7 +362,7 @@ static int iwl_testmode_reg(struct ieee80211_hw *hw, struct nlattr **tb)
cmd
==
IWL_TM_CMD_APP2DEV_DIRECT_REG_WRITE32
||
cmd
==
IWL_TM_CMD_APP2DEV_DIRECT_REG_WRITE8
)
&&
(
ofs
>=
FH_MEM_UPPER_BOUND
))
{
IWL_
DEBUG_INFO
(
priv
,
"offset out of segment (0x0 - 0x%x)
\n
"
,
IWL_
ERR
(
priv
,
"offset out of segment (0x0 - 0x%x)
\n
"
,
FH_MEM_UPPER_BOUND
);
return
-
EINVAL
;
}
...
...
@@ -321,19 +374,17 @@ static int iwl_testmode_reg(struct ieee80211_hw *hw, struct nlattr **tb)
skb
=
cfg80211_testmode_alloc_reply_skb
(
hw
->
wiphy
,
20
);
if
(
!
skb
)
{
IWL_
DEBUG_INFO
(
priv
,
"Error allocating memory
\n
"
);
IWL_
ERR
(
priv
,
"Memory allocation fail
\n
"
);
return
-
ENOMEM
;
}
NLA_PUT_U32
(
skb
,
IWL_TM_ATTR_REG_VALUE32
,
val32
);
status
=
cfg80211_testmode_reply
(
skb
);
if
(
status
<
0
)
IWL_DEBUG_INFO
(
priv
,
"Error sending msg : %d
\n
"
,
status
);
IWL_ERR
(
priv
,
"Error sending msg : %d
\n
"
,
status
);
break
;
case
IWL_TM_CMD_APP2DEV_DIRECT_REG_WRITE32
:
if
(
!
tb
[
IWL_TM_ATTR_REG_VALUE32
])
{
IWL_DEBUG_INFO
(
priv
,
"Error finding value to write
\n
"
);
IWL_ERR
(
priv
,
"Missing value to write
\n
"
);
return
-
ENOMSG
;
}
else
{
val32
=
nla_get_u32
(
tb
[
IWL_TM_ATTR_REG_VALUE32
]);
...
...
@@ -343,7 +394,7 @@ static int iwl_testmode_reg(struct ieee80211_hw *hw, struct nlattr **tb)
break
;
case
IWL_TM_CMD_APP2DEV_DIRECT_REG_WRITE8
:
if
(
!
tb
[
IWL_TM_ATTR_REG_VALUE8
])
{
IWL_
DEBUG_INFO
(
priv
,
"Error find
ing value to write
\n
"
);
IWL_
ERR
(
priv
,
"Miss
ing value to write
\n
"
);
return
-
ENOMSG
;
}
else
{
val8
=
nla_get_u8
(
tb
[
IWL_TM_ATTR_REG_VALUE8
]);
...
...
@@ -351,34 +402,8 @@ static int iwl_testmode_reg(struct ieee80211_hw *hw, struct nlattr **tb)
iwl_write8
(
trans
(
priv
),
ofs
,
val8
);
}
break
;
case
IWL_TM_CMD_APP2DEV_INDIRECT_REG_READ32
:
val32
=
iwl_read_prph
(
trans
(
priv
),
ofs
);
IWL_INFO
(
priv
,
"32bit value to read 0x%x
\n
"
,
val32
);
skb
=
cfg80211_testmode_alloc_reply_skb
(
hw
->
wiphy
,
20
);
if
(
!
skb
)
{
IWL_DEBUG_INFO
(
priv
,
"Error allocating memory
\n
"
);
return
-
ENOMEM
;
}
NLA_PUT_U32
(
skb
,
IWL_TM_ATTR_REG_VALUE32
,
val32
);
status
=
cfg80211_testmode_reply
(
skb
);
if
(
status
<
0
)
IWL_DEBUG_INFO
(
priv
,
"Error sending msg : %d
\n
"
,
status
);
break
;
case
IWL_TM_CMD_APP2DEV_INDIRECT_REG_WRITE32
:
if
(
!
tb
[
IWL_TM_ATTR_REG_VALUE32
])
{
IWL_DEBUG_INFO
(
priv
,
"Error finding value to write
\n
"
);
return
-
ENOMSG
;
}
else
{
val32
=
nla_get_u32
(
tb
[
IWL_TM_ATTR_REG_VALUE32
]);
IWL_INFO
(
priv
,
"32bit value to write 0x%x
\n
"
,
val32
);
iwl_write_prph
(
trans
(
priv
),
ofs
,
val32
);
}
break
;
default:
IWL_
DEBUG_INFO
(
priv
,
"Unknown testmode register command ID
\n
"
);
IWL_
ERR
(
priv
,
"Unknown testmode register command ID
\n
"
);
return
-
ENOSYS
;
}
...
...
@@ -400,14 +425,13 @@ static int iwl_testmode_cfg_init_calib(struct iwl_priv *priv)
NULL
,
NULL
);
ret
=
iwl_init_alive_start
(
trans
(
priv
));
if
(
ret
)
{
IWL_DEBUG_INFO
(
priv
,
"Error configuring init calibration: %d
\n
"
,
ret
);
IWL_ERR
(
priv
,
"Fail init calibration: %d
\n
"
,
ret
);
goto
cfg_init_calib_error
;
}
ret
=
iwl_wait_notification
(
priv
->
shrd
,
&
calib_wait
,
2
*
HZ
);
if
(
ret
)
IWL_
DEBUG_INFO
(
priv
,
"Error detecting"
IWL_
ERR
(
priv
,
"Error detecting"
" CALIBRATION_COMPLETE_NOTIFICATION: %d
\n
"
,
ret
);
return
ret
;
...
...
@@ -448,8 +472,7 @@ static int iwl_testmode_driver(struct ieee80211_hw *hw, struct nlattr **tb)
skb
=
cfg80211_testmode_alloc_reply_skb
(
hw
->
wiphy
,
rsp_data_len
+
20
);
if
(
!
skb
)
{
IWL_DEBUG_INFO
(
priv
,
"Error allocating memory
\n
"
);
IWL_ERR
(
priv
,
"Memory allocation fail
\n
"
);
return
-
ENOMEM
;
}
NLA_PUT_U32
(
skb
,
IWL_TM_ATTR_COMMAND
,
...
...
@@ -458,15 +481,13 @@ static int iwl_testmode_driver(struct ieee80211_hw *hw, struct nlattr **tb)
rsp_data_len
,
rsp_data_ptr
);
status
=
cfg80211_testmode_reply
(
skb
);
if
(
status
<
0
)
IWL_DEBUG_INFO
(
priv
,
"Error sending msg : %d
\n
"
,
status
);
IWL_ERR
(
priv
,
"Error sending msg : %d
\n
"
,
status
);
break
;
case
IWL_TM_CMD_APP2DEV_LOAD_INIT_FW
:
status
=
iwl_load_ucode_wait_alive
(
trans
,
IWL_UCODE_INIT
);
if
(
status
)
IWL_DEBUG_INFO
(
priv
,
"Error loading init ucode: %d
\n
"
,
status
);
IWL_ERR
(
priv
,
"Error loading init ucode: %d
\n
"
,
status
);
break
;
case
IWL_TM_CMD_APP2DEV_CFG_INIT_CALIB
:
...
...
@@ -477,13 +498,13 @@ static int iwl_testmode_driver(struct ieee80211_hw *hw, struct nlattr **tb)
case
IWL_TM_CMD_APP2DEV_LOAD_RUNTIME_FW
:
status
=
iwl_load_ucode_wait_alive
(
trans
,
IWL_UCODE_REGULAR
);
if
(
status
)
{
IWL_
DEBUG_INFO
(
priv
,
IWL_
ERR
(
priv
,
"Error loading runtime ucode: %d
\n
"
,
status
);
break
;
}
status
=
iwl_alive_start
(
priv
);
if
(
status
)
IWL_
DEBUG_INFO
(
priv
,
IWL_
ERR
(
priv
,
"Error starting the device: %d
\n
"
,
status
);
break
;
...
...
@@ -492,13 +513,13 @@ static int iwl_testmode_driver(struct ieee80211_hw *hw, struct nlattr **tb)
iwl_trans_stop_device
(
trans
);
status
=
iwl_load_ucode_wait_alive
(
trans
,
IWL_UCODE_WOWLAN
);
if
(
status
)
{
IWL_
DEBUG_INFO
(
priv
,
IWL_
ERR
(
priv
,
"Error loading WOWLAN ucode: %d
\n
"
,
status
);
break
;
}
status
=
iwl_alive_start
(
priv
);
if
(
status
)
IWL_
DEBUG_INFO
(
priv
,
IWL_
ERR
(
priv
,
"Error starting the device: %d
\n
"
,
status
);
break
;
...
...
@@ -507,8 +528,7 @@ static int iwl_testmode_driver(struct ieee80211_hw *hw, struct nlattr **tb)
skb
=
cfg80211_testmode_alloc_reply_skb
(
hw
->
wiphy
,
cfg
(
priv
)
->
base_params
->
eeprom_size
+
20
);
if
(
!
skb
)
{
IWL_DEBUG_INFO
(
priv
,
"Error allocating memory
\n
"
);
IWL_ERR
(
priv
,
"Memory allocation fail
\n
"
);
return
-
ENOMEM
;
}
NLA_PUT_U32
(
skb
,
IWL_TM_ATTR_COMMAND
,
...
...
@@ -518,35 +538,34 @@ static int iwl_testmode_driver(struct ieee80211_hw *hw, struct nlattr **tb)
priv
->
shrd
->
eeprom
);
status
=
cfg80211_testmode_reply
(
skb
);
if
(
status
<
0
)
IWL_DEBUG_INFO
(
priv
,
"Error sending msg : %d
\n
"
,
status
);
IWL_ERR
(
priv
,
"Error sending msg : %d
\n
"
,
status
);
}
else
return
-
EFAULT
;
break
;
case
IWL_TM_CMD_APP2DEV_FIXRATE_REQ
:
if
(
!
tb
[
IWL_TM_ATTR_FIXRATE
])
{
IWL_DEBUG_INFO
(
priv
,
"Error finding fixrate setting
\n
"
);
IWL_ERR
(
priv
,
"Missing fixrate setting
\n
"
);
return
-
ENOMSG
;
}
priv
->
tm_fixed_rate
=
nla_get_u32
(
tb
[
IWL_TM_ATTR_FIXRATE
]);
break
;
case
IWL_TM_CMD_APP2DEV_GET_FW_VERSION
:
IWL_INFO
(
priv
,
"uCode version raw: 0x%x
\n
"
,
priv
->
ucode_ver
);
IWL_INFO
(
priv
,
"uCode version raw: 0x%x
\n
"
,
nic
(
priv
)
->
fw
.
ucode_ver
);
skb
=
cfg80211_testmode_alloc_reply_skb
(
hw
->
wiphy
,
20
);
if
(
!
skb
)
{
IWL_
DEBUG_INFO
(
priv
,
"Error allocating memory
\n
"
);
IWL_
ERR
(
priv
,
"Memory allocation fail
\n
"
);
return
-
ENOMEM
;
}
NLA_PUT_U32
(
skb
,
IWL_TM_ATTR_FW_VERSION
,
priv
->
ucode_ver
);
NLA_PUT_U32
(
skb
,
IWL_TM_ATTR_FW_VERSION
,
nic
(
priv
)
->
fw
.
ucode_ver
);
status
=
cfg80211_testmode_reply
(
skb
);
if
(
status
<
0
)
IWL_DEBUG_INFO
(
priv
,
"Error sending msg : %d
\n
"
,
status
);
IWL_ERR
(
priv
,
"Error sending msg : %d
\n
"
,
status
);
break
;
case
IWL_TM_CMD_APP2DEV_GET_DEVICE_ID
:
...
...
@@ -555,40 +574,39 @@ static int iwl_testmode_driver(struct ieee80211_hw *hw, struct nlattr **tb)
skb
=
cfg80211_testmode_alloc_reply_skb
(
hw
->
wiphy
,
20
);
if
(
!
skb
)
{
IWL_
DEBUG_INFO
(
priv
,
"Error allocating memory
\n
"
);
IWL_
ERR
(
priv
,
"Memory allocation fail
\n
"
);
return
-
ENOMEM
;
}
NLA_PUT_U32
(
skb
,
IWL_TM_ATTR_DEVICE_ID
,
devid
);
status
=
cfg80211_testmode_reply
(
skb
);
if
(
status
<
0
)
IWL_DEBUG_INFO
(
priv
,
"Error sending msg : %d
\n
"
,
status
);
IWL_ERR
(
priv
,
"Error sending msg : %d
\n
"
,
status
);
break
;
case
IWL_TM_CMD_APP2DEV_GET_FW_INFO
:
skb
=
cfg80211_testmode_alloc_reply_skb
(
hw
->
wiphy
,
20
+
8
);
if
(
!
skb
)
{
IWL_
DEBUG_INFO
(
priv
,
"Error allocating memory
\n
"
);
IWL_
ERR
(
priv
,
"Memory allocation fail
\n
"
);
return
-
ENOMEM
;
}
switch
(
priv
->
shrd
->
ucode_type
)
{
case
IWL_UCODE_REGULAR
:
inst_size
=
trans
(
priv
)
->
ucode_rt
.
code
.
len
;
data_size
=
trans
(
priv
)
->
ucode_rt
.
data
.
len
;
inst_size
=
nic
(
priv
)
->
fw
.
ucode_rt
.
code
.
len
;
data_size
=
nic
(
priv
)
->
fw
.
ucode_rt
.
data
.
len
;
break
;
case
IWL_UCODE_INIT
:
inst_size
=
trans
(
priv
)
->
ucode_init
.
code
.
len
;
data_size
=
trans
(
priv
)
->
ucode_init
.
data
.
len
;
inst_size
=
nic
(
priv
)
->
fw
.
ucode_init
.
code
.
len
;
data_size
=
nic
(
priv
)
->
fw
.
ucode_init
.
data
.
len
;
break
;
case
IWL_UCODE_WOWLAN
:
inst_size
=
trans
(
priv
)
->
ucode_wowlan
.
code
.
len
;
data_size
=
trans
(
priv
)
->
ucode_wowlan
.
data
.
len
;
inst_size
=
nic
(
priv
)
->
fw
.
ucode_wowlan
.
code
.
len
;
data_size
=
nic
(
priv
)
->
fw
.
ucode_wowlan
.
data
.
len
;
break
;
case
IWL_UCODE_NONE
:
IWL_
DEBUG_INFO
(
priv
,
"The
uCode has not been loaded
\n
"
);
IWL_
ERR
(
priv
,
"No
uCode has not been loaded
\n
"
);
break
;
default:
IWL_
DEBUG_INFO
(
priv
,
"Unsupported uCode type
\n
"
);
IWL_
ERR
(
priv
,
"Unsupported uCode type
\n
"
);
break
;
}
NLA_PUT_U32
(
skb
,
IWL_TM_ATTR_FW_TYPE
,
priv
->
shrd
->
ucode_type
);
...
...
@@ -596,12 +614,11 @@ static int iwl_testmode_driver(struct ieee80211_hw *hw, struct nlattr **tb)
NLA_PUT_U32
(
skb
,
IWL_TM_ATTR_FW_DATA_SIZE
,
data_size
);
status
=
cfg80211_testmode_reply
(
skb
);
if
(
status
<
0
)
IWL_DEBUG_INFO
(
priv
,
"Error sending msg : %d
\n
"
,
status
);
IWL_ERR
(
priv
,
"Error sending msg : %d
\n
"
,
status
);
break
;
default:
IWL_
DEBUG_INFO
(
priv
,
"Unknown testmode driver command ID
\n
"
);
IWL_
ERR
(
priv
,
"Unknown testmode driver command ID
\n
"
);
return
-
ENOSYS
;
}
return
status
;
...
...
@@ -664,8 +681,7 @@ static int iwl_testmode_trace(struct ieee80211_hw *hw, struct nlattr **tb)
skb
=
cfg80211_testmode_alloc_reply_skb
(
hw
->
wiphy
,
sizeof
(
priv
->
testmode_trace
.
dma_addr
)
+
20
);
if
(
!
skb
)
{
IWL_DEBUG_INFO
(
priv
,
"Error allocating memory
\n
"
);
IWL_ERR
(
priv
,
"Memory allocation fail
\n
"
);
iwl_trace_cleanup
(
priv
);
return
-
ENOMEM
;
}
...
...
@@ -674,9 +690,7 @@ static int iwl_testmode_trace(struct ieee80211_hw *hw, struct nlattr **tb)
(
u64
*
)
&
priv
->
testmode_trace
.
dma_addr
);
status
=
cfg80211_testmode_reply
(
skb
);
if
(
status
<
0
)
{
IWL_DEBUG_INFO
(
priv
,
"Error sending msg : %d
\n
"
,
status
);
IWL_ERR
(
priv
,
"Error sending msg : %d
\n
"
,
status
);
}
priv
->
testmode_trace
.
num_chunks
=
DIV_ROUND_UP
(
priv
->
testmode_trace
.
buff_size
,
...
...
@@ -687,7 +701,7 @@ static int iwl_testmode_trace(struct ieee80211_hw *hw, struct nlattr **tb)
iwl_trace_cleanup
(
priv
);
break
;
default:
IWL_
DEBUG_INFO
(
priv
,
"Unknown testmode mem command ID
\n
"
);
IWL_
ERR
(
priv
,
"Unknown testmode mem command ID
\n
"
);
return
-
ENOSYS
;
}
return
status
;
...
...
@@ -752,7 +766,7 @@ static int iwl_testmode_ownership(struct ieee80211_hw *hw, struct nlattr **tb)
u8
owner
;
if
(
!
tb
[
IWL_TM_ATTR_UCODE_OWNER
])
{
IWL_
DEBUG_INFO
(
priv
,
"Error find
ing ucode owner
\n
"
);
IWL_
ERR
(
priv
,
"Miss
ing ucode owner
\n
"
);
return
-
ENOMSG
;
}
...
...
@@ -760,12 +774,89 @@ static int iwl_testmode_ownership(struct ieee80211_hw *hw, struct nlattr **tb)
if
((
owner
==
IWL_OWNERSHIP_DRIVER
)
||
(
owner
==
IWL_OWNERSHIP_TM
))
priv
->
shrd
->
ucode_owner
=
owner
;
else
{
IWL_
DEBUG_INFO
(
priv
,
"Invalid owner
\n
"
);
IWL_
ERR
(
priv
,
"Invalid owner
\n
"
);
return
-
EINVAL
;
}
return
0
;
}
static
int
iwl_testmode_indirect_read
(
struct
iwl_priv
*
priv
,
u32
addr
,
u32
size
)
{
struct
iwl_trans
*
trans
=
trans
(
priv
);
unsigned
long
flags
;
int
i
;
if
(
size
&
0x3
)
return
-
EINVAL
;
priv
->
testmode_mem
.
buff_size
=
size
;
priv
->
testmode_mem
.
buff_addr
=
kmalloc
(
priv
->
testmode_mem
.
buff_size
,
GFP_KERNEL
);
if
(
priv
->
testmode_mem
.
buff_addr
==
NULL
)
return
-
ENOMEM
;
/* Hard-coded periphery absolute address */
if
(
IWL_TM_ABS_PRPH_START
<=
addr
&&
addr
<
IWL_TM_ABS_PRPH_START
+
PRPH_END
)
{
spin_lock_irqsave
(
&
trans
->
reg_lock
,
flags
);
iwl_grab_nic_access
(
trans
);
iwl_write32
(
trans
,
HBUS_TARG_PRPH_RADDR
,
addr
|
(
3
<<
24
));
for
(
i
=
0
;
i
<
size
;
i
+=
4
)
*
(
u32
*
)(
priv
->
testmode_mem
.
buff_addr
+
i
)
=
iwl_read32
(
trans
,
HBUS_TARG_PRPH_RDAT
);
iwl_release_nic_access
(
trans
);
spin_unlock_irqrestore
(
&
trans
->
reg_lock
,
flags
);
}
else
{
/* target memory (SRAM) */
_iwl_read_targ_mem_words
(
trans
,
addr
,
priv
->
testmode_mem
.
buff_addr
,
priv
->
testmode_mem
.
buff_size
/
4
);
}
priv
->
testmode_mem
.
num_chunks
=
DIV_ROUND_UP
(
priv
->
testmode_mem
.
buff_size
,
DUMP_CHUNK_SIZE
);
priv
->
testmode_mem
.
read_in_progress
=
true
;
return
0
;
}
static
int
iwl_testmode_indirect_write
(
struct
iwl_priv
*
priv
,
u32
addr
,
u32
size
,
unsigned
char
*
buf
)
{
struct
iwl_trans
*
trans
=
trans
(
priv
);
u32
val
,
i
;
unsigned
long
flags
;
if
(
IWL_TM_ABS_PRPH_START
<=
addr
&&
addr
<
IWL_TM_ABS_PRPH_START
+
PRPH_END
)
{
/* Periphery writes can be 1-3 bytes long, or DWORDs */
if
(
size
<
4
)
{
memcpy
(
&
val
,
buf
,
size
);
spin_lock_irqsave
(
&
trans
->
reg_lock
,
flags
);
iwl_grab_nic_access
(
trans
);
iwl_write32
(
trans
,
HBUS_TARG_PRPH_WADDR
,
(
addr
&
0x0000FFFF
)
|
((
size
-
1
)
<<
24
));
iwl_write32
(
trans
,
HBUS_TARG_PRPH_WDAT
,
val
);
iwl_release_nic_access
(
trans
);
/* needed after consecutive writes w/o read */
mmiowb
();
spin_unlock_irqrestore
(
&
trans
->
reg_lock
,
flags
);
}
else
{
if
(
size
%
4
)
return
-
EINVAL
;
for
(
i
=
0
;
i
<
size
;
i
+=
4
)
iwl_write_prph
(
trans
,
addr
+
i
,
*
(
u32
*
)(
buf
+
i
));
}
}
else
if
(
iwlagn_hw_valid_rtc_data_addr
(
addr
)
||
(
IWLAGN_RTC_INST_LOWER_BOUND
<=
addr
&&
addr
<
IWLAGN_RTC_INST_UPPER_BOUND
))
{
_iwl_write_targ_mem_words
(
trans
,
addr
,
buf
,
size
/
4
);
}
else
return
-
EINVAL
;
return
0
;
}
/*
* This function handles the user application commands for SRAM data dump
*
...
...
@@ -782,82 +873,60 @@ static int iwl_testmode_ownership(struct ieee80211_hw *hw, struct nlattr **tb)
* @hw: ieee80211_hw object that represents the device
* @tb: gnl message fields from the user space
*/
static
int
iwl_testmode_sram
(
struct
ieee80211_hw
*
hw
,
struct
nlattr
**
tb
)
static
int
iwl_testmode_indirect_mem
(
struct
ieee80211_hw
*
hw
,
struct
nlattr
**
tb
)
{
struct
iwl_priv
*
priv
=
hw
->
priv
;
u32
ofs
,
size
,
maxsize
;
u32
addr
,
size
,
cmd
;
unsigned
char
*
buf
;
if
(
priv
->
testmode_sram
.
sram_readed
)
/* Both read and write should be blocked, for atomicity */
if
(
priv
->
testmode_mem
.
read_in_progress
)
return
-
EBUSY
;
if
(
!
tb
[
IWL_TM_ATTR_SRAM_ADDR
])
{
IWL_DEBUG_INFO
(
priv
,
"Error finding SRAM offset address
\n
"
);
cmd
=
nla_get_u32
(
tb
[
IWL_TM_ATTR_COMMAND
]);
if
(
!
tb
[
IWL_TM_ATTR_MEM_ADDR
])
{
IWL_ERR
(
priv
,
"Error finding memory offset address
\n
"
);
return
-
ENOMSG
;
}
ofs
=
nla_get_u32
(
tb
[
IWL_TM_ATTR_SRA
M_ADDR
]);
if
(
!
tb
[
IWL_TM_ATTR_
SRAM
_SIZE
])
{
IWL_
DEBUG_INFO
(
priv
,
"Error finding size for SRAM
reading
\n
"
);
addr
=
nla_get_u32
(
tb
[
IWL_TM_ATTR_ME
M_ADDR
]);
if
(
!
tb
[
IWL_TM_ATTR_
BUFFER
_SIZE
])
{
IWL_
ERR
(
priv
,
"Error finding size for memory
reading
\n
"
);
return
-
ENOMSG
;
}
size
=
nla_get_u32
(
tb
[
IWL_TM_ATTR_SRAM_SIZE
]);
switch
(
priv
->
shrd
->
ucode_type
)
{
case
IWL_UCODE_REGULAR
:
maxsize
=
trans
(
priv
)
->
ucode_rt
.
data
.
len
;
break
;
case
IWL_UCODE_INIT
:
maxsize
=
trans
(
priv
)
->
ucode_init
.
data
.
len
;
break
;
case
IWL_UCODE_WOWLAN
:
maxsize
=
trans
(
priv
)
->
ucode_wowlan
.
data
.
len
;
break
;
case
IWL_UCODE_NONE
:
IWL_ERR
(
priv
,
"Error, uCode does not been loaded
\n
"
);
return
-
ENOSYS
;
default:
IWL_ERR
(
priv
,
"Error, unsupported uCode type
\n
"
);
return
-
ENOSYS
;
}
if
((
ofs
+
size
)
>
(
maxsize
+
SRAM_DATA_SEG_OFFSET
))
{
IWL_ERR
(
priv
,
"Invalid offset/size: out of range
\n
"
);
return
-
EINVAL
;
}
priv
->
testmode_sram
.
buff_size
=
(
size
/
4
)
*
4
;
priv
->
testmode_sram
.
buff_addr
=
kmalloc
(
priv
->
testmode_sram
.
buff_size
,
GFP_KERNEL
);
if
(
priv
->
testmode_sram
.
buff_addr
==
NULL
)
{
IWL_ERR
(
priv
,
"Error allocating memory
\n
"
);
return
-
ENOMEM
;
size
=
nla_get_u32
(
tb
[
IWL_TM_ATTR_BUFFER_SIZE
]);
if
(
cmd
==
IWL_TM_CMD_APP2DEV_INDIRECT_BUFFER_READ
)
return
iwl_testmode_indirect_read
(
priv
,
addr
,
size
);
else
{
if
(
!
tb
[
IWL_TM_ATTR_BUFFER_DUMP
])
return
-
EINVAL
;
buf
=
(
unsigned
char
*
)
nla_data
(
tb
[
IWL_TM_ATTR_BUFFER_DUMP
]);
return
iwl_testmode_indirect_write
(
priv
,
addr
,
size
,
buf
);
}
_iwl_read_targ_mem_words
(
trans
(
priv
),
ofs
,
priv
->
testmode_sram
.
buff_addr
,
priv
->
testmode_sram
.
buff_size
/
4
);
priv
->
testmode_sram
.
num_chunks
=
DIV_ROUND_UP
(
priv
->
testmode_sram
.
buff_size
,
DUMP_CHUNK_SIZE
);
priv
->
testmode_sram
.
sram_readed
=
true
;
return
0
;
}
static
int
iwl_testmode_
sram
_dump
(
struct
ieee80211_hw
*
hw
,
struct
nlattr
**
tb
,
static
int
iwl_testmode_
buffer
_dump
(
struct
ieee80211_hw
*
hw
,
struct
nlattr
**
tb
,
struct
sk_buff
*
skb
,
struct
netlink_callback
*
cb
)
{
struct
iwl_priv
*
priv
=
hw
->
priv
;
int
idx
,
length
;
if
(
priv
->
testmode_
sram
.
sram_readed
)
{
if
(
priv
->
testmode_
mem
.
read_in_progress
)
{
idx
=
cb
->
args
[
4
];
if
(
idx
>=
priv
->
testmode_
sra
m
.
num_chunks
)
{
iwl_
sra
m_cleanup
(
priv
);
if
(
idx
>=
priv
->
testmode_
me
m
.
num_chunks
)
{
iwl_
me
m_cleanup
(
priv
);
return
-
ENOENT
;
}
length
=
DUMP_CHUNK_SIZE
;
if
(((
idx
+
1
)
==
priv
->
testmode_
sra
m
.
num_chunks
)
&&
(
priv
->
testmode_
sra
m
.
buff_size
%
DUMP_CHUNK_SIZE
))
length
=
priv
->
testmode_
sra
m
.
buff_size
%
if
(((
idx
+
1
)
==
priv
->
testmode_
me
m
.
num_chunks
)
&&
(
priv
->
testmode_
me
m
.
buff_size
%
DUMP_CHUNK_SIZE
))
length
=
priv
->
testmode_
me
m
.
buff_size
%
DUMP_CHUNK_SIZE
;
NLA_PUT
(
skb
,
IWL_TM_ATTR_
SRAM
_DUMP
,
length
,
priv
->
testmode_
sra
m
.
buff_addr
+
NLA_PUT
(
skb
,
IWL_TM_ATTR_
BUFFER
_DUMP
,
length
,
priv
->
testmode_
me
m
.
buff_addr
+
(
DUMP_CHUNK_SIZE
*
idx
));
idx
++
;
cb
->
args
[
4
]
=
idx
;
...
...
@@ -898,14 +967,13 @@ int iwlagn_mac_testmode_cmd(struct ieee80211_hw *hw, void *data, int len)
result
=
nla_parse
(
tb
,
IWL_TM_ATTR_MAX
-
1
,
data
,
len
,
iwl_testmode_gnl_msg_policy
);
if
(
result
!=
0
)
{
IWL_DEBUG_INFO
(
priv
,
"Error parsing the gnl message : %d
\n
"
,
result
);
IWL_ERR
(
priv
,
"Error parsing the gnl message : %d
\n
"
,
result
);
return
result
;
}
/* IWL_TM_ATTR_COMMAND is absolutely mandatory */
if
(
!
tb
[
IWL_TM_ATTR_COMMAND
])
{
IWL_
DEBUG_INFO
(
priv
,
"Error find
ing testmode command type
\n
"
);
IWL_
ERR
(
priv
,
"Miss
ing testmode command type
\n
"
);
return
-
ENOMSG
;
}
/* in case multiple accesses to the device happens */
...
...
@@ -919,8 +987,6 @@ int iwlagn_mac_testmode_cmd(struct ieee80211_hw *hw, void *data, int len)
case
IWL_TM_CMD_APP2DEV_DIRECT_REG_READ32
:
case
IWL_TM_CMD_APP2DEV_DIRECT_REG_WRITE32
:
case
IWL_TM_CMD_APP2DEV_DIRECT_REG_WRITE8
:
case
IWL_TM_CMD_APP2DEV_INDIRECT_REG_READ32
:
case
IWL_TM_CMD_APP2DEV_INDIRECT_REG_WRITE32
:
IWL_DEBUG_INFO
(
priv
,
"testmode cmd to register
\n
"
);
result
=
iwl_testmode_reg
(
hw
,
tb
);
break
;
...
...
@@ -950,13 +1016,15 @@ int iwlagn_mac_testmode_cmd(struct ieee80211_hw *hw, void *data, int len)
result
=
iwl_testmode_ownership
(
hw
,
tb
);
break
;
case
IWL_TM_CMD_APP2DEV_READ_SRAM
:
IWL_DEBUG_INFO
(
priv
,
"testmode sram read cmd to driver
\n
"
);
result
=
iwl_testmode_sram
(
hw
,
tb
);
case
IWL_TM_CMD_APP2DEV_INDIRECT_BUFFER_READ
:
case
IWL_TM_CMD_APP2DEV_INDIRECT_BUFFER_WRITE
:
IWL_DEBUG_INFO
(
priv
,
"testmode indirect memory cmd "
"to driver
\n
"
);
result
=
iwl_testmode_indirect_mem
(
hw
,
tb
);
break
;
default:
IWL_
DEBUG_INFO
(
priv
,
"Unknown testmode command
\n
"
);
IWL_
ERR
(
priv
,
"Unknown testmode command
\n
"
);
result
=
-
ENOSYS
;
break
;
}
...
...
@@ -981,15 +1049,14 @@ int iwlagn_mac_testmode_dump(struct ieee80211_hw *hw, struct sk_buff *skb,
result
=
nla_parse
(
tb
,
IWL_TM_ATTR_MAX
-
1
,
data
,
len
,
iwl_testmode_gnl_msg_policy
);
if
(
result
)
{
IWL_
DEBUG_INFO
(
priv
,
"Error parsing the gnl message : %d
\n
"
,
result
);
IWL_
ERR
(
priv
,
"Error parsing the gnl message : %d
\n
"
,
result
);
return
result
;
}
/* IWL_TM_ATTR_COMMAND is absolutely mandatory */
if
(
!
tb
[
IWL_TM_ATTR_COMMAND
])
{
IWL_DEBUG_INFO
(
priv
,
"Error finding testmode command type
\n
"
);
IWL_ERR
(
priv
,
"Missing testmode command type
\n
"
);
return
-
ENOMSG
;
}
cmd
=
nla_get_u32
(
tb
[
IWL_TM_ATTR_COMMAND
]);
...
...
@@ -1003,9 +1070,9 @@ int iwlagn_mac_testmode_dump(struct ieee80211_hw *hw, struct sk_buff *skb,
IWL_DEBUG_INFO
(
priv
,
"uCode trace cmd to driver
\n
"
);
result
=
iwl_testmode_trace_dump
(
hw
,
tb
,
skb
,
cb
);
break
;
case
IWL_TM_CMD_APP2DEV_
DUMP_SRAM
:
case
IWL_TM_CMD_APP2DEV_
INDIRECT_BUFFER_DUMP
:
IWL_DEBUG_INFO
(
priv
,
"testmode sram dump cmd to driver
\n
"
);
result
=
iwl_testmode_
sram
_dump
(
hw
,
tb
,
skb
,
cb
);
result
=
iwl_testmode_
buffer
_dump
(
hw
,
tb
,
skb
,
cb
);
break
;
default:
result
=
-
EINVAL
;
...
...
drivers/net/wireless/iwlwifi/iwl-testmode.h
View file @
d896d463
...
...
@@ -99,7 +99,7 @@
* to user application
* @IWL_TM_CMD_DEV2APP_UCODE_RX_PKT:
* commands from kernel space to multicast the spontaneous messages
* to user application
* to user application
, or reply of host commands
* @IWL_TM_CMD_DEV2APP_EEPROM_RSP:
* commands from kernel space to carry the eeprom response
* to user application
...
...
@@ -109,20 +109,19 @@
* if application has the ownership, the only host command from
* testmode will deliver to uCode. Default owner is driver
*
* @IWL_TM_CMD_APP2DEV_INDIRECT_REG_READ32:
* @IWL_TM_CMD_APP2DEV_INDIRECT_REG_WRITE32:
* commands from user application to indirectly access peripheral register
*
* @IWL_TM_CMD_APP2DEV_READ_SRAM:
* @IWL_TM_CMD_APP2DEV_DUMP_SRAM:
* commands from user application to read data in sram
*
* @IWL_TM_CMD_APP2DEV_LOAD_WOWLAN_FW: load Wake On Wireless LAN uCode image
* @IWL_TM_CMD_APP2DEV_GET_FW_VERSION: retrieve uCode version
* @IWL_TM_CMD_APP2DEV_GET_DEVICE_ID: retrieve ID information in device
* @IWL_TM_CMD_APP2DEV_GET_FW_INFO:
* retrieve information of existing loaded uCode image
*
* @IWL_TM_CMD_APP2DEV_INDIRECT_BUFFER_READ:
* @IWL_TM_CMD_APP2DEV_INDIRECT_BUFFER_DUMP:
* @IWL_TM_CMD_APP2DEV_INDIRECT_BUFFER_WRITE:
* Commands to read/write data from periphery or SRAM memory ranges.
* Fore reading, a READ command is sent from the userspace and the data
* is returned when the user calls a DUMP command.
* For writing, only a WRITE command is used.
*/
enum
iwl_tm_cmd_t
{
IWL_TM_CMD_APP2DEV_UCODE
=
1
,
...
...
@@ -142,15 +141,18 @@ enum iwl_tm_cmd_t {
IWL_TM_CMD_DEV2APP_UCODE_RX_PKT
=
15
,
IWL_TM_CMD_DEV2APP_EEPROM_RSP
=
16
,
IWL_TM_CMD_APP2DEV_OWNERSHIP
=
17
,
IWL_TM_CMD_APP2DEV_INDIRECT_REG_READ32
=
18
,
IWL_TM_CMD_APP2DEV_INDIRECT_REG_WRITE32
=
19
,
IWL_TM_CMD_APP2DEV_READ_SRAM
=
20
,
IWL_TM_CMD_APP2DEV_DUMP_SRAM
=
21
,
RESERVED_18
=
18
,
RESERVED_19
=
19
,
RESERVED_20
=
20
,
RESERVED_21
=
21
,
IWL_TM_CMD_APP2DEV_LOAD_WOWLAN_FW
=
22
,
IWL_TM_CMD_APP2DEV_GET_FW_VERSION
=
23
,
IWL_TM_CMD_APP2DEV_GET_DEVICE_ID
=
24
,
IWL_TM_CMD_APP2DEV_GET_FW_INFO
=
25
,
IWL_TM_CMD_MAX
=
26
,
IWL_TM_CMD_APP2DEV_INDIRECT_BUFFER_READ
=
26
,
IWL_TM_CMD_APP2DEV_INDIRECT_BUFFER_DUMP
=
27
,
IWL_TM_CMD_APP2DEV_INDIRECT_BUFFER_WRITE
=
28
,
IWL_TM_CMD_MAX
=
29
,
};
/*
...
...
@@ -171,8 +173,6 @@ enum iwl_tm_cmd_t {
* When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_APP2DEV_UCODE,
* The mandatory fields are :
* IWL_TM_ATTR_UCODE_CMD_ID for recognizable command ID;
* IWL_TM_ATTR_COMMAND_FLAG for the flags of the commands;
* The optional fields are:
* IWL_TM_ATTR_UCODE_CMD_DATA for the actual command payload
* to the ucode
*
...
...
@@ -221,16 +221,19 @@ enum iwl_tm_cmd_t {
* The mandatory fields are:
* IWL_TM_ATTR_UCODE_OWNER for the new owner
*
* @IWL_TM_ATTR_SRAM_ADDR:
* @IWL_TM_ATTR_SRAM_SIZE:
* When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_APP2DEV_READ_SRAM,
* @IWL_TM_ATTR_MEM_ADDR:
* @IWL_TM_ATTR_BUFFER_SIZE:
* When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_APP2DEV_INDIRECT_BUFFER_READ
* or IWL_TM_CMD_APP2DEV_INDIRECT_BUFFER_WRITE.
* The mandatory fields are:
* IWL_TM_ATTR_
SRAM_ADDR for the address in sram
* IWL_TM_ATTR_
SRAM_SIZE for the buffer size of data reading
* IWL_TM_ATTR_
MEM_ADDR for the address in SRAM/periphery to read/write
* IWL_TM_ATTR_
BUFFER_SIZE for the buffer size of data to read/write.
*
* @IWL_TM_ATTR_SRAM_DUMP:
* When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_APP2DEV_DUMP_SRAM,
* IWL_TM_ATTR_SRAM_DUMP for the data in sram
* @IWL_TM_ATTR_BUFFER_DUMP:
* When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_APP2DEV_INDIRECT_BUFFER_DUMP,
* IWL_TM_ATTR_BUFFER_DUMP is used for the data that was read.
* When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_APP2DEV_INDIRECT_BUFFER_WRITE,
* this attribute contains the data to write.
*
* @IWL_TM_ATTR_FW_VERSION:
* When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_APP2DEV_GET_FW_VERSION,
...
...
@@ -249,6 +252,10 @@ enum iwl_tm_cmd_t {
* IWL_TM_ATTR_FW_INST_SIZE for the size of instruction section
* IWL_TM_ATTR_FW_DATA_SIZE for the size of data section
*
* @IWL_TM_ATTR_UCODE_CMD_SKB:
* When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_APP2DEV_UCODE this flag
* indicates that the user wants to receive the response of the command
* in a reply SKB. If it's not present, the response is not returned.
*/
enum
iwl_tm_attr_t
{
IWL_TM_ATTR_NOT_APPLICABLE
=
0
,
...
...
@@ -266,15 +273,16 @@ enum iwl_tm_attr_t {
IWL_TM_ATTR_TRACE_DUMP
=
12
,
IWL_TM_ATTR_FIXRATE
=
13
,
IWL_TM_ATTR_UCODE_OWNER
=
14
,
IWL_TM_ATTR_
SRA
M_ADDR
=
15
,
IWL_TM_ATTR_
SRAM
_SIZE
=
16
,
IWL_TM_ATTR_
SRAM
_DUMP
=
17
,
IWL_TM_ATTR_
ME
M_ADDR
=
15
,
IWL_TM_ATTR_
BUFFER
_SIZE
=
16
,
IWL_TM_ATTR_
BUFFER
_DUMP
=
17
,
IWL_TM_ATTR_FW_VERSION
=
18
,
IWL_TM_ATTR_DEVICE_ID
=
19
,
IWL_TM_ATTR_FW_TYPE
=
20
,
IWL_TM_ATTR_FW_INST_SIZE
=
21
,
IWL_TM_ATTR_FW_DATA_SIZE
=
22
,
IWL_TM_ATTR_MAX
=
23
,
IWL_TM_ATTR_UCODE_CMD_SKB
=
23
,
IWL_TM_ATTR_MAX
=
24
,
};
/* uCode trace buffer */
...
...
drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h
View file @
d896d463
...
...
@@ -230,6 +230,7 @@ struct iwl_trans_pcie {
struct
tasklet_struct
irq_tasklet
;
struct
isr_statistics
isr_stats
;
spinlock_t
irq_lock
;
u32
inta_mask
;
u32
scd_base_addr
;
struct
iwl_dma_ptr
scd_bc_tbls
;
...
...
drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c
View file @
d896d463
...
...
@@ -34,6 +34,7 @@
#include "iwl-core.h"
#include "iwl-io.h"
#include "iwl-trans-pcie-int.h"
#include "iwl-wifi.h"
#ifdef CONFIG_IWLWIFI_IDI
#include "iwl-amfh.h"
...
...
@@ -227,7 +228,7 @@ static void iwlagn_rx_queue_restock(struct iwl_trans *trans)
/* If the pre-allocated buffer pool is dropping low, schedule to
* refill it */
if
(
rxq
->
free_count
<=
RX_LOW_WATERMARK
)
queue_work
(
trans
->
shrd
->
workqueue
,
&
trans_pcie
->
rx_replenish
);
schedule_work
(
&
trans_pcie
->
rx_replenish
);
/* If we've added more space for the firmware to place data, tell it.
...
...
@@ -331,13 +332,14 @@ static void iwlagn_rx_allocate(struct iwl_trans *trans, gfp_t priority)
void
iwlagn_rx_replenish
(
struct
iwl_trans
*
trans
)
{
struct
iwl_trans_pcie
*
trans_pcie
=
IWL_TRANS_GET_PCIE_TRANS
(
trans
);
unsigned
long
flags
;
iwlagn_rx_allocate
(
trans
,
GFP_KERNEL
);
spin_lock_irqsave
(
&
trans
->
shrd
->
lock
,
flags
);
spin_lock_irqsave
(
&
trans
_pcie
->
irq_
lock
,
flags
);
iwlagn_rx_queue_restock
(
trans
);
spin_unlock_irqrestore
(
&
trans
->
shrd
->
lock
,
flags
);
spin_unlock_irqrestore
(
&
trans
_pcie
->
irq_
lock
,
flags
);
}
static
void
iwlagn_rx_replenish_now
(
struct
iwl_trans
*
trans
)
...
...
@@ -351,14 +353,8 @@ void iwl_bg_rx_replenish(struct work_struct *data)
{
struct
iwl_trans_pcie
*
trans_pcie
=
container_of
(
data
,
struct
iwl_trans_pcie
,
rx_replenish
);
struct
iwl_trans
*
trans
=
trans_pcie
->
trans
;
if
(
test_bit
(
STATUS_EXIT_PENDING
,
&
trans
->
shrd
->
status
))
return
;
mutex_lock
(
&
trans
->
shrd
->
mutex
);
iwlagn_rx_replenish
(
trans
);
mutex_unlock
(
&
trans
->
shrd
->
mutex
);
iwlagn_rx_replenish
(
trans_pcie
->
trans
);
}
/**
...
...
@@ -594,17 +590,17 @@ static void iwl_dump_nic_error_log(struct iwl_trans *trans)
{
u32
base
;
struct
iwl_error_event_table
table
;
struct
iwl_
priv
*
priv
=
priv
(
trans
);
struct
iwl_
nic
*
nic
=
nic
(
trans
);
struct
iwl_trans_pcie
*
trans_pcie
=
IWL_TRANS_GET_PCIE_TRANS
(
trans
);
base
=
trans
->
shrd
->
device_pointers
.
error_event_table
;
if
(
trans
->
shrd
->
ucode_type
==
IWL_UCODE_INIT
)
{
if
(
!
base
)
base
=
priv
->
init_errlog_ptr
;
base
=
nic
->
init_errlog_ptr
;
}
else
{
if
(
!
base
)
base
=
priv
->
inst_errlog_ptr
;
base
=
nic
->
inst_errlog_ptr
;
}
if
(
!
iwlagn_hw_valid_rtc_data_addr
(
base
))
{
...
...
@@ -616,7 +612,7 @@ static void iwl_dump_nic_error_log(struct iwl_trans *trans)
return
;
}
iwl_read_targ_mem_words
(
trans
(
priv
)
,
base
,
&
table
,
sizeof
(
table
));
iwl_read_targ_mem_words
(
trans
,
base
,
&
table
,
sizeof
(
table
));
if
(
ERROR_START_OFFSET
<=
table
.
valid
*
ERROR_ELEM_SIZE
)
{
IWL_ERR
(
trans
,
"Start IWL Error Log Dump:
\n
"
);
...
...
@@ -626,7 +622,7 @@ static void iwl_dump_nic_error_log(struct iwl_trans *trans)
trans_pcie
->
isr_stats
.
err_code
=
table
.
error_id
;
trace_iwlwifi_dev_ucode_error
(
priv
,
table
.
error_id
,
table
.
tsf_low
,
trace_iwlwifi_dev_ucode_error
(
priv
(
nic
)
,
table
.
error_id
,
table
.
tsf_low
,
table
.
data1
,
table
.
data2
,
table
.
line
,
table
.
blink1
,
table
.
blink2
,
table
.
ilink1
,
table
.
ilink2
,
table
.
bcon_time
,
table
.
gp1
,
...
...
@@ -723,7 +719,7 @@ static int iwl_print_event_log(struct iwl_trans *trans, u32 start_idx,
u32
ptr
;
/* SRAM byte address of log data */
u32
ev
,
time
,
data
;
/* event log data */
unsigned
long
reg_flags
;
struct
iwl_
priv
*
priv
=
priv
(
trans
);
struct
iwl_
nic
*
nic
=
nic
(
trans
);
if
(
num_events
==
0
)
return
pos
;
...
...
@@ -731,10 +727,10 @@ static int iwl_print_event_log(struct iwl_trans *trans, u32 start_idx,
base
=
trans
->
shrd
->
device_pointers
.
log_event_table
;
if
(
trans
->
shrd
->
ucode_type
==
IWL_UCODE_INIT
)
{
if
(
!
base
)
base
=
priv
->
init_evtlog_ptr
;
base
=
nic
->
init_evtlog_ptr
;
}
else
{
if
(
!
base
)
base
=
priv
->
inst_evtlog_ptr
;
base
=
nic
->
inst_evtlog_ptr
;
}
if
(
mode
==
0
)
...
...
@@ -764,7 +760,7 @@ static int iwl_print_event_log(struct iwl_trans *trans, u32 start_idx,
"EVT_LOG:0x%08x:%04u
\n
"
,
time
,
ev
);
}
else
{
trace_iwlwifi_dev_ucode_event
(
priv
,
0
,
trace_iwlwifi_dev_ucode_event
(
priv
(
trans
)
,
0
,
time
,
ev
);
IWL_ERR
(
trans
,
"EVT_LOG:0x%08x:%04u
\n
"
,
time
,
ev
);
...
...
@@ -778,7 +774,7 @@ static int iwl_print_event_log(struct iwl_trans *trans, u32 start_idx,
}
else
{
IWL_ERR
(
trans
,
"EVT_LOGT:%010u:0x%08x:%04u
\n
"
,
time
,
data
,
ev
);
trace_iwlwifi_dev_ucode_event
(
priv
,
time
,
trace_iwlwifi_dev_ucode_event
(
priv
(
trans
)
,
time
,
data
,
ev
);
}
}
...
...
@@ -840,17 +836,17 @@ int iwl_dump_nic_event_log(struct iwl_trans *trans, bool full_log,
u32
logsize
;
int
pos
=
0
;
size_t
bufsz
=
0
;
struct
iwl_
priv
*
priv
=
priv
(
trans
);
struct
iwl_
nic
*
nic
=
nic
(
trans
);
base
=
trans
->
shrd
->
device_pointers
.
log_event_table
;
if
(
trans
->
shrd
->
ucode_type
==
IWL_UCODE_INIT
)
{
logsize
=
priv
->
init_evtlog_size
;
logsize
=
nic
->
init_evtlog_size
;
if
(
!
base
)
base
=
priv
->
init_evtlog_ptr
;
base
=
nic
->
init_evtlog_ptr
;
}
else
{
logsize
=
priv
->
inst_evtlog_size
;
logsize
=
nic
->
inst_evtlog_size
;
if
(
!
base
)
base
=
priv
->
inst_evtlog_ptr
;
base
=
nic
->
inst_evtlog_ptr
;
}
if
(
!
iwlagn_hw_valid_rtc_data_addr
(
base
))
{
...
...
@@ -949,7 +945,7 @@ void iwl_irq_tasklet(struct iwl_trans *trans)
struct
isr_statistics
*
isr_stats
=
&
trans_pcie
->
isr_stats
;
spin_lock_irqsave
(
&
trans
->
shrd
->
lock
,
flags
);
spin_lock_irqsave
(
&
trans
_pcie
->
irq_
lock
,
flags
);
/* Ack/clear/reset pending uCode interrupts.
* Note: Some bits in CSR_INT are "OR" of bits in CSR_FH_INT_STATUS,
...
...
@@ -979,7 +975,7 @@ void iwl_irq_tasklet(struct iwl_trans *trans)
/* saved interrupt in inta variable now we can reset trans_pcie->inta */
trans_pcie
->
inta
=
0
;
spin_unlock_irqrestore
(
&
trans
->
shrd
->
lock
,
flags
);
spin_unlock_irqrestore
(
&
trans
_pcie
->
irq_
lock
,
flags
);
/* Now service all interrupt bits discovered above. */
if
(
inta
&
CSR_INT_BIT_HW_ERR
)
{
...
...
@@ -1232,7 +1228,7 @@ void iwl_reset_ict(struct iwl_trans *trans)
if
(
!
trans_pcie
->
ict_tbl
)
return
;
spin_lock_irqsave
(
&
trans
->
shrd
->
lock
,
flags
);
spin_lock_irqsave
(
&
trans
_pcie
->
irq_
lock
,
flags
);
iwl_disable_interrupts
(
trans
);
memset
(
trans_pcie
->
ict_tbl
,
0
,
ICT_SIZE
);
...
...
@@ -1249,7 +1245,7 @@ void iwl_reset_ict(struct iwl_trans *trans)
trans_pcie
->
ict_index
=
0
;
iwl_write32
(
trans
,
CSR_INT
,
trans_pcie
->
inta_mask
);
iwl_enable_interrupts
(
trans
);
spin_unlock_irqrestore
(
&
trans
->
shrd
->
lock
,
flags
);
spin_unlock_irqrestore
(
&
trans
_pcie
->
irq_
lock
,
flags
);
}
/* Device is going down disable ict interrupt usage */
...
...
@@ -1260,9 +1256,9 @@ void iwl_disable_ict(struct iwl_trans *trans)
unsigned
long
flags
;
spin_lock_irqsave
(
&
trans
->
shrd
->
lock
,
flags
);
spin_lock_irqsave
(
&
trans
_pcie
->
irq_
lock
,
flags
);
trans_pcie
->
use_ict
=
false
;
spin_unlock_irqrestore
(
&
trans
->
shrd
->
lock
,
flags
);
spin_unlock_irqrestore
(
&
trans
_pcie
->
irq_
lock
,
flags
);
}
static
irqreturn_t
iwl_isr
(
int
irq
,
void
*
data
)
...
...
@@ -1281,7 +1277,7 @@ static irqreturn_t iwl_isr(int irq, void *data)
trans_pcie
=
IWL_TRANS_GET_PCIE_TRANS
(
trans
);
spin_lock_irqsave
(
&
trans
->
shrd
->
lock
,
flags
);
spin_lock_irqsave
(
&
trans
_pcie
->
irq_
lock
,
flags
);
/* Disable (but don't clear!) interrupts here to avoid
* back-to-back ISRs and sporadic interrupts from our NIC.
...
...
@@ -1325,7 +1321,7 @@ static irqreturn_t iwl_isr(int irq, void *data)
iwl_enable_interrupts
(
trans
);
unplugged:
spin_unlock_irqrestore
(
&
trans
->
shrd
->
lock
,
flags
);
spin_unlock_irqrestore
(
&
trans
_pcie
->
irq_
lock
,
flags
);
return
IRQ_HANDLED
;
none:
...
...
@@ -1335,7 +1331,7 @@ static irqreturn_t iwl_isr(int irq, void *data)
!
trans_pcie
->
inta
)
iwl_enable_interrupts
(
trans
);
spin_unlock_irqrestore
(
&
trans
->
shrd
->
lock
,
flags
);
spin_unlock_irqrestore
(
&
trans
_pcie
->
irq_
lock
,
flags
);
return
IRQ_NONE
;
}
...
...
@@ -1369,7 +1365,7 @@ irqreturn_t iwl_isr_ict(int irq, void *data)
trace_iwlwifi_dev_irq
(
priv
(
trans
));
spin_lock_irqsave
(
&
trans
->
shrd
->
lock
,
flags
);
spin_lock_irqsave
(
&
trans
_pcie
->
irq_
lock
,
flags
);
/* Disable (but don't clear!) interrupts here to avoid
* back-to-back ISRs and sporadic interrupts from our NIC.
...
...
@@ -1440,7 +1436,7 @@ irqreturn_t iwl_isr_ict(int irq, void *data)
iwl_enable_interrupts
(
trans
);
}
spin_unlock_irqrestore
(
&
trans
->
shrd
->
lock
,
flags
);
spin_unlock_irqrestore
(
&
trans
_pcie
->
irq_
lock
,
flags
);
return
IRQ_HANDLED
;
none:
...
...
@@ -1451,6 +1447,6 @@ irqreturn_t iwl_isr_ict(int irq, void *data)
!
trans_pcie
->
inta
)
iwl_enable_interrupts
(
trans
);
spin_unlock_irqrestore
(
&
trans
->
shrd
->
lock
,
flags
);
spin_unlock_irqrestore
(
&
trans
_pcie
->
irq_
lock
,
flags
);
return
IRQ_NONE
;
}
drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c
View file @
d896d463
...
...
@@ -492,7 +492,7 @@ void iwl_trans_pcie_tx_agg_setup(struct iwl_trans *trans,
ra_tid
=
BUILD_RAxTID
(
sta_id
,
tid
);
spin_lock_irqsave
(
&
trans
->
shrd
->
lock
,
flags
);
spin_lock_irqsave
(
&
trans
_pcie
->
irq_
lock
,
flags
);
/* Stop this Tx queue before configuring it */
iwlagn_tx_queue_stop_scheduler
(
trans
,
txq_id
);
...
...
@@ -532,7 +532,7 @@ void iwl_trans_pcie_tx_agg_setup(struct iwl_trans *trans,
trans_pcie
->
txq
[
txq_id
].
sta_id
=
sta_id
;
trans_pcie
->
txq
[
txq_id
].
tid
=
tid
;
spin_unlock_irqrestore
(
&
trans
->
shrd
->
lock
,
flags
);
spin_unlock_irqrestore
(
&
trans
_pcie
->
irq_
lock
,
flags
);
}
/*
...
...
drivers/net/wireless/iwlwifi/iwl-trans-pcie.c
View file @
d896d463
...
...
@@ -219,10 +219,10 @@ static int iwl_rx_init(struct iwl_trans *trans)
iwl_trans_rx_hw_init
(
trans
,
rxq
);
spin_lock_irqsave
(
&
trans
->
shrd
->
lock
,
flags
);
spin_lock_irqsave
(
&
trans
_pcie
->
irq_
lock
,
flags
);
rxq
->
need_update
=
1
;
iwl_rx_queue_update_write_ptr
(
trans
,
rxq
);
spin_unlock_irqrestore
(
&
trans
->
shrd
->
lock
,
flags
);
spin_unlock_irqrestore
(
&
trans
_pcie
->
irq_
lock
,
flags
);
return
0
;
}
...
...
@@ -585,7 +585,7 @@ static int iwl_tx_init(struct iwl_trans *trans)
alloc
=
true
;
}
spin_lock_irqsave
(
&
trans
->
shrd
->
lock
,
flags
);
spin_lock_irqsave
(
&
trans
_pcie
->
irq_
lock
,
flags
);
/* Turn off all Tx DMA fifos */
iwl_write_prph
(
trans
,
SCD_TXFACT
,
0
);
...
...
@@ -594,7 +594,7 @@ static int iwl_tx_init(struct iwl_trans *trans)
iwl_write_direct32
(
trans
,
FH_KW_MEM_ADDR_REG
,
trans_pcie
->
kw
.
dma
>>
4
);
spin_unlock_irqrestore
(
&
trans
->
shrd
->
lock
,
flags
);
spin_unlock_irqrestore
(
&
trans
_pcie
->
irq_
lock
,
flags
);
/* Alloc and init all Tx queues, including the command queue (#4/#9) */
for
(
txq_id
=
0
;
txq_id
<
hw_params
(
trans
).
max_txq_num
;
txq_id
++
)
{
...
...
@@ -803,17 +803,18 @@ static void iwl_apm_stop(struct iwl_trans *trans)
static
int
iwl_nic_init
(
struct
iwl_trans
*
trans
)
{
struct
iwl_trans_pcie
*
trans_pcie
=
IWL_TRANS_GET_PCIE_TRANS
(
trans
);
unsigned
long
flags
;
/* nic_init */
spin_lock_irqsave
(
&
trans
->
shrd
->
lock
,
flags
);
spin_lock_irqsave
(
&
trans
_pcie
->
irq_
lock
,
flags
);
iwl_apm_init
(
trans
);
/* Set interrupt coalescing calibration timer to default (512 usecs) */
iwl_write8
(
trans
,
CSR_INT_COALESCING
,
IWL_HOST_INT_CALIB_TIMEOUT_DEF
);
spin_unlock_irqrestore
(
&
trans
->
shrd
->
lock
,
flags
);
spin_unlock_irqrestore
(
&
trans
_pcie
->
irq_
lock
,
flags
);
iwl_set_pwr_vmain
(
trans
);
...
...
@@ -1078,10 +1079,15 @@ static int iwl_trans_pcie_start_fw(struct iwl_trans *trans, struct fw_img *fw)
/*
* Activate/Deactivate Tx DMA/FIFO channels according tx fifos mask
* must be called under
priv->shrd->lock and mac
access
* must be called under
the irq lock and with MAC
access
*/
static
void
iwl_trans_txq_set_sched
(
struct
iwl_trans
*
trans
,
u32
mask
)
{
struct
iwl_trans_pcie
__maybe_unused
*
trans_pcie
=
IWL_TRANS_GET_PCIE_TRANS
(
trans
);
lockdep_assert_held
(
&
trans_pcie
->
irq_lock
);
iwl_write_prph
(
trans
,
SCD_TXFACT
,
mask
);
}
...
...
@@ -1095,7 +1101,7 @@ static void iwl_tx_start(struct iwl_trans *trans)
int
i
,
chan
;
u32
reg_val
;
spin_lock_irqsave
(
&
trans
->
shrd
->
lock
,
flags
);
spin_lock_irqsave
(
&
trans
_pcie
->
irq_
lock
,
flags
);
trans_pcie
->
scd_base_addr
=
iwl_read_prph
(
trans
,
SCD_SRAM_BASE_ADDR
);
...
...
@@ -1191,7 +1197,7 @@ static void iwl_tx_start(struct iwl_trans *trans)
fifo
,
0
);
}
spin_unlock_irqrestore
(
&
trans
->
shrd
->
lock
,
flags
);
spin_unlock_irqrestore
(
&
trans
_pcie
->
irq_
lock
,
flags
);
/* Enable L1-Active */
iwl_clear_bits_prph
(
trans
,
APMG_PCIDEV_STT_REG
,
...
...
@@ -1214,7 +1220,7 @@ static int iwl_trans_tx_stop(struct iwl_trans *trans)
struct
iwl_trans_pcie
*
trans_pcie
=
IWL_TRANS_GET_PCIE_TRANS
(
trans
);
/* Turn off all Tx DMA fifos */
spin_lock_irqsave
(
&
trans
->
shrd
->
lock
,
flags
);
spin_lock_irqsave
(
&
trans
_pcie
->
irq_
lock
,
flags
);
iwl_trans_txq_set_sched
(
trans
,
0
);
...
...
@@ -1230,7 +1236,7 @@ static int iwl_trans_tx_stop(struct iwl_trans *trans)
iwl_read_direct32
(
trans
,
FH_TSSR_TX_STATUS_REG
));
}
spin_unlock_irqrestore
(
&
trans
->
shrd
->
lock
,
flags
);
spin_unlock_irqrestore
(
&
trans
_pcie
->
irq_
lock
,
flags
);
if
(
!
trans_pcie
->
txq
)
{
IWL_WARN
(
trans
,
"Stopping tx queues that aren't allocated..."
);
...
...
@@ -1250,9 +1256,9 @@ static void iwl_trans_pcie_stop_device(struct iwl_trans *trans)
struct
iwl_trans_pcie
*
trans_pcie
=
IWL_TRANS_GET_PCIE_TRANS
(
trans
);
/* tell the device to stop sending interrupts */
spin_lock_irqsave
(
&
trans
->
shrd
->
lock
,
flags
);
spin_lock_irqsave
(
&
trans
_pcie
->
irq_
lock
,
flags
);
iwl_disable_interrupts
(
trans
);
spin_unlock_irqrestore
(
&
trans
->
shrd
->
lock
,
flags
);
spin_unlock_irqrestore
(
&
trans
_pcie
->
irq_
lock
,
flags
);
/* device going down, Stop using ICT table */
iwl_disable_ict
(
trans
);
...
...
@@ -1285,14 +1291,16 @@ static void iwl_trans_pcie_stop_device(struct iwl_trans *trans)
/* Upon stop, the APM issues an interrupt if HW RF kill is set.
* Clean again the interrupt here
*/
spin_lock_irqsave
(
&
trans
->
shrd
->
lock
,
flags
);
spin_lock_irqsave
(
&
trans
_pcie
->
irq_
lock
,
flags
);
iwl_disable_interrupts
(
trans
);
spin_unlock_irqrestore
(
&
trans
->
shrd
->
lock
,
flags
);
spin_unlock_irqrestore
(
&
trans
_pcie
->
irq_
lock
,
flags
);
/* wait to make sure we flush pending tasklet*/
synchronize_irq
(
trans
->
irq
);
tasklet_kill
(
&
trans_pcie
->
irq_tasklet
);
cancel_work_sync
(
&
trans_pcie
->
rx_replenish
);
/* stop and reset the on-board processor */
iwl_write32
(
trans
,
CSR_RESET
,
CSR_RESET_REG_FLAG_NEVO_RESET
);
}
...
...
@@ -2259,6 +2267,7 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct iwl_shared *shrd,
trans
->
shrd
=
shrd
;
trans_pcie
->
trans
=
trans
;
spin_lock_init
(
&
trans
->
hcmd_lock
);
spin_lock_init
(
&
trans_pcie
->
irq_lock
);
/* W/A - seems to solve weird behavior. We need to remove this if we
* don't want to stay in L1 all the time. This wastes a lot of power */
...
...
drivers/net/wireless/iwlwifi/iwl-trans.h
View file @
d896d463
...
...
@@ -68,18 +68,75 @@
#include "iwl-shared.h"
#include "iwl-commands.h"
#include "iwl-ucode.h"
#include "iwl-debug.h"
/*This file includes the declaration that are exported from the transport
* layer */
/**
* DOC: Transport layer - what is it ?
*
* The tranport layer is the layer that deals with the HW directly. It provides
* an abstraction of the underlying HW to the upper layer. The transport layer
* doesn't provide any policy, algorithm or anything of this kind, but only
* mechanisms to make the HW do something.It is not completely stateless but
* close to it.
* We will have an implementation for each different supported bus.
*/
/**
* DOC: Life cycle of the transport layer
*
* The transport layer has a very precise life cycle.
*
* 1) A helper function is called during the module initialization and
* registers the bus driver's ops with the transport's alloc function.
* 2) Bus's probe calls to the transport layer's allocation functions.
* Of course this function is bus specific.
* 3) This allocation functions will spawn the upper layer which will
* register mac80211.
*
* 4) At some point (i.e. mac80211's start call), the op_mode will call
* the following sequence:
* start_hw
* start_fw
*
* 5) Then when finished (or reset):
* stop_fw (a.k.a. stop device for the moment)
* stop_hw
*
* 6) Eventually, the free function will be called.
*/
/**
* DOC: API needed by the transport layer from the op_mode
*
* TODO
*/
struct
iwl_priv
;
struct
iwl_shared
;
/**
* DOC: Host command section
*
* A host command is a commaned issued by the upper layer to the fw. There are
* several versions of fw that have several APIs. The transport layer is
* completely agnostic to these differences.
* The transport does provide helper functionnality (i.e. SYNC / ASYNC mode),
*/
#define SEQ_TO_SN(seq) (((seq) & IEEE80211_SCTL_SEQ) >> 4)
#define SN_TO_SEQ(ssn) (((ssn) << 4) & IEEE80211_SCTL_SEQ)
#define MAX_SN ((IEEE80211_SCTL_SEQ) >> 4)
enum
{
/**
* enum CMD_MODE - how to send the host commands ?
*
* @CMD_SYNC: The caller will be stalled until the fw responds to the command
* @CMD_ASYNC: Return right away and don't want for the response
* @CMD_WANT_SKB: valid only with CMD_SYNC. The caller needs the buffer of the
* response.
* @CMD_ON_DEMAND: This command is sent by the test mode pipe.
*/
enum
CMD_MODE
{
CMD_SYNC
=
0
,
CMD_ASYNC
=
BIT
(
0
),
CMD_WANT_SKB
=
BIT
(
1
),
...
...
@@ -104,20 +161,29 @@ struct iwl_device_cmd {
#define IWL_MAX_CMD_TFDS 2
/**
* struct iwl_hcmd_dataflag - flag for each one of the chunks of the command
*
* IWL_HCMD_DFL_NOCOPY: By default, the command is copied to the host command's
* ring. The transport layer doesn't map the command's buffer to DMA, but
* rather copies it to an previously allocated DMA buffer. This flag tells
* the transport layer not to copy the command, but to map the existing
* buffer. This can save memcpy and is worth with very big comamnds.
*/
enum
iwl_hcmd_dataflag
{
IWL_HCMD_DFL_NOCOPY
=
BIT
(
0
),
};
/**
* struct iwl_host_cmd - Host command to the uCode
*
* @data: array of chunks that composes the data of the host command
* @reply_page: pointer to the page that holds the response to the host command
* @handler_status: return value of the handler of the command
* (put in setup_rx_handlers) - valid for SYNC mode only
* @callback:
* @flags: can be CMD_* note CMD_WANT_SKB is incompatible withe CMD_ASYNC
* @flags: can be CMD_*
* @len: array of the lenths of the chunks in data
* @dataflags:
* @dataflags:
IWL_HCMD_DFL_*
* @id: id of the host command
*/
struct
iwl_host_cmd
{
...
...
@@ -131,40 +197,45 @@ struct iwl_host_cmd {
u8
id
;
};
/* one for each uCode image (inst/data, boot/init/runtime) */
struct
fw_desc
{
dma_addr_t
p_addr
;
/* hardware address */
void
*
v_addr
;
/* software address */
u32
len
;
/* size in bytes */
};
struct
fw_img
{
struct
fw_desc
code
;
/* firmware code image */
struct
fw_desc
data
;
/* firmware data image */
};
/**
* struct iwl_trans_ops - transport specific operations
*
* All the handlers MUST be implemented
*
* @start_hw: starts the HW- from that point on, the HW can send interrupts
* May sleep
* @stop_hw: stops the HW- from that point on, the HW will be in low power but
* will still issue interrupt if the HW RF kill is triggered.
* May sleep
* @start_fw: allocates and inits all the resources for the transport
* layer. Also kick a fw image. This handler may sleep.
* layer. Also kick a fw image.
* May sleep
* @fw_alive: called when the fw sends alive notification
* May sleep
* @wake_any_queue: wake all the queues of a specfic context IWL_RXON_CTX_*
* @stop_device:stops the whole device (embedded CPU put to reset)
* May sleep
* @send_cmd:send a host command
* May sleep only if CMD_SYNC is set
* @tx: send an skb
* Must be atomic
* @reclaim: free packet until ssn. Returns a list of freed packets.
* Must be atomic
* @tx_agg_alloc: allocate resources for a TX BA session
* May sleep
* @tx_agg_setup: setup a tx queue for AMPDU - will be called once the HW is
* ready and a successful ADDBA response has been received.
* ready and a successful ADDBA response has been received.
* May sleep
* @tx_agg_disable: de-configure a Tx queue to send AMPDUs
* May sleep
* @free: release all the ressource for the transport layer itself such as
* irq, tasklet etc...
* irq, tasklet etc... From this point on, the device may not issue
* any interrupt (incl. RFKILL).
* May sleep
* @stop_queue: stop a specific queue
* @check_stuck_queue: check if a specific queue is stuck
* @wait_tx_queue_empty: wait until all tx queues are empty
* May sleep
* @dbgfs_register: add the dbgfs files under this directory. Files will be
* automatically deleted.
* @suspend: stop the device unless WoWLAN is configured
...
...
@@ -226,8 +297,20 @@ struct iwl_calib_result {
/* data follows */
};
/**
* enum iwl_trans_state - state of the transport layer
*
* @IWL_TRANS_NO_FW: no fw has sent an alive response
* @IWL_TRANS_FW_ALIVE: a fw has sent an alive response
*/
enum
iwl_trans_state
{
IWL_TRANS_NO_FW
=
0
,
IWL_TRANS_FW_ALIVE
=
1
,
};
/**
* struct iwl_trans - transport common data
*
* @ops - pointer to iwl_trans_ops
* @shrd - pointer to iwl_shared which holds shared data from the upper layer
* @hcmd_lock: protects HCMD
...
...
@@ -235,12 +318,9 @@ struct iwl_calib_result {
* @dev - pointer to struct device * that represents the device
* @irq - the irq number for the device
* @hw_id: a u32 with the ID of the device / subdevice.
* Set during transport alloac
tion.
* Set during transport alloca
tion.
* @hw_id_str: a string with info about HW ID. Set during transport allocation.
* @ucode_write_complete: indicates that the ucode has been copied.
* @ucode_rt: run time ucode image
* @ucode_init: init ucode image
* @ucode_wowlan: wake on wireless ucode image (optional)
* @nvm_device_type: indicates OTP or eeprom
* @pm_support: set to true in start_hw if link pm is supported
* @calib_results: list head for init calibration results
...
...
@@ -248,6 +328,7 @@ struct iwl_calib_result {
struct
iwl_trans
{
const
struct
iwl_trans_ops
*
ops
;
struct
iwl_shared
*
shrd
;
enum
iwl_trans_state
state
;
spinlock_t
hcmd_lock
;
spinlock_t
reg_lock
;
...
...
@@ -257,16 +338,11 @@ struct iwl_trans {
u32
hw_id
;
char
hw_id_str
[
52
];
u8
ucode_write_complete
;
/* the image write is complete */
struct
fw_img
ucode_rt
;
struct
fw_img
ucode_init
;
struct
fw_img
ucode_wowlan
;
u8
ucode_write_complete
;
/* eeprom related variables */
int
nvm_device_type
;
bool
pm_support
;
/* init calibration results */
struct
list_head
calib_results
;
/* pointer to trans specific struct */
...
...
@@ -276,17 +352,27 @@ struct iwl_trans {
static
inline
int
iwl_trans_start_hw
(
struct
iwl_trans
*
trans
)
{
might_sleep
();
return
trans
->
ops
->
start_hw
(
trans
);
}
static
inline
void
iwl_trans_stop_hw
(
struct
iwl_trans
*
trans
)
{
might_sleep
();
trans
->
ops
->
stop_hw
(
trans
);
trans
->
state
=
IWL_TRANS_NO_FW
;
}
static
inline
void
iwl_trans_fw_alive
(
struct
iwl_trans
*
trans
)
{
might_sleep
();
trans
->
ops
->
fw_alive
(
trans
);
trans
->
state
=
IWL_TRANS_FW_ALIVE
;
}
static
inline
int
iwl_trans_start_fw
(
struct
iwl_trans
*
trans
,
struct
fw_img
*
fw
)
...
...
@@ -298,13 +384,20 @@ static inline int iwl_trans_start_fw(struct iwl_trans *trans, struct fw_img *fw)
static
inline
void
iwl_trans_stop_device
(
struct
iwl_trans
*
trans
)
{
might_sleep
();
trans
->
ops
->
stop_device
(
trans
);
trans
->
state
=
IWL_TRANS_NO_FW
;
}
static
inline
void
iwl_trans_wake_any_queue
(
struct
iwl_trans
*
trans
,
enum
iwl_rxon_context_id
ctx
,
const
char
*
msg
)
{
if
(
trans
->
state
!=
IWL_TRANS_FW_ALIVE
)
IWL_ERR
(
trans
,
"%s bad state = %d"
,
__func__
,
trans
->
state
);
trans
->
ops
->
wake_any_queue
(
trans
,
ctx
,
msg
);
}
...
...
@@ -312,6 +405,9 @@ static inline void iwl_trans_wake_any_queue(struct iwl_trans *trans,
static
inline
int
iwl_trans_send_cmd
(
struct
iwl_trans
*
trans
,
struct
iwl_host_cmd
*
cmd
)
{
if
(
trans
->
state
!=
IWL_TRANS_FW_ALIVE
)
IWL_ERR
(
trans
,
"%s bad state = %d"
,
__func__
,
trans
->
state
);
return
trans
->
ops
->
send_cmd
(
trans
,
cmd
);
}
...
...
@@ -322,6 +418,9 @@ static inline int iwl_trans_tx(struct iwl_trans *trans, struct sk_buff *skb,
struct
iwl_device_cmd
*
dev_cmd
,
enum
iwl_rxon_context_id
ctx
,
u8
sta_id
,
u8
tid
)
{
if
(
trans
->
state
!=
IWL_TRANS_FW_ALIVE
)
IWL_ERR
(
trans
,
"%s bad state = %d"
,
__func__
,
trans
->
state
);
return
trans
->
ops
->
tx
(
trans
,
skb
,
dev_cmd
,
ctx
,
sta_id
,
tid
);
}
...
...
@@ -329,6 +428,9 @@ static inline int iwl_trans_reclaim(struct iwl_trans *trans, int sta_id,
int
tid
,
int
txq_id
,
int
ssn
,
u32
status
,
struct
sk_buff_head
*
skbs
)
{
if
(
trans
->
state
!=
IWL_TRANS_FW_ALIVE
)
IWL_ERR
(
trans
,
"%s bad state = %d"
,
__func__
,
trans
->
state
);
return
trans
->
ops
->
reclaim
(
trans
,
sta_id
,
tid
,
txq_id
,
ssn
,
status
,
skbs
);
}
...
...
@@ -336,12 +438,22 @@ static inline int iwl_trans_reclaim(struct iwl_trans *trans, int sta_id,
static
inline
int
iwl_trans_tx_agg_disable
(
struct
iwl_trans
*
trans
,
int
sta_id
,
int
tid
)
{
might_sleep
();
if
(
trans
->
state
!=
IWL_TRANS_FW_ALIVE
)
IWL_ERR
(
trans
,
"%s bad state = %d"
,
__func__
,
trans
->
state
);
return
trans
->
ops
->
tx_agg_disable
(
trans
,
sta_id
,
tid
);
}
static
inline
int
iwl_trans_tx_agg_alloc
(
struct
iwl_trans
*
trans
,
int
sta_id
,
int
tid
)
{
might_sleep
();
if
(
trans
->
state
!=
IWL_TRANS_FW_ALIVE
)
IWL_ERR
(
trans
,
"%s bad state = %d"
,
__func__
,
trans
->
state
);
return
trans
->
ops
->
tx_agg_alloc
(
trans
,
sta_id
,
tid
);
}
...
...
@@ -351,6 +463,11 @@ static inline void iwl_trans_tx_agg_setup(struct iwl_trans *trans,
int
sta_id
,
int
tid
,
int
frame_limit
,
u16
ssn
)
{
might_sleep
();
if
(
trans
->
state
!=
IWL_TRANS_FW_ALIVE
)
IWL_ERR
(
trans
,
"%s bad state = %d"
,
__func__
,
trans
->
state
);
trans
->
ops
->
tx_agg_setup
(
trans
,
ctx
,
sta_id
,
tid
,
frame_limit
,
ssn
);
}
...
...
@@ -362,16 +479,25 @@ static inline void iwl_trans_free(struct iwl_trans *trans)
static
inline
void
iwl_trans_stop_queue
(
struct
iwl_trans
*
trans
,
int
q
,
const
char
*
msg
)
{
if
(
trans
->
state
!=
IWL_TRANS_FW_ALIVE
)
IWL_ERR
(
trans
,
"%s bad state = %d"
,
__func__
,
trans
->
state
);
trans
->
ops
->
stop_queue
(
trans
,
q
,
msg
);
}
static
inline
int
iwl_trans_wait_tx_queue_empty
(
struct
iwl_trans
*
trans
)
{
if
(
trans
->
state
!=
IWL_TRANS_FW_ALIVE
)
IWL_ERR
(
trans
,
"%s bad state = %d"
,
__func__
,
trans
->
state
);
return
trans
->
ops
->
wait_tx_queue_empty
(
trans
);
}
static
inline
int
iwl_trans_check_stuck_queue
(
struct
iwl_trans
*
trans
,
int
q
)
{
if
(
trans
->
state
!=
IWL_TRANS_FW_ALIVE
)
IWL_ERR
(
trans
,
"%s bad state = %d"
,
__func__
,
trans
->
state
);
return
trans
->
ops
->
check_stuck_queue
(
trans
,
q
);
}
static
inline
int
iwl_trans_dbgfs_register
(
struct
iwl_trans
*
trans
,
...
...
@@ -410,8 +536,6 @@ static inline u32 iwl_trans_read32(struct iwl_trans *trans, u32 ofs)
/*****************************************************
* Utils functions
******************************************************/
void
iwl_dealloc_ucode
(
struct
iwl_trans
*
trans
);
int
iwl_send_calib_results
(
struct
iwl_trans
*
trans
);
int
iwl_calib_set
(
struct
iwl_trans
*
trans
,
const
struct
iwl_calib_hdr
*
cmd
,
int
len
);
...
...
drivers/net/wireless/iwlwifi/iwl-ucode.c
View file @
d896d463
...
...
@@ -82,29 +82,29 @@ static struct iwl_wimax_coex_event_entry cu_priorities[COEX_NUM_OF_EVENTS] = {
*
******************************************************************************/
static
void
iwl_free_fw_desc
(
struct
iwl_
trans
*
trans
,
struct
fw_desc
*
desc
)
static
void
iwl_free_fw_desc
(
struct
iwl_
nic
*
nic
,
struct
fw_desc
*
desc
)
{
if
(
desc
->
v_addr
)
dma_free_coherent
(
trans
->
dev
,
desc
->
len
,
dma_free_coherent
(
trans
(
nic
)
->
dev
,
desc
->
len
,
desc
->
v_addr
,
desc
->
p_addr
);
desc
->
v_addr
=
NULL
;
desc
->
len
=
0
;
}
static
void
iwl_free_fw_img
(
struct
iwl_
trans
*
trans
,
struct
fw_img
*
img
)
static
void
iwl_free_fw_img
(
struct
iwl_
nic
*
nic
,
struct
fw_img
*
img
)
{
iwl_free_fw_desc
(
trans
,
&
img
->
code
);
iwl_free_fw_desc
(
trans
,
&
img
->
data
);
iwl_free_fw_desc
(
nic
,
&
img
->
code
);
iwl_free_fw_desc
(
nic
,
&
img
->
data
);
}
void
iwl_dealloc_ucode
(
struct
iwl_
trans
*
trans
)
void
iwl_dealloc_ucode
(
struct
iwl_
nic
*
nic
)
{
iwl_free_fw_img
(
trans
,
&
trans
->
ucode_rt
);
iwl_free_fw_img
(
trans
,
&
trans
->
ucode_init
);
iwl_free_fw_img
(
trans
,
&
trans
->
ucode_wowlan
);
iwl_free_fw_img
(
nic
,
&
nic
->
fw
.
ucode_rt
);
iwl_free_fw_img
(
nic
,
&
nic
->
fw
.
ucode_init
);
iwl_free_fw_img
(
nic
,
&
nic
->
fw
.
ucode_wowlan
);
}
static
int
iwl_alloc_fw_desc
(
struct
iwl_
trans
*
trans
,
struct
fw_desc
*
desc
,
static
int
iwl_alloc_fw_desc
(
struct
iwl_
nic
*
nic
,
struct
fw_desc
*
desc
,
const
void
*
data
,
size_t
len
)
{
if
(
!
len
)
{
...
...
@@ -112,7 +112,7 @@ static int iwl_alloc_fw_desc(struct iwl_trans *trans, struct fw_desc *desc,
return
-
EINVAL
;
}
desc
->
v_addr
=
dma_alloc_coherent
(
trans
->
dev
,
len
,
desc
->
v_addr
=
dma_alloc_coherent
(
trans
(
nic
)
->
dev
,
len
,
&
desc
->
p_addr
,
GFP_KERNEL
);
if
(
!
desc
->
v_addr
)
return
-
ENOMEM
;
...
...
@@ -122,16 +122,16 @@ static int iwl_alloc_fw_desc(struct iwl_trans *trans, struct fw_desc *desc,
return
0
;
}
static
inline
struct
fw_img
*
iwl_get_ucode_image
(
struct
iwl_
trans
*
trans
,
static
inline
struct
fw_img
*
iwl_get_ucode_image
(
struct
iwl_
nic
*
nic
,
enum
iwl_ucode_type
ucode_type
)
{
switch
(
ucode_type
)
{
case
IWL_UCODE_INIT
:
return
&
trans
->
ucode_init
;
return
&
nic
->
fw
.
ucode_init
;
case
IWL_UCODE_WOWLAN
:
return
&
trans
->
ucode_wowlan
;
return
&
nic
->
fw
.
ucode_wowlan
;
case
IWL_UCODE_REGULAR
:
return
&
trans
->
ucode_rt
;
return
&
nic
->
fw
.
ucode_rt
;
case
IWL_UCODE_NONE
:
break
;
}
...
...
@@ -397,15 +397,16 @@ static int iwl_alive_notify(struct iwl_trans *trans)
* using sample data 100 bytes apart. If these sample points are good,
* it's a pretty good bet that everything between them is good, too.
*/
static
int
iwl_verify_inst_sparse
(
struct
iwl_
trans
*
trans
,
static
int
iwl_verify_inst_sparse
(
struct
iwl_
nic
*
nic
,
struct
fw_desc
*
fw_desc
)
{
struct
iwl_trans
*
trans
=
trans
(
nic
);
__le32
*
image
=
(
__le32
*
)
fw_desc
->
v_addr
;
u32
len
=
fw_desc
->
len
;
u32
val
;
u32
i
;
IWL_DEBUG_FW
(
trans
,
"ucode inst image size is %u
\n
"
,
len
);
IWL_DEBUG_FW
(
nic
,
"ucode inst image size is %u
\n
"
,
len
);
for
(
i
=
0
;
i
<
len
;
i
+=
100
,
image
+=
100
/
sizeof
(
u32
))
{
/* read data comes through single port, auto-incr addr */
...
...
@@ -421,16 +422,17 @@ static int iwl_verify_inst_sparse(struct iwl_trans *trans,
return
0
;
}
static
void
iwl_print_mismatch_inst
(
struct
iwl_
trans
*
trans
,
static
void
iwl_print_mismatch_inst
(
struct
iwl_
nic
*
nic
,
struct
fw_desc
*
fw_desc
)
{
struct
iwl_trans
*
trans
=
trans
(
nic
);
__le32
*
image
=
(
__le32
*
)
fw_desc
->
v_addr
;
u32
len
=
fw_desc
->
len
;
u32
val
;
u32
offs
;
int
errors
=
0
;
IWL_DEBUG_FW
(
trans
,
"ucode inst image size is %u
\n
"
,
len
);
IWL_DEBUG_FW
(
nic
,
"ucode inst image size is %u
\n
"
,
len
);
iwl_write_direct32
(
trans
,
HBUS_TARG_MEM_RADDR
,
IWLAGN_RTC_INST_LOWER_BOUND
);
...
...
@@ -441,7 +443,7 @@ static void iwl_print_mismatch_inst(struct iwl_trans *trans,
/* read data comes through single port, auto-incr addr */
val
=
iwl_read32
(
trans
,
HBUS_TARG_MEM_RDAT
);
if
(
val
!=
le32_to_cpu
(
*
image
))
{
IWL_ERR
(
trans
,
"uCode INST section at "
IWL_ERR
(
nic
,
"uCode INST section at "
"offset 0x%x, is 0x%x, s/b 0x%x
\n
"
,
offs
,
val
,
le32_to_cpu
(
*
image
));
errors
++
;
...
...
@@ -453,24 +455,24 @@ static void iwl_print_mismatch_inst(struct iwl_trans *trans,
* iwl_verify_ucode - determine which instruction image is in SRAM,
* and verify its contents
*/
static
int
iwl_verify_ucode
(
struct
iwl_
trans
*
trans
,
static
int
iwl_verify_ucode
(
struct
iwl_
nic
*
nic
,
enum
iwl_ucode_type
ucode_type
)
{
struct
fw_img
*
img
=
iwl_get_ucode_image
(
trans
,
ucode_type
);
struct
fw_img
*
img
=
iwl_get_ucode_image
(
nic
,
ucode_type
);
if
(
!
img
)
{
IWL_ERR
(
trans
,
"Invalid ucode requested (%d)
\n
"
,
ucode_type
);
IWL_ERR
(
nic
,
"Invalid ucode requested (%d)
\n
"
,
ucode_type
);
return
-
EINVAL
;
}
if
(
!
iwl_verify_inst_sparse
(
trans
,
&
img
->
code
))
{
IWL_DEBUG_FW
(
trans
,
"uCode is good in inst SRAM
\n
"
);
if
(
!
iwl_verify_inst_sparse
(
nic
,
&
img
->
code
))
{
IWL_DEBUG_FW
(
nic
,
"uCode is good in inst SRAM
\n
"
);
return
0
;
}
IWL_ERR
(
trans
,
"UCODE IMAGE IN INSTRUCTION SRAM NOT VALID!!
\n
"
);
IWL_ERR
(
nic
,
"UCODE IMAGE IN INSTRUCTION SRAM NOT VALID!!
\n
"
);
iwl_print_mismatch_inst
(
trans
,
&
img
->
code
);
iwl_print_mismatch_inst
(
nic
,
&
img
->
code
);
return
-
EIO
;
}
...
...
@@ -583,7 +585,7 @@ int iwl_load_ucode_wait_alive(struct iwl_trans *trans,
old_type
=
trans
->
shrd
->
ucode_type
;
trans
->
shrd
->
ucode_type
=
ucode_type
;
fw
=
iwl_get_ucode_image
(
trans
,
ucode_type
);
fw
=
iwl_get_ucode_image
(
nic
(
trans
)
,
ucode_type
);
if
(
!
fw
)
return
-
EINVAL
;
...
...
@@ -618,7 +620,7 @@ int iwl_load_ucode_wait_alive(struct iwl_trans *trans,
* skip it for WoWLAN.
*/
if
(
ucode_type
!=
IWL_UCODE_WOWLAN
)
{
ret
=
iwl_verify_ucode
(
trans
,
ucode_type
);
ret
=
iwl_verify_ucode
(
nic
(
trans
)
,
ucode_type
);
if
(
ret
)
{
trans
->
shrd
->
ucode_type
=
old_type
;
return
ret
;
...
...
@@ -647,7 +649,7 @@ int iwl_run_init_ucode(struct iwl_trans *trans)
lockdep_assert_held
(
&
trans
->
shrd
->
mutex
);
/* No init ucode required? Curious, but maybe ok */
if
(
!
trans
->
ucode_init
.
code
.
len
)
if
(
!
nic
(
trans
)
->
fw
.
ucode_init
.
code
.
len
)
return
0
;
if
(
trans
->
shrd
->
ucode_type
!=
IWL_UCODE_NONE
)
...
...
@@ -688,39 +690,40 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context);
#define UCODE_EXPERIMENTAL_INDEX 100
#define UCODE_EXPERIMENTAL_TAG "exp"
int
__must_check
iwl_request_firmware
(
struct
iwl_
priv
*
priv
,
bool
first
)
int
__must_check
iwl_request_firmware
(
struct
iwl_
nic
*
nic
,
bool
first
)
{
const
char
*
name_pre
=
cfg
(
priv
)
->
fw_name_pre
;
struct
iwl_cfg
*
cfg
=
cfg
(
nic
);
const
char
*
name_pre
=
cfg
->
fw_name_pre
;
char
tag
[
8
];
if
(
first
)
{
#ifdef CONFIG_IWLWIFI_DEBUG_EXPERIMENTAL_UCODE
priv
->
fw_index
=
UCODE_EXPERIMENTAL_INDEX
;
nic
->
fw_index
=
UCODE_EXPERIMENTAL_INDEX
;
strcpy
(
tag
,
UCODE_EXPERIMENTAL_TAG
);
}
else
if
(
priv
->
fw_index
==
UCODE_EXPERIMENTAL_INDEX
)
{
}
else
if
(
nic
->
fw_index
==
UCODE_EXPERIMENTAL_INDEX
)
{
#endif
priv
->
fw_index
=
cfg
(
priv
)
->
ucode_api_max
;
sprintf
(
tag
,
"%d"
,
priv
->
fw_index
);
nic
->
fw_index
=
cfg
->
ucode_api_max
;
sprintf
(
tag
,
"%d"
,
nic
->
fw_index
);
}
else
{
priv
->
fw_index
--
;
sprintf
(
tag
,
"%d"
,
priv
->
fw_index
);
nic
->
fw_index
--
;
sprintf
(
tag
,
"%d"
,
nic
->
fw_index
);
}
if
(
priv
->
fw_index
<
cfg
(
priv
)
->
ucode_api_min
)
{
IWL_ERR
(
priv
,
"no suitable firmware found!
\n
"
);
if
(
nic
->
fw_index
<
cfg
->
ucode_api_min
)
{
IWL_ERR
(
nic
,
"no suitable firmware found!
\n
"
);
return
-
ENOENT
;
}
sprintf
(
priv
->
firmware_name
,
"%s%s%s"
,
name_pre
,
tag
,
".ucode"
);
sprintf
(
nic
->
firmware_name
,
"%s%s%s"
,
name_pre
,
tag
,
".ucode"
);
IWL_DEBUG_INFO
(
priv
,
"attempting to load firmware %s'%s'
\n
"
,
(
priv
->
fw_index
==
UCODE_EXPERIMENTAL_INDEX
)
IWL_DEBUG_INFO
(
nic
,
"attempting to load firmware %s'%s'
\n
"
,
(
nic
->
fw_index
==
UCODE_EXPERIMENTAL_INDEX
)
?
"EXPERIMENTAL "
:
""
,
priv
->
firmware_name
);
nic
->
firmware_name
);
return
request_firmware_nowait
(
THIS_MODULE
,
1
,
priv
->
firmware_name
,
trans
(
priv
)
->
dev
,
GFP_KERNEL
,
priv
,
iwl_ucode_callback
);
return
request_firmware_nowait
(
THIS_MODULE
,
1
,
nic
->
firmware_name
,
trans
(
nic
)
->
dev
,
GFP_KERNEL
,
nic
,
iwl_ucode_callback
);
}
struct
iwlagn_firmware_pieces
{
...
...
@@ -734,7 +737,7 @@ struct iwlagn_firmware_pieces {
u32
inst_evtlog_ptr
,
inst_evtlog_size
,
inst_errlog_ptr
;
};
static
int
iwl
agn_load_legacy_firmware
(
struct
iwl_priv
*
priv
,
static
int
iwl
_parse_v1_v2_firmware
(
struct
iwl_nic
*
nic
,
const
struct
firmware
*
ucode_raw
,
struct
iwlagn_firmware_pieces
*
pieces
)
{
...
...
@@ -742,14 +745,14 @@ static int iwlagn_load_legacy_firmware(struct iwl_priv *priv,
u32
api_ver
,
hdr_size
;
const
u8
*
src
;
priv
->
ucode_ver
=
le32_to_cpu
(
ucode
->
ver
);
api_ver
=
IWL_UCODE_API
(
priv
->
ucode_ver
);
nic
->
fw
.
ucode_ver
=
le32_to_cpu
(
ucode
->
ver
);
api_ver
=
IWL_UCODE_API
(
nic
->
fw
.
ucode_ver
);
switch
(
api_ver
)
{
default:
hdr_size
=
28
;
if
(
ucode_raw
->
size
<
hdr_size
)
{
IWL_ERR
(
priv
,
"File size too small!
\n
"
);
IWL_ERR
(
nic
,
"File size too small!
\n
"
);
return
-
EINVAL
;
}
pieces
->
build
=
le32_to_cpu
(
ucode
->
u
.
v2
.
build
);
...
...
@@ -764,7 +767,7 @@ static int iwlagn_load_legacy_firmware(struct iwl_priv *priv,
case
2
:
hdr_size
=
24
;
if
(
ucode_raw
->
size
<
hdr_size
)
{
IWL_ERR
(
priv
,
"File size too small!
\n
"
);
IWL_ERR
(
nic
,
"File size too small!
\n
"
);
return
-
EINVAL
;
}
pieces
->
build
=
0
;
...
...
@@ -781,7 +784,7 @@ static int iwlagn_load_legacy_firmware(struct iwl_priv *priv,
pieces
->
data_size
+
pieces
->
init_size
+
pieces
->
init_data_size
)
{
IWL_ERR
(
priv
,
IWL_ERR
(
nic
,
"uCode file size %d does not match expected size
\n
"
,
(
int
)
ucode_raw
->
size
);
return
-
EINVAL
;
...
...
@@ -799,10 +802,10 @@ static int iwlagn_load_legacy_firmware(struct iwl_priv *priv,
return
0
;
}
static
int
iwl
agn_load_firmware
(
struct
iwl_priv
*
priv
,
static
int
iwl
_parse_tlv_firmware
(
struct
iwl_nic
*
nic
,
const
struct
firmware
*
ucode_raw
,
struct
iwlagn_firmware_pieces
*
pieces
,
struct
iwl
agn
_ucode_capabilities
*
capa
)
struct
iwl_ucode_capabilities
*
capa
)
{
struct
iwl_tlv_ucode_header
*
ucode
=
(
void
*
)
ucode_raw
->
data
;
struct
iwl_ucode_tlv
*
tlv
;
...
...
@@ -816,12 +819,12 @@ static int iwlagn_load_firmware(struct iwl_priv *priv,
const
u8
*
tlv_data
;
if
(
len
<
sizeof
(
*
ucode
))
{
IWL_ERR
(
priv
,
"uCode has invalid length: %zd
\n
"
,
len
);
IWL_ERR
(
nic
,
"uCode has invalid length: %zd
\n
"
,
len
);
return
-
EINVAL
;
}
if
(
ucode
->
magic
!=
cpu_to_le32
(
IWL_TLV_UCODE_MAGIC
))
{
IWL_ERR
(
priv
,
"invalid uCode magic: 0X%x
\n
"
,
IWL_ERR
(
nic
,
"invalid uCode magic: 0X%x
\n
"
,
le32_to_cpu
(
ucode
->
magic
));
return
-
EINVAL
;
}
...
...
@@ -839,11 +842,11 @@ static int iwlagn_load_firmware(struct iwl_priv *priv,
while
(
wanted_alternative
&&
!
(
alternatives
&
BIT
(
wanted_alternative
)))
wanted_alternative
--
;
if
(
wanted_alternative
&&
wanted_alternative
!=
tmp
)
IWL_WARN
(
priv
,
IWL_WARN
(
nic
,
"uCode alternative %d not available, choosing %d
\n
"
,
tmp
,
wanted_alternative
);
priv
->
ucode_ver
=
le32_to_cpu
(
ucode
->
ver
);
nic
->
fw
.
ucode_ver
=
le32_to_cpu
(
ucode
->
ver
);
pieces
->
build
=
le32_to_cpu
(
ucode
->
build
);
data
=
ucode
->
data
;
...
...
@@ -861,7 +864,7 @@ static int iwlagn_load_firmware(struct iwl_priv *priv,
tlv_data
=
tlv
->
data
;
if
(
len
<
tlv_len
)
{
IWL_ERR
(
priv
,
"invalid TLV len: %zd/%u
\n
"
,
IWL_ERR
(
nic
,
"invalid TLV len: %zd/%u
\n
"
,
len
,
tlv_len
);
return
-
EINVAL
;
}
...
...
@@ -894,7 +897,7 @@ static int iwlagn_load_firmware(struct iwl_priv *priv,
pieces
->
init_data_size
=
tlv_len
;
break
;
case
IWL_UCODE_TLV_BOOT
:
IWL_ERR
(
priv
,
"Found unexpected BOOT ucode
\n
"
);
IWL_ERR
(
nic
,
"Found unexpected BOOT ucode
\n
"
);
break
;
case
IWL_UCODE_TLV_PROBE_MAX_LEN
:
if
(
tlv_len
!=
sizeof
(
u32
))
...
...
@@ -962,7 +965,7 @@ static int iwlagn_load_firmware(struct iwl_priv *priv,
case
IWL_UCODE_TLV_ENHANCE_SENS_TBL
:
if
(
tlv_len
)
goto
invalid_tlv_len
;
priv
->
enhance_sensitivity_table
=
true
;
nic
->
fw
.
enhance_sensitivity_table
=
true
;
break
;
case
IWL_UCODE_TLV_WOWLAN_INST
:
pieces
->
wowlan_inst
=
tlv_data
;
...
...
@@ -979,22 +982,22 @@ static int iwlagn_load_firmware(struct iwl_priv *priv,
le32_to_cpup
((
__le32
*
)
tlv_data
);
break
;
default:
IWL_DEBUG_INFO
(
priv
,
"unknown TLV: %d
\n
"
,
tlv_type
);
IWL_DEBUG_INFO
(
nic
,
"unknown TLV: %d
\n
"
,
tlv_type
);
break
;
}
}
if
(
len
)
{
IWL_ERR
(
priv
,
"invalid TLV after parsing: %zd
\n
"
,
len
);
iwl_print_hex_dump
(
priv
,
IWL_DL_FW
,
(
u8
*
)
data
,
len
);
IWL_ERR
(
nic
,
"invalid TLV after parsing: %zd
\n
"
,
len
);
iwl_print_hex_dump
(
nic
,
IWL_DL_FW
,
(
u8
*
)
data
,
len
);
return
-
EINVAL
;
}
return
0
;
invalid_tlv_len:
IWL_ERR
(
priv
,
"TLV %d has invalid size: %u
\n
"
,
tlv_type
,
tlv_len
);
iwl_print_hex_dump
(
priv
,
IWL_DL_FW
,
tlv_data
,
tlv_len
);
IWL_ERR
(
nic
,
"TLV %d has invalid size: %u
\n
"
,
tlv_type
,
tlv_len
);
iwl_print_hex_dump
(
nic
,
IWL_DL_FW
,
tlv_data
,
tlv_len
);
return
-
EINVAL
;
}
...
...
@@ -1007,21 +1010,23 @@ static int iwlagn_load_firmware(struct iwl_priv *priv,
*/
static
void
iwl_ucode_callback
(
const
struct
firmware
*
ucode_raw
,
void
*
context
)
{
struct
iwl_priv
*
priv
=
context
;
struct
iwl_nic
*
nic
=
context
;
struct
iwl_cfg
*
cfg
=
cfg
(
nic
);
struct
iwl_fw
*
fw
=
&
nic
->
fw
;
struct
iwl_priv
*
priv
=
priv
(
nic
);
/* temporary */
struct
iwl_ucode_header
*
ucode
;
int
err
;
struct
iwlagn_firmware_pieces
pieces
;
const
unsigned
int
api_max
=
cfg
(
priv
)
->
ucode_api_max
;
unsigned
int
api_ok
=
cfg
(
priv
)
->
ucode_api_ok
;
const
unsigned
int
api_min
=
cfg
(
priv
)
->
ucode_api_min
;
const
unsigned
int
api_max
=
cfg
->
ucode_api_max
;
unsigned
int
api_ok
=
cfg
->
ucode_api_ok
;
const
unsigned
int
api_min
=
cfg
->
ucode_api_min
;
u32
api_ver
;
char
buildstr
[
25
];
u32
build
;
struct
iwlagn_ucode_capabilities
ucode_capa
=
{
.
max_probe_length
=
200
,
.
standard_phy_calibration_size
=
IWL_DEFAULT_STANDARD_PHY_CALIBRATE_TBL_SIZE
,
};
fw
->
ucode_capa
.
max_probe_length
=
200
;
fw
->
ucode_capa
.
standard_phy_calibration_size
=
IWL_DEFAULT_STANDARD_PHY_CALIBRATE_TBL_SIZE
;
if
(
!
api_ok
)
api_ok
=
api_max
;
...
...
@@ -1029,19 +1034,19 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context)
memset
(
&
pieces
,
0
,
sizeof
(
pieces
));
if
(
!
ucode_raw
)
{
if
(
priv
->
fw_index
<=
api_ok
)
IWL_ERR
(
priv
,
if
(
nic
->
fw_index
<=
api_ok
)
IWL_ERR
(
nic
,
"request for firmware file '%s' failed.
\n
"
,
priv
->
firmware_name
);
nic
->
firmware_name
);
goto
try_again
;
}
IWL_DEBUG_INFO
(
priv
,
"Loaded firmware file '%s' (%zd bytes).
\n
"
,
priv
->
firmware_name
,
ucode_raw
->
size
);
IWL_DEBUG_INFO
(
nic
,
"Loaded firmware file '%s' (%zd bytes).
\n
"
,
nic
->
firmware_name
,
ucode_raw
->
size
);
/* Make sure that we got at least the API version number */
if
(
ucode_raw
->
size
<
4
)
{
IWL_ERR
(
priv
,
"File size way too small!
\n
"
);
IWL_ERR
(
nic
,
"File size way too small!
\n
"
);
goto
try_again
;
}
...
...
@@ -1049,15 +1054,15 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context)
ucode
=
(
struct
iwl_ucode_header
*
)
ucode_raw
->
data
;
if
(
ucode
->
ver
)
err
=
iwl
agn_load_legacy_firmware
(
priv
,
ucode_raw
,
&
pieces
);
err
=
iwl
_parse_v1_v2_firmware
(
nic
,
ucode_raw
,
&
pieces
);
else
err
=
iwl
agn_load_firmware
(
priv
,
ucode_raw
,
&
pieces
,
&
ucode_capa
);
err
=
iwl
_parse_tlv_firmware
(
nic
,
ucode_raw
,
&
pieces
,
&
fw
->
ucode_capa
);
if
(
err
)
goto
try_again
;
api_ver
=
IWL_UCODE_API
(
priv
->
ucode_ver
);
api_ver
=
IWL_UCODE_API
(
nic
->
fw
.
ucode_ver
);
build
=
pieces
.
build
;
/*
...
...
@@ -1066,9 +1071,9 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context)
* on the API version read from firmware header from here on forward
*/
/* no api version check required for experimental uCode */
if
(
priv
->
fw_index
!=
UCODE_EXPERIMENTAL_INDEX
)
{
if
(
nic
->
fw_index
!=
UCODE_EXPERIMENTAL_INDEX
)
{
if
(
api_ver
<
api_min
||
api_ver
>
api_max
)
{
IWL_ERR
(
priv
,
IWL_ERR
(
nic
,
"Driver unable to support your firmware API. "
"Driver supports v%u, firmware is v%u.
\n
"
,
api_max
,
api_ver
);
...
...
@@ -1077,39 +1082,39 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context)
if
(
api_ver
<
api_ok
)
{
if
(
api_ok
!=
api_max
)
IWL_ERR
(
priv
,
"Firmware has old API version, "
IWL_ERR
(
nic
,
"Firmware has old API version, "
"expected v%u through v%u, got v%u.
\n
"
,
api_ok
,
api_max
,
api_ver
);
else
IWL_ERR
(
priv
,
"Firmware has old API version, "
IWL_ERR
(
nic
,
"Firmware has old API version, "
"expected v%u, got v%u.
\n
"
,
api_max
,
api_ver
);
IWL_ERR
(
priv
,
"New firmware can be obtained from "
IWL_ERR
(
nic
,
"New firmware can be obtained from "
"http://www.intellinuxwireless.org/.
\n
"
);
}
}
if
(
build
)
sprintf
(
buildstr
,
" build %u%s"
,
build
,
(
priv
->
fw_index
==
UCODE_EXPERIMENTAL_INDEX
)
(
nic
->
fw_index
==
UCODE_EXPERIMENTAL_INDEX
)
?
" (EXP)"
:
""
);
else
buildstr
[
0
]
=
'\0'
;
IWL_INFO
(
priv
,
"loaded firmware version %u.%u.%u.%u%s
\n
"
,
IWL_UCODE_MAJOR
(
priv
->
ucode_ver
),
IWL_UCODE_MINOR
(
priv
->
ucode_ver
),
IWL_UCODE_API
(
priv
->
ucode_ver
),
IWL_UCODE_SERIAL
(
priv
->
ucode_ver
),
IWL_INFO
(
nic
,
"loaded firmware version %u.%u.%u.%u%s
\n
"
,
IWL_UCODE_MAJOR
(
nic
->
fw
.
ucode_ver
),
IWL_UCODE_MINOR
(
nic
->
fw
.
ucode_ver
),
IWL_UCODE_API
(
nic
->
fw
.
ucode_ver
),
IWL_UCODE_SERIAL
(
nic
->
fw
.
ucode_ver
),
buildstr
);
snprintf
(
priv
->
hw
->
wiphy
->
fw_version
,
sizeof
(
priv
->
hw
->
wiphy
->
fw_version
),
"%u.%u.%u.%u%s"
,
IWL_UCODE_MAJOR
(
priv
->
ucode_ver
),
IWL_UCODE_MINOR
(
priv
->
ucode_ver
),
IWL_UCODE_API
(
priv
->
ucode_ver
),
IWL_UCODE_SERIAL
(
priv
->
ucode_ver
),
IWL_UCODE_MAJOR
(
nic
->
fw
.
ucode_ver
),
IWL_UCODE_MINOR
(
nic
->
fw
.
ucode_ver
),
IWL_UCODE_API
(
nic
->
fw
.
ucode_ver
),
IWL_UCODE_SERIAL
(
nic
->
fw
.
ucode_ver
),
buildstr
);
/*
...
...
@@ -1118,38 +1123,38 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context)
* user just got a corrupted version of the latest API.
*/
IWL_DEBUG_INFO
(
priv
,
"f/w package hdr ucode version raw = 0x%x
\n
"
,
priv
->
ucode_ver
);
IWL_DEBUG_INFO
(
priv
,
"f/w package hdr runtime inst size = %Zd
\n
"
,
IWL_DEBUG_INFO
(
nic
,
"f/w package hdr ucode version raw = 0x%x
\n
"
,
nic
->
fw
.
ucode_ver
);
IWL_DEBUG_INFO
(
nic
,
"f/w package hdr runtime inst size = %Zd
\n
"
,
pieces
.
inst_size
);
IWL_DEBUG_INFO
(
priv
,
"f/w package hdr runtime data size = %Zd
\n
"
,
IWL_DEBUG_INFO
(
nic
,
"f/w package hdr runtime data size = %Zd
\n
"
,
pieces
.
data_size
);
IWL_DEBUG_INFO
(
priv
,
"f/w package hdr init inst size = %Zd
\n
"
,
IWL_DEBUG_INFO
(
nic
,
"f/w package hdr init inst size = %Zd
\n
"
,
pieces
.
init_size
);
IWL_DEBUG_INFO
(
priv
,
"f/w package hdr init data size = %Zd
\n
"
,
IWL_DEBUG_INFO
(
nic
,
"f/w package hdr init data size = %Zd
\n
"
,
pieces
.
init_data_size
);
/* Verify that uCode images will fit in card's SRAM */
if
(
pieces
.
inst_size
>
hw_params
(
priv
).
max_inst_size
)
{
IWL_ERR
(
priv
,
"uCode instr len %Zd too large to fit in
\n
"
,
if
(
pieces
.
inst_size
>
cfg
->
max_inst_size
)
{
IWL_ERR
(
nic
,
"uCode instr len %Zd too large to fit in
\n
"
,
pieces
.
inst_size
);
goto
try_again
;
}
if
(
pieces
.
data_size
>
hw_params
(
priv
).
max_data_size
)
{
IWL_ERR
(
priv
,
"uCode data len %Zd too large to fit in
\n
"
,
if
(
pieces
.
data_size
>
cfg
->
max_data_size
)
{
IWL_ERR
(
nic
,
"uCode data len %Zd too large to fit in
\n
"
,
pieces
.
data_size
);
goto
try_again
;
}
if
(
pieces
.
init_size
>
hw_params
(
priv
).
max_inst_size
)
{
IWL_ERR
(
priv
,
"uCode init instr len %Zd too large to fit in
\n
"
,
if
(
pieces
.
init_size
>
cfg
->
max_inst_size
)
{
IWL_ERR
(
nic
,
"uCode init instr len %Zd too large to fit in
\n
"
,
pieces
.
init_size
);
goto
try_again
;
}
if
(
pieces
.
init_data_size
>
hw_params
(
priv
).
max_data_size
)
{
IWL_ERR
(
priv
,
"uCode init data len %Zd too large to fit in
\n
"
,
if
(
pieces
.
init_data_size
>
cfg
->
max_data_size
)
{
IWL_ERR
(
nic
,
"uCode init data len %Zd too large to fit in
\n
"
,
pieces
.
init_data_size
);
goto
try_again
;
}
...
...
@@ -1159,34 +1164,34 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context)
/* Runtime instructions and 2 copies of data:
* 1) unmodified from disk
* 2) backup cache for save/restore during power-downs */
if
(
iwl_alloc_fw_desc
(
trans
(
priv
),
&
trans
(
priv
)
->
ucode_rt
.
code
,
if
(
iwl_alloc_fw_desc
(
nic
,
&
nic
->
fw
.
ucode_rt
.
code
,
pieces
.
inst
,
pieces
.
inst_size
))
goto
err_pci_alloc
;
if
(
iwl_alloc_fw_desc
(
trans
(
priv
),
&
trans
(
priv
)
->
ucode_rt
.
data
,
if
(
iwl_alloc_fw_desc
(
nic
,
&
nic
->
fw
.
ucode_rt
.
data
,
pieces
.
data
,
pieces
.
data_size
))
goto
err_pci_alloc
;
/* Initialization instructions and data */
if
(
pieces
.
init_size
&&
pieces
.
init_data_size
)
{
if
(
iwl_alloc_fw_desc
(
trans
(
priv
)
,
&
trans
(
priv
)
->
ucode_init
.
code
,
if
(
iwl_alloc_fw_desc
(
nic
,
&
nic
->
fw
.
ucode_init
.
code
,
pieces
.
init
,
pieces
.
init_size
))
goto
err_pci_alloc
;
if
(
iwl_alloc_fw_desc
(
trans
(
priv
)
,
&
trans
(
priv
)
->
ucode_init
.
data
,
if
(
iwl_alloc_fw_desc
(
nic
,
&
nic
->
fw
.
ucode_init
.
data
,
pieces
.
init_data
,
pieces
.
init_data_size
))
goto
err_pci_alloc
;
}
/* WoWLAN instructions and data */
if
(
pieces
.
wowlan_inst_size
&&
pieces
.
wowlan_data_size
)
{
if
(
iwl_alloc_fw_desc
(
trans
(
priv
)
,
&
trans
(
priv
)
->
ucode_wowlan
.
code
,
if
(
iwl_alloc_fw_desc
(
nic
,
&
nic
->
fw
.
ucode_wowlan
.
code
,
pieces
.
wowlan_inst
,
pieces
.
wowlan_inst_size
))
goto
err_pci_alloc
;
if
(
iwl_alloc_fw_desc
(
trans
(
priv
)
,
&
trans
(
priv
)
->
ucode_wowlan
.
data
,
if
(
iwl_alloc_fw_desc
(
nic
,
&
nic
->
fw
.
ucode_wowlan
.
data
,
pieces
.
wowlan_data
,
pieces
.
wowlan_data_size
))
goto
err_pci_alloc
;
...
...
@@ -1199,92 +1204,94 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context)
* for each event, which is of mode 1 (including timestamp) for all
* new microcodes that include this information.
*/
priv
->
init_evtlog_ptr
=
pieces
.
init_evtlog_ptr
;
nic
->
init_evtlog_ptr
=
pieces
.
init_evtlog_ptr
;
if
(
pieces
.
init_evtlog_size
)
priv
->
init_evtlog_size
=
(
pieces
.
init_evtlog_size
-
16
)
/
12
;
nic
->
init_evtlog_size
=
(
pieces
.
init_evtlog_size
-
16
)
/
12
;
else
priv
->
init_evtlog_size
=
cfg
(
priv
)
->
base_params
->
max_event_log_size
;
priv
->
init_errlog_ptr
=
pieces
.
init_errlog_ptr
;
priv
->
inst_evtlog_ptr
=
pieces
.
inst_evtlog_ptr
;
nic
->
init_evtlog_size
=
cfg
->
base_params
->
max_event_log_size
;
nic
->
init_errlog_ptr
=
pieces
.
init_errlog_ptr
;
nic
->
inst_evtlog_ptr
=
pieces
.
inst_evtlog_ptr
;
if
(
pieces
.
inst_evtlog_size
)
priv
->
inst_evtlog_size
=
(
pieces
.
inst_evtlog_size
-
16
)
/
12
;
nic
->
inst_evtlog_size
=
(
pieces
.
inst_evtlog_size
-
16
)
/
12
;
else
priv
->
inst_evtlog_size
=
cfg
(
priv
)
->
base_params
->
max_event_log_size
;
priv
->
inst_errlog_ptr
=
pieces
.
inst_errlog_ptr
;
nic
->
inst_evtlog_size
=
cfg
->
base_params
->
max_event_log_size
;
nic
->
inst_errlog_ptr
=
pieces
.
inst_errlog_ptr
;
#ifndef CONFIG_IWLWIFI_P2P
ucode_capa
.
flags
&=
~
IWL_UCODE_TLV_FLAGS_PAN
;
fw
->
ucode_capa
.
flags
&=
~
IWL_UCODE_TLV_FLAGS_PAN
;
#endif
priv
->
new_scan_threshold_behaviour
=
!!
(
ucode_capa
.
flags
&
IWL_UCODE_TLV_FLAGS_NEWSCAN
);
!!
(
fw
->
ucode_capa
.
flags
&
IWL_UCODE_TLV_FLAGS_NEWSCAN
);
if
(
!
(
cfg
(
priv
)
->
sku
&
EEPROM_SKU_CAP_IPAN_ENABLE
))
ucode_capa
.
flags
&=
~
IWL_UCODE_TLV_FLAGS_PAN
;
if
(
!
(
cfg
->
sku
&
EEPROM_SKU_CAP_IPAN_ENABLE
))
fw
->
ucode_capa
.
flags
&=
~
IWL_UCODE_TLV_FLAGS_PAN
;
/*
* if not PAN, then don't support P2P -- might be a uCode
* packaging bug or due to the eeprom check above
*/
if
(
!
(
ucode_capa
.
flags
&
IWL_UCODE_TLV_FLAGS_PAN
))
ucode_capa
.
flags
&=
~
IWL_UCODE_TLV_FLAGS_P2P
;
if
(
!
(
fw
->
ucode_capa
.
flags
&
IWL_UCODE_TLV_FLAGS_PAN
))
fw
->
ucode_capa
.
flags
&=
~
IWL_UCODE_TLV_FLAGS_P2P
;
if
(
ucode_capa
.
flags
&
IWL_UCODE_TLV_FLAGS_PAN
)
{
if
(
fw
->
ucode_capa
.
flags
&
IWL_UCODE_TLV_FLAGS_PAN
)
{
priv
->
sta_key_max_num
=
STA_KEY_MAX_NUM_PAN
;
priv
->
shrd
->
cmd_queue
=
IWL_IPAN_CMD_QUEUE_NUM
;
nic
->
shrd
->
cmd_queue
=
IWL_IPAN_CMD_QUEUE_NUM
;
}
else
{
priv
->
sta_key_max_num
=
STA_KEY_MAX_NUM
;
priv
->
shrd
->
cmd_queue
=
IWL_DEFAULT_CMD_QUEUE_NUM
;
nic
->
shrd
->
cmd_queue
=
IWL_DEFAULT_CMD_QUEUE_NUM
;
}
/*
* figure out the offset of chain noise reset and gain commands
* base on the size of standard phy calibration commands table size
*/
if
(
ucode_capa
.
standard_phy_calibration_size
>
if
(
fw
->
ucode_capa
.
standard_phy_calibration_size
>
IWL_MAX_PHY_CALIBRATE_TBL_SIZE
)
ucode_capa
.
standard_phy_calibration_size
=
fw
->
ucode_capa
.
standard_phy_calibration_size
=
IWL_MAX_STANDARD_PHY_CALIBRATE_TBL_SIZE
;
priv
->
phy_calib_chain_noise_reset_cmd
=
ucode_capa
.
standard_phy_calibration_size
;
fw
->
ucode_capa
.
standard_phy_calibration_size
;
priv
->
phy_calib_chain_noise_gain_cmd
=
ucode_capa
.
standard_phy_calibration_size
+
1
;
fw
->
ucode_capa
.
standard_phy_calibration_size
+
1
;
/* initialize all valid contexts */
iwl_init_context
(
priv
,
ucode_capa
.
flags
);
iwl_init_context
(
priv
,
fw
->
ucode_capa
.
flags
);
/**************************************************
* This is still part of probe() in a sense...
*
* 9. Setup and register with mac80211 and debugfs
**************************************************/
err
=
iwlagn_mac_setup_register
(
priv
,
&
ucode_capa
);
err
=
iwlagn_mac_setup_register
(
priv
,
&
fw
->
ucode_capa
);
if
(
err
)
goto
out_unbind
;
err
=
iwl_dbgfs_register
(
priv
,
DRV_NAME
);
if
(
err
)
IWL_ERR
(
priv
,
"failed to create debugfs files. Ignoring error: %d
\n
"
,
err
);
IWL_ERR
(
nic
,
"failed to create debugfs files. Ignoring error: %d
\n
"
,
err
);
/* We have our copies now, allow OS release its copies */
release_firmware
(
ucode_raw
);
complete
(
&
priv
->
firmware_loading
_complete
);
complete
(
&
nic
->
request_firmware
_complete
);
return
;
try_again:
/* try next, if any */
if
(
iwl_request_firmware
(
priv
,
false
))
if
(
iwl_request_firmware
(
nic
,
false
))
goto
out_unbind
;
release_firmware
(
ucode_raw
);
return
;
err_pci_alloc:
IWL_ERR
(
priv
,
"failed to allocate pci memory
\n
"
);
iwl_dealloc_ucode
(
trans
(
priv
)
);
IWL_ERR
(
nic
,
"failed to allocate pci memory
\n
"
);
iwl_dealloc_ucode
(
nic
);
out_unbind:
complete
(
&
priv
->
firmware_loading
_complete
);
device_release_driver
(
trans
(
priv
)
->
dev
);
complete
(
&
nic
->
request_firmware
_complete
);
device_release_driver
(
trans
(
nic
)
->
dev
);
release_firmware
(
ucode_raw
);
}
drivers/net/wireless/iwlwifi/iwl-ucode.h
View file @
d896d463
...
...
@@ -63,6 +63,8 @@
#ifndef __iwl_ucode_h__
#define __iwl_ucode_h__
#include <linux/netdevice.h>
/* v1/v2 uCode file layout */
struct
iwl_ucode_header
{
__le32
ver
;
/* major/minor/API/serial */
...
...
@@ -171,8 +173,49 @@ struct iwl_tlv_ucode_header {
u8
data
[
0
];
};
struct
iwl_priv
;
struct
iwl_ucode_capabilities
{
u32
max_probe_length
;
u32
standard_phy_calibration_size
;
u32
flags
;
};
/* one for each uCode image (inst/data, boot/init/runtime) */
struct
fw_desc
{
dma_addr_t
p_addr
;
/* hardware address */
void
*
v_addr
;
/* software address */
u32
len
;
/* size in bytes */
};
int
__must_check
iwl_request_firmware
(
struct
iwl_priv
*
priv
,
bool
first
);
struct
fw_img
{
struct
fw_desc
code
;
/* firmware code image */
struct
fw_desc
data
;
/* firmware data image */
};
/**
* struct iwl_fw - variables associated with the firmware
*
* @ucode_ver: ucode version from the ucode file
* @fw_version: firmware version string
* @ucode_rt: run time ucode image
* @ucode_init: init ucode image
* @ucode_wowlan: wake on wireless ucode image (optional)
* @ucode_capa: capabilities parsed from the ucode file.
* @enhance_sensitivity_table: device can do enhanced sensitivity.
*/
struct
iwl_fw
{
/* ucode image and variables */
u32
ucode_ver
;
/* version of ucode, copy of
iwl_ucode.ver */
char
fw_version
[
ETHTOOL_BUSINFO_LEN
];
/* ucode images */
struct
fw_img
ucode_rt
;
struct
fw_img
ucode_init
;
struct
fw_img
ucode_wowlan
;
struct
iwl_ucode_capabilities
ucode_capa
;
bool
enhance_sensitivity_table
;
};
#endif
/* __iwl_ucode_h__ */
drivers/net/wireless/iwlwifi/iwl-wifi.h
View file @
d896d463
...
...
@@ -64,6 +64,39 @@
#define __iwl_wifi_h__
#include "iwl-shared.h"
#include "iwl-ucode.h"
/**
* struct iwl_nic - nic common data
* @fw: the iwl_fw structure
* @shrd: pointer to common shared structure
* @fw_index: firmware revision to try loading
* @firmware_name: composite filename of ucode file to load
* @init_evtlog_ptr: event log offset for init ucode.
* @init_evtlog_size: event log size for init ucode.
* @init_errlog_ptr: error log offfset for init ucode.
* @inst_evtlog_ptr: event log offset for runtime ucode.
* @inst_evtlog_size: event log size for runtime ucode.
* @inst_errlog_ptr: error log offfset for runtime ucode.
* @request_firmware_complete: the firmware has been obtained from user space
*/
struct
iwl_nic
{
struct
iwl_fw
fw
;
struct
iwl_shared
*
shrd
;
int
fw_index
;
/* firmware we're trying to load */
char
firmware_name
[
25
];
/* name of firmware file to load */
u32
init_evtlog_ptr
,
init_evtlog_size
,
init_errlog_ptr
;
u32
inst_evtlog_ptr
,
inst_evtlog_size
,
inst_errlog_ptr
;
struct
completion
request_firmware_complete
;
};
int
__must_check
iwl_request_firmware
(
struct
iwl_nic
*
nic
,
bool
first
);
void
iwl_dealloc_ucode
(
struct
iwl_nic
*
nic
);
int
iwl_send_bt_env
(
struct
iwl_trans
*
trans
,
u8
action
,
u8
type
);
void
iwl_send_prio_tbl
(
struct
iwl_trans
*
trans
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment