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
d91547c0
Commit
d91547c0
authored
May 17, 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
e248ad30
e3d4bc8c
Changes
9
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
105 additions
and
22 deletions
+105
-22
drivers/net/wireless/iwlwifi/mvm/fw-api.h
drivers/net/wireless/iwlwifi/mvm/fw-api.h
+27
-0
drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c
drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c
+8
-4
drivers/net/wireless/iwlwifi/mvm/mac80211.c
drivers/net/wireless/iwlwifi/mvm/mac80211.c
+16
-1
drivers/net/wireless/iwlwifi/mvm/mvm.h
drivers/net/wireless/iwlwifi/mvm/mvm.h
+1
-0
drivers/net/wireless/iwlwifi/mvm/ops.c
drivers/net/wireless/iwlwifi/mvm/ops.c
+1
-0
drivers/net/wireless/iwlwifi/mvm/scan.c
drivers/net/wireless/iwlwifi/mvm/scan.c
+6
-0
drivers/net/wireless/iwlwifi/mvm/sta.c
drivers/net/wireless/iwlwifi/mvm/sta.c
+10
-3
drivers/net/wireless/iwlwifi/mvm/sta.h
drivers/net/wireless/iwlwifi/mvm/sta.h
+0
-2
drivers/net/wireless/iwlwifi/mvm/tx.c
drivers/net/wireless/iwlwifi/mvm/tx.c
+36
-12
No files found.
drivers/net/wireless/iwlwifi/mvm/fw-api.h
View file @
d91547c0
...
...
@@ -173,6 +173,8 @@ enum {
REPLY_DEBUG_CMD
=
0xf0
,
DEBUG_LOG_MSG
=
0xf7
,
MCAST_FILTER_CMD
=
0xd0
,
/* D3 commands/notifications */
D3_CONFIG_CMD
=
0xd3
,
PROT_OFFLOAD_CONFIG_CMD
=
0xd4
,
...
...
@@ -948,4 +950,29 @@ struct iwl_set_calib_default_cmd {
u8
data
[
0
];
}
__packed
;
/* PHY_CALIB_OVERRIDE_VALUES_S */
#define MAX_PORT_ID_NUM 2
/**
* struct iwl_mcast_filter_cmd - configure multicast filter.
* @filter_own: Set 1 to filter out multicast packets sent by station itself
* @port_id: Multicast MAC addresses array specifier. This is a strange way
* to identify network interface adopted in host-device IF.
* It is used by FW as index in array of addresses. This array has
* MAX_PORT_ID_NUM members.
* @count: Number of MAC addresses in the array
* @pass_all: Set 1 to pass all multicast packets.
* @bssid: current association BSSID.
* @addr_list: Place holder for array of MAC addresses.
* IMPORTANT: add padding if necessary to ensure DWORD alignment.
*/
struct
iwl_mcast_filter_cmd
{
u8
filter_own
;
u8
port_id
;
u8
count
;
u8
pass_all
;
u8
bssid
[
6
];
u8
reserved
[
2
];
u8
addr_list
[
0
];
}
__packed
;
/* MCAST_FILTERING_CMD_API_S_VER_1 */
#endif
/* __fw_api_h__ */
drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c
View file @
d91547c0
...
...
@@ -586,10 +586,12 @@ static int iwl_mvm_mac_ctxt_send_cmd(struct iwl_mvm *mvm,
*/
static
void
iwl_mvm_mac_ctxt_cmd_fill_sta
(
struct
iwl_mvm
*
mvm
,
struct
ieee80211_vif
*
vif
,
struct
iwl_mac_data_sta
*
ctxt_sta
)
struct
iwl_mac_data_sta
*
ctxt_sta
,
bool
force_assoc_off
)
{
/* We need the dtim_period to set the MAC as associated */
if
(
vif
->
bss_conf
.
assoc
&&
vif
->
bss_conf
.
dtim_period
)
{
if
(
vif
->
bss_conf
.
assoc
&&
vif
->
bss_conf
.
dtim_period
&&
!
force_assoc_off
)
{
u32
dtim_offs
;
/*
...
...
@@ -659,7 +661,8 @@ static int iwl_mvm_mac_ctxt_cmd_station(struct iwl_mvm *mvm,
cmd
.
filter_flags
&=
~
cpu_to_le32
(
MAC_FILTER_IN_BEACON
);
/* Fill the data specific for station mode */
iwl_mvm_mac_ctxt_cmd_fill_sta
(
mvm
,
vif
,
&
cmd
.
sta
);
iwl_mvm_mac_ctxt_cmd_fill_sta
(
mvm
,
vif
,
&
cmd
.
sta
,
action
==
FW_CTXT_ACTION_ADD
);
return
iwl_mvm_mac_ctxt_send_cmd
(
mvm
,
&
cmd
);
}
...
...
@@ -677,7 +680,8 @@ static int iwl_mvm_mac_ctxt_cmd_p2p_client(struct iwl_mvm *mvm,
iwl_mvm_mac_ctxt_cmd_common
(
mvm
,
vif
,
&
cmd
,
action
);
/* Fill the data specific for station mode */
iwl_mvm_mac_ctxt_cmd_fill_sta
(
mvm
,
vif
,
&
cmd
.
p2p_sta
.
sta
);
iwl_mvm_mac_ctxt_cmd_fill_sta
(
mvm
,
vif
,
&
cmd
.
p2p_sta
.
sta
,
action
==
FW_CTXT_ACTION_ADD
);
cmd
.
p2p_sta
.
ctwin
=
cpu_to_le32
(
noa
->
oppps_ctwindow
&
IEEE80211_P2P_OPPPS_CTWINDOW_MASK
);
...
...
drivers/net/wireless/iwlwifi/mvm/mac80211.c
View file @
d91547c0
...
...
@@ -701,6 +701,20 @@ static void iwl_mvm_configure_filter(struct ieee80211_hw *hw,
*
total_flags
=
0
;
}
static
int
iwl_mvm_configure_mcast_filter
(
struct
iwl_mvm
*
mvm
,
struct
ieee80211_vif
*
vif
)
{
struct
iwl_mcast_filter_cmd
mcast_filter_cmd
=
{
.
pass_all
=
1
,
};
memcpy
(
mcast_filter_cmd
.
bssid
,
vif
->
bss_conf
.
bssid
,
ETH_ALEN
);
return
iwl_mvm_send_cmd_pdu
(
mvm
,
MCAST_FILTER_CMD
,
CMD_SYNC
,
sizeof
(
mcast_filter_cmd
),
&
mcast_filter_cmd
);
}
static
void
iwl_mvm_bss_info_changed_station
(
struct
iwl_mvm
*
mvm
,
struct
ieee80211_vif
*
vif
,
struct
ieee80211_bss_conf
*
bss_conf
,
...
...
@@ -722,6 +736,7 @@ static void iwl_mvm_bss_info_changed_station(struct iwl_mvm *mvm,
return
;
}
iwl_mvm_bt_coex_vif_assoc
(
mvm
,
vif
);
iwl_mvm_configure_mcast_filter
(
mvm
,
vif
);
}
else
if
(
mvmvif
->
ap_sta_id
!=
IWL_MVM_STATION_COUNT
)
{
/* remove AP station now that the MAC is unassoc */
ret
=
iwl_mvm_rm_sta_id
(
mvm
,
vif
,
mvmvif
->
ap_sta_id
);
...
...
@@ -931,7 +946,7 @@ static void iwl_mvm_mac_sta_notify(struct ieee80211_hw *hw,
switch
(
cmd
)
{
case
STA_NOTIFY_SLEEP
:
if
(
atomic_read
(
&
mvm
sta
->
pending_frames
)
>
0
)
if
(
atomic_read
(
&
mvm
->
pending_frames
[
mvmsta
->
sta_id
]
)
>
0
)
ieee80211_sta_block_awake
(
hw
,
sta
,
true
);
/*
* The fw updates the STA to be asleep. Tx packets on the Tx
...
...
drivers/net/wireless/iwlwifi/mvm/mvm.h
View file @
d91547c0
...
...
@@ -292,6 +292,7 @@ struct iwl_mvm {
struct
ieee80211_sta
__rcu
*
fw_id_to_mac_id
[
IWL_MVM_STATION_COUNT
];
struct
work_struct
sta_drained_wk
;
unsigned
long
sta_drained
[
BITS_TO_LONGS
(
IWL_MVM_STATION_COUNT
)];
atomic_t
pending_frames
[
IWL_MVM_STATION_COUNT
];
/* configured by mac80211 */
u32
rts_threshold
;
...
...
drivers/net/wireless/iwlwifi/mvm/ops.c
View file @
d91547c0
...
...
@@ -292,6 +292,7 @@ static const char *iwl_mvm_cmd_strings[REPLY_MAX] = {
CMD
(
BT_COEX_PROT_ENV
),
CMD
(
BT_PROFILE_NOTIFICATION
),
CMD
(
BT_CONFIG
),
CMD
(
MCAST_FILTER_CMD
),
};
#undef CMD
...
...
drivers/net/wireless/iwlwifi/mvm/scan.c
View file @
d91547c0
...
...
@@ -298,6 +298,12 @@ int iwl_mvm_scan_request(struct iwl_mvm *mvm,
else
cmd
->
type
=
cpu_to_le32
(
SCAN_TYPE_FORCED
);
/*
* TODO: This is a WA due to a bug in the FW AUX framework that does not
* properly handle time events that fail to be scheduled
*/
cmd
->
type
=
cpu_to_le32
(
SCAN_TYPE_FORCED
);
cmd
->
repeats
=
cpu_to_le32
(
1
);
/*
...
...
drivers/net/wireless/iwlwifi/mvm/sta.c
View file @
d91547c0
...
...
@@ -219,7 +219,7 @@ int iwl_mvm_add_sta(struct iwl_mvm *mvm,
mvm_sta
->
max_agg_bufsize
=
LINK_QUAL_AGG_FRAME_LIMIT_DEF
;
/* HW restart, don't assume the memory has been zeroed */
atomic_set
(
&
mvm
_sta
->
pending_frames
,
0
);
atomic_set
(
&
mvm
->
pending_frames
[
sta_id
]
,
0
);
mvm_sta
->
tid_disable_agg
=
0
;
mvm_sta
->
tfd_queue_msk
=
0
;
for
(
i
=
0
;
i
<
IEEE80211_NUM_ACS
;
i
++
)
...
...
@@ -406,15 +406,22 @@ int iwl_mvm_rm_sta(struct iwl_mvm *mvm,
mvmvif
->
ap_sta_id
=
IWL_MVM_STATION_COUNT
;
}
/*
* Make sure that the tx response code sees the station as -EBUSY and
* calls the drain worker.
*/
spin_lock_bh
(
&
mvm_sta
->
lock
);
/*
* There are frames pending on the AC queues for this station.
* We need to wait until all the frames are drained...
*/
if
(
atomic_read
(
&
mvm_sta
->
pending_frames
))
{
ret
=
iwl_mvm_drain_sta
(
mvm
,
mvm_sta
,
true
);
if
(
atomic_read
(
&
mvm
->
pending_frames
[
mvm_sta
->
sta_id
]))
{
rcu_assign_pointer
(
mvm
->
fw_id_to_mac_id
[
mvm_sta
->
sta_id
],
ERR_PTR
(
-
EBUSY
));
spin_unlock_bh
(
&
mvm_sta
->
lock
);
ret
=
iwl_mvm_drain_sta
(
mvm
,
mvm_sta
,
true
);
}
else
{
spin_unlock_bh
(
&
mvm_sta
->
lock
);
ret
=
iwl_mvm_rm_sta_common
(
mvm
,
mvm_sta
->
sta_id
);
rcu_assign_pointer
(
mvm
->
fw_id_to_mac_id
[
mvm_sta
->
sta_id
],
NULL
);
}
...
...
drivers/net/wireless/iwlwifi/mvm/sta.h
View file @
d91547c0
...
...
@@ -274,7 +274,6 @@ struct iwl_mvm_tid_data {
* @bt_reduced_txpower: is reduced tx power enabled for this station
* @lock: lock to protect the whole struct. Since %tid_data is access from Tx
* and from Tx response flow, it needs a spinlock.
* @pending_frames: number of frames for this STA on the shared Tx queues.
* @tid_data: per tid data. Look at %iwl_mvm_tid_data.
*
* When mac80211 creates a station it reserves some space (hw->sta_data_size)
...
...
@@ -290,7 +289,6 @@ struct iwl_mvm_sta {
u8
max_agg_bufsize
;
bool
bt_reduced_txpower
;
spinlock_t
lock
;
atomic_t
pending_frames
;
struct
iwl_mvm_tid_data
tid_data
[
IWL_MAX_TID_COUNT
];
struct
iwl_lq_sta
lq_sta
;
struct
ieee80211_vif
*
vif
;
...
...
drivers/net/wireless/iwlwifi/mvm/tx.c
View file @
d91547c0
...
...
@@ -416,9 +416,8 @@ int iwl_mvm_tx_skb(struct iwl_mvm *mvm, struct sk_buff *skb,
spin_unlock
(
&
mvmsta
->
lock
);
if
(
mvmsta
->
vif
->
type
==
NL80211_IFTYPE_AP
&&
txq_id
<
IWL_MVM_FIRST_AGG_QUEUE
)
atomic_inc
(
&
mvmsta
->
pending_frames
);
if
(
txq_id
<
IWL_MVM_FIRST_AGG_QUEUE
)
atomic_inc
(
&
mvm
->
pending_frames
[
mvmsta
->
sta_id
]);
return
0
;
...
...
@@ -680,16 +679,41 @@ static void iwl_mvm_rx_tx_cmd_single(struct iwl_mvm *mvm,
/*
* If the txq is not an AMPDU queue, there is no chance we freed
* several skbs. Check that out...
* If there are no pending frames for this STA, notify mac80211 that
* this station can go to sleep in its STA table.
*/
if
(
txq_id
<
IWL_MVM_FIRST_AGG_QUEUE
&&
mvmsta
&&
!
WARN_ON
(
skb_freed
>
1
)
&&
mvmsta
->
vif
->
type
==
NL80211_IFTYPE_AP
&&
atomic_sub_and_test
(
skb_freed
,
&
mvmsta
->
pending_frames
))
{
ieee80211_sta_block_awake
(
mvm
->
hw
,
sta
,
false
);
set_bit
(
sta_id
,
mvm
->
sta_drained
);
schedule_work
(
&
mvm
->
sta_drained_wk
);
if
(
txq_id
<
IWL_MVM_FIRST_AGG_QUEUE
&&
!
WARN_ON
(
skb_freed
>
1
)
&&
atomic_sub_and_test
(
skb_freed
,
&
mvm
->
pending_frames
[
sta_id
]))
{
if
(
mvmsta
)
{
/*
* If there are no pending frames for this STA, notify
* mac80211 that this station can go to sleep in its
* STA table.
*/
if
(
mvmsta
->
vif
->
type
==
NL80211_IFTYPE_AP
)
ieee80211_sta_block_awake
(
mvm
->
hw
,
sta
,
false
);
/*
* We might very well have taken mvmsta pointer while
* the station was being removed. The remove flow might
* have seen a pending_frame (because we didn't take
* the lock) even if now the queues are drained. So make
* really sure now that this the station is not being
* removed. If it is, run the drain worker to remove it.
*/
spin_lock_bh
(
&
mvmsta
->
lock
);
sta
=
rcu_dereference
(
mvm
->
fw_id_to_mac_id
[
sta_id
]);
if
(
IS_ERR_OR_NULL
(
sta
))
{
/*
* Station disappeared in the meantime:
* so we are draining.
*/
set_bit
(
sta_id
,
mvm
->
sta_drained
);
schedule_work
(
&
mvm
->
sta_drained_wk
);
}
spin_unlock_bh
(
&
mvmsta
->
lock
);
}
else
if
(
!
mvmsta
)
{
/* Tx response without STA, so we are draining */
set_bit
(
sta_id
,
mvm
->
sta_drained
);
schedule_work
(
&
mvm
->
sta_drained_wk
);
}
}
rcu_read_unlock
();
...
...
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