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
6de3f7e9
Commit
6de3f7e9
authored
Aug 22, 2012
by
John W. Linville
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'for-john' of
git://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi/iwlwifi-next
parents
33dd7699
40503f7b
Changes
15
Hide whitespace changes
Inline
Side-by-side
Showing
15 changed files
with
241 additions
and
93 deletions
+241
-93
drivers/net/wireless/iwlwifi/dvm/agn.h
drivers/net/wireless/iwlwifi/dvm/agn.h
+3
-6
drivers/net/wireless/iwlwifi/dvm/debugfs.c
drivers/net/wireless/iwlwifi/dvm/debugfs.c
+28
-28
drivers/net/wireless/iwlwifi/dvm/mac80211.c
drivers/net/wireless/iwlwifi/dvm/mac80211.c
+1
-1
drivers/net/wireless/iwlwifi/dvm/main.c
drivers/net/wireless/iwlwifi/dvm/main.c
+16
-8
drivers/net/wireless/iwlwifi/dvm/sta.c
drivers/net/wireless/iwlwifi/dvm/sta.c
+1
-1
drivers/net/wireless/iwlwifi/dvm/tx.c
drivers/net/wireless/iwlwifi/dvm/tx.c
+1
-1
drivers/net/wireless/iwlwifi/iwl-drv.c
drivers/net/wireless/iwlwifi/iwl-drv.c
+119
-22
drivers/net/wireless/iwlwifi/iwl-drv.h
drivers/net/wireless/iwlwifi/iwl-drv.h
+3
-3
drivers/net/wireless/iwlwifi/iwl-op-mode.h
drivers/net/wireless/iwlwifi/iwl-op-mode.h
+2
-1
drivers/net/wireless/iwlwifi/iwl-trans.h
drivers/net/wireless/iwlwifi/iwl-trans.h
+10
-2
drivers/net/wireless/iwlwifi/pcie/drv.c
drivers/net/wireless/iwlwifi/pcie/drv.c
+6
-0
drivers/net/wireless/iwlwifi/pcie/internal.h
drivers/net/wireless/iwlwifi/pcie/internal.h
+1
-0
drivers/net/wireless/iwlwifi/pcie/rx.c
drivers/net/wireless/iwlwifi/pcie/rx.c
+13
-3
drivers/net/wireless/iwlwifi/pcie/trans.c
drivers/net/wireless/iwlwifi/pcie/trans.c
+16
-12
drivers/net/wireless/iwlwifi/pcie/tx.c
drivers/net/wireless/iwlwifi/pcie/tx.c
+21
-5
No files found.
drivers/net/wireless/iwlwifi/dvm/agn.h
View file @
6de3f7e9
...
...
@@ -487,16 +487,13 @@ static inline void iwl_dvm_set_pmi(struct iwl_priv *priv, bool state)
}
#ifdef CONFIG_IWLWIFI_DEBUGFS
int
iwl_dbgfs_register
(
struct
iwl_priv
*
priv
,
const
char
*
name
);
void
iwl_dbgfs_unregister
(
struct
iwl_priv
*
priv
);
int
iwl_dbgfs_register
(
struct
iwl_priv
*
priv
,
struct
dentry
*
dbgfs_dir
);
#else
static
inline
int
iwl_dbgfs_register
(
struct
iwl_priv
*
priv
,
const
char
*
name
)
static
inline
int
iwl_dbgfs_register
(
struct
iwl_priv
*
priv
,
struct
dentry
*
dbgfs_dir
)
{
return
0
;
}
static
inline
void
iwl_dbgfs_unregister
(
struct
iwl_priv
*
priv
)
{
}
#endif
/* CONFIG_IWLWIFI_DEBUGFS */
#ifdef CONFIG_IWLWIFI_DEBUG
...
...
drivers/net/wireless/iwlwifi/dvm/debugfs.c
View file @
6de3f7e9
...
...
@@ -2349,24 +2349,19 @@ DEBUGFS_READ_WRITE_FILE_OPS(calib_disabled);
* Create the debugfs files and directories
*
*/
int
iwl_dbgfs_register
(
struct
iwl_priv
*
priv
,
const
char
*
name
)
int
iwl_dbgfs_register
(
struct
iwl_priv
*
priv
,
struct
dentry
*
dbgfs_dir
)
{
struct
dentry
*
phyd
=
priv
->
hw
->
wiphy
->
debugfsdir
;
struct
dentry
*
dir_drv
,
*
dir_data
,
*
dir_rf
,
*
dir_debug
;
struct
dentry
*
dir_data
,
*
dir_rf
,
*
dir_debug
;
dir_drv
=
debugfs_create_dir
(
name
,
phyd
);
if
(
!
dir_drv
)
return
-
ENOMEM
;
priv
->
debugfs_dir
=
dir_drv
;
priv
->
debugfs_dir
=
dbgfs_dir
;
dir_data
=
debugfs_create_dir
(
"data"
,
d
ir_drv
);
dir_data
=
debugfs_create_dir
(
"data"
,
d
bgfs_dir
);
if
(
!
dir_data
)
goto
err
;
dir_rf
=
debugfs_create_dir
(
"rf"
,
d
ir_drv
);
dir_rf
=
debugfs_create_dir
(
"rf"
,
d
bgfs_dir
);
if
(
!
dir_rf
)
goto
err
;
dir_debug
=
debugfs_create_dir
(
"debug"
,
d
ir_drv
);
dir_debug
=
debugfs_create_dir
(
"debug"
,
d
bgfs_dir
);
if
(
!
dir_debug
)
goto
err
;
...
...
@@ -2412,25 +2407,30 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name)
/* Calibrations disabled/enabled status*/
DEBUGFS_ADD_FILE
(
calib_disabled
,
dir_rf
,
S_IWUSR
|
S_IRUSR
);
if
(
iwl_trans_dbgfs_register
(
priv
->
trans
,
dir_debug
))
goto
err
;
/*
* Create a symlink with mac80211. This is not very robust, as it does
* not remove the symlink created. The implicit assumption is that
* when the opmode exits, mac80211 will also exit, and will remove
* this symlink as part of its cleanup.
*/
if
(
priv
->
mac80211_registered
)
{
char
buf
[
100
];
struct
dentry
*
mac80211_dir
,
*
dev_dir
,
*
root_dir
;
dev_dir
=
dbgfs_dir
->
d_parent
;
root_dir
=
dev_dir
->
d_parent
;
mac80211_dir
=
priv
->
hw
->
wiphy
->
debugfsdir
;
snprintf
(
buf
,
100
,
"../../%s/%s"
,
root_dir
->
d_name
.
name
,
dev_dir
->
d_name
.
name
);
if
(
!
debugfs_create_symlink
(
"iwlwifi"
,
mac80211_dir
,
buf
))
goto
err
;
}
return
0
;
err:
IWL_ERR
(
priv
,
"Can't create the debugfs directory
\n
"
);
iwl_dbgfs_unregister
(
priv
);
IWL_ERR
(
priv
,
"failed to create the dvm debugfs entries
\n
"
);
return
-
ENOMEM
;
}
/**
* Remove the debugfs files and directories
*
*/
void
iwl_dbgfs_unregister
(
struct
iwl_priv
*
priv
)
{
if
(
!
priv
->
debugfs_dir
)
return
;
debugfs_remove_recursive
(
priv
->
debugfs_dir
);
priv
->
debugfs_dir
=
NULL
;
}
drivers/net/wireless/iwlwifi/dvm/mac80211.c
View file @
6de3f7e9
...
...
@@ -195,7 +195,7 @@ int iwlagn_mac_setup_register(struct iwl_priv *priv,
ARRAY_SIZE
(
iwlagn_iface_combinations_dualmode
);
}
hw
->
wiphy
->
max_remain_on_channel_duration
=
10
00
;
hw
->
wiphy
->
max_remain_on_channel_duration
=
5
00
;
hw
->
wiphy
->
flags
|=
WIPHY_FLAG_CUSTOM_REGULATORY
|
WIPHY_FLAG_DISABLE_BEACON_HINTS
|
...
...
drivers/net/wireless/iwlwifi/dvm/main.c
View file @
6de3f7e9
...
...
@@ -862,7 +862,8 @@ void iwl_down(struct iwl_priv *priv)
* No race since we hold the mutex here and a new one
* can't come in at this time.
*/
ieee80211_remain_on_channel_expired
(
priv
->
hw
);
if
(
priv
->
ucode_loaded
&&
priv
->
cur_ucode
!=
IWL_UCODE_INIT
)
ieee80211_remain_on_channel_expired
(
priv
->
hw
);
exit_pending
=
test_and_set_bit
(
STATUS_EXIT_PENDING
,
&
priv
->
status
);
...
...
@@ -994,7 +995,11 @@ static void iwl_bg_restart(struct work_struct *data)
iwlagn_prepare_restart
(
priv
);
mutex_unlock
(
&
priv
->
mutex
);
iwl_cancel_deferred_work
(
priv
);
ieee80211_restart_hw
(
priv
->
hw
);
if
(
priv
->
mac80211_registered
)
ieee80211_restart_hw
(
priv
->
hw
);
else
IWL_ERR
(
priv
,
"Cannot request restart before registrating with mac80211"
);
}
else
{
WARN_ON
(
1
);
}
...
...
@@ -1222,7 +1227,8 @@ static int iwl_eeprom_init_hw_params(struct iwl_priv *priv)
static
struct
iwl_op_mode
*
iwl_op_mode_dvm_start
(
struct
iwl_trans
*
trans
,
const
struct
iwl_cfg
*
cfg
,
const
struct
iwl_fw
*
fw
)
const
struct
iwl_fw
*
fw
,
struct
dentry
*
dbgfs_dir
)
{
struct
iwl_priv
*
priv
;
struct
ieee80211_hw
*
hw
;
...
...
@@ -1466,13 +1472,17 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans,
if
(
iwlagn_mac_setup_register
(
priv
,
&
fw
->
ucode_capa
))
goto
out_destroy_workqueue
;
if
(
iwl_dbgfs_register
(
priv
,
DRV_NAME
))
IWL_ERR
(
priv
,
"failed to create debugfs files. Ignoring error
\n
"
);
if
(
iwl_dbgfs_register
(
priv
,
dbgfs_dir
))
goto
out_mac80211_unregister
;
return
op_mode
;
out_mac80211_unregister:
iwlagn_mac_unregister
(
priv
);
out_destroy_workqueue:
iwl_tt_exit
(
priv
);
iwl_testmode_free
(
priv
);
iwl_cancel_deferred_work
(
priv
);
destroy_workqueue
(
priv
->
workqueue
);
priv
->
workqueue
=
NULL
;
iwl_uninit_drv
(
priv
);
...
...
@@ -1493,8 +1503,6 @@ static void iwl_op_mode_dvm_stop(struct iwl_op_mode *op_mode)
IWL_DEBUG_INFO
(
priv
,
"*** UNLOAD DRIVER ***
\n
"
);
iwl_dbgfs_unregister
(
priv
);
iwl_testmode_free
(
priv
);
iwlagn_mac_unregister
(
priv
);
...
...
drivers/net/wireless/iwlwifi/dvm/sta.c
View file @
6de3f7e9
...
...
@@ -150,7 +150,7 @@ int iwl_send_add_sta(struct iwl_priv *priv,
sta_id
,
sta
->
sta
.
addr
,
flags
&
CMD_ASYNC
?
"a"
:
""
);
if
(
!
(
flags
&
CMD_ASYNC
))
{
cmd
.
flags
|=
CMD_WANT_SKB
;
cmd
.
flags
|=
CMD_WANT_SKB
|
CMD_WANT_HCMD
;
might_sleep
();
}
...
...
drivers/net/wireless/iwlwifi/dvm/tx.c
View file @
6de3f7e9
...
...
@@ -433,7 +433,7 @@ int iwlagn_tx_skb(struct iwl_priv *priv,
* only. Check this here.
*/
if
(
WARN_ONCE
(
tid_data
->
agg
.
state
!=
IWL_AGG_ON
&&
tid_data
->
agg
.
state
!=
IWL_AGG_OFF
,
tid_data
->
agg
.
state
!=
IWL_AGG_OFF
,
"Tx while agg.state = %d"
,
tid_data
->
agg
.
state
))
goto
drop_unlock_sta
;
...
...
drivers/net/wireless/iwlwifi/iwl-drv.c
View file @
6de3f7e9
...
...
@@ -101,6 +101,10 @@ MODULE_VERSION(DRV_VERSION);
MODULE_AUTHOR
(
DRV_COPYRIGHT
" "
DRV_AUTHOR
);
MODULE_LICENSE
(
"GPL"
);
#ifdef CONFIG_IWLWIFI_DEBUGFS
static
struct
dentry
*
iwl_dbgfs_root
;
#endif
/**
* struct iwl_drv - drv common data
* @list: list of drv structures using this opmode
...
...
@@ -126,6 +130,12 @@ struct iwl_drv {
char
firmware_name
[
25
];
/* name of firmware file to load */
struct
completion
request_firmware_complete
;
#ifdef CONFIG_IWLWIFI_DEBUGFS
struct
dentry
*
dbgfs_drv
;
struct
dentry
*
dbgfs_trans
;
struct
dentry
*
dbgfs_op_mode
;
#endif
};
#define DVM_OP_MODE 0
...
...
@@ -194,7 +204,8 @@ static int iwl_alloc_fw_desc(struct iwl_drv *drv, struct fw_desc *desc,
return
0
;
}
static
void
iwl_ucode_callback
(
const
struct
firmware
*
ucode_raw
,
void
*
context
);
static
void
iwl_req_fw_callback
(
const
struct
firmware
*
ucode_raw
,
void
*
context
);
#define UCODE_EXPERIMENTAL_INDEX 100
#define UCODE_EXPERIMENTAL_TAG "exp"
...
...
@@ -231,7 +242,7 @@ static int iwl_request_firmware(struct iwl_drv *drv, bool first)
return
request_firmware_nowait
(
THIS_MODULE
,
1
,
drv
->
firmware_name
,
drv
->
trans
->
dev
,
GFP_KERNEL
,
drv
,
iwl_
ucode
_callback
);
GFP_KERNEL
,
drv
,
iwl_
req_fw
_callback
);
}
struct
fw_img_parsing
{
...
...
@@ -759,13 +770,57 @@ static int validate_sec_sizes(struct iwl_drv *drv,
return
0
;
}
static
struct
iwl_op_mode
*
_iwl_op_mode_start
(
struct
iwl_drv
*
drv
,
struct
iwlwifi_opmode_table
*
op
)
{
const
struct
iwl_op_mode_ops
*
ops
=
op
->
ops
;
struct
dentry
*
dbgfs_dir
=
NULL
;
struct
iwl_op_mode
*
op_mode
=
NULL
;
#ifdef CONFIG_IWLWIFI_DEBUGFS
drv
->
dbgfs_op_mode
=
debugfs_create_dir
(
op
->
name
,
drv
->
dbgfs_drv
);
if
(
!
drv
->
dbgfs_op_mode
)
{
IWL_ERR
(
drv
,
"failed to create opmode debugfs directory
\n
"
);
return
op_mode
;
}
dbgfs_dir
=
drv
->
dbgfs_op_mode
;
#endif
op_mode
=
ops
->
start
(
drv
->
trans
,
drv
->
cfg
,
&
drv
->
fw
,
dbgfs_dir
);
#ifdef CONFIG_IWLWIFI_DEBUGFS
if
(
!
op_mode
)
{
debugfs_remove_recursive
(
drv
->
dbgfs_op_mode
);
drv
->
dbgfs_op_mode
=
NULL
;
}
#endif
return
op_mode
;
}
static
void
_iwl_op_mode_stop
(
struct
iwl_drv
*
drv
)
{
/* op_mode can be NULL if its start failed */
if
(
drv
->
op_mode
)
{
iwl_op_mode_stop
(
drv
->
op_mode
);
drv
->
op_mode
=
NULL
;
#ifdef CONFIG_IWLWIFI_DEBUGFS
debugfs_remove_recursive
(
drv
->
dbgfs_op_mode
);
drv
->
dbgfs_op_mode
=
NULL
;
#endif
}
}
/**
* iwl_
ucode
_callback - callback when firmware was loaded
* iwl_
req_fw
_callback - callback when firmware was loaded
*
* If loaded successfully, copies the firmware into buffers
* for the card to fetch (via DMA).
*/
static
void
iwl_
ucode
_callback
(
const
struct
firmware
*
ucode_raw
,
void
*
context
)
static
void
iwl_
req_fw
_callback
(
const
struct
firmware
*
ucode_raw
,
void
*
context
)
{
struct
iwl_drv
*
drv
=
context
;
struct
iwl_fw
*
fw
=
&
drv
->
fw
;
...
...
@@ -908,8 +963,7 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context)
list_add_tail
(
&
drv
->
list
,
&
op
->
drv
);
if
(
op
->
ops
)
{
const
struct
iwl_op_mode_ops
*
ops
=
op
->
ops
;
drv
->
op_mode
=
ops
->
start
(
drv
->
trans
,
drv
->
cfg
,
&
drv
->
fw
);
drv
->
op_mode
=
_iwl_op_mode_start
(
drv
,
op
);
if
(
!
drv
->
op_mode
)
{
mutex_unlock
(
&
iwlwifi_opmode_table_mtx
);
...
...
@@ -969,14 +1023,43 @@ struct iwl_drv *iwl_drv_start(struct iwl_trans *trans,
init_completion
(
&
drv
->
request_firmware_complete
);
INIT_LIST_HEAD
(
&
drv
->
list
);
#ifdef CONFIG_IWLWIFI_DEBUGFS
/* Create the device debugfs entries. */
drv
->
dbgfs_drv
=
debugfs_create_dir
(
dev_name
(
trans
->
dev
),
iwl_dbgfs_root
);
if
(
!
drv
->
dbgfs_drv
)
{
IWL_ERR
(
drv
,
"failed to create debugfs directory
\n
"
);
goto
err_free_drv
;
}
/* Create transport layer debugfs dir */
drv
->
trans
->
dbgfs_dir
=
debugfs_create_dir
(
"trans"
,
drv
->
dbgfs_drv
);
if
(
!
drv
->
trans
->
dbgfs_dir
)
{
IWL_ERR
(
drv
,
"failed to create transport debugfs directory
\n
"
);
goto
err_free_dbgfs
;
}
#endif
ret
=
iwl_request_firmware
(
drv
,
true
);
if
(
ret
)
{
IWL_ERR
(
trans
,
"Couldn't request the fw
\n
"
);
kfree
(
drv
);
drv
=
NULL
;
goto
err_fw
;
}
return
drv
;
err_fw:
#ifdef CONFIG_IWLWIFI_DEBUGFS
err_free_dbgfs:
debugfs_remove_recursive
(
drv
->
dbgfs_drv
);
err_free_drv:
#endif
kfree
(
drv
);
drv
=
NULL
;
return
drv
;
}
...
...
@@ -984,9 +1067,7 @@ void iwl_drv_stop(struct iwl_drv *drv)
{
wait_for_completion
(
&
drv
->
request_firmware_complete
);
/* op_mode can be NULL if its start failed */
if
(
drv
->
op_mode
)
iwl_op_mode_stop
(
drv
->
op_mode
);
_iwl_op_mode_stop
(
drv
);
iwl_dealloc_ucode
(
drv
);
...
...
@@ -1000,6 +1081,10 @@ void iwl_drv_stop(struct iwl_drv *drv)
list_del
(
&
drv
->
list
);
mutex_unlock
(
&
iwlwifi_opmode_table_mtx
);
#ifdef CONFIG_IWLWIFI_DEBUGFS
debugfs_remove_recursive
(
drv
->
dbgfs_drv
);
#endif
kfree
(
drv
);
}
...
...
@@ -1022,15 +1107,18 @@ int iwl_opmode_register(const char *name, const struct iwl_op_mode_ops *ops)
{
int
i
;
struct
iwl_drv
*
drv
;
struct
iwlwifi_opmode_table
*
op
;
mutex_lock
(
&
iwlwifi_opmode_table_mtx
);
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
iwlwifi_opmode_table
);
i
++
)
{
if
(
strcmp
(
iwlwifi_opmode_table
[
i
].
name
,
name
))
op
=
&
iwlwifi_opmode_table
[
i
];
if
(
strcmp
(
op
->
name
,
name
))
continue
;
iwlwifi_opmode_table
[
i
].
ops
=
ops
;
list_for_each_entry
(
drv
,
&
iwlwifi_opmode_table
[
i
].
drv
,
list
)
drv
->
op_mode
=
ops
->
start
(
drv
->
trans
,
drv
->
cfg
,
&
drv
->
fw
);
op
->
ops
=
ops
;
/* TODO: need to handle exceptional case */
list_for_each_entry
(
drv
,
&
op
->
drv
,
list
)
drv
->
op_mode
=
_iwl_op_mode_start
(
drv
,
op
);
mutex_unlock
(
&
iwlwifi_opmode_table_mtx
);
return
0
;
}
...
...
@@ -1051,12 +1139,9 @@ void iwl_opmode_deregister(const char *name)
iwlwifi_opmode_table
[
i
].
ops
=
NULL
;
/* call the stop routine for all devices */
list_for_each_entry
(
drv
,
&
iwlwifi_opmode_table
[
i
].
drv
,
list
)
{
if
(
drv
->
op_mode
)
{
iwl_op_mode_stop
(
drv
->
op_mode
);
drv
->
op_mode
=
NULL
;
}
}
list_for_each_entry
(
drv
,
&
iwlwifi_opmode_table
[
i
].
drv
,
list
)
_iwl_op_mode_stop
(
drv
);
mutex_unlock
(
&
iwlwifi_opmode_table_mtx
);
return
;
}
...
...
@@ -1076,6 +1161,14 @@ static int __init iwl_drv_init(void)
pr_info
(
DRV_DESCRIPTION
", "
DRV_VERSION
"
\n
"
);
pr_info
(
DRV_COPYRIGHT
"
\n
"
);
#ifdef CONFIG_IWLWIFI_DEBUGFS
/* Create the root of iwlwifi debugfs subsystem. */
iwl_dbgfs_root
=
debugfs_create_dir
(
DRV_NAME
,
NULL
);
if
(
!
iwl_dbgfs_root
)
return
-
EFAULT
;
#endif
return
iwl_pci_register_driver
();
}
module_init
(
iwl_drv_init
);
...
...
@@ -1083,6 +1176,10 @@ module_init(iwl_drv_init);
static
void
__exit
iwl_drv_exit
(
void
)
{
iwl_pci_unregister_driver
();
#ifdef CONFIG_IWLWIFI_DEBUGFS
debugfs_remove_recursive
(
iwl_dbgfs_root
);
#endif
}
module_exit
(
iwl_drv_exit
);
...
...
drivers/net/wireless/iwlwifi/iwl-drv.h
View file @
6de3f7e9
...
...
@@ -90,9 +90,9 @@
* 4) The bus specific component configures the bus
* 5) The bus specific component calls to the drv bus agnostic part
* (iwl_drv_start)
* 6) iwl_drv_start fetches the fw ASYNC, iwl_
ucode
_callback
* 7) iwl_
ucode
_callback parses the fw file
* 8) iwl_
ucode
_callback starts the wifi implementation to matches the fw
* 6) iwl_drv_start fetches the fw ASYNC, iwl_
req_fw
_callback
* 7) iwl_
req_fw
_callback parses the fw file
* 8) iwl_
req_fw
_callback starts the wifi implementation to matches the fw
*/
struct
iwl_drv
;
...
...
drivers/net/wireless/iwlwifi/iwl-op-mode.h
View file @
6de3f7e9
...
...
@@ -134,7 +134,8 @@ struct iwl_cfg;
struct
iwl_op_mode_ops
{
struct
iwl_op_mode
*
(
*
start
)(
struct
iwl_trans
*
trans
,
const
struct
iwl_cfg
*
cfg
,
const
struct
iwl_fw
*
fw
);
const
struct
iwl_fw
*
fw
,
struct
dentry
*
dbgfs_dir
);
void
(
*
stop
)(
struct
iwl_op_mode
*
op_mode
);
int
(
*
rx
)(
struct
iwl_op_mode
*
op_mode
,
struct
iwl_rx_cmd_buffer
*
rxb
,
struct
iwl_device_cmd
*
cmd
);
...
...
drivers/net/wireless/iwlwifi/iwl-trans.h
View file @
6de3f7e9
...
...
@@ -184,14 +184,20 @@ struct iwl_rx_packet {
* @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.
* response. The caller needs to call iwl_free_resp when done.
* @CMD_WANT_HCMD: The caller needs to get the HCMD that was sent in the
* response handler. Chunks flagged by %IWL_HCMD_DFL_NOCOPY won't be
* copied. The pointer passed to the response handler is in the transport
* ownership and don't need to be freed by the op_mode. This also means
* that the pointer is invalidated after the op_mode's handler returns.
* @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
),
CMD_ON_DEMAND
=
BIT
(
2
),
CMD_WANT_HCMD
=
BIT
(
2
),
CMD_ON_DEMAND
=
BIT
(
3
),
};
#define DEF_CMD_PAYLOAD_SIZE 320
...
...
@@ -460,6 +466,8 @@ struct iwl_trans {
size_t
dev_cmd_headroom
;
char
dev_cmd_pool_name
[
50
];
struct
dentry
*
dbgfs_dir
;
/* pointer to trans specific struct */
/*Ensure that this pointer will always be aligned to sizeof pointer */
char
trans_specific
[
0
]
__aligned
(
sizeof
(
void
*
));
...
...
drivers/net/wireless/iwlwifi/pcie/drv.c
View file @
6de3f7e9
...
...
@@ -282,8 +282,14 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
if
(
!
trans_pcie
->
drv
)
goto
out_free_trans
;
/* register transport layer debugfs here */
if
(
iwl_trans_dbgfs_register
(
iwl_trans
,
iwl_trans
->
dbgfs_dir
))
goto
out_free_drv
;
return
0
;
out_free_drv:
iwl_drv_stop
(
trans_pcie
->
drv
);
out_free_trans:
iwl_trans_pcie_free
(
iwl_trans
);
pci_set_drvdata
(
pdev
,
NULL
);
...
...
drivers/net/wireless/iwlwifi/pcie/internal.h
View file @
6de3f7e9
...
...
@@ -184,6 +184,7 @@ struct iwl_queue {
struct
iwl_pcie_tx_queue_entry
{
struct
iwl_device_cmd
*
cmd
;
struct
iwl_device_cmd
*
copy_cmd
;
struct
sk_buff
*
skb
;
struct
iwl_cmd_meta
meta
;
};
...
...
drivers/net/wireless/iwlwifi/pcie/rx.c
View file @
6de3f7e9
...
...
@@ -421,13 +421,23 @@ static void iwl_rx_handle_rxbuf(struct iwl_trans *trans,
index
=
SEQ_TO_INDEX
(
sequence
);
cmd_index
=
get_cmd_index
(
&
txq
->
q
,
index
);
if
(
reclaim
)
cmd
=
txq
->
entries
[
cmd_index
].
cmd
;
else
if
(
reclaim
)
{
struct
iwl_pcie_tx_queue_entry
*
ent
;
ent
=
&
txq
->
entries
[
cmd_index
];
cmd
=
ent
->
copy_cmd
;
WARN_ON_ONCE
(
!
cmd
&&
ent
->
meta
.
flags
&
CMD_WANT_HCMD
);
}
else
{
cmd
=
NULL
;
}
err
=
iwl_op_mode_rx
(
trans
->
op_mode
,
&
rxcb
,
cmd
);
if
(
reclaim
)
{
/* The original command isn't needed any more */
kfree
(
txq
->
entries
[
cmd_index
].
copy_cmd
);
txq
->
entries
[
cmd_index
].
copy_cmd
=
NULL
;
}
/*
* After here, we should always check rxcb._page_stolen,
* if it is true then one of the handlers took the page.
...
...
drivers/net/wireless/iwlwifi/pcie/trans.c
View file @
6de3f7e9
...
...
@@ -492,10 +492,11 @@ static void iwl_tx_queue_free(struct iwl_trans *trans, int txq_id)
iwl_tx_queue_unmap
(
trans
,
txq_id
);
/* De-alloc array of command/tx buffers */
if
(
txq_id
==
trans_pcie
->
cmd_queue
)
for
(
i
=
0
;
i
<
txq
->
q
.
n_window
;
i
++
)
for
(
i
=
0
;
i
<
txq
->
q
.
n_window
;
i
++
)
{
kfree
(
txq
->
entries
[
i
].
cmd
);
kfree
(
txq
->
entries
[
i
].
copy_cmd
);
}
/* De-alloc circular buffer of TFDs */
if
(
txq
->
q
.
n_bd
)
{
...
...
@@ -896,6 +897,7 @@ static int iwl_set_hw_ready(struct iwl_trans *trans)
static
int
iwl_prepare_card_hw
(
struct
iwl_trans
*
trans
)
{
int
ret
;
int
t
=
0
;
IWL_DEBUG_INFO
(
trans
,
"iwl_trans_prepare_card_hw enter
\n
"
);
...
...
@@ -908,17 +910,15 @@ static int iwl_prepare_card_hw(struct iwl_trans *trans)
iwl_set_bit
(
trans
,
CSR_HW_IF_CONFIG_REG
,
CSR_HW_IF_CONFIG_REG_PREPARE
);
ret
=
iwl_poll_bit
(
trans
,
CSR_HW_IF_CONFIG_REG
,
~
CSR_HW_IF_CONFIG_REG_BIT_NIC_PREPARE_DONE
,
CSR_HW_IF_CONFIG_REG_BIT_NIC_PREPARE_DONE
,
150000
);
do
{
ret
=
iwl_set_hw_ready
(
trans
);
if
(
ret
>=
0
)
return
0
;
if
(
ret
<
0
)
return
ret
;
usleep_range
(
200
,
1000
);
t
+=
200
;
}
while
(
t
<
150000
);
/* HW should be ready by now, check again. */
ret
=
iwl_set_hw_ready
(
trans
);
if
(
ret
>=
0
)
return
0
;
return
ret
;
}
...
...
@@ -1769,7 +1769,7 @@ void iwl_dump_csr(struct iwl_trans *trans)
#define DEBUGFS_ADD_FILE(name, parent, mode) do { \
if (!debugfs_create_file(#name, mode, parent, trans, \
&iwl_dbgfs_##name##_ops)) \
return -ENOMEM
; \
goto err
; \
} while (0)
/* file operation */
...
...
@@ -2033,6 +2033,10 @@ static int iwl_trans_pcie_dbgfs_register(struct iwl_trans *trans,
DEBUGFS_ADD_FILE
(
fh_reg
,
dir
,
S_IRUSR
);
DEBUGFS_ADD_FILE
(
fw_restart
,
dir
,
S_IWUSR
);
return
0
;
err:
IWL_ERR
(
trans
,
"failed to create the trans debugfs entry
\n
"
);
return
-
ENOMEM
;
}
#else
static
int
iwl_trans_pcie_dbgfs_register
(
struct
iwl_trans
*
trans
,
...
...
drivers/net/wireless/iwlwifi/pcie/tx.c
View file @
6de3f7e9
...
...
@@ -521,7 +521,7 @@ static int iwl_enqueue_hcmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd)
u16
copy_size
,
cmd_size
;
bool
had_nocopy
=
false
;
int
i
;
u
8
*
cmd_dest
;
u
32
cmd_pos
;
#ifdef CONFIG_IWLWIFI_DEVICE_TRACING
const
void
*
trace_bufs
[
IWL_MAX_CMD_TFDS
+
1
]
=
{};
int
trace_lens
[
IWL_MAX_CMD_TFDS
+
1
]
=
{};
...
...
@@ -584,15 +584,31 @@ static int iwl_enqueue_hcmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd)
INDEX_TO_SEQ
(
q
->
write_ptr
));
/* and copy the data that needs to be copied */
cmd_dest
=
out_cmd
->
payload
;
cmd_pos
=
offsetof
(
struct
iwl_device_cmd
,
payload
);
for
(
i
=
0
;
i
<
IWL_MAX_CMD_TFDS
;
i
++
)
{
if
(
!
cmd
->
len
[
i
])
continue
;
if
(
cmd
->
dataflags
[
i
]
&
IWL_HCMD_DFL_NOCOPY
)
break
;
memcpy
(
cmd_dest
,
cmd
->
data
[
i
],
cmd
->
len
[
i
]);
cmd_dest
+=
cmd
->
len
[
i
];
memcpy
((
u8
*
)
out_cmd
+
cmd_pos
,
cmd
->
data
[
i
],
cmd
->
len
[
i
]);
cmd_pos
+=
cmd
->
len
[
i
];
}
WARN_ON_ONCE
(
txq
->
entries
[
idx
].
copy_cmd
);
/*
* since out_cmd will be the source address of the FH, it will write
* the retry count there. So when the user needs to receivce the HCMD
* that corresponds to the response in the response handler, it needs
* to set CMD_WANT_HCMD.
*/
if
(
cmd
->
flags
&
CMD_WANT_HCMD
)
{
txq
->
entries
[
idx
].
copy_cmd
=
kmemdup
(
out_cmd
,
cmd_pos
,
GFP_ATOMIC
);
if
(
unlikely
(
!
txq
->
entries
[
idx
].
copy_cmd
))
{
idx
=
-
ENOMEM
;
goto
out
;
}
}
IWL_DEBUG_HC
(
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