/* df2255_verbatim.inc -- GENERATED by extract.sh, do not edit.
 * byte-identical extraction from:
 *   /usr/src/sys/contrib/dev/ath/ath_hal/ar9300/ar9300_eeprom.c (sha256 952817c63489c99f44f665c1fddaaebfdd80117effd33eb0eba271491e88d8f8)
 *   /usr/src/sys/contrib/dev/ath/ath_hal/ar9300/ar9300eep.h (sha256 ea73b386800c492640914b55386cf6f2f696b8964c97658b9357e5404aa965df)
 * generated: Sat Oct 17 17:53:48 UTC 2026
 */

ar9300_eeprom_t *
ar9300_eeprom_struct_default_find_by_id(int id) 
{
    int it;

    for (it = 0; it < ARRAY_LENGTH(default9300); it++) {
        if (default9300[it] != 0 && default9300[it]->template_version == id) {
            return default9300[it];
        }
    }
    return 0;
}

HAL_BOOL
ar9300_calibration_data_read_eeprom(struct ath_hal *ah, long address,
    u_int8_t *buffer, int many)
{
    int i;
    u_int8_t value[2];
    unsigned long eep_addr;
    unsigned long byte_addr;
    u_int16_t *svalue;

    if (((address) < 0) || ((address + many) > AR9300_EEPROM_SIZE)) {
        return AH_FALSE;
    }

    for (i = 0; i < many; i++) {
        eep_addr = (u_int16_t) (address + i) / 2;
        byte_addr = (u_int16_t) (address + i) % 2;
        svalue = (u_int16_t *) value;
        if (! ath_hal_eepromRead(ah, eep_addr, svalue)) {
            HALDEBUG(ah, HAL_DEBUG_EEPROM,
                "%s: Unable to read eeprom region \n", __func__);
            return AH_FALSE;
        }  
        buffer[i] = (*svalue >> (8 * byte_addr)) & 0xff;
    }  
    return AH_TRUE;
}

HAL_BOOL
ar9300_calibration_data_read(struct ath_hal *ah, long address,
    u_int8_t *buffer, int many)
{
    switch (AH9300(ah)->calibration_data_source) {
    case calibration_data_flash:
        return ar9300_calibration_data_read_flash(ah, address, buffer, many);
    case calibration_data_eeprom:
        return ar9300_calibration_data_read_eeprom(ah, address, buffer, many);
    case calibration_data_otp:
        return ar9300_calibration_data_read_otp(ah, address, buffer, many, 1);
#ifdef ATH_CAL_NAND_FLASH
    case calibration_data_nand:
        return ar9300_calibration_data_read_nand(ah,address,buffer,many);
#endif

    }
    return AH_FALSE;
}

HAL_BOOL 
ar9300_calibration_data_read_array(struct ath_hal *ah, int address,
    u_int8_t *buffer, int many)
{
    int it;

    for (it = 0; it < many; it++) {
        if (!ar9300_calibration_data_read(ah, address - it,
                buffer + it, 1)) {
            return AH_FALSE;
        }
    }
    return AH_TRUE;
}

u_int16_t
ar9300_compression_checksum(u_int8_t *data, int dsize)
{
    int it;
    int checksum = 0;

    for (it = 0; it < dsize; it++) {
        checksum += data[it];
        checksum &= 0xffff;
    }

    return checksum;
}

int
ar9300_compression_header_unpack(u_int8_t *best, int *code, int *reference,
    int *length, int *major, int *minor)
{
    unsigned long value[4];

    value[0] = best[0];
    value[1] = best[1];
    value[2] = best[2];
    value[3] = best[3];
    *code = ((value[0] >> 5) & 0x0007);
    *reference = (value[0] & 0x001f) | ((value[1] >> 2) & 0x0020);
    *length = ((value[1] << 4) & 0x07f0) | ((value[2] >> 4) & 0x000f);
    *major = (value[2] & 0x000f);
    *minor = (value[3] & 0x00ff);

    return 4;
}

static HAL_BOOL
ar9300_uncompress_block(struct ath_hal *ah, u_int8_t *mptr, int mdata_size,
    u_int8_t *block, int size)
{
    int it;
    int spot;
    int offset;
    int length;

    spot = 0;
    for (it = 0; it < size; it += (length + 2)) {
        offset = block[it];
        offset &= 0xff;
        spot += offset;
        length = block[it + 1];
        length &= 0xff;
        if (length > 0 && spot >= 0 && spot + length <= mdata_size) {
            HALDEBUG(ah, HAL_DEBUG_EEPROM,
                "%s: Restore at %d: spot=%d offset=%d length=%d\n",
                __func__, it, spot, offset, length);
            OS_MEMCPY(&mptr[spot], &block[it + 2], length);
            spot += length;
        } else if (length > 0) {
            HALDEBUG(ah, HAL_DEBUG_EEPROM,
                "%s: Bad restore at %d: spot=%d offset=%d length=%d\n",
                __func__, it, spot, offset, length);
            return AH_FALSE;
        }
    }
    return AH_TRUE;
}

static int
ar9300_eeprom_restore_internal_address(struct ath_hal *ah,
    ar9300_eeprom_t *mptr, int mdata_size, int cptr, u_int8_t blank)
{
    u_int8_t word[MOUTPUT]; 
    ar9300_eeprom_t *dptr; /* was uint8 */
    int code;
    int reference, length, major, minor;
    int osize;
    int it;
    int restored;
    u_int16_t checksum, mchecksum;

    restored = 0;
    for (it = 0; it < MSTATE; it++) {            
        if (! ar9300_calibration_data_read_array(
                ah, cptr, word, compression_header_length)) {
            break;
        }
        if (word[0] == blank && word[1] == blank && word[2] == blank && word[3] == blank)
        {
            break;
        }
        ar9300_compression_header_unpack(
            word, &code, &reference, &length, &major, &minor);
        HALDEBUG(ah, HAL_DEBUG_EEPROM,
            "%s: Found block at %x: "
            "code=%d ref=%d length=%d major=%d minor=%d\n",
            __func__, cptr, code, reference, length, major, minor);
        /*
         * DF-2255: length is an 11-bit field taken from the on-card
         * eeprom (max 2047).  The whole block is read into
         * u_int8_t word[MOUTPUT] below, so 4 + length + 2 bytes must
         * fit in MOUTPUT or the read runs past the end of the stack
         * buffer (1-5 byte kernel-stack overwrite with eeprom data).
         * The old length >= 1024 guard was disabled behind
         * "#ifdef DONTUSE"; enforce the real buffer bound instead.
         */
        if (length > MOUTPUT - compression_header_length -
                compression_checksum_length) {
            HALDEBUG(ah, HAL_DEBUG_EEPROM, "%s: Skipping bad header\n", __func__);
            cptr -= compression_header_length;
            continue;
        }
        osize = length;                
        if (! ar9300_calibration_data_read_array(
                ah, cptr, word,
                compression_header_length + osize +
                compression_checksum_length)) {
            break;
        }
        checksum = ar9300_compression_checksum(
            &word[compression_header_length], length);
        mchecksum =
            word[compression_header_length + osize] |
            (word[compression_header_length + osize + 1] << 8);
        HALDEBUG(ah, HAL_DEBUG_EEPROM,
            "%s: checksum %x %x\n", __func__, checksum, mchecksum);
        if (checksum == mchecksum) {
            switch (code) {
            case _compress_none:
                if (length != mdata_size) {
                    HALDEBUG(ah, HAL_DEBUG_EEPROM,
                        "%s: EEPROM structure size mismatch "
                        "memory=%d eeprom=%d\n", __func__, mdata_size, length);
                    return -1;
                }
                OS_MEMCPY((u_int8_t *)mptr,
                    (u_int8_t *)(word + compression_header_length), length);
                HALDEBUG(ah, HAL_DEBUG_EEPROM,
                    "%s: restored eeprom %d: uncompressed, length %d\n",
                    __func__, it, length);
                restored = 1;
                break;
#ifdef UNUSED
            case _compress_lzma:
                if (reference == reference_current) {
                    dptr = mptr;
                } else {
                    dptr = (u_int8_t *)ar9300_eeprom_struct_default_find_by_id(
                        reference);
                    if (dptr == 0) {
                        HALDEBUG(ah, HAL_DEBUG_EEPROM,
                            "%s: Can't find reference eeprom struct %d\n",
                            __func__, reference);
                        goto done;
                    }
                }
                usize = -1;
                if (usize != mdata_size) {
                    HALDEBUG(ah, HAL_DEBUG_EEPROM,
                        "%s: uncompressed data is wrong size %d %d\n",
                        __func__, usize, mdata_size);
                    goto done;
                }

                for (ib = 0; ib < mdata_size; ib++) {
                    mptr[ib] = dptr[ib] ^ word[ib + overhead];
                }
                HALDEBUG(ah, HAL_DEBUG_EEPROM,
                    "%s: restored eeprom %d: compressed, "
                    "reference %d, length %d\n",
                    __func__, it, reference, length);
                break;
            case _compress_pairs:
                if (reference == reference_current) {
                    dptr = mptr;
                } else {
                    dptr = (u_int8_t *)ar9300_eeprom_struct_default_find_by_id(
                        reference);
                    if (dptr == 0) {
                        HALDEBUG(ah, HAL_DEBUG_EEPROM,
                            "%s: Can't find the reference "
                            "eeprom structure %d\n",
                            __func__, reference);
                        goto done;
                    }
                }
                HALDEBUG(ah, HAL_DEBUG_EEPROM,
                    "%s: restored eeprom %d: "
                    "pairs, reference %d, length %d,\n",
                    __func__, it, reference, length);
                break;
#endif
            case _compress_block:
                if (reference == reference_current) {
                    dptr = mptr;
                } else {
                    dptr = ar9300_eeprom_struct_default_find_by_id(reference);
                    if (dptr == 0) {
                        HALDEBUG(ah, HAL_DEBUG_EEPROM,
                            "%s: can't find reference eeprom struct %d\n",
                            __func__, reference);
                        break;
                    }
                    OS_MEMCPY(mptr, dptr, mdata_size);
                }

                HALDEBUG(ah, HAL_DEBUG_EEPROM,
                    "%s: restore eeprom %d: block, reference %d, length %d\n",
                    __func__, it, reference, length);
                (void) ar9300_uncompress_block(ah,
                    (u_int8_t *) mptr, mdata_size,
                    (u_int8_t *) (word + compression_header_length), length);
                restored = 1;
                break;
            default:
                HALDEBUG(ah, HAL_DEBUG_EEPROM,
                    "%s: unknown compression code %d\n", __func__, code);
                break;
            }
        } else {
            HALDEBUG(ah, HAL_DEBUG_EEPROM,
                "%s: skipping block with bad checksum\n", __func__);
        }
        cptr -= compression_header_length + osize + compression_checksum_length;
    }

    if (!restored) {
        cptr = -1;
    }
    return cptr;
}

