Skip to content

Commit c61b655

Browse files
egrumbachjmberg-intel
authored andcommitted
iwlwifi: mvm: add a new RSS sync notification for NSSN sync
We will soon be using a new notification that will be initiated by the driver, sent to the firmware and sent back to all the RSS queues by the firmware. This new notification will be useful to synchronize the NSSN across all the queues. For now, don't send the notification, just add the code to handle it. Later patch will add the code to actually send it. While at it, validate the baid coming from the firmware to avoid accessing an array with a bad index in the driver. Signed-off-by: Emmanuel Grumbach <[email protected]> Signed-off-by: Luca Coelho <[email protected]> Signed-off-by: Johannes Berg <[email protected]>
1 parent 6b2dbce commit c61b655

File tree

5 files changed

+64
-36
lines changed

5 files changed

+64
-36
lines changed

drivers/net/wireless/intel/iwlwifi/fw/api/rx.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -812,10 +812,12 @@ struct iwl_rxq_sync_notification {
812812
*
813813
* @IWL_MVM_RXQ_EMPTY: empty sync notification
814814
* @IWL_MVM_RXQ_NOTIF_DEL_BA: notify RSS queues of delBA
815+
* @IWL_MVM_RXQ_NSSN_SYNC: notify all the RSS queues with the new NSSN
815816
*/
816817
enum iwl_mvm_rxq_notif_type {
817818
IWL_MVM_RXQ_EMPTY,
818819
IWL_MVM_RXQ_NOTIF_DEL_BA,
820+
IWL_MVM_RXQ_NSSN_SYNC,
819821
};
820822

821823
/**

drivers/net/wireless/intel/iwlwifi/mvm/mvm.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1665,8 +1665,8 @@ void iwl_mvm_rx_frame_release(struct iwl_mvm *mvm, struct napi_struct *napi,
16651665
struct iwl_rx_cmd_buffer *rxb, int queue);
16661666
int iwl_mvm_notify_rx_queue(struct iwl_mvm *mvm, u32 rxq_mask,
16671667
const u8 *data, u32 count);
1668-
void iwl_mvm_rx_queue_notif(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb,
1669-
int queue);
1668+
void iwl_mvm_rx_queue_notif(struct iwl_mvm *mvm, struct napi_struct *napi,
1669+
struct iwl_rx_cmd_buffer *rxb, int queue);
16701670
void iwl_mvm_rx_tx_cmd(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb);
16711671
void iwl_mvm_mfu_assert_dump_notif(struct iwl_mvm *mvm,
16721672
struct iwl_rx_cmd_buffer *rxb);

drivers/net/wireless/intel/iwlwifi/mvm/ops.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1088,7 +1088,7 @@ static void iwl_mvm_rx_mq(struct iwl_op_mode *op_mode,
10881088
iwl_mvm_rx_mpdu_mq(mvm, napi, rxb, 0);
10891089
else if (unlikely(cmd == WIDE_ID(DATA_PATH_GROUP,
10901090
RX_QUEUES_NOTIFICATION)))
1091-
iwl_mvm_rx_queue_notif(mvm, rxb, 0);
1091+
iwl_mvm_rx_queue_notif(mvm, napi, rxb, 0);
10921092
else if (cmd == WIDE_ID(LEGACY_GROUP, FRAME_RELEASE))
10931093
iwl_mvm_rx_frame_release(mvm, napi, rxb, 0);
10941094
else if (cmd == WIDE_ID(DATA_PATH_GROUP, RX_NO_DATA_NOTIF))
@@ -1812,7 +1812,7 @@ static void iwl_mvm_rx_mq_rss(struct iwl_op_mode *op_mode,
18121812
iwl_mvm_rx_frame_release(mvm, napi, rxb, queue);
18131813
else if (unlikely(cmd == WIDE_ID(DATA_PATH_GROUP,
18141814
RX_QUEUES_NOTIFICATION)))
1815-
iwl_mvm_rx_queue_notif(mvm, rxb, queue);
1815+
iwl_mvm_rx_queue_notif(mvm, napi, rxb, queue);
18161816
else if (likely(cmd == WIDE_ID(LEGACY_GROUP, REPLY_RX_MPDU_CMD)))
18171817
iwl_mvm_rx_mpdu_mq(mvm, napi, rxb, queue);
18181818
}

drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c

Lines changed: 52 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -665,8 +665,51 @@ static void iwl_mvm_del_ba(struct iwl_mvm *mvm, int queue,
665665
rcu_read_unlock();
666666
}
667667

668-
void iwl_mvm_rx_queue_notif(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb,
669-
int queue)
668+
static void iwl_mvm_release_frames_from_notif(struct iwl_mvm *mvm,
669+
struct napi_struct *napi,
670+
u8 baid, u16 nssn, int queue)
671+
{
672+
struct ieee80211_sta *sta;
673+
struct iwl_mvm_reorder_buffer *reorder_buf;
674+
struct iwl_mvm_baid_data *ba_data;
675+
676+
IWL_DEBUG_HT(mvm, "Frame release notification for BAID %u, NSSN %d\n",
677+
baid, nssn);
678+
679+
if (WARN_ON_ONCE(baid == IWL_RX_REORDER_DATA_INVALID_BAID ||
680+
baid >= ARRAY_SIZE(mvm->baid_map)))
681+
return;
682+
683+
rcu_read_lock();
684+
685+
ba_data = rcu_dereference(mvm->baid_map[baid]);
686+
if (WARN_ON_ONCE(!ba_data))
687+
goto out;
688+
689+
sta = rcu_dereference(mvm->fw_id_to_mac_id[ba_data->sta_id]);
690+
if (WARN_ON_ONCE(IS_ERR_OR_NULL(sta)))
691+
goto out;
692+
693+
reorder_buf = &ba_data->reorder_buf[queue];
694+
695+
spin_lock_bh(&reorder_buf->lock);
696+
iwl_mvm_release_frames(mvm, sta, napi, ba_data, reorder_buf, nssn);
697+
spin_unlock_bh(&reorder_buf->lock);
698+
699+
out:
700+
rcu_read_unlock();
701+
}
702+
703+
static void iwl_mvm_nssn_sync(struct iwl_mvm *mvm,
704+
struct napi_struct *napi, int queue,
705+
const struct iwl_mvm_nssn_sync_data *data)
706+
{
707+
iwl_mvm_release_frames_from_notif(mvm, napi, data->baid,
708+
data->nssn, queue);
709+
}
710+
711+
void iwl_mvm_rx_queue_notif(struct iwl_mvm *mvm, struct napi_struct *napi,
712+
struct iwl_rx_cmd_buffer *rxb, int queue)
670713
{
671714
struct iwl_rx_packet *pkt = rxb_addr(rxb);
672715
struct iwl_rxq_sync_notification *notif;
@@ -687,6 +730,10 @@ void iwl_mvm_rx_queue_notif(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb,
687730
case IWL_MVM_RXQ_NOTIF_DEL_BA:
688731
iwl_mvm_del_ba(mvm, queue, (void *)internal_notif->data);
689732
break;
733+
case IWL_MVM_RXQ_NSSN_SYNC:
734+
iwl_mvm_nssn_sync(mvm, napi, queue,
735+
(void *)internal_notif->data);
736+
break;
690737
default:
691738
WARN_ONCE(1, "Invalid identifier %d", internal_notif->type);
692739
}
@@ -1840,40 +1887,13 @@ void iwl_mvm_rx_monitor_no_data(struct iwl_mvm *mvm, struct napi_struct *napi,
18401887
out:
18411888
rcu_read_unlock();
18421889
}
1890+
18431891
void iwl_mvm_rx_frame_release(struct iwl_mvm *mvm, struct napi_struct *napi,
18441892
struct iwl_rx_cmd_buffer *rxb, int queue)
18451893
{
18461894
struct iwl_rx_packet *pkt = rxb_addr(rxb);
18471895
struct iwl_frame_release *release = (void *)pkt->data;
1848-
struct ieee80211_sta *sta;
1849-
struct iwl_mvm_reorder_buffer *reorder_buf;
1850-
struct iwl_mvm_baid_data *ba_data;
1851-
1852-
int baid = release->baid;
18531896

1854-
IWL_DEBUG_HT(mvm, "Frame release notification for BAID %u, NSSN %d\n",
1855-
release->baid, le16_to_cpu(release->nssn));
1856-
1857-
if (WARN_ON_ONCE(baid == IWL_RX_REORDER_DATA_INVALID_BAID))
1858-
return;
1859-
1860-
rcu_read_lock();
1861-
1862-
ba_data = rcu_dereference(mvm->baid_map[baid]);
1863-
if (WARN_ON_ONCE(!ba_data))
1864-
goto out;
1865-
1866-
sta = rcu_dereference(mvm->fw_id_to_mac_id[ba_data->sta_id]);
1867-
if (WARN_ON_ONCE(IS_ERR_OR_NULL(sta)))
1868-
goto out;
1869-
1870-
reorder_buf = &ba_data->reorder_buf[queue];
1871-
1872-
spin_lock_bh(&reorder_buf->lock);
1873-
iwl_mvm_release_frames(mvm, sta, napi, ba_data, reorder_buf,
1874-
le16_to_cpu(release->nssn));
1875-
spin_unlock_bh(&reorder_buf->lock);
1876-
1877-
out:
1878-
rcu_read_unlock();
1897+
iwl_mvm_release_frames_from_notif(mvm, napi, release->baid,
1898+
le16_to_cpu(release->nssn), queue);
18791899
}

drivers/net/wireless/intel/iwlwifi/mvm/sta.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -343,10 +343,16 @@ struct iwl_mvm_delba_data {
343343
u32 baid;
344344
} __packed;
345345

346+
struct iwl_mvm_nssn_sync_data {
347+
u32 baid;
348+
u32 nssn;
349+
} __packed;
350+
346351
struct iwl_mvm_rss_sync_notif {
347352
struct iwl_mvm_internal_rxq_notif metadata;
348353
union {
349354
struct iwl_mvm_delba_data delba;
355+
struct iwl_mvm_nssn_sync_data nssn_sync;
350356
};
351357
} __packed;
352358

0 commit comments

Comments
 (0)