Commit 062a6c41 authored by Jérôme Pouiller's avatar Jérôme Pouiller Committed by Greg Kroah-Hartman
Browse files

staging: wfx: drop useless sta_asleep_mask



Currently, the driver tracks power save state of the stations with the
variable sta_asleep_mask. Then, it takes care to not sent data to asleep
stations.

However, this work is already done by mac80211. Normally, there are no
frames for asleep stations in our queues. So, driver do not have to
filter frames in its queues (apart the frames marked "AFTER_DTIM").

Notice that there is a risk of race between state of the station and
data send to the firmware. However, this risk is limited since the
number of frame in queues are small. In add, this race also exists with
the current code. Anyway, the firmware is able to detect the problem and
driver will receive a 'REQUEUE' status (translated in
TX_STAT_TX_FILTERED for mac80211).

Reviewed-by: default avatarDan Carpenter <dan.carpenter@oracle.com>
Signed-off-by: default avatarJérôme Pouiller <jerome.pouiller@silabs.com>
Link: https://lore.kernel.org/r/20200401110405.80282-13-Jerome.Pouiller@silabs.com


Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 517b358f
Loading
Loading
Loading
Loading
+0 −6
Original line number Diff line number Diff line
@@ -275,15 +275,9 @@ static void wfx_tx_manage_pm(struct wfx_vif *wvif, struct ieee80211_hdr *hdr,
			     struct wfx_tx_priv *tx_priv,
			     struct ieee80211_sta *sta)
{
	u32 mask = ~BIT(tx_priv->raw_link_id);
	struct wfx_sta_priv *sta_priv;
	int tid = ieee80211_get_tid(hdr);

	spin_lock_bh(&wvif->ps_state_lock);
	if (ieee80211_is_auth(hdr->frame_control))
		wvif->sta_asleep_mask &= mask;
	spin_unlock_bh(&wvif->ps_state_lock);

	if (sta) {
		sta_priv = (struct wfx_sta_priv *)&sta->drv_priv;
		spin_lock_bh(&sta_priv->lock);
+0 −1
Original line number Diff line number Diff line
@@ -138,7 +138,6 @@ static const struct ieee80211_ops wfx_ops = {
	.cancel_hw_scan		= wfx_cancel_hw_scan,
	.sta_add		= wfx_sta_add,
	.sta_remove		= wfx_sta_remove,
	.sta_notify		= wfx_sta_notify,
	.set_tim		= wfx_set_tim,
	.set_key		= wfx_set_key,
	.set_rts_threshold	= wfx_set_rts_threshold,
+2 −12
Original line number Diff line number Diff line
@@ -388,13 +388,8 @@ static struct wfx_queue *wfx_tx_queue_mask_get(struct wfx_vif *wvif,
	int idx;
	u32 tx_allowed_mask;

	/* Search for unicast traffic */
	tx_allowed_mask = ~wvif->sta_asleep_mask;
	tx_allowed_mask |= BIT(WFX_LINK_ID_UAPSD);
	if (wvif->sta_asleep_mask)
	tx_allowed_mask = BIT(WFX_LINK_ID_MAX) - 1;
	tx_allowed_mask &= ~BIT(WFX_LINK_ID_AFTER_DTIM);
	else
		tx_allowed_mask |= BIT(WFX_LINK_ID_AFTER_DTIM);
	idx = wfx_get_prio_queue(wvif, tx_allowed_mask);
	if (idx < 0)
		return NULL;
@@ -464,13 +459,8 @@ struct hif_msg *wfx_tx_queues_get(struct wfx_dev *wdev)

		wvif = NULL;
		while ((wvif = wvif_iterate(wdev, wvif)) != NULL) {
			spin_lock_bh(&wvif->ps_state_lock);

			vif_queue = wfx_tx_queue_mask_get(wvif,
							  &vif_tx_allowed_mask);

			spin_unlock_bh(&wvif->ps_state_lock);

			if (vif_queue) {
				if (queue && queue != vif_queue)
					dev_info(wdev->dev, "vifs disagree about queue priority\n");
+0 −29
Original line number Diff line number Diff line
@@ -590,11 +590,6 @@ int wfx_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
	WARN_ON(sta_priv->link_id >= WFX_MAX_STA_IN_AP_MODE);
	hif_map_link(wvif, sta->addr, 0, sta_priv->link_id);

	spin_lock_bh(&wvif->ps_state_lock);
	if ((sta->uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_MASK) ==
					IEEE80211_WMM_IE_STA_QOSINFO_AC_MASK)
		wvif->sta_asleep_mask |= BIT(sta_priv->link_id);
	spin_unlock_bh(&wvif->ps_state_lock);
	return 0;
}

@@ -841,28 +836,6 @@ void wfx_bss_info_changed(struct ieee80211_hw *hw,
		wfx_do_join(wvif);
}

static void wfx_ps_notify_sta(struct wfx_vif *wvif,
			      enum sta_notify_cmd notify_cmd, int link_id)
{
	spin_lock_bh(&wvif->ps_state_lock);
	if (notify_cmd == STA_NOTIFY_SLEEP)
		wvif->sta_asleep_mask |= BIT(link_id);
	else // notify_cmd == STA_NOTIFY_AWAKE
		wvif->sta_asleep_mask &= ~BIT(link_id);
	spin_unlock_bh(&wvif->ps_state_lock);
	if (notify_cmd == STA_NOTIFY_AWAKE)
		wfx_bh_request_tx(wvif->wdev);
}

void wfx_sta_notify(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
		    enum sta_notify_cmd notify_cmd, struct ieee80211_sta *sta)
{
	struct wfx_vif *wvif = (struct wfx_vif *) vif->drv_priv;
	struct wfx_sta_priv *sta_priv = (struct wfx_sta_priv *) &sta->drv_priv;

	wfx_ps_notify_sta(wvif, notify_cmd, sta_priv->link_id);
}

static int wfx_update_tim(struct wfx_vif *wvif)
{
	struct sk_buff *skb;
@@ -1019,7 +992,6 @@ int wfx_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
	wvif->wdev = wdev;

	wvif->link_id_map = 1; // link-id 0 is reserved for multicast
	spin_lock_init(&wvif->ps_state_lock);
	INIT_WORK(&wvif->update_tim_work, wfx_update_tim_work);

	memset(&wvif->bss_params, 0, sizeof(wvif->bss_params));
@@ -1083,7 +1055,6 @@ void wfx_remove_interface(struct ieee80211_hw *hw,
			wfx_tx_unlock(wdev);
		break;
	case WFX_STATE_AP:
		wvif->sta_asleep_mask = 0;
		/* reset.link_id = 0; */
		hif_reset(wvif, false);
		break;
+0 −2
Original line number Diff line number Diff line
@@ -85,8 +85,6 @@ struct wfx_vif {
	struct tx_policy_cache	tx_policy_cache;
	struct work_struct	tx_policy_upload_work;

	u32			sta_asleep_mask;
	spinlock_t		ps_state_lock;
	struct work_struct	update_tim_work;

	int			beacon_int;