qcacmn: Fix UL delay value > 0x80000000 issue
buffer_timestamp in wbm2sw ring descriptor is 19 bits only with unit 1024 us, so it can only accommodate 0x7FFF * 1024 us same as 29 bits value with unit us. but if the timestamp value is > 0x7FFF * 1024 us, then the value stored in buffer_timestamp is not right as other higher bits bit29 ~ bit31 is lost. restore bit29 ~bit31 value for buffer_timestamp to fix current issue. Change-Id: Ie929f560365cc822883711133541772348775357 CRs-Fixed: 3336241
此提交包含在:
@@ -5030,6 +5030,51 @@ void dp_tx_update_connectivity_stats(struct dp_soc *soc,
|
||||
#endif
|
||||
|
||||
#if defined(WLAN_FEATURE_TSF_UPLINK_DELAY) || defined(WLAN_CONFIG_TX_DELAY)
|
||||
/* Mask for bit29 ~ bit31 */
|
||||
#define DP_TX_TS_BIT29_31_MASK 0xE0000000
|
||||
/* Timestamp value (unit us) if bit29 is set */
|
||||
#define DP_TX_TS_BIT29_SET_VALUE BIT(29)
|
||||
/**
|
||||
* dp_tx_adjust_enqueue_buffer_ts() - adjust the enqueue buffer_timestamp
|
||||
* @ack_ts: OTA ack timestamp, unit us.
|
||||
* @enqueue_ts: TCL enqueue TX data to TQM timestamp, unit us.
|
||||
* @base_delta_ts: base timestamp delta for ack_ts and enqueue_ts
|
||||
*
|
||||
* this function will restore the bit29 ~ bit31 3 bits value for
|
||||
* buffer_timestamp in wbm2sw ring entry, currently buffer_timestamp only
|
||||
* can support 0x7FFF * 1024 us (29 bits), but if the timestamp is >
|
||||
* 0x7FFF * 1024 us, bit29~ bit31 will be lost.
|
||||
*
|
||||
* Return: the adjusted buffer_timestamp value
|
||||
*/
|
||||
static inline
|
||||
uint32_t dp_tx_adjust_enqueue_buffer_ts(uint32_t ack_ts,
|
||||
uint32_t enqueue_ts,
|
||||
uint32_t base_delta_ts)
|
||||
{
|
||||
uint32_t ack_buffer_ts;
|
||||
uint32_t ack_buffer_ts_bit29_31;
|
||||
uint32_t adjusted_enqueue_ts;
|
||||
|
||||
/* corresponding buffer_timestamp value when receive OTA Ack */
|
||||
ack_buffer_ts = ack_ts - base_delta_ts;
|
||||
ack_buffer_ts_bit29_31 = ack_buffer_ts & DP_TX_TS_BIT29_31_MASK;
|
||||
|
||||
/* restore the bit29 ~ bit31 value */
|
||||
adjusted_enqueue_ts = ack_buffer_ts_bit29_31 | enqueue_ts;
|
||||
|
||||
/*
|
||||
* if actual enqueue_ts value occupied 29 bits only, this enqueue_ts
|
||||
* value + real UL delay overflow 29 bits, then 30th bit (bit-29)
|
||||
* should not be marked, otherwise extra 0x20000000 us is added to
|
||||
* enqueue_ts.
|
||||
*/
|
||||
if (qdf_unlikely(adjusted_enqueue_ts > ack_buffer_ts))
|
||||
adjusted_enqueue_ts -= DP_TX_TS_BIT29_SET_VALUE;
|
||||
|
||||
return adjusted_enqueue_ts;
|
||||
}
|
||||
|
||||
QDF_STATUS
|
||||
dp_tx_compute_hw_delay_us(struct hal_tx_completion_status *ts,
|
||||
uint32_t delta_tsf,
|
||||
@@ -5050,6 +5095,8 @@ dp_tx_compute_hw_delay_us(struct hal_tx_completion_status *ts,
|
||||
* valid up to 29 bits.
|
||||
*/
|
||||
buffer_ts = ts->buffer_timestamp << 10;
|
||||
buffer_ts = dp_tx_adjust_enqueue_buffer_ts(ts->tsf,
|
||||
buffer_ts, delta_tsf);
|
||||
|
||||
delay = ts->tsf - buffer_ts - delta_tsf;
|
||||
|
||||
|
新增問題並參考
封鎖使用者