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
20 &baid_data->entries[reorder_buf->queue * in iwl_mld_reorder_release_frames()
21 baid_data->entries_per_queue]; in iwl_mld_reorder_release_frames()
22 u16 ssn = reorder_buf->head_sn; in iwl_mld_reorder_release_frames()
25 int index = ssn % baid_data->buf_size; in iwl_mld_reorder_release_frames()
31 /* Empty the list. Will have more than one frame for A-MSDU. in iwl_mld_reorder_release_frames()
37 reorder_buf->queue, in iwl_mld_reorder_release_frames()
39 reorder_buf->num_stored--; in iwl_mld_reorder_release_frames()
42 reorder_buf->head_sn = nssn; in iwl_mld_reorder_release_frames()
47 u8 baid, u16 nssn, int queue) in iwl_mld_release_frames_from_notif() argument
58 baid >= ARRAY_SIZE(mld->fw_id_to_ba))) in iwl_mld_release_frames_from_notif()
63 ba_data = rcu_dereference(mld->fw_id_to_ba[baid]); in iwl_mld_release_frames_from_notif()
70 sta_id = ffs(ba_data->sta_mask) - 1; in iwl_mld_release_frames_from_notif()
71 link_sta = rcu_dereference(mld->fw_id_to_link_sta[sta_id]); in iwl_mld_release_frames_from_notif()
72 if (WARN_ON_ONCE(IS_ERR_OR_NULL(link_sta) || !link_sta->sta)) in iwl_mld_release_frames_from_notif()
75 reorder_buf = &ba_data->reorder_buf[queue]; in iwl_mld_release_frames_from_notif()
77 iwl_mld_reorder_release_frames(mld, link_sta->sta, napi, ba_data, in iwl_mld_release_frames_from_notif()
85 struct iwl_rx_packet *pkt, int queue) in iwl_mld_handle_frame_release_notif() argument
87 struct iwl_frame_release *release = (void *)pkt->data; in iwl_mld_handle_frame_release_notif()
88 u32 pkt_len = iwl_rx_packet_payload_len(pkt); in iwl_mld_handle_frame_release_notif()
95 iwl_mld_release_frames_from_notif(mld, napi, release->baid, in iwl_mld_handle_frame_release_notif()
96 le16_to_cpu(release->nssn), in iwl_mld_handle_frame_release_notif()
97 queue); in iwl_mld_handle_frame_release_notif()
102 struct iwl_rx_packet *pkt, in iwl_mld_handle_bar_frame_release_notif() argument
103 int queue) in iwl_mld_handle_bar_frame_release_notif() argument
105 struct iwl_bar_frame_release *release = (void *)pkt->data; in iwl_mld_handle_bar_frame_release_notif()
108 u32 pkt_len = iwl_rx_packet_payload_len(pkt); in iwl_mld_handle_bar_frame_release_notif()
115 baid = le32_get_bits(release->ba_info, in iwl_mld_handle_bar_frame_release_notif()
117 nssn = le32_get_bits(release->ba_info, in iwl_mld_handle_bar_frame_release_notif()
119 sta_id = le32_get_bits(release->sta_tid, in iwl_mld_handle_bar_frame_release_notif()
121 tid = le32_get_bits(release->sta_tid, in iwl_mld_handle_bar_frame_release_notif()
124 if (IWL_FW_CHECK(mld, baid >= ARRAY_SIZE(mld->fw_id_to_ba), in iwl_mld_handle_bar_frame_release_notif()
129 baid_data = rcu_dereference(mld->fw_id_to_ba[baid]); in iwl_mld_handle_bar_frame_release_notif()
137 if (IWL_FW_CHECK(mld, tid != baid_data->tid || in iwl_mld_handle_bar_frame_release_notif()
138 sta_id > mld->fw->ucode_capa.num_stations || in iwl_mld_handle_bar_frame_release_notif()
139 !(baid_data->sta_mask & BIT(sta_id)), in iwl_mld_handle_bar_frame_release_notif()
141 baid, baid_data->sta_mask, baid_data->tid, sta_id, in iwl_mld_handle_bar_frame_release_notif()
148 iwl_mld_release_frames_from_notif(mld, napi, baid, nssn, queue); in iwl_mld_handle_bar_frame_release_notif()
153 void iwl_mld_del_ba(struct iwl_mld *mld, int queue, in iwl_mld_del_ba() argument
159 u8 baid = data->baid; in iwl_mld_del_ba()
167 ba_data = rcu_dereference(mld->fw_id_to_ba[baid]); in iwl_mld_del_ba()
172 sta_id = ffs(ba_data->sta_mask) - 1; in iwl_mld_del_ba()
173 link_sta = rcu_dereference(mld->fw_id_to_link_sta[sta_id]); in iwl_mld_del_ba()
174 if (WARN_ON_ONCE(IS_ERR_OR_NULL(link_sta) || !link_sta->sta)) in iwl_mld_del_ba()
177 reorder_buf = &ba_data->reorder_buf[queue]; in iwl_mld_del_ba()
180 iwl_mld_reorder_release_frames(mld, link_sta->sta, NULL, in iwl_mld_del_ba()
182 ieee80211_sn_add(reorder_buf->head_sn, in iwl_mld_del_ba()
183 ba_data->buf_size)); in iwl_mld_del_ba()
193 int queue, struct ieee80211_sta *sta, in iwl_mld_reorder() argument
202 u32 reorder = le32_to_cpu(desc->reorder_data); in iwl_mld_reorder()
228 if (!ieee80211_is_data_qos(hdr->frame_control) || in iwl_mld_reorder()
229 is_multicast_ether_addr(hdr->addr1)) in iwl_mld_reorder()
232 if (unlikely(!ieee80211_is_data_present(hdr->frame_control))) in iwl_mld_reorder()
235 baid_data = rcu_dereference(mld->fw_id_to_ba[baid]); in iwl_mld_reorder()
238 "Got valid BAID but no baid allocated, bypass re-ordering (BAID=%d reorder=0x%x)\n", in iwl_mld_reorder()
244 sta_mask |= BIT(mld_link_sta->fw_id); in iwl_mld_reorder()
248 tid != baid_data->tid || in iwl_mld_reorder()
249 !(sta_mask & baid_data->sta_mask), in iwl_mld_reorder()
251 baid, baid_data->sta_mask, baid_data->tid, in iwl_mld_reorder()
255 buffer = &baid_data->reorder_buf[queue]; in iwl_mld_reorder()
256 entries = &baid_data->entries[queue * baid_data->entries_per_queue]; in iwl_mld_reorder()
260 if (!buffer->valid && is_old_sn) in iwl_mld_reorder()
263 buffer->valid = true; in iwl_mld_reorder()
265 is_dup = !!(desc->status & cpu_to_le32(IWL_RX_MPDU_STATUS_DUPLICATE)); in iwl_mld_reorder()
273 amsdu = desc->mac_flags2 & IWL_RX_MPDU_MFLG2_AMSDU; in iwl_mld_reorder()
274 last_subframe = desc->amsdu_info & IWL_RX_MPDU_AMSDU_LAST_SUBFRAME; in iwl_mld_reorder()
277 if (!buffer->num_stored && ieee80211_sn_less(sn, nssn)) { in iwl_mld_reorder()
279 buffer->head_sn = nssn; in iwl_mld_reorder()
290 if (!buffer->num_stored && sn == buffer->head_sn) { in iwl_mld_reorder()
292 buffer->head_sn = ieee80211_sn_inc(buffer->head_sn); in iwl_mld_reorder()
297 index = sn % baid_data->buf_size; in iwl_mld_reorder()
299 buffer->num_stored++; in iwl_mld_reorder()
301 /* We cannot trust NSSN for AMSDU sub-frames that are not the last. The in iwl_mld_reorder()
302 * reason is that NSSN advances on the first sub-frame, and may cause in iwl_mld_reorder()
303 * the reorder buffer to advance before all the sub-frames arrive. in iwl_mld_reorder()
307 * releasing SN 0,1, 2. When sub-frame 1 arrives - reorder buffer is in iwl_mld_reorder()
309 * If the last sub-frame is not on this queue - we will get frame in iwl_mld_reorder()
318 else if (buffer->num_stored == 1) in iwl_mld_reorder()
319 buffer->head_sn = nssn; in iwl_mld_reorder()
329 struct iwl_mld_baid_data __rcu **rcu_ptr = data->rcu_ptr; in iwl_mld_rx_agg_session_expired()
342 if (WARN_ON(!ba_data->timeout)) in iwl_mld_rx_agg_session_expired()
345 timeout = ba_data->last_rx_timestamp + in iwl_mld_rx_agg_session_expired()
346 TU_TO_JIFFIES(ba_data->timeout * 2); in iwl_mld_rx_agg_session_expired()
348 mod_timer(&ba_data->session_timer, timeout); in iwl_mld_rx_agg_session_expired()
353 sta_id = ffs(ba_data->sta_mask) - 1; in iwl_mld_rx_agg_session_expired()
354 link_sta = rcu_dereference(ba_data->mld->fw_id_to_link_sta[sta_id]); in iwl_mld_rx_agg_session_expired()
360 * A-MPDU and hence the timer continues to run. Then, the in iwl_mld_rx_agg_session_expired()
363 if (IS_ERR_OR_NULL(link_sta) || WARN_ON(!link_sta->sta)) in iwl_mld_rx_agg_session_expired()
366 mld_sta = iwl_mld_sta_from_mac80211(link_sta->sta); in iwl_mld_rx_agg_session_expired()
367 ieee80211_rx_ba_timer_expired(mld_sta->vif, link_sta->sta->addr, in iwl_mld_rx_agg_session_expired()
368 ba_data->tid); in iwl_mld_rx_agg_session_expired()
392 IWL_DEBUG_HT(mld, "RX BA Session stopped in fw\n"); in iwl_mld_stop_ba_in_fw()
416 struct iwl_rx_packet *pkt; in iwl_mld_start_ba_in_fw() local
426 pkt = hcmd.resp_pkt; in iwl_mld_start_ba_in_fw()
428 resp_len = iwl_rx_packet_payload_len(pkt); in iwl_mld_start_ba_in_fw()
432 ret = -EIO; in iwl_mld_start_ba_in_fw()
436 IWL_DEBUG_HT(mld, "RX BA Session started in fw\n"); in iwl_mld_start_ba_in_fw()
438 resp = (void *)pkt->data; in iwl_mld_start_ba_in_fw()
439 baid = le32_to_cpu(resp->baid); in iwl_mld_start_ba_in_fw()
441 if (IWL_FW_CHECK(mld, baid < 0 || baid >= ARRAY_SIZE(mld->fw_id_to_ba), in iwl_mld_start_ba_in_fw()
443 ret = -EINVAL; in iwl_mld_start_ba_in_fw()
457 for (int i = 0; i < mld->trans->info.num_rxqs; i++) { in iwl_mld_init_reorder_buffer()
459 &data->reorder_buf[i]; in iwl_mld_init_reorder_buffer()
461 &data->entries[i * data->entries_per_queue]; in iwl_mld_init_reorder_buffer()
463 reorder_buf->head_sn = ssn; in iwl_mld_init_reorder_buffer()
464 reorder_buf->queue = i; in iwl_mld_init_reorder_buffer()
466 for (int j = 0; j < data->buf_size; j++) in iwl_mld_init_reorder_buffer()
475 .baid = data->baid, in iwl_mld_free_reorder_buffer()
481 for (int i = 0; i < mld->trans->info.num_rxqs; i++) { in iwl_mld_free_reorder_buffer()
483 &data->reorder_buf[i]; in iwl_mld_free_reorder_buffer()
485 &data->entries[i * data->entries_per_queue]; in iwl_mld_free_reorder_buffer()
487 if (likely(!reorder_buf->num_stored)) in iwl_mld_free_reorder_buffer()
490 /* This shouldn't happen in regular DELBA since the RX queues in iwl_mld_free_reorder_buffer()
496 for (int j = 0; j < data->buf_size; j++) in iwl_mld_free_reorder_buffer()
506 u32 reorder_buf_size = buf_size * sizeof(baid_data->entries[0]); in iwl_mld_ampdu_rx_start()
510 lockdep_assert_wiphy(mld->wiphy); in iwl_mld_ampdu_rx_start()
512 if (mld->num_rx_ba_sessions >= IWL_MAX_BAID) { in iwl_mld_ampdu_rx_start()
514 "Max num of RX BA sessions reached; blocking new session\n"); in iwl_mld_ampdu_rx_start()
515 return -ENOSPC; in iwl_mld_ampdu_rx_start()
520 return -EINVAL; in iwl_mld_ampdu_rx_start()
529 BUILD_BUG_ON(SMP_CACHE_BYTES % sizeof(baid_data->entries[0]) && in iwl_mld_ampdu_rx_start()
530 sizeof(baid_data->entries[0]) % SMP_CACHE_BYTES); in iwl_mld_ampdu_rx_start()
534 * line for each queue, to avoid sharing cache lines between in iwl_mld_ampdu_rx_start()
543 mld->trans->info.num_rxqs * reorder_buf_size, in iwl_mld_ampdu_rx_start()
546 return -ENOMEM; in iwl_mld_ampdu_rx_start()
551 baid_data->entries_per_queue = in iwl_mld_ampdu_rx_start()
552 reorder_buf_size / sizeof(baid_data->entries[0]); in iwl_mld_ampdu_rx_start()
560 mld->num_rx_ba_sessions++; in iwl_mld_ampdu_rx_start()
561 mld_sta->tid_to_baid[tid] = baid; in iwl_mld_ampdu_rx_start()
563 baid_data->baid = baid; in iwl_mld_ampdu_rx_start()
564 baid_data->mld = mld; in iwl_mld_ampdu_rx_start()
565 baid_data->tid = tid; in iwl_mld_ampdu_rx_start()
566 baid_data->buf_size = buf_size; in iwl_mld_ampdu_rx_start()
567 baid_data->sta_mask = sta_mask; in iwl_mld_ampdu_rx_start()
568 baid_data->timeout = timeout; in iwl_mld_ampdu_rx_start()
569 baid_data->last_rx_timestamp = jiffies; in iwl_mld_ampdu_rx_start()
570 baid_data->rcu_ptr = &mld->fw_id_to_ba[baid]; in iwl_mld_ampdu_rx_start()
574 timer_setup(&baid_data->session_timer, iwl_mld_rx_agg_session_expired, in iwl_mld_ampdu_rx_start()
577 mod_timer(&baid_data->session_timer, in iwl_mld_ampdu_rx_start()
581 baid_data->sta_mask, tid, baid); in iwl_mld_ampdu_rx_start()
584 * internal RX sync mechanism will timeout (not that it's in iwl_mld_ampdu_rx_start()
586 * RX is being processed in parallel in iwl_mld_ampdu_rx_start()
588 WARN_ON(rcu_access_pointer(mld->fw_id_to_ba[baid])); in iwl_mld_ampdu_rx_start()
589 rcu_assign_pointer(mld->fw_id_to_ba[baid], baid_data); in iwl_mld_ampdu_rx_start()
602 int baid = mld_sta->tid_to_baid[tid]; in iwl_mld_ampdu_rx_stop()
606 lockdep_assert_wiphy(mld->wiphy); in iwl_mld_ampdu_rx_stop()
612 if (!mld->fw_status.in_hw_restart) { in iwl_mld_ampdu_rx_stop()
618 if (!WARN_ON(mld->num_rx_ba_sessions == 0)) in iwl_mld_ampdu_rx_stop()
619 mld->num_rx_ba_sessions--; in iwl_mld_ampdu_rx_stop()
621 baid_data = wiphy_dereference(mld->wiphy, mld->fw_id_to_ba[baid]); in iwl_mld_ampdu_rx_stop()
623 return -EINVAL; in iwl_mld_ampdu_rx_stop()
625 if (timer_pending(&baid_data->session_timer)) in iwl_mld_ampdu_rx_stop()
626 timer_shutdown_sync(&baid_data->session_timer); in iwl_mld_ampdu_rx_stop()
630 RCU_INIT_POINTER(mld->fw_id_to_ba[baid], NULL); in iwl_mld_ampdu_rx_stop()
651 if (mld->fw_status.in_hw_restart) in iwl_mld_update_sta_baids()
656 for (baid = 0; baid < ARRAY_SIZE(mld->fw_id_to_ba); baid++) { in iwl_mld_update_sta_baids()
660 data = wiphy_dereference(mld->wiphy, mld->fw_id_to_ba[baid]); in iwl_mld_update_sta_baids()
664 if (!(data->sta_mask & old_sta_mask)) in iwl_mld_update_sta_baids()
667 WARN_ONCE(data->sta_mask != old_sta_mask, in iwl_mld_update_sta_baids()
668 "BAID data for %d corrupted - expected 0x%x found 0x%x\n", in iwl_mld_update_sta_baids()
669 baid, old_sta_mask, data->sta_mask); in iwl_mld_update_sta_baids()
671 cmd.modify.tid = cpu_to_le32(data->tid); in iwl_mld_update_sta_baids()
676 data->sta_mask = new_sta_mask; in iwl_mld_update_sta_baids()