Lines Matching +full:queue +full:- +full:pkt +full:- +full:rx
1 // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
3 * Copyright (C) 2024-2025 Intel Corporation
17 &baid_data->entries[reorder_buf->queue * in iwl_mld_reorder_release_frames()
18 baid_data->entries_per_queue]; in iwl_mld_reorder_release_frames()
19 u16 ssn = reorder_buf->head_sn; in iwl_mld_reorder_release_frames()
22 int index = ssn % baid_data->buf_size; in iwl_mld_reorder_release_frames()
28 /* Empty the list. Will have more than one frame for A-MSDU. in iwl_mld_reorder_release_frames()
34 reorder_buf->queue, in iwl_mld_reorder_release_frames()
36 reorder_buf->num_stored--; in iwl_mld_reorder_release_frames()
39 reorder_buf->head_sn = nssn; in iwl_mld_reorder_release_frames()
44 u8 baid, u16 nssn, int queue) in iwl_mld_release_frames_from_notif() argument
55 baid >= ARRAY_SIZE(mld->fw_id_to_ba))) in iwl_mld_release_frames_from_notif()
60 ba_data = rcu_dereference(mld->fw_id_to_ba[baid]); in iwl_mld_release_frames_from_notif()
67 sta_id = ffs(ba_data->sta_mask) - 1; in iwl_mld_release_frames_from_notif()
68 link_sta = rcu_dereference(mld->fw_id_to_link_sta[sta_id]); in iwl_mld_release_frames_from_notif()
69 if (WARN_ON_ONCE(IS_ERR_OR_NULL(link_sta) || !link_sta->sta)) in iwl_mld_release_frames_from_notif()
72 reorder_buf = &ba_data->reorder_buf[queue]; in iwl_mld_release_frames_from_notif()
74 iwl_mld_reorder_release_frames(mld, link_sta->sta, napi, ba_data, in iwl_mld_release_frames_from_notif()
82 struct iwl_rx_packet *pkt, int queue) in iwl_mld_handle_frame_release_notif() argument
84 struct iwl_frame_release *release = (void *)pkt->data; in iwl_mld_handle_frame_release_notif()
85 u32 pkt_len = iwl_rx_packet_payload_len(pkt); in iwl_mld_handle_frame_release_notif()
92 iwl_mld_release_frames_from_notif(mld, napi, release->baid, in iwl_mld_handle_frame_release_notif()
93 le16_to_cpu(release->nssn), in iwl_mld_handle_frame_release_notif()
94 queue); in iwl_mld_handle_frame_release_notif()
99 struct iwl_rx_packet *pkt, in iwl_mld_handle_bar_frame_release_notif() argument
100 int queue) in iwl_mld_handle_bar_frame_release_notif() argument
102 struct iwl_bar_frame_release *release = (void *)pkt->data; in iwl_mld_handle_bar_frame_release_notif()
105 u32 pkt_len = iwl_rx_packet_payload_len(pkt); in iwl_mld_handle_bar_frame_release_notif()
112 baid = le32_get_bits(release->ba_info, in iwl_mld_handle_bar_frame_release_notif()
114 nssn = le32_get_bits(release->ba_info, in iwl_mld_handle_bar_frame_release_notif()
116 sta_id = le32_get_bits(release->sta_tid, in iwl_mld_handle_bar_frame_release_notif()
118 tid = le32_get_bits(release->sta_tid, in iwl_mld_handle_bar_frame_release_notif()
121 if (IWL_FW_CHECK(mld, baid >= ARRAY_SIZE(mld->fw_id_to_ba), in iwl_mld_handle_bar_frame_release_notif()
126 baid_data = rcu_dereference(mld->fw_id_to_ba[baid]); in iwl_mld_handle_bar_frame_release_notif()
132 if (IWL_FW_CHECK(mld, tid != baid_data->tid || in iwl_mld_handle_bar_frame_release_notif()
133 sta_id > mld->fw->ucode_capa.num_stations || in iwl_mld_handle_bar_frame_release_notif()
134 !(baid_data->sta_mask & BIT(sta_id)), in iwl_mld_handle_bar_frame_release_notif()
136 baid, baid_data->sta_mask, baid_data->tid, sta_id, in iwl_mld_handle_bar_frame_release_notif()
143 iwl_mld_release_frames_from_notif(mld, napi, baid, nssn, queue); in iwl_mld_handle_bar_frame_release_notif()
148 void iwl_mld_del_ba(struct iwl_mld *mld, int queue, in iwl_mld_del_ba() argument
154 u8 baid = data->baid; in iwl_mld_del_ba()
162 ba_data = rcu_dereference(mld->fw_id_to_ba[baid]); in iwl_mld_del_ba()
167 sta_id = ffs(ba_data->sta_mask) - 1; in iwl_mld_del_ba()
168 link_sta = rcu_dereference(mld->fw_id_to_link_sta[sta_id]); in iwl_mld_del_ba()
169 if (WARN_ON_ONCE(IS_ERR_OR_NULL(link_sta) || !link_sta->sta)) in iwl_mld_del_ba()
172 reorder_buf = &ba_data->reorder_buf[queue]; in iwl_mld_del_ba()
175 iwl_mld_reorder_release_frames(mld, link_sta->sta, NULL, in iwl_mld_del_ba()
177 ieee80211_sn_add(reorder_buf->head_sn, in iwl_mld_del_ba()
178 ba_data->buf_size)); in iwl_mld_del_ba()
188 int queue, struct ieee80211_sta *sta, in iwl_mld_reorder() argument
197 u32 reorder = le32_to_cpu(desc->reorder_data); in iwl_mld_reorder()
223 if (!ieee80211_is_data_qos(hdr->frame_control) || in iwl_mld_reorder()
224 is_multicast_ether_addr(hdr->addr1)) in iwl_mld_reorder()
227 if (unlikely(!ieee80211_is_data_present(hdr->frame_control))) in iwl_mld_reorder()
230 baid_data = rcu_dereference(mld->fw_id_to_ba[baid]); in iwl_mld_reorder()
233 "Got valid BAID but no baid allocated, bypass re-ordering (BAID=%d reorder=0x%x)\n", in iwl_mld_reorder()
239 sta_mask |= BIT(mld_link_sta->fw_id); in iwl_mld_reorder()
243 tid != baid_data->tid || in iwl_mld_reorder()
244 !(sta_mask & baid_data->sta_mask), in iwl_mld_reorder()
246 baid, baid_data->sta_mask, baid_data->tid, in iwl_mld_reorder()
250 buffer = &baid_data->reorder_buf[queue]; in iwl_mld_reorder()
251 entries = &baid_data->entries[queue * baid_data->entries_per_queue]; in iwl_mld_reorder()
255 if (!buffer->valid && is_old_sn) in iwl_mld_reorder()
258 buffer->valid = true; in iwl_mld_reorder()
260 is_dup = !!(desc->status & cpu_to_le32(IWL_RX_MPDU_STATUS_DUPLICATE)); in iwl_mld_reorder()
268 amsdu = desc->mac_flags2 & IWL_RX_MPDU_MFLG2_AMSDU; in iwl_mld_reorder()
269 last_subframe = desc->amsdu_info & IWL_RX_MPDU_AMSDU_LAST_SUBFRAME; in iwl_mld_reorder()
272 if (!buffer->num_stored && ieee80211_sn_less(sn, nssn)) { in iwl_mld_reorder()
274 buffer->head_sn = nssn; in iwl_mld_reorder()
285 if (!buffer->num_stored && sn == buffer->head_sn) { in iwl_mld_reorder()
287 buffer->head_sn = ieee80211_sn_inc(buffer->head_sn); in iwl_mld_reorder()
292 index = sn % baid_data->buf_size; in iwl_mld_reorder()
294 buffer->num_stored++; in iwl_mld_reorder()
296 /* We cannot trust NSSN for AMSDU sub-frames that are not the last. The in iwl_mld_reorder()
297 * reason is that NSSN advances on the first sub-frame, and may cause in iwl_mld_reorder()
298 * the reorder buffer to advance before all the sub-frames arrive. in iwl_mld_reorder()
302 * releasing SN 0,1, 2. When sub-frame 1 arrives - reorder buffer is in iwl_mld_reorder()
304 * If the last sub-frame is not on this queue - we will get frame in iwl_mld_reorder()
319 struct iwl_mld_baid_data __rcu **rcu_ptr = data->rcu_ptr; in iwl_mld_rx_agg_session_expired()
332 if (WARN_ON(!ba_data->timeout)) in iwl_mld_rx_agg_session_expired()
335 timeout = ba_data->last_rx_timestamp + in iwl_mld_rx_agg_session_expired()
336 TU_TO_JIFFIES(ba_data->timeout * 2); in iwl_mld_rx_agg_session_expired()
338 mod_timer(&ba_data->session_timer, timeout); in iwl_mld_rx_agg_session_expired()
343 sta_id = ffs(ba_data->sta_mask) - 1; in iwl_mld_rx_agg_session_expired()
344 link_sta = rcu_dereference(ba_data->mld->fw_id_to_link_sta[sta_id]); in iwl_mld_rx_agg_session_expired()
350 * A-MPDU and hence the timer continues to run. Then, the in iwl_mld_rx_agg_session_expired()
353 if (IS_ERR_OR_NULL(link_sta) || WARN_ON(!link_sta->sta)) in iwl_mld_rx_agg_session_expired()
356 mld_sta = iwl_mld_sta_from_mac80211(link_sta->sta); in iwl_mld_rx_agg_session_expired()
357 ieee80211_rx_ba_timer_expired(mld_sta->vif, link_sta->sta->addr, in iwl_mld_rx_agg_session_expired()
358 ba_data->tid); in iwl_mld_rx_agg_session_expired()
382 IWL_DEBUG_HT(mld, "RX BA Session stopped in fw\n"); in iwl_mld_stop_ba_in_fw()
406 struct iwl_rx_packet *pkt; in iwl_mld_start_ba_in_fw() local
416 pkt = hcmd.resp_pkt; in iwl_mld_start_ba_in_fw()
418 resp_len = iwl_rx_packet_payload_len(pkt); in iwl_mld_start_ba_in_fw()
422 ret = -EIO; in iwl_mld_start_ba_in_fw()
426 IWL_DEBUG_HT(mld, "RX BA Session started in fw\n"); in iwl_mld_start_ba_in_fw()
428 resp = (void *)pkt->data; in iwl_mld_start_ba_in_fw()
429 baid = le32_to_cpu(resp->baid); in iwl_mld_start_ba_in_fw()
431 if (IWL_FW_CHECK(mld, baid < 0 || baid >= ARRAY_SIZE(mld->fw_id_to_ba), in iwl_mld_start_ba_in_fw()
433 ret = -EINVAL; in iwl_mld_start_ba_in_fw()
447 for (int i = 0; i < mld->trans->num_rx_queues; i++) { in iwl_mld_init_reorder_buffer()
449 &data->reorder_buf[i]; in iwl_mld_init_reorder_buffer()
451 &data->entries[i * data->entries_per_queue]; in iwl_mld_init_reorder_buffer()
453 reorder_buf->head_sn = ssn; in iwl_mld_init_reorder_buffer()
454 reorder_buf->queue = i; in iwl_mld_init_reorder_buffer()
456 for (int j = 0; j < data->buf_size; j++) in iwl_mld_init_reorder_buffer()
465 .baid = data->baid, in iwl_mld_free_reorder_buffer()
471 for (int i = 0; i < mld->trans->num_rx_queues; i++) { in iwl_mld_free_reorder_buffer()
473 &data->reorder_buf[i]; in iwl_mld_free_reorder_buffer()
475 &data->entries[i * data->entries_per_queue]; in iwl_mld_free_reorder_buffer()
477 if (likely(!reorder_buf->num_stored)) in iwl_mld_free_reorder_buffer()
480 /* This shouldn't happen in regular DELBA since the RX queues in iwl_mld_free_reorder_buffer()
486 for (int j = 0; j < data->buf_size; j++) in iwl_mld_free_reorder_buffer()
496 u32 reorder_buf_size = buf_size * sizeof(baid_data->entries[0]); in iwl_mld_ampdu_rx_start()
500 lockdep_assert_wiphy(mld->wiphy); in iwl_mld_ampdu_rx_start()
502 if (mld->num_rx_ba_sessions >= IWL_MAX_BAID) { in iwl_mld_ampdu_rx_start()
504 "Max num of RX BA sessions reached; blocking new session\n"); in iwl_mld_ampdu_rx_start()
505 return -ENOSPC; in iwl_mld_ampdu_rx_start()
510 return -EINVAL; in iwl_mld_ampdu_rx_start()
519 BUILD_BUG_ON(SMP_CACHE_BYTES % sizeof(baid_data->entries[0]) && in iwl_mld_ampdu_rx_start()
520 sizeof(baid_data->entries[0]) % SMP_CACHE_BYTES); in iwl_mld_ampdu_rx_start()
524 * line for each queue, to avoid sharing cache lines between in iwl_mld_ampdu_rx_start()
533 mld->trans->num_rx_queues * reorder_buf_size, in iwl_mld_ampdu_rx_start()
536 return -ENOMEM; in iwl_mld_ampdu_rx_start()
541 baid_data->entries_per_queue = in iwl_mld_ampdu_rx_start()
542 reorder_buf_size / sizeof(baid_data->entries[0]); in iwl_mld_ampdu_rx_start()
550 mld->num_rx_ba_sessions++; in iwl_mld_ampdu_rx_start()
551 mld_sta->tid_to_baid[tid] = baid; in iwl_mld_ampdu_rx_start()
553 baid_data->baid = baid; in iwl_mld_ampdu_rx_start()
554 baid_data->mld = mld; in iwl_mld_ampdu_rx_start()
555 baid_data->tid = tid; in iwl_mld_ampdu_rx_start()
556 baid_data->buf_size = buf_size; in iwl_mld_ampdu_rx_start()
557 baid_data->sta_mask = sta_mask; in iwl_mld_ampdu_rx_start()
558 baid_data->timeout = timeout; in iwl_mld_ampdu_rx_start()
559 baid_data->last_rx_timestamp = jiffies; in iwl_mld_ampdu_rx_start()
560 baid_data->rcu_ptr = &mld->fw_id_to_ba[baid]; in iwl_mld_ampdu_rx_start()
564 timer_setup(&baid_data->session_timer, iwl_mld_rx_agg_session_expired, in iwl_mld_ampdu_rx_start()
567 mod_timer(&baid_data->session_timer, in iwl_mld_ampdu_rx_start()
571 baid_data->sta_mask, tid, baid); in iwl_mld_ampdu_rx_start()
574 * internal RX sync mechanism will timeout (not that it's in iwl_mld_ampdu_rx_start()
576 * RX is being processed in parallel in iwl_mld_ampdu_rx_start()
578 WARN_ON(rcu_access_pointer(mld->fw_id_to_ba[baid])); in iwl_mld_ampdu_rx_start()
579 rcu_assign_pointer(mld->fw_id_to_ba[baid], baid_data); in iwl_mld_ampdu_rx_start()
592 int baid = mld_sta->tid_to_baid[tid]; in iwl_mld_ampdu_rx_stop()
596 lockdep_assert_wiphy(mld->wiphy); in iwl_mld_ampdu_rx_stop()
602 if (!mld->fw_status.in_hw_restart) { in iwl_mld_ampdu_rx_stop()
608 if (!WARN_ON(mld->num_rx_ba_sessions == 0)) in iwl_mld_ampdu_rx_stop()
609 mld->num_rx_ba_sessions--; in iwl_mld_ampdu_rx_stop()
611 baid_data = wiphy_dereference(mld->wiphy, mld->fw_id_to_ba[baid]); in iwl_mld_ampdu_rx_stop()
613 return -EINVAL; in iwl_mld_ampdu_rx_stop()
615 if (timer_pending(&baid_data->session_timer)) in iwl_mld_ampdu_rx_stop()
616 timer_shutdown_sync(&baid_data->session_timer); in iwl_mld_ampdu_rx_stop()
620 RCU_INIT_POINTER(mld->fw_id_to_ba[baid], NULL); in iwl_mld_ampdu_rx_stop()
641 if (mld->fw_status.in_hw_restart) in iwl_mld_update_sta_baids()
646 for (baid = 0; baid < ARRAY_SIZE(mld->fw_id_to_ba); baid++) { in iwl_mld_update_sta_baids()
650 data = wiphy_dereference(mld->wiphy, mld->fw_id_to_ba[baid]); in iwl_mld_update_sta_baids()
654 if (!(data->sta_mask & old_sta_mask)) in iwl_mld_update_sta_baids()
657 WARN_ONCE(data->sta_mask != old_sta_mask, in iwl_mld_update_sta_baids()
658 "BAID data for %d corrupted - expected 0x%x found 0x%x\n", in iwl_mld_update_sta_baids()
659 baid, old_sta_mask, data->sta_mask); in iwl_mld_update_sta_baids()
661 cmd.modify.tid = cpu_to_le32(data->tid); in iwl_mld_update_sta_baids()
666 data->sta_mask = new_sta_mask; in iwl_mld_update_sta_baids()