On Tue, 4 Nov 2025 at 15:22, <[email protected]> wrote:
>
> From: Soumyajyotii Ssarkar <[email protected]>
>
> In this patch I have added the following:
> - Rewrote transmit path with CSMA/CD collision handling and retry logic
> - Implemented flexible TX buffer descriptor (TBD) chain processing
> - Rewrote receive path with packet filtering and monitor mode support
> - Added RX packet queue for handling resource exhaustion
> - Implemented queue flush timer and management
> - Added RX state machine with proper state transitions
> - Implemented packet filtering (unicast, broadcast, multicast, promiscuous)
> - Added SCB RU_START enhancement to find usable RFDs
> - Implemented dump command support
> - Added bus throttle timer loading (LOAD_THROTTLE/LOAD_START commands)
> - Enhanced signal_ca with proper initialization sequence
> - Finally, adding self-test functionality
>
> Note:
> With this patch, and the previous ones in the patch series, we are able
> to achive proper 82596 NIC emulation.

Hi; Coverity spotted an issue in this code (CID 1642868):

> +static ssize_t i82596_receive_packet(I82596State *s, const uint8_t *buf,
> +                                      size_t size, bool from_queue)
> +{
> +    struct i82596_rx_descriptor rfd;
> +    uint32_t rfd_addr, rbd_addr;
> +    uint16_t rx_status = 0;
> +    uint16_t is_broadcast = 0;
> +    bool packet_completed = true;
> +    bool simplified_mode = false;
> +    size_t frame_size = size;
> +    size_t payload_size = 0;
> +    size_t bytes_copied = 0;
> +    const uint8_t *packet_data = buf;
> +    bool crc_valid = true;

Here we set crc_valid to true...

> +    bool out_of_resources = false;
> +    size_t crc_size = i82596_get_crc_size(s);
> +
> +    trace_i82596_receive_packet(buf, size);

[snipped]

> +rx_complete:
> +    if (I596_CRCINM && !I596_LOOPBACK && packet_completed) {
> +        uint8_t crc_data[4];
> +        size_t crc_len = crc_size;
> +
> +        if (I596_CRC16_32) {
> +            uint32_t crc = crc32(~0, packet_data, frame_size);
> +            crc = cpu_to_be32(crc);
> +            memcpy(crc_data, &crc, 4);
> +        } else {
> +            uint16_t crc = i82596_calculate_crc16(packet_data, frame_size);
> +            crc = cpu_to_be16(crc);
> +            memcpy(crc_data, &crc, 2);
>          }
>
> -        if (s->cu_status != CU_ACTIVE) {
> -            break;
> +        if (simplified_mode) {
> +            address_space_write(&address_space_memory,
> +                                rfd_addr + 0x1E + bytes_copied,
> +                                MEMTXATTRS_UNSPECIFIED, crc_data, crc_len);
> +        }
> +    }

...but nowhere in any of this code do we ever set crc_valid to
anything else...

> +
> +    if (packet_completed && crc_valid) {

...so this condition is the same as "if (packet_completed)"...

> +        rx_status |= STAT_C | STAT_OK;
> +        if (is_broadcast) {
> +            rx_status |= 0x0001;
> +        }
> +    } else if (packet_completed) {

...and the code in this block is unreachable.


> +        rx_status |= STAT_C;
> +        if (!crc_valid) {
> +            rx_status |= RX_CRC_ERRORS;
> +        }
> +    } else {
> +        rx_status |= STAT_B;
> +    }
> +

What was the intention here?

thanks
-- PMM

Reply via email to