Lines Matching +full:tcm +full:- +full:mode

1 // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
3 * Copyright (C) 2012-2014, 2018-2024 Intel Corporation
4 * Copyright (C) 2013-2015 Intel Mobile Communications GmbH
5 * Copyright (C) 2016-2017 Intel Deutschland GmbH
10 #include "iwl-trans.h"
12 #include "fw-api.h"
15 * iwl_mvm_rx_rx_phy_cmd - REPLY_RX_PHY_CMD handler
17 * Copies the phy information in mvm->last_phy_info, it will be used when the
25 if (unlikely(pkt_len < sizeof(mvm->last_phy_info)))
28 memcpy(&mvm->last_phy_info, pkt->data, sizeof(mvm->last_phy_info));
29 mvm->ampdu_ref++;
32 if (mvm->last_phy_info.phy_flags & cpu_to_le16(RX_RES_PHY_FLAGS_AGG)) {
33 spin_lock(&mvm->drv_stats_lock);
34 mvm->drv_rx_stats.ampdu_count++;
35 spin_unlock(&mvm->drv_stats_lock);
41 * iwl_mvm_pass_packet_to_mac80211 - builds the packet for mac80211
53 unsigned int hdrlen = ieee80211_hdrlen(hdr->frame_control);
61 * The beginning of the skb->data is aligned on at least a 4-byte
63 * on a 2-byte boundary so we can just take hdrlen & 3 and pad by
68 /* If frame is small enough to fit in skb->head, pull it completely.
83 fraglen = len - hdrlen;
86 int offset = (u8 *)hdr + hdrlen -
90 fraglen, rxb->truesize);
93 ieee80211_rx_napi(mvm->hw, sta, skb, napi);
97 * iwl_mvm_get_signal_strength - use new rx PHY INFO API
98 * values are reported by the fw as positive values - need to negate
100 * values by -256dBm: practically 0 power and a non-feasible 8 bit value.
110 le32_to_cpu(phy_info->non_cfg_phy[IWL_RX_INFO_ENERGY_ANT_ABC_IDX]);
113 energy_a = energy_a ? -energy_a : S8_MIN;
116 energy_b = energy_b ? -energy_b : S8_MIN;
122 rx_status->signal = max_energy;
123 rx_status->chains = (le16_to_cpu(phy_info->phy_flags) &
126 rx_status->chain_signal[0] = energy_a;
127 rx_status->chain_signal[1] = energy_b;
131 * iwl_mvm_set_mac80211_rx_flag - translate fw status to mac80211 format
145 if (!ieee80211_has_protected(hdr->frame_control) ||
159 return -1;
161 stats->flag |= RX_FLAG_DECRYPTED;
167 if (!fw_has_api(&mvm->fw->ucode_capa,
176 return -1;
178 stats->flag |= RX_FLAG_DECRYPTED;
186 return -1;
187 stats->flag |= RX_FLAG_DECRYPTED;
193 if (!mvm->monitor_on)
196 if (!mvm->monitor_on && net_ratelimit())
213 int ac = IEEE80211_AC_BE; /* treat non-QoS as BE */
221 if (ieee80211_is_data_qos(hdr->frame_control)) {
229 mac = mvmsta->mac_id_n_color & FW_CTXT_ID_MSK;
231 if (time_after(jiffies, mvm->tcm.ts + MVM_TCM_PERIOD))
232 schedule_delayed_work(&mvm->tcm.work, 0);
233 mdata = &mvm->tcm.data[mac];
234 mdata->rx.pkts[ac]++;
237 if (mdata->rx.last_ampdu_ref != mvm->ampdu_ref) {
238 mdata->rx.last_ampdu_ref = mvm->ampdu_ref;
239 mdata->rx.airtime += le16_to_cpu(phy_info->frame_time);
245 mvmvif = iwl_mvm_vif_from_mac80211(mvmsta->vif);
247 if (mdata->opened_rx_ba_sessions ||
248 mdata->uapsd_nonagg_detect.detected ||
249 (!mvmvif->deflink.queue_params[IEEE80211_AC_VO].uapsd &&
250 !mvmvif->deflink.queue_params[IEEE80211_AC_VI].uapsd &&
251 !mvmvif->deflink.queue_params[IEEE80211_AC_BE].uapsd &&
252 !mvmvif->deflink.queue_params[IEEE80211_AC_BK].uapsd) ||
253 mvmsta->deflink.sta_id != mvmvif->deflink.ap_sta_id)
271 mdata->uapsd_nonagg_detect.rx_bytes += len;
272 ewma_rate_add(&mdata->uapsd_nonagg_detect.rate, thr);
280 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(mvmsta->vif);
282 if (mvmvif->features & NETIF_F_RXCSUM &&
285 skb->ip_summed = CHECKSUM_UNNECESSARY;
289 * iwl_mvm_rx_rx_mpdu - REPLY_RX_MPDU_CMD handler
313 phy_info = &mvm->last_phy_info;
314 rx_res = (struct iwl_rx_mpdu_res_start *)pkt->data;
315 hdr = (struct ieee80211_hdr *)(pkt->data + sizeof(*rx_res));
316 len = le16_to_cpu(rx_res->byte_count);
324 (pkt->data + sizeof(*rx_res) + len));
338 * Keep packets with CRC errors (and with overrun) for monitor mode
344 rx_status->flag |= RX_FLAG_FAILED_FCS_CRC;
348 rate_n_flags = le32_to_cpu(phy_info->rate_n_flags);
351 rx_status->mactime = le64_to_cpu(phy_info->timestamp);
352 rx_status->device_timestamp = le32_to_cpu(phy_info->system_timestamp);
353 rx_status->band =
354 (phy_info->phy_flags & cpu_to_le16(RX_RES_PHY_FLAGS_BAND_24)) ?
356 rx_status->freq =
357 ieee80211_channel_to_frequency(le16_to_cpu(phy_info->channel),
358 rx_status->band);
361 rx_status->flag |= RX_FLAG_MACTIME_PLCP_START;
365 IWL_DEBUG_STATS_LIMIT(mvm, "Rssi %d, TSF %llu\n", rx_status->signal,
366 (unsigned long long)rx_status->mactime);
374 if (!WARN_ON_ONCE(id >= mvm->fw->ucode_capa.num_stations)) {
375 sta = rcu_dereference(mvm->fw_id_to_mac_id[id]);
379 } else if (!is_multicast_ether_addr(hdr->addr2)) {
383 sta = ieee80211_find_sta_by_ifaddr(mvm->hw, hdr->addr2, NULL);
388 struct ieee80211_vif *vif = mvmsta->vif;
395 if (is_multicast_ether_addr(hdr->addr1) &&
396 vif->type == NL80211_IFTYPE_STATION &&
397 !mvmvif->authorized &&
398 ieee80211_has_protected(hdr->frame_control)) {
421 rcu_dereference(mvm->csa_tx_blocked_vif);
423 struct ieee80211_vif *vif = mvmsta->vif;
433 if (mvmvif->csa_target_freq == rx_status->freq)
440 trig = iwl_fw_dbg_trigger_on(&mvm->fwrt,
444 if (trig && ieee80211_is_beacon(hdr->frame_control)) {
448 rssi_trig = (void *)trig->data;
449 rssi = le32_to_cpu(rssi_trig->rssi);
451 if (rx_status->signal < rssi)
452 iwl_fw_dbg_collect_trig(&mvm->fwrt, trig,
460 if (!mvm->tcm.paused && len >= sizeof(*hdr) &&
461 !is_multicast_ether_addr(hdr->addr1) &&
462 ieee80211_is_data(hdr->frame_control))
466 if (ieee80211_is_data(hdr->frame_control))
472 if (phy_info->phy_flags & cpu_to_le16(RX_RES_PHY_FLAGS_SHORT_PREAMBLE))
473 rx_status->enc_flags |= RX_ENC_FLAG_SHORTPRE;
475 if (phy_info->phy_flags & cpu_to_le16(RX_RES_PHY_FLAGS_AGG)) {
477 * We know which subframes of an A-MPDU belong
481 rx_status->flag |= RX_FLAG_AMPDU_DETAILS;
482 rx_status->ampdu_reference = mvm->ampdu_ref;
490 rx_status->bw = RATE_INFO_BW_40;
493 rx_status->bw = RATE_INFO_BW_80;
496 rx_status->bw = RATE_INFO_BW_160;
501 rx_status->enc_flags |= RX_ENC_FLAG_SHORT_GI;
503 rx_status->enc_flags |= RX_ENC_FLAG_HT_GF;
505 rx_status->enc_flags |= RX_ENC_FLAG_LDPC;
509 rx_status->encoding = RX_ENC_HT;
510 rx_status->rate_idx = rate_n_flags & RATE_HT_MCS_INDEX_MSK_V1;
511 rx_status->enc_flags |= stbc << RX_ENC_FLAG_STBC_SHIFT;
515 rx_status->nss =
517 rx_status->rate_idx = rate_n_flags & RATE_VHT_MCS_RATE_CODE_MSK;
518 rx_status->encoding = RX_ENC_VHT;
519 rx_status->enc_flags |= stbc << RX_ENC_FLAG_STBC_SHIFT;
521 rx_status->enc_flags |= RX_ENC_FLAG_BF;
524 rx_status->band);
528 rate_n_flags, rx_status->band)) {
532 rx_status->rate_idx = rate;
537 rx_status->flag & RX_FLAG_AMPDU_DETAILS);
540 if (unlikely((ieee80211_is_beacon(hdr->frame_control) ||
541 ieee80211_is_probe_resp(hdr->frame_control)) &&
542 mvm->sched_scan_pass_all == SCHED_SCAN_PASS_ALL_ENABLED))
543 mvm->sched_scan_pass_all = SCHED_SCAN_PASS_ALL_FOUND;
545 if (unlikely(ieee80211_is_beacon(hdr->frame_control) ||
546 ieee80211_is_probe_resp(hdr->frame_control)))
547 rx_status->boottime_ns = ktime_get_boottime_ns();
572 struct iwl_mvm *mvm = iwl_mvm_vif_from_mac80211(vif)->mvm;
573 int thold = bss_conf->cqm_rssi_thold;
574 int hyst = bss_conf->cqm_rssi_hyst;
579 IWL_DEBUG_RX(mvm, "RSSI is 0 - skip signal based decision\n");
583 link_info->bf_data.ave_beacon_signal = sig;
586 if (link_info->bf_data.bt_coex_min_thold !=
587 link_info->bf_data.bt_coex_max_thold) {
588 last_event = link_info->bf_data.last_bt_coex_event;
589 if (sig > link_info->bf_data.bt_coex_max_thold &&
590 (last_event <= link_info->bf_data.bt_coex_min_thold ||
592 link_info->bf_data.last_bt_coex_event = sig;
596 } else if (sig < link_info->bf_data.bt_coex_min_thold &&
597 (last_event >= link_info->bf_data.bt_coex_max_thold ||
599 link_info->bf_data.last_bt_coex_event = sig;
606 if (!(vif->driver_flags & IEEE80211_VIF_SUPPORTS_CQM_RSSI))
610 last_event = link_info->bf_data.last_cqm_event;
612 sig < last_event - hyst)) {
613 link_info->bf_data.last_cqm_event = sig;
623 link_info->bf_data.last_cqm_event = sig;
634 if (!vif->cfg.assoc || !ieee80211_vif_is_mld(vif))
639 &bss_conf->chanreq.oper,
645 bss_conf->link_id));
652 int sig = -data->beacon_filter_average_energy;
653 u16 id = le32_to_cpu(data->mac_id);
655 u16 vif_id = mvmvif->id;
661 mvmvif->deflink.beacon_stats.num_beacons =
662 le32_to_cpu(data->beacon_counter[vif_id]);
663 mvmvif->deflink.beacon_stats.avg_signal =
664 -data->beacon_average_energy[vif_id];
666 if (mvmvif->id != id)
669 if (vif->type != NL80211_IFTYPE_STATION)
672 /* make sure that beacon statistics don't go backwards with TCM
675 if (le32_to_cpu(data->flags) & IWL_STATISTICS_REPLY_FLG_CLEAR)
676 mvmvif->deflink.beacon_stats.accu_num_beacons +=
677 mvmvif->deflink.beacon_stats.num_beacons;
679 /* This is used in pre-MLO API so use deflink */
680 iwl_mvm_update_link_sig(vif, sig, &mvmvif->deflink, &vif->bss_conf);
690 u16 vif_id = mvmvif->id;
695 if (vif->type != NL80211_IFTYPE_STATION)
698 mac_stats = &data->per_mac[vif_id];
700 mvmvif->deflink.beacon_stats.num_beacons =
701 le32_to_cpu(mac_stats->beacon_counter);
702 mvmvif->deflink.beacon_stats.avg_signal =
703 -le32_to_cpu(mac_stats->beacon_average_energy);
705 /* make sure that beacon statistics don't go backwards with TCM
708 if (le32_to_cpu(data->flags) & IWL_STATISTICS_REPLY_FLG_CLEAR)
709 mvmvif->deflink.beacon_stats.accu_num_beacons +=
710 mvmvif->deflink.beacon_stats.num_beacons;
712 sig = -le32_to_cpu(mac_stats->beacon_filter_average_energy);
714 /* This is used in pre-MLO API so use deflink */
715 iwl_mvm_update_link_sig(vif, sig, &mvmvif->deflink, &vif->bss_conf);
725 trig = iwl_fw_dbg_trigger_on(&mvm->fwrt, NULL, FW_DBG_TRIGGER_STATS);
729 trig_stats = (void *)trig->data;
731 trig_offset = le32_to_cpu(trig_stats->stop_offset);
732 trig_thold = le32_to_cpu(trig_stats->stop_threshold);
737 if (le32_to_cpup((__le32 *) (pkt->data + trig_offset)) < trig_thold)
741 iwl_fw_dbg_collect_trig(&mvm->fwrt, trig, NULL);
743 iwl_fw_dbg_collect_trig(&mvm->fwrt, trig, "");
752 u32 sta_id = mvmsta->deflink.sta_id;
759 mvmsta->deflink.avg_energy = energy[sta_id];
769 spin_lock(&mvm->tcm.lock);
771 struct iwl_mvm_tcm_mac *mdata = &mvm->tcm.data[i];
775 mdata->rx.airtime += airtime;
776 mdata->uapsd_nonagg_detect.rx_bytes += rx_bytes;
778 /* re-init every time to store rate from FW */
779 ewma_rate_init(&mdata->uapsd_nonagg_detect.rate);
780 ewma_rate_add(&mdata->uapsd_nonagg_detect.rate,
784 spin_unlock(&mvm->tcm.lock);
793 if (!mvm->phy_ctxts[i].ref)
795 mvm->phy_ctxts[i].channel_load_by_us =
806 .flags = stats->flags,
807 .per_mac = stats->per_mac,
810 ieee80211_iterate_active_interfaces(mvm->hw,
814 iwl_mvm_handle_per_phy_stats(mvm, stats->per_phy);
829 flags = stats->flags;
831 data.mac_id = stats->mac_id;
833 le32_to_cpu(stats->beacon_filter_average_energy);
835 data.beacon_counter = stats->beacon_counter;
839 le32_to_cpu(stats->beacon_average_energy[i]);
843 ieee80211_iterate_active_interfaces(mvm->hw,
860 hdr = (void *)&pkt->data;
862 if (WARN_ONCE((hdr->type & IWL_STATISTICS_TYPE_MSK) != FW_STATISTICS_OPERATIONAL ||
863 hdr->version !=
864 iwl_fw_lookup_notif_ver(mvm->fw, LEGACY_GROUP, STATISTICS_NOTIFICATION, 0),
866 hdr->type, hdr->version))
869 if (WARN_ONCE(le16_to_cpu(hdr->size) != expected_size,
871 le16_to_cpu(hdr->size), expected_size))
885 for (fw_link_id = 0; fw_link_id < ARRAY_SIZE(mvm->link_id_to_link_conf);
899 if (bss_conf->vif->type != NL80211_IFTYPE_STATION)
902 link_id = bss_conf->link_id;
903 if (link_id >= ARRAY_SIZE(mvmvif->link))
906 mvmvif = iwl_mvm_vif_from_mac80211(bss_conf->vif);
907 link_info = mvmvif->link[link_id];
913 link_info->beacon_stats.num_beacons =
914 le32_to_cpu(link_stats->beacon_counter);
919 link_info->beacon_stats.avg_signal =
920 -le32_to_cpu(link_stats->beacon_average_energy);
922 if (link_info->phy_ctxt &&
923 link_info->phy_ctxt->channel->band == NL80211_BAND_2GHZ)
924 iwl_mvm_bt_coex_update_link_esr(mvm, bss_conf->vif,
927 /* make sure that beacon statistics don't go backwards with TCM
930 if (mvm->statistics_clear)
931 mvmvif->link[link_id]->beacon_stats.accu_num_beacons +=
932 mvmvif->link[link_id]->beacon_stats.num_beacons;
934 sig = -le32_to_cpu(link_stats->beacon_filter_average_energy);
935 iwl_mvm_update_link_sig(bss_conf->vif, sig, link_info,
938 if (WARN_ONCE(mvmvif->id >= MAC_INDEX_AUX,
939 "invalid mvmvif id: %d", mvmvif->id))
942 air_time[mvmvif->id] +=
944 rx_bytes[mvmvif->id] +=
949 * we will end up counting twice the same airtime, once in TCM
952 if (mvm->statistics_clear) {
980 lockdep_assert_held(&mvm->mutex);
987 if (!mvmvif->esr_active || !mvmvif->ap_sta)
990 mvmsta = iwl_mvm_sta_from_mac80211(mvmvif->ap_sta);
992 if (!mvmsta->mpdu_counters)
998 if (WARN_ON(!mvmvif->link[sec_link]))
1000 sec_link = mvmvif->link[sec_link]->fw_link_id;
1003 for (int q = 0; q < mvm->trans->num_rx_queues; q++) {
1004 spin_lock_bh(&mvmsta->mpdu_counters[q].lock);
1008 total_tx += mvmsta->mpdu_counters[q].per_link[link].tx;
1009 total_rx += mvmsta->mpdu_counters[q].per_link[link].rx;
1012 sec_link_tx += mvmsta->mpdu_counters[q].per_link[sec_link].tx;
1013 sec_link_rx += mvmsta->mpdu_counters[q].per_link[sec_link].rx;
1019 memset(mvmsta->mpdu_counters[q].per_link, 0,
1020 sizeof(mvmsta->mpdu_counters[q].per_link));
1022 spin_unlock_bh(&mvmsta->mpdu_counters[q].lock);
1028 /* If we don't have enough MPDUs - exit EMLSR */
1059 u32 notif_ver = iwl_fw_lookup_notif_ver(mvm->fw, STATISTICS_GROUP,
1069 stats = (void *)&pkt->data;
1070 iwl_mvm_stat_iterator_all_links(mvm, stats->per_link);
1074 le32_to_cpu(stats->per_sta[i].average_energy);
1076 ieee80211_iterate_stations_atomic(mvm->hw, iwl_mvm_stats_energy_iter,
1078 iwl_mvm_handle_per_phy_stats(mvm, stats->per_phy);
1089 u32 notif_ver = iwl_fw_lookup_notif_ver(mvm->fw, STATISTICS_GROUP,
1099 part1_stats = (void *)&pkt->data;
1100 mvm->radio_stats.rx_time = 0;
1101 mvm->radio_stats.tx_time = 0;
1102 for (i = 0; i < ARRAY_SIZE(part1_stats->per_link); i++) {
1103 mvm->radio_stats.rx_time +=
1104 le64_to_cpu(part1_stats->per_link[i].rx_time);
1105 mvm->radio_stats.tx_time +=
1106 le64_to_cpu(part1_stats->per_link[i].tx_time);
1119 u32 notif_ver = iwl_fw_lookup_notif_ver(mvm->fw, LEGACY_GROUP,
1128 (void *)pkt->data;
1135 flags = stats->flags;
1136 mvm->radio_stats.rx_time = le64_to_cpu(stats->rx_time);
1137 mvm->radio_stats.tx_time = le64_to_cpu(stats->tx_time);
1138 mvm->radio_stats.on_time_rf = le64_to_cpu(stats->on_time_rf);
1139 mvm->radio_stats.on_time_scan =
1140 le64_to_cpu(stats->on_time_scan);
1143 average_energy[i] = le32_to_cpu(stats->average_energy[i]);
1146 air_time[i] = stats->air_time[i];
1147 rx_bytes[i] = stats->rx_bytes[i];
1153 (void *)pkt->data;
1160 flags = stats->flags;
1161 mvm->radio_stats.rx_time = le64_to_cpu(stats->rx_time);
1162 mvm->radio_stats.tx_time = le64_to_cpu(stats->tx_time);
1163 mvm->radio_stats.on_time_rf = le64_to_cpu(stats->on_time_rf);
1164 mvm->radio_stats.on_time_scan =
1165 le64_to_cpu(stats->on_time_scan);
1169 le32_to_cpu(stats->per_sta[i].average_energy);
1172 air_time[i] = stats->per_mac[i].air_time;
1173 rx_bytes[i] = stats->per_mac[i].rx_bytes;
1179 ieee80211_iterate_stations_atomic(mvm->hw, iwl_mvm_stats_energy_iter,
1183 * we will end up counting twice the same airtime, once in TCM
1199 u8 cmd_ver = iwl_fw_lookup_cmd_ver(mvm->fw,
1208 if (iwl_fw_lookup_notif_ver(mvm->fw, LEGACY_GROUP,
1227 struct iwl_notif_statistics_v11 *stats = (void *)&pkt->data;
1229 data.mac_id = stats->rx.general.mac_id;
1231 stats->general.common.beacon_filter_average_energy;
1233 mvm->rx_stats_v3 = stats->rx;
1235 mvm->radio_stats.rx_time =
1236 le64_to_cpu(stats->general.common.rx_time);
1237 mvm->radio_stats.tx_time =
1238 le64_to_cpu(stats->general.common.tx_time);
1239 mvm->radio_stats.on_time_rf =
1240 le64_to_cpu(stats->general.common.on_time_rf);
1241 mvm->radio_stats.on_time_scan =
1242 le64_to_cpu(stats->general.common.on_time_scan);
1244 data.beacon_counter = stats->general.beacon_counter;
1246 stats->general.beacon_average_energy;
1247 flags = stats->flag;
1249 struct iwl_notif_statistics *stats = (void *)&pkt->data;
1251 data.mac_id = stats->rx.general.mac_id;
1253 stats->general.common.beacon_filter_average_energy;
1255 mvm->rx_stats = stats->rx;
1257 mvm->radio_stats.rx_time =
1258 le64_to_cpu(stats->general.common.rx_time);
1259 mvm->radio_stats.tx_time =
1260 le64_to_cpu(stats->general.common.tx_time);
1261 mvm->radio_stats.on_time_rf =
1262 le64_to_cpu(stats->general.common.on_time_rf);
1263 mvm->radio_stats.on_time_scan =
1264 le64_to_cpu(stats->general.common.on_time_scan);
1266 data.beacon_counter = stats->general.beacon_counter;
1268 stats->general.beacon_average_energy;
1269 flags = stats->flag;
1275 ieee80211_iterate_active_interfaces(mvm->hw,
1284 struct iwl_notif_statistics_v11 *v11 = (void *)&pkt->data;
1286 energy = (void *)&v11->load_stats.avg_energy;
1287 bytes = (void *)&v11->load_stats.byte_count;
1288 air_time = (void *)&v11->load_stats.air_time;
1290 struct iwl_notif_statistics *stats = (void *)&pkt->data;
1292 energy = (void *)&stats->load_stats.avg_energy;
1293 bytes = (void *)&stats->load_stats.byte_count;
1294 air_time = (void *)&stats->load_stats.air_time;
1296 ieee80211_iterate_stations_atomic(mvm->hw, iwl_mvm_stats_energy_iter,
1301 * we will end up counting twice the same airtime, once in TCM
1318 struct iwl_ba_window_status_notif *notif = (void *)pkt->data;
1321 BUILD_BUG_ON(ARRAY_SIZE(notif->ra_tid) != BA_WINDOW_STREAMS_MAX);
1322 BUILD_BUG_ON(ARRAY_SIZE(notif->mpdu_rx_count) != BA_WINDOW_STREAMS_MAX);
1323 BUILD_BUG_ON(ARRAY_SIZE(notif->bitmap) != BA_WINDOW_STREAMS_MAX);
1324 BUILD_BUG_ON(ARRAY_SIZE(notif->start_seq_num) != BA_WINDOW_STREAMS_MAX);
1335 ratid = le16_to_cpu(notif->ra_tid[i]);
1340 received_mpdu = le16_to_cpu(notif->mpdu_rx_count[i]);
1348 sta = rcu_dereference(mvm->fw_id_to_mac_id[sta_id]);
1351 bitmap = le64_to_cpu(notif->bitmap[i]);
1352 ssn = le32_to_cpu(notif->start_seq_num[i]);