DF-3960 / fix.diff
--- a/sys/dev/netif/ath/ath_hal/ar5416/ar5416_reset.c 2026-09-17 05:19:20.556938969 +0000 +++ b/sys/dev/netif/ath/ath_hal/ar5416/ar5416_reset.c 2026-09-17 05:19:35.712746537 +0000 @@ -2369,7 +2369,18 @@ /* Calculate the value of xpdgains from the xpdGain Mask */ numXpdGain = ar5416GetXpdGainValues(ah, xpdMask, xpdGainValues); - + + /* + * An empty xpdGain mask is invalid EEPROM data: with numXpdGain == 0 + * the backfill loops in ar5416GetGainBoundariesAndPdadcs() read + * gainBoundaries[-1] and pdadcValues[-1]. Fail the calibration. + */ + if (numXpdGain == 0) { + HALDEBUG(ah, HAL_DEBUG_ANY, "%s: invalid xpdGain mask 0x%x\n", + __func__, xpdMask); + return AH_FALSE; + } + /* Write the detector gain biases and their number */ ar5416WriteDetectorGainBiases(ah, numXpdGain, xpdGainValues); @@ -2539,6 +2550,16 @@ } sizeCurrVpdTable = (uint8_t)((maxPwrT4[i] - minPwrT4[i]) / 2 +1); + /* + * Degenerate pier ranges from corrupt EEPROM: a zero range makes + * the vpdStep read below index [-1]/[-2]; an inverted range wraps + * the uint8_t size past the 64-entry vpd table row, so the copy + * loop walks off the row. Clamp before deriving maxIndex. + */ + if (sizeCurrVpdTable < 2) + sizeCurrVpdTable = 2; + if (sizeCurrVpdTable > AR5416_MAX_PWR_RANGE_IN_HALF_DB) + sizeCurrVpdTable = AR5416_MAX_PWR_RANGE_IN_HALF_DB; tgtIndex = (uint8_t)(pPdGainBoundaries[i] + tPdGainOverlap - (minPwrT4[i] / 2)); maxIndex = (tgtIndex < sizeCurrVpdTable) ? tgtIndex : sizeCurrVpdTable; |