Loading dp/inc/cdp_txrx_mob_def.h +9 −3 Original line number Diff line number Diff line /* * Copyright (c) 2016-2020 The Linux Foundation. All rights reserved. * Copyright (c) 2016-2021 The Linux Foundation. All rights reserved. * Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the Loading Loading @@ -104,8 +105,9 @@ enum netif_action_type { WLAN_NETIF_VI_QUEUE_ON = 14, WLAN_NETIF_VI_QUEUE_OFF = 15, WLAN_NETIF_BE_BK_QUEUE_OFF = 16, WLAN_WAKE_NON_PRIORITY_QUEUE = 17, WLAN_STOP_NON_PRIORITY_QUEUE = 18, WLAN_NETIF_BE_BK_QUEUE_ON = 17, WLAN_WAKE_NON_PRIORITY_QUEUE = 18, WLAN_STOP_NON_PRIORITY_QUEUE = 19, WLAN_NETIF_ACTION_TYPE_MAX, }; Loading @@ -128,6 +130,10 @@ enum netif_reason_type { WLAN_PEER_UNAUTHORISED, WLAN_THERMAL_MITIGATION, WLAN_DATA_FLOW_CONTROL_PRIORITY, WLAN_DATA_FLOW_CTRL_BE_BK, WLAN_DATA_FLOW_CTRL_VI, WLAN_DATA_FLOW_CTRL_VO, WLAN_DATA_FLOW_CTRL_PRI, WLAN_REASON_TYPE_MAX, }; Loading dp/inc/cdp_txrx_stats_struct.h +48 −2 Original line number Diff line number Diff line /* * Copyright (c) 2016-2020 The Linux Foundation. All rights reserved. * Copyright (c) 2016-2021 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the Loading Loading @@ -465,8 +465,46 @@ struct cdp_tidq_stats { * @rtt_che_buffer_pointer_low32 : The low 32 bits of the 40 bits pointer to * external RTT channel information buffer * * @rtt_cfo_measurement : raw cfo data extracted from hardware, which is 14 bit * signed number. The first bit used for sign representation and 13 bits for * fractional part. * * @agc_gain_info0: Chain 0 & chain 1 agc gain information reported by PHY * * @agc_gain_info1: Chain 2 & chain 3 agc gain information reported by PHY * * @agc_gain_info2: Chain 4 & chain 5 agc gain information reported by PHY * * @agc_gain_info3: Chain 6 & chain 7 agc gain information reported by PHY * * @rx_start_ts: Rx packet timestamp, the time the first L-STF ADC sample * arrived at Rx antenna. * * @mcs_rate: Indicates the mcs/rate in which packet is received. * If HT, * 0-7: MCS0-MCS7 * If VHT, * 0-9: MCS0 to MCS9 * If HE, * 0-11: MCS0 to MCS11, * 12-13: 4096QAM, * 14-15: reserved * If Legacy, * 0: 48 Mbps * 1: 24 Mbps * 2: 12 Mbps * 3: 6 Mbps * 4: 54 Mbps * 5: 36 Mbps * 6: 18 Mbps * 7: 9 Mbps * * @gi_type: Indicates the gaurd interval. * 0: 0.8 us * 1: 0.4 us * 2: 1.6 us * 3: 3.2 us */ struct cdp_rx_ppdu_cfr_info { bool bb_captured_channel; bool bb_captured_timeout; Loading @@ -475,6 +513,14 @@ struct cdp_rx_ppdu_cfr_info { uint8_t chan_capture_status; uint8_t rtt_che_buffer_pointer_high8; uint32_t rtt_che_buffer_pointer_low32; int16_t rtt_cfo_measurement; uint32_t agc_gain_info0; uint32_t agc_gain_info1; uint32_t agc_gain_info2; uint32_t agc_gain_info3; uint32_t rx_start_ts; uint32_t mcs_rate; uint32_t gi_type; }; #endif /* Loading dp/wifi3.0/dp_rx_mon_status.c +77 −2 Original line number Diff line number Diff line /* * Copyright (c) 2017-2020 The Linux Foundation. All rights reserved. * Copyright (c) 2017-2021 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the Loading Loading @@ -489,6 +489,16 @@ dp_rx_populate_cdp_indication_ppdu(struct dp_pdev *pdev, cdp_rx_ppdu->lsig_a = ppdu_info->rx_status.rate; cdp_rx_ppdu->u.ltf_size = ppdu_info->rx_status.ltf_size; if (ppdu_info->rx_status.preamble_type == HAL_RX_PKT_TYPE_11AC) { cdp_rx_ppdu->u.stbc = ppdu_info->rx_status.is_stbc; } else if (ppdu_info->rx_status.preamble_type == HAL_RX_PKT_TYPE_11AX) { cdp_rx_ppdu->u.stbc = (ppdu_info->rx_status.he_data3 >> QDF_MON_STATUS_STBC_SHIFT) & 0x1; cdp_rx_ppdu->u.dcm = (ppdu_info->rx_status.he_data3 >> QDF_MON_STATUS_DCM_SHIFT) & 0x1; } dp_rx_populate_rx_rssi_chain(ppdu_info, cdp_rx_ppdu); dp_rx_populate_su_evm_details(ppdu_info, cdp_rx_ppdu); cdp_rx_ppdu->rx_antenna = ppdu_info->rx_status.rx_antenna; Loading Loading @@ -1187,17 +1197,66 @@ dp_rx_mon_populate_cfr_ppdu_info(struct dp_pdev *pdev, struct hal_rx_ppdu_info *ppdu_info, struct cdp_rx_indication_ppdu *cdp_rx_ppdu) { struct dp_peer *peer; struct dp_ast_entry *ast_entry; struct dp_soc *soc = pdev->soc; uint32_t ast_index; int chain; cdp_rx_ppdu->ppdu_id = ppdu_info->com_info.ppdu_id; cdp_rx_ppdu->timestamp = ppdu_info->rx_status.tsft; cdp_rx_ppdu->u.ppdu_type = ppdu_info->rx_status.reception_type; cdp_rx_ppdu->num_users = ppdu_info->com_info.num_users; for (chain = 0; chain < MAX_CHAIN; chain++) cdp_rx_ppdu->per_chain_rssi[chain] = ppdu_info->rx_status.rssi[chain]; cdp_rx_ppdu->u.ltf_size = ppdu_info->rx_status.ltf_size; cdp_rx_ppdu->beamformed = ppdu_info->rx_status.beamformed; cdp_rx_ppdu->u.ldpc = ppdu_info->rx_status.ldpc; if ((ppdu_info->rx_status.sgi == VHT_SGI_NYSM) && (ppdu_info->rx_status.preamble_type == HAL_RX_PKT_TYPE_11AC)) cdp_rx_ppdu->u.gi = CDP_SGI_0_4_US; else cdp_rx_ppdu->u.gi = ppdu_info->rx_status.sgi; if (ppdu_info->rx_status.preamble_type == HAL_RX_PKT_TYPE_11AC) { cdp_rx_ppdu->u.stbc = ppdu_info->rx_status.is_stbc; } else if (ppdu_info->rx_status.preamble_type == HAL_RX_PKT_TYPE_11AX) { cdp_rx_ppdu->u.stbc = (ppdu_info->rx_status.he_data3 >> QDF_MON_STATUS_STBC_SHIFT) & 0x1; cdp_rx_ppdu->u.dcm = (ppdu_info->rx_status.he_data3 >> QDF_MON_STATUS_DCM_SHIFT) & 0x1; } dp_rx_mon_handle_cfr_mu_info(pdev, ppdu_info, cdp_rx_ppdu); ast_index = ppdu_info->rx_status.ast_index; if (ast_index >= wlan_cfg_get_max_ast_idx(soc->wlan_cfg_ctx)) { cdp_rx_ppdu->peer_id = HTT_INVALID_PEER; cdp_rx_ppdu->num_users = 0; return; } ast_entry = soc->ast_table[ast_index]; if (!ast_entry || ast_entry->peer_id == HTT_INVALID_PEER) { cdp_rx_ppdu->peer_id = HTT_INVALID_PEER; cdp_rx_ppdu->num_users = 0; return; } peer = dp_peer_get_ref_by_id(soc, ast_entry->peer_id, DP_MOD_ID_RX_PPDU_STATS); if (!peer) { cdp_rx_ppdu->peer_id = HTT_INVALID_PEER; cdp_rx_ppdu->num_users = 0; return; } cdp_rx_ppdu->peer_id = peer->peer_id; cdp_rx_ppdu->vdev_id = peer->vdev->vdev_id; cdp_rx_ppdu->num_users = ppdu_info->com_info.num_users; } /** Loading Loading @@ -1247,6 +1306,22 @@ dp_rx_mon_populate_cfr_info(struct dp_pdev *pdev, = ppdu_info->cfr_info.rtt_che_buffer_pointer_high8; cfr_info->rtt_che_buffer_pointer_low32 = ppdu_info->cfr_info.rtt_che_buffer_pointer_low32; cfr_info->rtt_cfo_measurement = (int16_t)ppdu_info->cfr_info.rtt_cfo_measurement; cfr_info->agc_gain_info0 = ppdu_info->cfr_info.agc_gain_info0; cfr_info->agc_gain_info1 = ppdu_info->cfr_info.agc_gain_info1; cfr_info->agc_gain_info2 = ppdu_info->cfr_info.agc_gain_info2; cfr_info->agc_gain_info3 = ppdu_info->cfr_info.agc_gain_info3; cfr_info->rx_start_ts = ppdu_info->cfr_info.rx_start_ts; cfr_info->mcs_rate = ppdu_info->cfr_info.mcs_rate; cfr_info->gi_type = ppdu_info->cfr_info.gi_type; } /** Loading dp/wifi3.0/dp_tx_desc.h +80 −5 Original line number Diff line number Diff line /* * Copyright (c) 2016-2020 The Linux Foundation. All rights reserved. * Copyright (c) 2016-2021 The Linux Foundation. All rights reserved. * Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the Loading Loading @@ -219,6 +220,61 @@ dp_tx_is_threshold_reached(struct dp_tx_desc_pool_s *pool, uint16_t avail_desc) return false; } /** * dp_tx_adjust_flow_pool_state() - Adjust flow pool state * * @soc: dp soc * @pool: flow pool */ static inline void dp_tx_adjust_flow_pool_state(struct dp_soc *soc, struct dp_tx_desc_pool_s *pool) { if (pool->avail_desc > pool->stop_th[DP_TH_BE_BK]) { pool->status = FLOW_POOL_ACTIVE_UNPAUSED; return; } else if (pool->avail_desc <= pool->stop_th[DP_TH_BE_BK] && pool->avail_desc > pool->stop_th[DP_TH_VI]) { pool->status = FLOW_POOL_BE_BK_PAUSED; } else if (pool->avail_desc <= pool->stop_th[DP_TH_VI] && pool->avail_desc > pool->stop_th[DP_TH_VO]) { pool->status = FLOW_POOL_VI_PAUSED; } else if (pool->avail_desc <= pool->stop_th[DP_TH_VO] && pool->avail_desc > pool->stop_th[DP_TH_HI]) { pool->status = FLOW_POOL_VO_PAUSED; } else if (pool->avail_desc <= pool->stop_th[DP_TH_HI]) { pool->status = FLOW_POOL_ACTIVE_PAUSED; } switch (pool->status) { case FLOW_POOL_ACTIVE_PAUSED: soc->pause_cb(pool->flow_pool_id, WLAN_NETIF_PRIORITY_QUEUE_OFF, WLAN_DATA_FLOW_CTRL_PRI); /* fallthrough */ case FLOW_POOL_VO_PAUSED: soc->pause_cb(pool->flow_pool_id, WLAN_NETIF_VO_QUEUE_OFF, WLAN_DATA_FLOW_CTRL_VO); /* fallthrough */ case FLOW_POOL_VI_PAUSED: soc->pause_cb(pool->flow_pool_id, WLAN_NETIF_VI_QUEUE_OFF, WLAN_DATA_FLOW_CTRL_VI); /* fallthrough */ case FLOW_POOL_BE_BK_PAUSED: soc->pause_cb(pool->flow_pool_id, WLAN_NETIF_BE_BK_QUEUE_OFF, WLAN_DATA_FLOW_CTRL_BE_BK); break; default: dp_err("Invalid pool staus:%u to adjust", pool->status); } } /** * dp_tx_desc_alloc() - Allocate a Software Tx descriptor from given pool * Loading @@ -235,39 +291,53 @@ dp_tx_desc_alloc(struct dp_soc *soc, uint8_t desc_pool_id) bool is_pause = false; enum netif_action_type act = WLAN_NETIF_ACTION_TYPE_NONE; enum dp_fl_ctrl_threshold level = DP_TH_BE_BK; enum netif_reason_type reason; if (qdf_likely(pool)) { qdf_spin_lock_bh(&pool->flow_pool_lock); if (qdf_likely(pool->avail_desc)) { if (qdf_likely(pool->avail_desc && pool->status != FLOW_POOL_INVALID && pool->status != FLOW_POOL_INACTIVE)) { tx_desc = dp_tx_get_desc_flow_pool(pool); tx_desc->pool_id = desc_pool_id; tx_desc->flags = DP_TX_DESC_FLAG_ALLOCATED; is_pause = dp_tx_is_threshold_reached(pool, pool->avail_desc); if (qdf_unlikely(pool->status == FLOW_POOL_ACTIVE_UNPAUSED_REATTACH)) { dp_tx_adjust_flow_pool_state(soc, pool); is_pause = false; } if (qdf_unlikely(is_pause)) { switch (pool->status) { case FLOW_POOL_ACTIVE_UNPAUSED: /* pause network BE\BK queue */ act = WLAN_NETIF_BE_BK_QUEUE_OFF; reason = WLAN_DATA_FLOW_CTRL_BE_BK; level = DP_TH_BE_BK; pool->status = FLOW_POOL_BE_BK_PAUSED; break; case FLOW_POOL_BE_BK_PAUSED: /* pause network VI queue */ act = WLAN_NETIF_VI_QUEUE_OFF; reason = WLAN_DATA_FLOW_CTRL_VI; level = DP_TH_VI; pool->status = FLOW_POOL_VI_PAUSED; break; case FLOW_POOL_VI_PAUSED: /* pause network VO queue */ act = WLAN_NETIF_VO_QUEUE_OFF; reason = WLAN_DATA_FLOW_CTRL_VO; level = DP_TH_VO; pool->status = FLOW_POOL_VO_PAUSED; break; case FLOW_POOL_VO_PAUSED: /* pause network HI PRI queue */ act = WLAN_NETIF_PRIORITY_QUEUE_OFF; reason = WLAN_DATA_FLOW_CTRL_PRI; level = DP_TH_HI; pool->status = FLOW_POOL_ACTIVE_PAUSED; break; Loading @@ -285,7 +355,7 @@ dp_tx_desc_alloc(struct dp_soc *soc, uint8_t desc_pool_id) qdf_get_system_timestamp(); soc->pause_cb(desc_pool_id, act, WLAN_DATA_FLOW_CONTROL); reason); } } } else { Loading Loading @@ -315,6 +385,7 @@ dp_tx_desc_free(struct dp_soc *soc, struct dp_tx_desc_s *tx_desc, struct dp_tx_desc_pool_s *pool = &soc->tx_desc[desc_pool_id]; qdf_time_t unpause_time = qdf_get_system_timestamp(), pause_dur; enum netif_action_type act = WLAN_WAKE_ALL_NETIF_QUEUE; enum netif_reason_type reason; qdf_spin_lock_bh(&pool->flow_pool_lock); tx_desc->vdev_id = DP_INVALID_VDEV_ID; Loading @@ -325,6 +396,7 @@ dp_tx_desc_free(struct dp_soc *soc, struct dp_tx_desc_s *tx_desc, case FLOW_POOL_ACTIVE_PAUSED: if (pool->avail_desc > pool->start_th[DP_TH_HI]) { act = WLAN_NETIF_PRIORITY_QUEUE_ON; reason = WLAN_DATA_FLOW_CTRL_PRI; pool->status = FLOW_POOL_VO_PAUSED; /* Update maxinum pause duration for HI queue */ Loading @@ -337,6 +409,7 @@ dp_tx_desc_free(struct dp_soc *soc, struct dp_tx_desc_s *tx_desc, case FLOW_POOL_VO_PAUSED: if (pool->avail_desc > pool->start_th[DP_TH_VO]) { act = WLAN_NETIF_VO_QUEUE_ON; reason = WLAN_DATA_FLOW_CTRL_VO; pool->status = FLOW_POOL_VI_PAUSED; /* Update maxinum pause duration for VO queue */ Loading @@ -349,6 +422,7 @@ dp_tx_desc_free(struct dp_soc *soc, struct dp_tx_desc_s *tx_desc, case FLOW_POOL_VI_PAUSED: if (pool->avail_desc > pool->start_th[DP_TH_VI]) { act = WLAN_NETIF_VI_QUEUE_ON; reason = WLAN_DATA_FLOW_CTRL_VI; pool->status = FLOW_POOL_BE_BK_PAUSED; /* Update maxinum pause duration for VI queue */ Loading @@ -360,7 +434,8 @@ dp_tx_desc_free(struct dp_soc *soc, struct dp_tx_desc_s *tx_desc, break; case FLOW_POOL_BE_BK_PAUSED: if (pool->avail_desc > pool->start_th[DP_TH_BE_BK]) { act = WLAN_WAKE_NON_PRIORITY_QUEUE; act = WLAN_NETIF_BE_BK_QUEUE_ON; reason = WLAN_DATA_FLOW_CTRL_BE_BK; pool->status = FLOW_POOL_ACTIVE_UNPAUSED; /* Update maxinum pause duration for BE_BK queue */ Loading Loading @@ -393,7 +468,7 @@ dp_tx_desc_free(struct dp_soc *soc, struct dp_tx_desc_s *tx_desc, if (act != WLAN_WAKE_ALL_NETIF_QUEUE) soc->pause_cb(pool->flow_pool_id, act, WLAN_DATA_FLOW_CONTROL); act, reason); qdf_spin_unlock_bh(&pool->flow_pool_lock); } #else /* QCA_AC_BASED_FLOW_CONTROL */ Loading dp/wifi3.0/dp_tx_flow_control.c +55 −14 Original line number Diff line number Diff line /* * Copyright (c) 2015-2021 The Linux Foundation. All rights reserved. * Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the Loading Loading @@ -90,20 +91,7 @@ dp_tx_flow_pool_reattach(struct dp_tx_desc_pool_s *pool) "%s: flow pool already allocated, attached %d times", __func__, pool->pool_create_cnt); if (pool->avail_desc > pool->start_th[DP_TH_BE_BK]) pool->status = FLOW_POOL_ACTIVE_UNPAUSED; else if (pool->avail_desc <= pool->start_th[DP_TH_BE_BK] && pool->avail_desc > pool->start_th[DP_TH_VI]) pool->status = FLOW_POOL_BE_BK_PAUSED; else if (pool->avail_desc <= pool->start_th[DP_TH_VI] && pool->avail_desc > pool->start_th[DP_TH_VO]) pool->status = FLOW_POOL_VI_PAUSED; else if (pool->avail_desc <= pool->start_th[DP_TH_VO] && pool->avail_desc > pool->start_th[DP_TH_HI]) pool->status = FLOW_POOL_VO_PAUSED; else pool->status = FLOW_POOL_ACTIVE_PAUSED; pool->status = FLOW_POOL_ACTIVE_UNPAUSED_REATTACH; pool->pool_create_cnt++; } Loading Loading @@ -131,6 +119,48 @@ dp_tx_flow_pool_dump_threshold(struct dp_tx_desc_pool_s *pool) } } /** * dp_tx_flow_ctrl_reset_subqueues() - Reset subqueues to orginal state * @soc: dp soc * @pool: flow pool * @pool_status: flow pool status * * Return: none */ static inline void dp_tx_flow_ctrl_reset_subqueues(struct dp_soc *soc, struct dp_tx_desc_pool_s *pool, enum flow_pool_status pool_status) { switch (pool_status) { case FLOW_POOL_ACTIVE_PAUSED: soc->pause_cb(pool->flow_pool_id, WLAN_NETIF_PRIORITY_QUEUE_ON, WLAN_DATA_FLOW_CTRL_PRI); /* fallthrough */ case FLOW_POOL_VO_PAUSED: soc->pause_cb(pool->flow_pool_id, WLAN_NETIF_VO_QUEUE_ON, WLAN_DATA_FLOW_CTRL_VO); /* fallthrough */ case FLOW_POOL_VI_PAUSED: soc->pause_cb(pool->flow_pool_id, WLAN_NETIF_VI_QUEUE_ON, WLAN_DATA_FLOW_CTRL_VI); /* fallthrough */ case FLOW_POOL_BE_BK_PAUSED: soc->pause_cb(pool->flow_pool_id, WLAN_NETIF_BE_BK_QUEUE_ON, WLAN_DATA_FLOW_CTRL_BE_BK); /* fallthrough */ default: break; } } #else static inline void dp_tx_initialize_threshold(struct dp_tx_desc_pool_s *pool, Loading Loading @@ -166,6 +196,13 @@ dp_tx_flow_pool_dump_threshold(struct dp_tx_desc_pool_s *pool) pool->start_th, pool->stop_th); } static inline void dp_tx_flow_ctrl_reset_subqueues(struct dp_soc *soc, struct dp_tx_desc_pool_s *pool, enum flow_pool_status pool_status) { } #endif /** Loading Loading @@ -356,6 +393,7 @@ int dp_tx_delete_flow_pool(struct dp_soc *soc, struct dp_tx_desc_pool_s *pool, bool force) { struct dp_vdev *vdev; enum flow_pool_status pool_status; if (!soc || !pool) { dp_err("pool or soc is NULL"); Loading @@ -381,7 +419,10 @@ int dp_tx_delete_flow_pool(struct dp_soc *soc, struct dp_tx_desc_pool_s *pool, } if (pool->avail_desc < pool->pool_size) { pool_status = pool->status; pool->status = FLOW_POOL_INVALID; dp_tx_flow_ctrl_reset_subqueues(soc, pool, pool_status); qdf_spin_unlock_bh(&pool->flow_pool_lock); /* Reset TX desc associated to this Vdev as NULL */ vdev = dp_vdev_get_ref_by_id(soc, pool->flow_pool_id, Loading Loading
dp/inc/cdp_txrx_mob_def.h +9 −3 Original line number Diff line number Diff line /* * Copyright (c) 2016-2020 The Linux Foundation. All rights reserved. * Copyright (c) 2016-2021 The Linux Foundation. All rights reserved. * Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the Loading Loading @@ -104,8 +105,9 @@ enum netif_action_type { WLAN_NETIF_VI_QUEUE_ON = 14, WLAN_NETIF_VI_QUEUE_OFF = 15, WLAN_NETIF_BE_BK_QUEUE_OFF = 16, WLAN_WAKE_NON_PRIORITY_QUEUE = 17, WLAN_STOP_NON_PRIORITY_QUEUE = 18, WLAN_NETIF_BE_BK_QUEUE_ON = 17, WLAN_WAKE_NON_PRIORITY_QUEUE = 18, WLAN_STOP_NON_PRIORITY_QUEUE = 19, WLAN_NETIF_ACTION_TYPE_MAX, }; Loading @@ -128,6 +130,10 @@ enum netif_reason_type { WLAN_PEER_UNAUTHORISED, WLAN_THERMAL_MITIGATION, WLAN_DATA_FLOW_CONTROL_PRIORITY, WLAN_DATA_FLOW_CTRL_BE_BK, WLAN_DATA_FLOW_CTRL_VI, WLAN_DATA_FLOW_CTRL_VO, WLAN_DATA_FLOW_CTRL_PRI, WLAN_REASON_TYPE_MAX, }; Loading
dp/inc/cdp_txrx_stats_struct.h +48 −2 Original line number Diff line number Diff line /* * Copyright (c) 2016-2020 The Linux Foundation. All rights reserved. * Copyright (c) 2016-2021 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the Loading Loading @@ -465,8 +465,46 @@ struct cdp_tidq_stats { * @rtt_che_buffer_pointer_low32 : The low 32 bits of the 40 bits pointer to * external RTT channel information buffer * * @rtt_cfo_measurement : raw cfo data extracted from hardware, which is 14 bit * signed number. The first bit used for sign representation and 13 bits for * fractional part. * * @agc_gain_info0: Chain 0 & chain 1 agc gain information reported by PHY * * @agc_gain_info1: Chain 2 & chain 3 agc gain information reported by PHY * * @agc_gain_info2: Chain 4 & chain 5 agc gain information reported by PHY * * @agc_gain_info3: Chain 6 & chain 7 agc gain information reported by PHY * * @rx_start_ts: Rx packet timestamp, the time the first L-STF ADC sample * arrived at Rx antenna. * * @mcs_rate: Indicates the mcs/rate in which packet is received. * If HT, * 0-7: MCS0-MCS7 * If VHT, * 0-9: MCS0 to MCS9 * If HE, * 0-11: MCS0 to MCS11, * 12-13: 4096QAM, * 14-15: reserved * If Legacy, * 0: 48 Mbps * 1: 24 Mbps * 2: 12 Mbps * 3: 6 Mbps * 4: 54 Mbps * 5: 36 Mbps * 6: 18 Mbps * 7: 9 Mbps * * @gi_type: Indicates the gaurd interval. * 0: 0.8 us * 1: 0.4 us * 2: 1.6 us * 3: 3.2 us */ struct cdp_rx_ppdu_cfr_info { bool bb_captured_channel; bool bb_captured_timeout; Loading @@ -475,6 +513,14 @@ struct cdp_rx_ppdu_cfr_info { uint8_t chan_capture_status; uint8_t rtt_che_buffer_pointer_high8; uint32_t rtt_che_buffer_pointer_low32; int16_t rtt_cfo_measurement; uint32_t agc_gain_info0; uint32_t agc_gain_info1; uint32_t agc_gain_info2; uint32_t agc_gain_info3; uint32_t rx_start_ts; uint32_t mcs_rate; uint32_t gi_type; }; #endif /* Loading
dp/wifi3.0/dp_rx_mon_status.c +77 −2 Original line number Diff line number Diff line /* * Copyright (c) 2017-2020 The Linux Foundation. All rights reserved. * Copyright (c) 2017-2021 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the Loading Loading @@ -489,6 +489,16 @@ dp_rx_populate_cdp_indication_ppdu(struct dp_pdev *pdev, cdp_rx_ppdu->lsig_a = ppdu_info->rx_status.rate; cdp_rx_ppdu->u.ltf_size = ppdu_info->rx_status.ltf_size; if (ppdu_info->rx_status.preamble_type == HAL_RX_PKT_TYPE_11AC) { cdp_rx_ppdu->u.stbc = ppdu_info->rx_status.is_stbc; } else if (ppdu_info->rx_status.preamble_type == HAL_RX_PKT_TYPE_11AX) { cdp_rx_ppdu->u.stbc = (ppdu_info->rx_status.he_data3 >> QDF_MON_STATUS_STBC_SHIFT) & 0x1; cdp_rx_ppdu->u.dcm = (ppdu_info->rx_status.he_data3 >> QDF_MON_STATUS_DCM_SHIFT) & 0x1; } dp_rx_populate_rx_rssi_chain(ppdu_info, cdp_rx_ppdu); dp_rx_populate_su_evm_details(ppdu_info, cdp_rx_ppdu); cdp_rx_ppdu->rx_antenna = ppdu_info->rx_status.rx_antenna; Loading Loading @@ -1187,17 +1197,66 @@ dp_rx_mon_populate_cfr_ppdu_info(struct dp_pdev *pdev, struct hal_rx_ppdu_info *ppdu_info, struct cdp_rx_indication_ppdu *cdp_rx_ppdu) { struct dp_peer *peer; struct dp_ast_entry *ast_entry; struct dp_soc *soc = pdev->soc; uint32_t ast_index; int chain; cdp_rx_ppdu->ppdu_id = ppdu_info->com_info.ppdu_id; cdp_rx_ppdu->timestamp = ppdu_info->rx_status.tsft; cdp_rx_ppdu->u.ppdu_type = ppdu_info->rx_status.reception_type; cdp_rx_ppdu->num_users = ppdu_info->com_info.num_users; for (chain = 0; chain < MAX_CHAIN; chain++) cdp_rx_ppdu->per_chain_rssi[chain] = ppdu_info->rx_status.rssi[chain]; cdp_rx_ppdu->u.ltf_size = ppdu_info->rx_status.ltf_size; cdp_rx_ppdu->beamformed = ppdu_info->rx_status.beamformed; cdp_rx_ppdu->u.ldpc = ppdu_info->rx_status.ldpc; if ((ppdu_info->rx_status.sgi == VHT_SGI_NYSM) && (ppdu_info->rx_status.preamble_type == HAL_RX_PKT_TYPE_11AC)) cdp_rx_ppdu->u.gi = CDP_SGI_0_4_US; else cdp_rx_ppdu->u.gi = ppdu_info->rx_status.sgi; if (ppdu_info->rx_status.preamble_type == HAL_RX_PKT_TYPE_11AC) { cdp_rx_ppdu->u.stbc = ppdu_info->rx_status.is_stbc; } else if (ppdu_info->rx_status.preamble_type == HAL_RX_PKT_TYPE_11AX) { cdp_rx_ppdu->u.stbc = (ppdu_info->rx_status.he_data3 >> QDF_MON_STATUS_STBC_SHIFT) & 0x1; cdp_rx_ppdu->u.dcm = (ppdu_info->rx_status.he_data3 >> QDF_MON_STATUS_DCM_SHIFT) & 0x1; } dp_rx_mon_handle_cfr_mu_info(pdev, ppdu_info, cdp_rx_ppdu); ast_index = ppdu_info->rx_status.ast_index; if (ast_index >= wlan_cfg_get_max_ast_idx(soc->wlan_cfg_ctx)) { cdp_rx_ppdu->peer_id = HTT_INVALID_PEER; cdp_rx_ppdu->num_users = 0; return; } ast_entry = soc->ast_table[ast_index]; if (!ast_entry || ast_entry->peer_id == HTT_INVALID_PEER) { cdp_rx_ppdu->peer_id = HTT_INVALID_PEER; cdp_rx_ppdu->num_users = 0; return; } peer = dp_peer_get_ref_by_id(soc, ast_entry->peer_id, DP_MOD_ID_RX_PPDU_STATS); if (!peer) { cdp_rx_ppdu->peer_id = HTT_INVALID_PEER; cdp_rx_ppdu->num_users = 0; return; } cdp_rx_ppdu->peer_id = peer->peer_id; cdp_rx_ppdu->vdev_id = peer->vdev->vdev_id; cdp_rx_ppdu->num_users = ppdu_info->com_info.num_users; } /** Loading Loading @@ -1247,6 +1306,22 @@ dp_rx_mon_populate_cfr_info(struct dp_pdev *pdev, = ppdu_info->cfr_info.rtt_che_buffer_pointer_high8; cfr_info->rtt_che_buffer_pointer_low32 = ppdu_info->cfr_info.rtt_che_buffer_pointer_low32; cfr_info->rtt_cfo_measurement = (int16_t)ppdu_info->cfr_info.rtt_cfo_measurement; cfr_info->agc_gain_info0 = ppdu_info->cfr_info.agc_gain_info0; cfr_info->agc_gain_info1 = ppdu_info->cfr_info.agc_gain_info1; cfr_info->agc_gain_info2 = ppdu_info->cfr_info.agc_gain_info2; cfr_info->agc_gain_info3 = ppdu_info->cfr_info.agc_gain_info3; cfr_info->rx_start_ts = ppdu_info->cfr_info.rx_start_ts; cfr_info->mcs_rate = ppdu_info->cfr_info.mcs_rate; cfr_info->gi_type = ppdu_info->cfr_info.gi_type; } /** Loading
dp/wifi3.0/dp_tx_desc.h +80 −5 Original line number Diff line number Diff line /* * Copyright (c) 2016-2020 The Linux Foundation. All rights reserved. * Copyright (c) 2016-2021 The Linux Foundation. All rights reserved. * Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the Loading Loading @@ -219,6 +220,61 @@ dp_tx_is_threshold_reached(struct dp_tx_desc_pool_s *pool, uint16_t avail_desc) return false; } /** * dp_tx_adjust_flow_pool_state() - Adjust flow pool state * * @soc: dp soc * @pool: flow pool */ static inline void dp_tx_adjust_flow_pool_state(struct dp_soc *soc, struct dp_tx_desc_pool_s *pool) { if (pool->avail_desc > pool->stop_th[DP_TH_BE_BK]) { pool->status = FLOW_POOL_ACTIVE_UNPAUSED; return; } else if (pool->avail_desc <= pool->stop_th[DP_TH_BE_BK] && pool->avail_desc > pool->stop_th[DP_TH_VI]) { pool->status = FLOW_POOL_BE_BK_PAUSED; } else if (pool->avail_desc <= pool->stop_th[DP_TH_VI] && pool->avail_desc > pool->stop_th[DP_TH_VO]) { pool->status = FLOW_POOL_VI_PAUSED; } else if (pool->avail_desc <= pool->stop_th[DP_TH_VO] && pool->avail_desc > pool->stop_th[DP_TH_HI]) { pool->status = FLOW_POOL_VO_PAUSED; } else if (pool->avail_desc <= pool->stop_th[DP_TH_HI]) { pool->status = FLOW_POOL_ACTIVE_PAUSED; } switch (pool->status) { case FLOW_POOL_ACTIVE_PAUSED: soc->pause_cb(pool->flow_pool_id, WLAN_NETIF_PRIORITY_QUEUE_OFF, WLAN_DATA_FLOW_CTRL_PRI); /* fallthrough */ case FLOW_POOL_VO_PAUSED: soc->pause_cb(pool->flow_pool_id, WLAN_NETIF_VO_QUEUE_OFF, WLAN_DATA_FLOW_CTRL_VO); /* fallthrough */ case FLOW_POOL_VI_PAUSED: soc->pause_cb(pool->flow_pool_id, WLAN_NETIF_VI_QUEUE_OFF, WLAN_DATA_FLOW_CTRL_VI); /* fallthrough */ case FLOW_POOL_BE_BK_PAUSED: soc->pause_cb(pool->flow_pool_id, WLAN_NETIF_BE_BK_QUEUE_OFF, WLAN_DATA_FLOW_CTRL_BE_BK); break; default: dp_err("Invalid pool staus:%u to adjust", pool->status); } } /** * dp_tx_desc_alloc() - Allocate a Software Tx descriptor from given pool * Loading @@ -235,39 +291,53 @@ dp_tx_desc_alloc(struct dp_soc *soc, uint8_t desc_pool_id) bool is_pause = false; enum netif_action_type act = WLAN_NETIF_ACTION_TYPE_NONE; enum dp_fl_ctrl_threshold level = DP_TH_BE_BK; enum netif_reason_type reason; if (qdf_likely(pool)) { qdf_spin_lock_bh(&pool->flow_pool_lock); if (qdf_likely(pool->avail_desc)) { if (qdf_likely(pool->avail_desc && pool->status != FLOW_POOL_INVALID && pool->status != FLOW_POOL_INACTIVE)) { tx_desc = dp_tx_get_desc_flow_pool(pool); tx_desc->pool_id = desc_pool_id; tx_desc->flags = DP_TX_DESC_FLAG_ALLOCATED; is_pause = dp_tx_is_threshold_reached(pool, pool->avail_desc); if (qdf_unlikely(pool->status == FLOW_POOL_ACTIVE_UNPAUSED_REATTACH)) { dp_tx_adjust_flow_pool_state(soc, pool); is_pause = false; } if (qdf_unlikely(is_pause)) { switch (pool->status) { case FLOW_POOL_ACTIVE_UNPAUSED: /* pause network BE\BK queue */ act = WLAN_NETIF_BE_BK_QUEUE_OFF; reason = WLAN_DATA_FLOW_CTRL_BE_BK; level = DP_TH_BE_BK; pool->status = FLOW_POOL_BE_BK_PAUSED; break; case FLOW_POOL_BE_BK_PAUSED: /* pause network VI queue */ act = WLAN_NETIF_VI_QUEUE_OFF; reason = WLAN_DATA_FLOW_CTRL_VI; level = DP_TH_VI; pool->status = FLOW_POOL_VI_PAUSED; break; case FLOW_POOL_VI_PAUSED: /* pause network VO queue */ act = WLAN_NETIF_VO_QUEUE_OFF; reason = WLAN_DATA_FLOW_CTRL_VO; level = DP_TH_VO; pool->status = FLOW_POOL_VO_PAUSED; break; case FLOW_POOL_VO_PAUSED: /* pause network HI PRI queue */ act = WLAN_NETIF_PRIORITY_QUEUE_OFF; reason = WLAN_DATA_FLOW_CTRL_PRI; level = DP_TH_HI; pool->status = FLOW_POOL_ACTIVE_PAUSED; break; Loading @@ -285,7 +355,7 @@ dp_tx_desc_alloc(struct dp_soc *soc, uint8_t desc_pool_id) qdf_get_system_timestamp(); soc->pause_cb(desc_pool_id, act, WLAN_DATA_FLOW_CONTROL); reason); } } } else { Loading Loading @@ -315,6 +385,7 @@ dp_tx_desc_free(struct dp_soc *soc, struct dp_tx_desc_s *tx_desc, struct dp_tx_desc_pool_s *pool = &soc->tx_desc[desc_pool_id]; qdf_time_t unpause_time = qdf_get_system_timestamp(), pause_dur; enum netif_action_type act = WLAN_WAKE_ALL_NETIF_QUEUE; enum netif_reason_type reason; qdf_spin_lock_bh(&pool->flow_pool_lock); tx_desc->vdev_id = DP_INVALID_VDEV_ID; Loading @@ -325,6 +396,7 @@ dp_tx_desc_free(struct dp_soc *soc, struct dp_tx_desc_s *tx_desc, case FLOW_POOL_ACTIVE_PAUSED: if (pool->avail_desc > pool->start_th[DP_TH_HI]) { act = WLAN_NETIF_PRIORITY_QUEUE_ON; reason = WLAN_DATA_FLOW_CTRL_PRI; pool->status = FLOW_POOL_VO_PAUSED; /* Update maxinum pause duration for HI queue */ Loading @@ -337,6 +409,7 @@ dp_tx_desc_free(struct dp_soc *soc, struct dp_tx_desc_s *tx_desc, case FLOW_POOL_VO_PAUSED: if (pool->avail_desc > pool->start_th[DP_TH_VO]) { act = WLAN_NETIF_VO_QUEUE_ON; reason = WLAN_DATA_FLOW_CTRL_VO; pool->status = FLOW_POOL_VI_PAUSED; /* Update maxinum pause duration for VO queue */ Loading @@ -349,6 +422,7 @@ dp_tx_desc_free(struct dp_soc *soc, struct dp_tx_desc_s *tx_desc, case FLOW_POOL_VI_PAUSED: if (pool->avail_desc > pool->start_th[DP_TH_VI]) { act = WLAN_NETIF_VI_QUEUE_ON; reason = WLAN_DATA_FLOW_CTRL_VI; pool->status = FLOW_POOL_BE_BK_PAUSED; /* Update maxinum pause duration for VI queue */ Loading @@ -360,7 +434,8 @@ dp_tx_desc_free(struct dp_soc *soc, struct dp_tx_desc_s *tx_desc, break; case FLOW_POOL_BE_BK_PAUSED: if (pool->avail_desc > pool->start_th[DP_TH_BE_BK]) { act = WLAN_WAKE_NON_PRIORITY_QUEUE; act = WLAN_NETIF_BE_BK_QUEUE_ON; reason = WLAN_DATA_FLOW_CTRL_BE_BK; pool->status = FLOW_POOL_ACTIVE_UNPAUSED; /* Update maxinum pause duration for BE_BK queue */ Loading Loading @@ -393,7 +468,7 @@ dp_tx_desc_free(struct dp_soc *soc, struct dp_tx_desc_s *tx_desc, if (act != WLAN_WAKE_ALL_NETIF_QUEUE) soc->pause_cb(pool->flow_pool_id, act, WLAN_DATA_FLOW_CONTROL); act, reason); qdf_spin_unlock_bh(&pool->flow_pool_lock); } #else /* QCA_AC_BASED_FLOW_CONTROL */ Loading
dp/wifi3.0/dp_tx_flow_control.c +55 −14 Original line number Diff line number Diff line /* * Copyright (c) 2015-2021 The Linux Foundation. All rights reserved. * Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the Loading Loading @@ -90,20 +91,7 @@ dp_tx_flow_pool_reattach(struct dp_tx_desc_pool_s *pool) "%s: flow pool already allocated, attached %d times", __func__, pool->pool_create_cnt); if (pool->avail_desc > pool->start_th[DP_TH_BE_BK]) pool->status = FLOW_POOL_ACTIVE_UNPAUSED; else if (pool->avail_desc <= pool->start_th[DP_TH_BE_BK] && pool->avail_desc > pool->start_th[DP_TH_VI]) pool->status = FLOW_POOL_BE_BK_PAUSED; else if (pool->avail_desc <= pool->start_th[DP_TH_VI] && pool->avail_desc > pool->start_th[DP_TH_VO]) pool->status = FLOW_POOL_VI_PAUSED; else if (pool->avail_desc <= pool->start_th[DP_TH_VO] && pool->avail_desc > pool->start_th[DP_TH_HI]) pool->status = FLOW_POOL_VO_PAUSED; else pool->status = FLOW_POOL_ACTIVE_PAUSED; pool->status = FLOW_POOL_ACTIVE_UNPAUSED_REATTACH; pool->pool_create_cnt++; } Loading Loading @@ -131,6 +119,48 @@ dp_tx_flow_pool_dump_threshold(struct dp_tx_desc_pool_s *pool) } } /** * dp_tx_flow_ctrl_reset_subqueues() - Reset subqueues to orginal state * @soc: dp soc * @pool: flow pool * @pool_status: flow pool status * * Return: none */ static inline void dp_tx_flow_ctrl_reset_subqueues(struct dp_soc *soc, struct dp_tx_desc_pool_s *pool, enum flow_pool_status pool_status) { switch (pool_status) { case FLOW_POOL_ACTIVE_PAUSED: soc->pause_cb(pool->flow_pool_id, WLAN_NETIF_PRIORITY_QUEUE_ON, WLAN_DATA_FLOW_CTRL_PRI); /* fallthrough */ case FLOW_POOL_VO_PAUSED: soc->pause_cb(pool->flow_pool_id, WLAN_NETIF_VO_QUEUE_ON, WLAN_DATA_FLOW_CTRL_VO); /* fallthrough */ case FLOW_POOL_VI_PAUSED: soc->pause_cb(pool->flow_pool_id, WLAN_NETIF_VI_QUEUE_ON, WLAN_DATA_FLOW_CTRL_VI); /* fallthrough */ case FLOW_POOL_BE_BK_PAUSED: soc->pause_cb(pool->flow_pool_id, WLAN_NETIF_BE_BK_QUEUE_ON, WLAN_DATA_FLOW_CTRL_BE_BK); /* fallthrough */ default: break; } } #else static inline void dp_tx_initialize_threshold(struct dp_tx_desc_pool_s *pool, Loading Loading @@ -166,6 +196,13 @@ dp_tx_flow_pool_dump_threshold(struct dp_tx_desc_pool_s *pool) pool->start_th, pool->stop_th); } static inline void dp_tx_flow_ctrl_reset_subqueues(struct dp_soc *soc, struct dp_tx_desc_pool_s *pool, enum flow_pool_status pool_status) { } #endif /** Loading Loading @@ -356,6 +393,7 @@ int dp_tx_delete_flow_pool(struct dp_soc *soc, struct dp_tx_desc_pool_s *pool, bool force) { struct dp_vdev *vdev; enum flow_pool_status pool_status; if (!soc || !pool) { dp_err("pool or soc is NULL"); Loading @@ -381,7 +419,10 @@ int dp_tx_delete_flow_pool(struct dp_soc *soc, struct dp_tx_desc_pool_s *pool, } if (pool->avail_desc < pool->pool_size) { pool_status = pool->status; pool->status = FLOW_POOL_INVALID; dp_tx_flow_ctrl_reset_subqueues(soc, pool, pool_status); qdf_spin_unlock_bh(&pool->flow_pool_lock); /* Reset TX desc associated to this Vdev as NULL */ vdev = dp_vdev_get_ref_by_id(soc, pool->flow_pool_id, Loading