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
Kirill Smelkov
linux
Commits
1615a743
Commit
1615a743
authored
Feb 27, 2013
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-fixes
parents
cb601ffa
e4775983
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
166 additions
and
71 deletions
+166
-71
drivers/net/wireless/iwlwifi/iwl-devtrace.h
drivers/net/wireless/iwlwifi/iwl-devtrace.h
+4
-6
drivers/net/wireless/iwlwifi/iwl-phy-db.c
drivers/net/wireless/iwlwifi/iwl-phy-db.c
+0
-16
drivers/net/wireless/iwlwifi/mvm/d3.c
drivers/net/wireless/iwlwifi/mvm/d3.c
+77
-27
drivers/net/wireless/iwlwifi/mvm/mac80211.c
drivers/net/wireless/iwlwifi/mvm/mac80211.c
+14
-5
drivers/net/wireless/iwlwifi/mvm/mvm.h
drivers/net/wireless/iwlwifi/mvm/mvm.h
+4
-0
drivers/net/wireless/iwlwifi/pcie/internal.h
drivers/net/wireless/iwlwifi/pcie/internal.h
+9
-0
drivers/net/wireless/iwlwifi/pcie/tx.c
drivers/net/wireless/iwlwifi/pcie/tx.c
+58
-17
No files found.
drivers/net/wireless/iwlwifi/iwl-devtrace.h
View file @
1615a743
...
@@ -349,25 +349,23 @@ TRACE_EVENT(iwlwifi_dev_rx_data,
...
@@ -349,25 +349,23 @@ TRACE_EVENT(iwlwifi_dev_rx_data,
TRACE_EVENT
(
iwlwifi_dev_hcmd
,
TRACE_EVENT
(
iwlwifi_dev_hcmd
,
TP_PROTO
(
const
struct
device
*
dev
,
TP_PROTO
(
const
struct
device
*
dev
,
struct
iwl_host_cmd
*
cmd
,
u16
total_size
,
struct
iwl_host_cmd
*
cmd
,
u16
total_size
,
const
void
*
hdr
,
size_t
hdr_len
),
struct
iwl_cmd_header
*
hdr
),
TP_ARGS
(
dev
,
cmd
,
total_size
,
hdr
,
hdr_len
),
TP_ARGS
(
dev
,
cmd
,
total_size
,
hdr
),
TP_STRUCT__entry
(
TP_STRUCT__entry
(
DEV_ENTRY
DEV_ENTRY
__dynamic_array
(
u8
,
hcmd
,
total_size
)
__dynamic_array
(
u8
,
hcmd
,
total_size
)
__field
(
u32
,
flags
)
__field
(
u32
,
flags
)
),
),
TP_fast_assign
(
TP_fast_assign
(
int
i
,
offset
=
hdr_len
;
int
i
,
offset
=
sizeof
(
*
hdr
)
;
DEV_ASSIGN
;
DEV_ASSIGN
;
__entry
->
flags
=
cmd
->
flags
;
__entry
->
flags
=
cmd
->
flags
;
memcpy
(
__get_dynamic_array
(
hcmd
),
hdr
,
hdr_len
);
memcpy
(
__get_dynamic_array
(
hcmd
),
hdr
,
sizeof
(
*
hdr
)
);
for
(
i
=
0
;
i
<
IWL_MAX_CMD_TFDS
;
i
++
)
{
for
(
i
=
0
;
i
<
IWL_MAX_CMD_TFDS
;
i
++
)
{
if
(
!
cmd
->
len
[
i
])
if
(
!
cmd
->
len
[
i
])
continue
;
continue
;
if
(
!
(
cmd
->
dataflags
[
i
]
&
IWL_HCMD_DFL_NOCOPY
))
continue
;
memcpy
((
u8
*
)
__get_dynamic_array
(
hcmd
)
+
offset
,
memcpy
((
u8
*
)
__get_dynamic_array
(
hcmd
)
+
offset
,
cmd
->
data
[
i
],
cmd
->
len
[
i
]);
cmd
->
data
[
i
],
cmd
->
len
[
i
]);
offset
+=
cmd
->
len
[
i
];
offset
+=
cmd
->
len
[
i
];
...
...
drivers/net/wireless/iwlwifi/iwl-phy-db.c
View file @
1615a743
...
@@ -136,12 +136,6 @@ struct iwl_calib_res_notif_phy_db {
...
@@ -136,12 +136,6 @@ struct iwl_calib_res_notif_phy_db {
u8
data
[];
u8
data
[];
}
__packed
;
}
__packed
;
#define IWL_PHY_DB_STATIC_PIC cpu_to_le32(0x21436587)
static
inline
void
iwl_phy_db_test_pic
(
__le32
pic
)
{
WARN_ON
(
IWL_PHY_DB_STATIC_PIC
!=
pic
);
}
struct
iwl_phy_db
*
iwl_phy_db_init
(
struct
iwl_trans
*
trans
)
struct
iwl_phy_db
*
iwl_phy_db_init
(
struct
iwl_trans
*
trans
)
{
{
struct
iwl_phy_db
*
phy_db
=
kzalloc
(
sizeof
(
struct
iwl_phy_db
),
struct
iwl_phy_db
*
phy_db
=
kzalloc
(
sizeof
(
struct
iwl_phy_db
),
...
@@ -260,11 +254,6 @@ int iwl_phy_db_set_section(struct iwl_phy_db *phy_db, struct iwl_rx_packet *pkt,
...
@@ -260,11 +254,6 @@ int iwl_phy_db_set_section(struct iwl_phy_db *phy_db, struct iwl_rx_packet *pkt,
(
size
-
CHANNEL_NUM_SIZE
)
/
phy_db
->
channel_num
;
(
size
-
CHANNEL_NUM_SIZE
)
/
phy_db
->
channel_num
;
}
}
/* Test PIC */
if
(
type
!=
IWL_PHY_DB_CFG
)
iwl_phy_db_test_pic
(
*
(((
__le32
*
)
phy_db_notif
->
data
)
+
(
size
/
sizeof
(
__le32
))
-
1
));
IWL_DEBUG_INFO
(
phy_db
->
trans
,
IWL_DEBUG_INFO
(
phy_db
->
trans
,
"%s(%d): [PHYDB]SET: Type %d , Size: %d
\n
"
,
"%s(%d): [PHYDB]SET: Type %d , Size: %d
\n
"
,
__func__
,
__LINE__
,
type
,
size
);
__func__
,
__LINE__
,
type
,
size
);
...
@@ -372,11 +361,6 @@ int iwl_phy_db_get_section_data(struct iwl_phy_db *phy_db,
...
@@ -372,11 +361,6 @@ int iwl_phy_db_get_section_data(struct iwl_phy_db *phy_db,
*
size
=
entry
->
size
;
*
size
=
entry
->
size
;
}
}
/* Test PIC */
if
(
type
!=
IWL_PHY_DB_CFG
)
iwl_phy_db_test_pic
(
*
(((
__le32
*
)
*
data
)
+
(
*
size
/
sizeof
(
__le32
))
-
1
));
IWL_DEBUG_INFO
(
phy_db
->
trans
,
IWL_DEBUG_INFO
(
phy_db
->
trans
,
"%s(%d): [PHYDB] GET: Type %d , Size: %d
\n
"
,
"%s(%d): [PHYDB] GET: Type %d , Size: %d
\n
"
,
__func__
,
__LINE__
,
type
,
*
size
);
__func__
,
__LINE__
,
type
,
*
size
);
...
...
drivers/net/wireless/iwlwifi/mvm/d3.c
View file @
1615a743
...
@@ -61,6 +61,7 @@
...
@@ -61,6 +61,7 @@
*
*
*****************************************************************************/
*****************************************************************************/
#include <linux/etherdevice.h>
#include <net/cfg80211.h>
#include <net/cfg80211.h>
#include <net/ipv6.h>
#include <net/ipv6.h>
#include "iwl-modparams.h"
#include "iwl-modparams.h"
...
@@ -192,6 +193,11 @@ static void iwl_mvm_wowlan_program_keys(struct ieee80211_hw *hw,
...
@@ -192,6 +193,11 @@ static void iwl_mvm_wowlan_program_keys(struct ieee80211_hw *hw,
sizeof
(
wkc
),
&
wkc
);
sizeof
(
wkc
),
&
wkc
);
data
->
error
=
ret
!=
0
;
data
->
error
=
ret
!=
0
;
mvm
->
ptk_ivlen
=
key
->
iv_len
;
mvm
->
ptk_icvlen
=
key
->
icv_len
;
mvm
->
gtk_ivlen
=
key
->
iv_len
;
mvm
->
gtk_icvlen
=
key
->
icv_len
;
/* don't upload key again */
/* don't upload key again */
goto
out_unlock
;
goto
out_unlock
;
}
}
...
@@ -304,9 +310,13 @@ static void iwl_mvm_wowlan_program_keys(struct ieee80211_hw *hw,
...
@@ -304,9 +310,13 @@ static void iwl_mvm_wowlan_program_keys(struct ieee80211_hw *hw,
*/
*/
if
(
key
->
flags
&
IEEE80211_KEY_FLAG_PAIRWISE
)
{
if
(
key
->
flags
&
IEEE80211_KEY_FLAG_PAIRWISE
)
{
key
->
hw_key_idx
=
0
;
key
->
hw_key_idx
=
0
;
mvm
->
ptk_ivlen
=
key
->
iv_len
;
mvm
->
ptk_icvlen
=
key
->
icv_len
;
}
else
{
}
else
{
data
->
gtk_key_idx
++
;
data
->
gtk_key_idx
++
;
key
->
hw_key_idx
=
data
->
gtk_key_idx
;
key
->
hw_key_idx
=
data
->
gtk_key_idx
;
mvm
->
gtk_ivlen
=
key
->
iv_len
;
mvm
->
gtk_icvlen
=
key
->
icv_len
;
}
}
ret
=
iwl_mvm_set_sta_key
(
mvm
,
vif
,
sta
,
key
,
true
);
ret
=
iwl_mvm_set_sta_key
(
mvm
,
vif
,
sta
,
key
,
true
);
...
@@ -649,6 +659,11 @@ int iwl_mvm_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan)
...
@@ -649,6 +659,11 @@ int iwl_mvm_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan)
/* We reprogram keys and shouldn't allocate new key indices */
/* We reprogram keys and shouldn't allocate new key indices */
memset
(
mvm
->
fw_key_table
,
0
,
sizeof
(
mvm
->
fw_key_table
));
memset
(
mvm
->
fw_key_table
,
0
,
sizeof
(
mvm
->
fw_key_table
));
mvm
->
ptk_ivlen
=
0
;
mvm
->
ptk_icvlen
=
0
;
mvm
->
ptk_ivlen
=
0
;
mvm
->
ptk_icvlen
=
0
;
/*
/*
* The D3 firmware still hardcodes the AP station ID for the
* The D3 firmware still hardcodes the AP station ID for the
* BSS we're associated with as 0. As a result, we have to move
* BSS we're associated with as 0. As a result, we have to move
...
@@ -783,7 +798,6 @@ static void iwl_mvm_query_wakeup_reasons(struct iwl_mvm *mvm,
...
@@ -783,7 +798,6 @@ static void iwl_mvm_query_wakeup_reasons(struct iwl_mvm *mvm,
struct
iwl_wowlan_status
*
status
;
struct
iwl_wowlan_status
*
status
;
u32
reasons
;
u32
reasons
;
int
ret
,
len
;
int
ret
,
len
;
bool
pkt8023
=
false
;
struct
sk_buff
*
pkt
=
NULL
;
struct
sk_buff
*
pkt
=
NULL
;
iwl_trans_read_mem_bytes
(
mvm
->
trans
,
base
,
iwl_trans_read_mem_bytes
(
mvm
->
trans
,
base
,
...
@@ -824,7 +838,8 @@ static void iwl_mvm_query_wakeup_reasons(struct iwl_mvm *mvm,
...
@@ -824,7 +838,8 @@ static void iwl_mvm_query_wakeup_reasons(struct iwl_mvm *mvm,
status
=
(
void
*
)
cmd
.
resp_pkt
->
data
;
status
=
(
void
*
)
cmd
.
resp_pkt
->
data
;
if
(
len
-
sizeof
(
struct
iwl_cmd_header
)
!=
if
(
len
-
sizeof
(
struct
iwl_cmd_header
)
!=
sizeof
(
*
status
)
+
le32_to_cpu
(
status
->
wake_packet_bufsize
))
{
sizeof
(
*
status
)
+
ALIGN
(
le32_to_cpu
(
status
->
wake_packet_bufsize
),
4
))
{
IWL_ERR
(
mvm
,
"Invalid WoWLAN status response!
\n
"
);
IWL_ERR
(
mvm
,
"Invalid WoWLAN status response!
\n
"
);
goto
out
;
goto
out
;
}
}
...
@@ -836,61 +851,96 @@ static void iwl_mvm_query_wakeup_reasons(struct iwl_mvm *mvm,
...
@@ -836,61 +851,96 @@ static void iwl_mvm_query_wakeup_reasons(struct iwl_mvm *mvm,
goto
report
;
goto
report
;
}
}
if
(
reasons
&
IWL_WOWLAN_WAKEUP_BY_MAGIC_PACKET
)
{
if
(
reasons
&
IWL_WOWLAN_WAKEUP_BY_MAGIC_PACKET
)
wakeup
.
magic_pkt
=
true
;
wakeup
.
magic_pkt
=
true
;
pkt8023
=
true
;
}
if
(
reasons
&
IWL_WOWLAN_WAKEUP_BY_PATTERN
)
{
if
(
reasons
&
IWL_WOWLAN_WAKEUP_BY_PATTERN
)
wakeup
.
pattern_idx
=
wakeup
.
pattern_idx
=
le16_to_cpu
(
status
->
pattern_number
);
le16_to_cpu
(
status
->
pattern_number
);
pkt8023
=
true
;
}
if
(
reasons
&
(
IWL_WOWLAN_WAKEUP_BY_DISCONNECTION_ON_MISSED_BEACON
|
if
(
reasons
&
(
IWL_WOWLAN_WAKEUP_BY_DISCONNECTION_ON_MISSED_BEACON
|
IWL_WOWLAN_WAKEUP_BY_DISCONNECTION_ON_DEAUTH
))
IWL_WOWLAN_WAKEUP_BY_DISCONNECTION_ON_DEAUTH
))
wakeup
.
disconnect
=
true
;
wakeup
.
disconnect
=
true
;
if
(
reasons
&
IWL_WOWLAN_WAKEUP_BY_GTK_REKEY_FAILURE
)
{
if
(
reasons
&
IWL_WOWLAN_WAKEUP_BY_GTK_REKEY_FAILURE
)
wakeup
.
gtk_rekey_failure
=
true
;
wakeup
.
gtk_rekey_failure
=
true
;
pkt8023
=
true
;
}
if
(
reasons
&
IWL_WOWLAN_WAKEUP_BY_RFKILL_DEASSERTED
)
{
if
(
reasons
&
IWL_WOWLAN_WAKEUP_BY_RFKILL_DEASSERTED
)
wakeup
.
rfkill_release
=
true
;
wakeup
.
rfkill_release
=
true
;
pkt8023
=
true
;
}
if
(
reasons
&
IWL_WOWLAN_WAKEUP_BY_EAPOL_REQUEST
)
{
if
(
reasons
&
IWL_WOWLAN_WAKEUP_BY_EAPOL_REQUEST
)
wakeup
.
eap_identity_req
=
true
;
wakeup
.
eap_identity_req
=
true
;
pkt8023
=
true
;
}
if
(
reasons
&
IWL_WOWLAN_WAKEUP_BY_FOUR_WAY_HANDSHAKE
)
{
if
(
reasons
&
IWL_WOWLAN_WAKEUP_BY_FOUR_WAY_HANDSHAKE
)
wakeup
.
four_way_handshake
=
true
;
wakeup
.
four_way_handshake
=
true
;
pkt8023
=
true
;
}
if
(
status
->
wake_packet_bufsize
)
{
if
(
status
->
wake_packet_bufsize
)
{
u32
pktsize
=
le32_to_cpu
(
status
->
wake_packet_bufsize
);
int
pktsize
=
le32_to_cpu
(
status
->
wake_packet_bufsize
);
u32
pktlen
=
le32_to_cpu
(
status
->
wake_packet_length
);
int
pktlen
=
le32_to_cpu
(
status
->
wake_packet_length
);
const
u8
*
pktdata
=
status
->
wake_packet
;
struct
ieee80211_hdr
*
hdr
=
(
void
*
)
pktdata
;
int
truncated
=
pktlen
-
pktsize
;
/* this would be a firmware bug */
if
(
WARN_ON_ONCE
(
truncated
<
0
))
truncated
=
0
;
if
(
ieee80211_is_data
(
hdr
->
frame_control
))
{
int
hdrlen
=
ieee80211_hdrlen
(
hdr
->
frame_control
);
int
ivlen
=
0
,
icvlen
=
4
;
/* also FCS */
if
(
pkt8023
)
{
pkt
=
alloc_skb
(
pktsize
,
GFP_KERNEL
);
pkt
=
alloc_skb
(
pktsize
,
GFP_KERNEL
);
if
(
!
pkt
)
if
(
!
pkt
)
goto
report
;
goto
report
;
memcpy
(
skb_put
(
pkt
,
pktsize
),
status
->
wake_packet
,
pktsize
);
memcpy
(
skb_put
(
pkt
,
hdrlen
),
pktdata
,
hdrlen
);
pktdata
+=
hdrlen
;
pktsize
-=
hdrlen
;
if
(
ieee80211_has_protected
(
hdr
->
frame_control
))
{
if
(
is_multicast_ether_addr
(
hdr
->
addr1
))
{
ivlen
=
mvm
->
gtk_ivlen
;
icvlen
+=
mvm
->
gtk_icvlen
;
}
else
{
ivlen
=
mvm
->
ptk_ivlen
;
icvlen
+=
mvm
->
ptk_icvlen
;
}
}
/* if truncated, FCS/ICV is (partially) gone */
if
(
truncated
>=
icvlen
)
{
icvlen
=
0
;
truncated
-=
icvlen
;
}
else
{
icvlen
-=
truncated
;
truncated
=
0
;
}
pktsize
-=
ivlen
+
icvlen
;
pktdata
+=
ivlen
;
memcpy
(
skb_put
(
pkt
,
pktsize
),
pktdata
,
pktsize
);
if
(
ieee80211_data_to_8023
(
pkt
,
vif
->
addr
,
vif
->
type
))
if
(
ieee80211_data_to_8023
(
pkt
,
vif
->
addr
,
vif
->
type
))
goto
report
;
goto
report
;
wakeup
.
packet
=
pkt
->
data
;
wakeup
.
packet
=
pkt
->
data
;
wakeup
.
packet_present_len
=
pkt
->
len
;
wakeup
.
packet_present_len
=
pkt
->
len
;
wakeup
.
packet_len
=
pkt
->
len
-
(
pktlen
-
pktsize
)
;
wakeup
.
packet_len
=
pkt
->
len
-
truncated
;
wakeup
.
packet_80211
=
false
;
wakeup
.
packet_80211
=
false
;
}
else
{
}
else
{
int
fcslen
=
4
;
if
(
truncated
>=
4
)
{
truncated
-=
4
;
fcslen
=
0
;
}
else
{
fcslen
-=
truncated
;
truncated
=
0
;
}
pktsize
-=
fcslen
;
wakeup
.
packet
=
status
->
wake_packet
;
wakeup
.
packet
=
status
->
wake_packet
;
wakeup
.
packet_present_len
=
pktsize
;
wakeup
.
packet_present_len
=
pktsize
;
wakeup
.
packet_len
=
pktlen
;
wakeup
.
packet_len
=
pktlen
-
truncated
;
wakeup
.
packet_80211
=
true
;
wakeup
.
packet_80211
=
true
;
}
}
}
}
...
...
drivers/net/wireless/iwlwifi/mvm/mac80211.c
View file @
1615a743
...
@@ -557,11 +557,9 @@ static int iwl_mvm_mac_add_interface(struct ieee80211_hw *hw,
...
@@ -557,11 +557,9 @@ static int iwl_mvm_mac_add_interface(struct ieee80211_hw *hw,
return
ret
;
return
ret
;
}
}
static
void
iwl_mvm_
mac_remove_interface
(
struct
ieee80211_hw
*
hw
,
static
void
iwl_mvm_
prepare_mac_removal
(
struct
iwl_mvm
*
mvm
,
struct
ieee80211_vif
*
vif
)
struct
ieee80211_vif
*
vif
)
{
{
struct
iwl_mvm
*
mvm
=
IWL_MAC80211_GET_MVM
(
hw
);
struct
iwl_mvm_vif
*
mvmvif
=
iwl_mvm_vif_from_mac80211
(
vif
);
u32
tfd_msk
=
0
,
ac
;
u32
tfd_msk
=
0
,
ac
;
for
(
ac
=
0
;
ac
<
IEEE80211_NUM_ACS
;
ac
++
)
for
(
ac
=
0
;
ac
<
IEEE80211_NUM_ACS
;
ac
++
)
...
@@ -594,12 +592,21 @@ static void iwl_mvm_mac_remove_interface(struct ieee80211_hw *hw,
...
@@ -594,12 +592,21 @@ static void iwl_mvm_mac_remove_interface(struct ieee80211_hw *hw,
*/
*/
flush_work
(
&
mvm
->
sta_drained_wk
);
flush_work
(
&
mvm
->
sta_drained_wk
);
}
}
}
static
void
iwl_mvm_mac_remove_interface
(
struct
ieee80211_hw
*
hw
,
struct
ieee80211_vif
*
vif
)
{
struct
iwl_mvm
*
mvm
=
IWL_MAC80211_GET_MVM
(
hw
);
struct
iwl_mvm_vif
*
mvmvif
=
iwl_mvm_vif_from_mac80211
(
vif
);
iwl_mvm_prepare_mac_removal
(
mvm
,
vif
);
mutex_lock
(
&
mvm
->
mutex
);
mutex_lock
(
&
mvm
->
mutex
);
/*
/*
* For AP/GO interface, the tear down of the resources allocated to the
* For AP/GO interface, the tear down of the resources allocated to the
* interface
should be handled as part of the bss_info_changed
flow.
* interface
is be handled as part of the stop_ap
flow.
*/
*/
if
(
vif
->
type
==
NL80211_IFTYPE_AP
)
{
if
(
vif
->
type
==
NL80211_IFTYPE_AP
)
{
iwl_mvm_dealloc_int_sta
(
mvm
,
&
mvmvif
->
bcast_sta
);
iwl_mvm_dealloc_int_sta
(
mvm
,
&
mvmvif
->
bcast_sta
);
...
@@ -763,6 +770,8 @@ static void iwl_mvm_stop_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
...
@@ -763,6 +770,8 @@ static void iwl_mvm_stop_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
struct
iwl_mvm
*
mvm
=
IWL_MAC80211_GET_MVM
(
hw
);
struct
iwl_mvm
*
mvm
=
IWL_MAC80211_GET_MVM
(
hw
);
struct
iwl_mvm_vif
*
mvmvif
=
iwl_mvm_vif_from_mac80211
(
vif
);
struct
iwl_mvm_vif
*
mvmvif
=
iwl_mvm_vif_from_mac80211
(
vif
);
iwl_mvm_prepare_mac_removal
(
mvm
,
vif
);
mutex_lock
(
&
mvm
->
mutex
);
mutex_lock
(
&
mvm
->
mutex
);
mvmvif
->
ap_active
=
false
;
mvmvif
->
ap_active
=
false
;
...
...
drivers/net/wireless/iwlwifi/mvm/mvm.h
View file @
1615a743
...
@@ -327,6 +327,10 @@ struct iwl_mvm {
...
@@ -327,6 +327,10 @@ struct iwl_mvm {
struct
led_classdev
led
;
struct
led_classdev
led
;
struct
ieee80211_vif
*
p2p_device_vif
;
struct
ieee80211_vif
*
p2p_device_vif
;
#ifdef CONFIG_PM_SLEEP
int
gtk_ivlen
,
gtk_icvlen
,
ptk_ivlen
,
ptk_icvlen
;
#endif
};
};
/* Extract MVM priv from op_mode and _hw */
/* Extract MVM priv from op_mode and _hw */
...
...
drivers/net/wireless/iwlwifi/pcie/internal.h
View file @
1615a743
...
@@ -182,6 +182,15 @@ struct iwl_queue {
...
@@ -182,6 +182,15 @@ struct iwl_queue {
#define TFD_TX_CMD_SLOTS 256
#define TFD_TX_CMD_SLOTS 256
#define TFD_CMD_SLOTS 32
#define TFD_CMD_SLOTS 32
/*
* The FH will write back to the first TB only, so we need
* to copy some data into the buffer regardless of whether
* it should be mapped or not. This indicates how much to
* copy, even for HCMDs it must be big enough to fit the
* DRAM scratch from the TX cmd, at least 16 bytes.
*/
#define IWL_HCMD_MIN_COPY_SIZE 16
struct
iwl_pcie_txq_entry
{
struct
iwl_pcie_txq_entry
{
struct
iwl_device_cmd
*
cmd
;
struct
iwl_device_cmd
*
cmd
;
struct
iwl_device_cmd
*
copy_cmd
;
struct
iwl_device_cmd
*
copy_cmd
;
...
...
drivers/net/wireless/iwlwifi/pcie/tx.c
View file @
1615a743
...
@@ -1152,10 +1152,12 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans,
...
@@ -1152,10 +1152,12 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans,
void
*
dup_buf
=
NULL
;
void
*
dup_buf
=
NULL
;
dma_addr_t
phys_addr
;
dma_addr_t
phys_addr
;
int
idx
;
int
idx
;
u16
copy_size
,
cmd_size
;
u16
copy_size
,
cmd_size
,
dma_size
;
bool
had_nocopy
=
false
;
bool
had_nocopy
=
false
;
int
i
;
int
i
;
u32
cmd_pos
;
u32
cmd_pos
;
const
u8
*
cmddata
[
IWL_MAX_CMD_TFDS
];
u16
cmdlen
[
IWL_MAX_CMD_TFDS
];
copy_size
=
sizeof
(
out_cmd
->
hdr
);
copy_size
=
sizeof
(
out_cmd
->
hdr
);
cmd_size
=
sizeof
(
out_cmd
->
hdr
);
cmd_size
=
sizeof
(
out_cmd
->
hdr
);
...
@@ -1164,8 +1166,23 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans,
...
@@ -1164,8 +1166,23 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans,
BUILD_BUG_ON
(
IWL_MAX_CMD_TFDS
>
IWL_NUM_OF_TBS
-
1
);
BUILD_BUG_ON
(
IWL_MAX_CMD_TFDS
>
IWL_NUM_OF_TBS
-
1
);
for
(
i
=
0
;
i
<
IWL_MAX_CMD_TFDS
;
i
++
)
{
for
(
i
=
0
;
i
<
IWL_MAX_CMD_TFDS
;
i
++
)
{
cmddata
[
i
]
=
cmd
->
data
[
i
];
cmdlen
[
i
]
=
cmd
->
len
[
i
];
if
(
!
cmd
->
len
[
i
])
if
(
!
cmd
->
len
[
i
])
continue
;
continue
;
/* need at least IWL_HCMD_MIN_COPY_SIZE copied */
if
(
copy_size
<
IWL_HCMD_MIN_COPY_SIZE
)
{
int
copy
=
IWL_HCMD_MIN_COPY_SIZE
-
copy_size
;
if
(
copy
>
cmdlen
[
i
])
copy
=
cmdlen
[
i
];
cmdlen
[
i
]
-=
copy
;
cmddata
[
i
]
+=
copy
;
copy_size
+=
copy
;
}
if
(
cmd
->
dataflags
[
i
]
&
IWL_HCMD_DFL_NOCOPY
)
{
if
(
cmd
->
dataflags
[
i
]
&
IWL_HCMD_DFL_NOCOPY
)
{
had_nocopy
=
true
;
had_nocopy
=
true
;
if
(
WARN_ON
(
cmd
->
dataflags
[
i
]
&
IWL_HCMD_DFL_DUP
))
{
if
(
WARN_ON
(
cmd
->
dataflags
[
i
]
&
IWL_HCMD_DFL_DUP
))
{
...
@@ -1185,7 +1202,7 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans,
...
@@ -1185,7 +1202,7 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans,
goto
free_dup_buf
;
goto
free_dup_buf
;
}
}
dup_buf
=
kmemdup
(
cmd
->
data
[
i
],
cmd
->
len
[
i
],
dup_buf
=
kmemdup
(
cmd
data
[
i
],
cmd
len
[
i
],
GFP_ATOMIC
);
GFP_ATOMIC
);
if
(
!
dup_buf
)
if
(
!
dup_buf
)
return
-
ENOMEM
;
return
-
ENOMEM
;
...
@@ -1195,7 +1212,7 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans,
...
@@ -1195,7 +1212,7 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans,
idx
=
-
EINVAL
;
idx
=
-
EINVAL
;
goto
free_dup_buf
;
goto
free_dup_buf
;
}
}
copy_size
+=
cmd
->
len
[
i
];
copy_size
+=
cmdlen
[
i
];
}
}
cmd_size
+=
cmd
->
len
[
i
];
cmd_size
+=
cmd
->
len
[
i
];
}
}
...
@@ -1242,14 +1259,31 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans,
...
@@ -1242,14 +1259,31 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans,
/* and copy the data that needs to be copied */
/* and copy the data that needs to be copied */
cmd_pos
=
offsetof
(
struct
iwl_device_cmd
,
payload
);
cmd_pos
=
offsetof
(
struct
iwl_device_cmd
,
payload
);
copy_size
=
sizeof
(
out_cmd
->
hdr
);
for
(
i
=
0
;
i
<
IWL_MAX_CMD_TFDS
;
i
++
)
{
for
(
i
=
0
;
i
<
IWL_MAX_CMD_TFDS
;
i
++
)
{
if
(
!
cmd
->
len
[
i
])
int
copy
=
0
;
if
(
!
cmd
->
len
)
continue
;
continue
;
if
(
cmd
->
dataflags
[
i
]
&
(
IWL_HCMD_DFL_NOCOPY
|
IWL_HCMD_DFL_DUP
))
/* need at least IWL_HCMD_MIN_COPY_SIZE copied */
break
;
if
(
copy_size
<
IWL_HCMD_MIN_COPY_SIZE
)
{
memcpy
((
u8
*
)
out_cmd
+
cmd_pos
,
cmd
->
data
[
i
],
cmd
->
len
[
i
]);
copy
=
IWL_HCMD_MIN_COPY_SIZE
-
copy_size
;
cmd_pos
+=
cmd
->
len
[
i
];
if
(
copy
>
cmd
->
len
[
i
])
copy
=
cmd
->
len
[
i
];
}
/* copy everything if not nocopy/dup */
if
(
!
(
cmd
->
dataflags
[
i
]
&
(
IWL_HCMD_DFL_NOCOPY
|
IWL_HCMD_DFL_DUP
)))
copy
=
cmd
->
len
[
i
];
if
(
copy
)
{
memcpy
((
u8
*
)
out_cmd
+
cmd_pos
,
cmd
->
data
[
i
],
copy
);
cmd_pos
+=
copy
;
copy_size
+=
copy
;
}
}
}
WARN_ON_ONCE
(
txq
->
entries
[
idx
].
copy_cmd
);
WARN_ON_ONCE
(
txq
->
entries
[
idx
].
copy_cmd
);
...
@@ -1275,7 +1309,14 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans,
...
@@ -1275,7 +1309,14 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans,
out_cmd
->
hdr
.
cmd
,
le16_to_cpu
(
out_cmd
->
hdr
.
sequence
),
out_cmd
->
hdr
.
cmd
,
le16_to_cpu
(
out_cmd
->
hdr
.
sequence
),
cmd_size
,
q
->
write_ptr
,
idx
,
trans_pcie
->
cmd_queue
);
cmd_size
,
q
->
write_ptr
,
idx
,
trans_pcie
->
cmd_queue
);
phys_addr
=
dma_map_single
(
trans
->
dev
,
&
out_cmd
->
hdr
,
copy_size
,
/*
* If the entire command is smaller than IWL_HCMD_MIN_COPY_SIZE, we must
* still map at least that many bytes for the hardware to write back to.
* We have enough space, so that's not a problem.
*/
dma_size
=
max_t
(
u16
,
copy_size
,
IWL_HCMD_MIN_COPY_SIZE
);
phys_addr
=
dma_map_single
(
trans
->
dev
,
&
out_cmd
->
hdr
,
dma_size
,
DMA_BIDIRECTIONAL
);
DMA_BIDIRECTIONAL
);
if
(
unlikely
(
dma_mapping_error
(
trans
->
dev
,
phys_addr
)))
{
if
(
unlikely
(
dma_mapping_error
(
trans
->
dev
,
phys_addr
)))
{
idx
=
-
ENOMEM
;
idx
=
-
ENOMEM
;
...
@@ -1283,14 +1324,15 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans,
...
@@ -1283,14 +1324,15 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans,
}
}
dma_unmap_addr_set
(
out_meta
,
mapping
,
phys_addr
);
dma_unmap_addr_set
(
out_meta
,
mapping
,
phys_addr
);
dma_unmap_len_set
(
out_meta
,
len
,
copy
_size
);
dma_unmap_len_set
(
out_meta
,
len
,
dma
_size
);
iwl_pcie_txq_build_tfd
(
trans
,
txq
,
phys_addr
,
copy_size
,
1
);
iwl_pcie_txq_build_tfd
(
trans
,
txq
,
phys_addr
,
copy_size
,
1
);
/* map the remaining (adjusted) nocopy/dup fragments */
for
(
i
=
0
;
i
<
IWL_MAX_CMD_TFDS
;
i
++
)
{
for
(
i
=
0
;
i
<
IWL_MAX_CMD_TFDS
;
i
++
)
{
const
void
*
data
=
cmd
->
data
[
i
];
const
void
*
data
=
cmddata
[
i
];
if
(
!
cmd
->
len
[
i
])
if
(
!
cmdlen
[
i
])
continue
;
continue
;
if
(
!
(
cmd
->
dataflags
[
i
]
&
(
IWL_HCMD_DFL_NOCOPY
|
if
(
!
(
cmd
->
dataflags
[
i
]
&
(
IWL_HCMD_DFL_NOCOPY
|
IWL_HCMD_DFL_DUP
)))
IWL_HCMD_DFL_DUP
)))
...
@@ -1298,7 +1340,7 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans,
...
@@ -1298,7 +1340,7 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans,
if
(
cmd
->
dataflags
[
i
]
&
IWL_HCMD_DFL_DUP
)
if
(
cmd
->
dataflags
[
i
]
&
IWL_HCMD_DFL_DUP
)
data
=
dup_buf
;
data
=
dup_buf
;
phys_addr
=
dma_map_single
(
trans
->
dev
,
(
void
*
)
data
,
phys_addr
=
dma_map_single
(
trans
->
dev
,
(
void
*
)
data
,
cmd
->
len
[
i
],
DMA_BIDIRECTIONAL
);
cmdlen
[
i
],
DMA_BIDIRECTIONAL
);
if
(
dma_mapping_error
(
trans
->
dev
,
phys_addr
))
{
if
(
dma_mapping_error
(
trans
->
dev
,
phys_addr
))
{
iwl_pcie_tfd_unmap
(
trans
,
out_meta
,
iwl_pcie_tfd_unmap
(
trans
,
out_meta
,
&
txq
->
tfds
[
q
->
write_ptr
],
&
txq
->
tfds
[
q
->
write_ptr
],
...
@@ -1307,7 +1349,7 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans,
...
@@ -1307,7 +1349,7 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans,
goto
out
;
goto
out
;
}
}
iwl_pcie_txq_build_tfd
(
trans
,
txq
,
phys_addr
,
cmd
->
len
[
i
],
0
);
iwl_pcie_txq_build_tfd
(
trans
,
txq
,
phys_addr
,
cmdlen
[
i
],
0
);
}
}
out_meta
->
flags
=
cmd
->
flags
;
out_meta
->
flags
=
cmd
->
flags
;
...
@@ -1317,8 +1359,7 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans,
...
@@ -1317,8 +1359,7 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans,
txq
->
need_update
=
1
;
txq
->
need_update
=
1
;
trace_iwlwifi_dev_hcmd
(
trans
->
dev
,
cmd
,
cmd_size
,
trace_iwlwifi_dev_hcmd
(
trans
->
dev
,
cmd
,
cmd_size
,
&
out_cmd
->
hdr
);
&
out_cmd
->
hdr
,
copy_size
);
/* start timer if queue currently empty */
/* start timer if queue currently empty */
if
(
q
->
read_ptr
==
q
->
write_ptr
&&
trans_pcie
->
wd_timeout
)
if
(
q
->
read_ptr
==
q
->
write_ptr
&&
trans_pcie
->
wd_timeout
)
...
...
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