xmit_seg(E1000State *s)

{

    uint16_t len;

    unsigned int frames = s->tx.tso_frames, css, sofar;

    struct e1000_tx *tp = &s->tx;



    if (tp->props.tse && tp->props.cptse) {

        css = tp->props.ipcss;

        DBGOUT(TXSUM, "frames %d size %d ipcss %d\n",

               frames, tp->size, css);

        if (tp->props.ip) {    /* IPv4 */

            stw_be_p(tp->data+css+2, tp->size - css);

            stw_be_p(tp->data+css+4,

                     lduw_be_p(tp->data + css + 4) + frames);

        } else {         /* IPv6 */

            stw_be_p(tp->data+css+4, tp->size - css);

        }

        css = tp->props.tucss;

        len = tp->size - css;

        DBGOUT(TXSUM, "tcp %d tucss %d len %d\n", tp->props.tcp, css, len);

        if (tp->props.tcp) {

            sofar = frames * tp->props.mss;

            stl_be_p(tp->data+css+4, ldl_be_p(tp->data+css+4)+sofar); /* seq */

            if (tp->props.paylen - sofar > tp->props.mss) {

                tp->data[css + 13] &= ~9;    /* PSH, FIN */

            } else if (frames) {

                e1000x_inc_reg_if_not_full(s->mac_reg, TSCTC);

            }

        } else    /* UDP */

            stw_be_p(tp->data+css+4, len);

        if (tp->props.sum_needed & E1000_TXD_POPTS_TXSM) {

            unsigned int phsum;

            // add pseudo-header length before checksum calculation

            void *sp = tp->data + tp->props.tucso;



            phsum = lduw_be_p(sp) + len;

            phsum = (phsum >> 16) + (phsum & 0xffff);

            stw_be_p(sp, phsum);

        }

        tp->tso_frames++;

    }



    if (tp->props.sum_needed & E1000_TXD_POPTS_TXSM) {

        putsum(tp->data, tp->size, tp->props.tucso,

               tp->props.tucss, tp->props.tucse);

    }

    if (tp->props.sum_needed & E1000_TXD_POPTS_IXSM) {

        putsum(tp->data, tp->size, tp->props.ipcso,

               tp->props.ipcss, tp->props.ipcse);

    }

    if (tp->vlan_needed) {

        memmove(tp->vlan, tp->data, 4);

        memmove(tp->data, tp->data + 4, 8);

        memcpy(tp->data + 8, tp->vlan_header, 4);

        e1000_send_packet(s, tp->vlan, tp->size + 4);

    } else {

        e1000_send_packet(s, tp->data, tp->size);

    }



    e1000x_inc_reg_if_not_full(s->mac_reg, TPT);

    e1000x_grow_8reg_if_not_full(s->mac_reg, TOTL, s->tx.size);

    s->mac_reg[GPTC] = s->mac_reg[TPT];

    s->mac_reg[GOTCL] = s->mac_reg[TOTL];

    s->mac_reg[GOTCH] = s->mac_reg[TOTH];

}

xmit_seg(E1000State *s)

{

    uint16_t len;

    unsigned int frames = s->tx.tso_frames, css, sofar;

    struct e1000_tx *tp = &s->tx;



    if (tp->props.tse && tp->props.cptse) {

        css = tp->props.ipcss;

        DBGOUT(TXSUM, "frames %d size %d ipcss %d\n",

               frames, tp->size, css);

        if (tp->props.ip) {    

            stw_be_p(tp->data+css+2, tp->size - css);

            stw_be_p(tp->data+css+4,

                     lduw_be_p(tp->data + css + 4) + frames);

        } else {         

            stw_be_p(tp->data+css+4, tp->size - css);

        }

        css = tp->props.tucss;

        len = tp->size - css;

        DBGOUT(TXSUM, "tcp %d tucss %d len %d\n", tp->props.tcp, css, len);

        if (tp->props.tcp) {

            sofar = frames * tp->props.mss;

            stl_be_p(tp->data+css+4, ldl_be_p(tp->data+css+4)+sofar); 

            if (tp->props.paylen - sofar > tp->props.mss) {

                tp->data[css + 13] &= ~9;    

            } else if (frames) {

                e1000x_inc_reg_if_not_full(s->mac_reg, TSCTC);

            }

        } else    

            stw_be_p(tp->data+css+4, len);

        if (tp->props.sum_needed & E1000_TXD_POPTS_TXSM) {

            unsigned int phsum;

            

            void *sp = tp->data + tp->props.tucso;



            phsum = lduw_be_p(sp) + len;

            phsum = (phsum >> 16) + (phsum & 0xffff);

            stw_be_p(sp, phsum);

        }

        tp->tso_frames++;

    }



    if (tp->props.sum_needed & E1000_TXD_POPTS_TXSM) {

        putsum(tp->data, tp->size, tp->props.tucso,

               tp->props.tucss, tp->props.tucse);

    }

    if (tp->props.sum_needed & E1000_TXD_POPTS_IXSM) {

        putsum(tp->data, tp->size, tp->props.ipcso,

               tp->props.ipcss, tp->props.ipcse);

    }

    if (tp->vlan_needed) {

        memmove(tp->vlan, tp->data, 4);

        memmove(tp->data, tp->data + 4, 8);

        memcpy(tp->data + 8, tp->vlan_header, 4);

        e1000_send_packet(s, tp->vlan, tp->size + 4);

    } else {

        e1000_send_packet(s, tp->data, tp->size);

    }



    e1000x_inc_reg_if_not_full(s->mac_reg, TPT);

    e1000x_grow_8reg_if_not_full(s->mac_reg, TOTL, s->tx.size);

    s->mac_reg[GPTC] = s->mac_reg[TPT];

    s->mac_reg[GOTCL] = s->mac_reg[TOTL];

    s->mac_reg[GOTCH] = s->mac_reg[TOTH];

}

FUNC_0(E1000State *VAR_0)

{

    uint16_t len;

    unsigned int VAR_1 = VAR_0->tx.tso_frames, VAR_2, VAR_3;

    struct e1000_tx *VAR_4 = &VAR_0->tx;



    if (VAR_4->props.tse && VAR_4->props.cptse) {

        VAR_2 = VAR_4->props.ipcss;

        DBGOUT(TXSUM, "VAR_1 %d size %d ipcss %d\n",

               VAR_1, VAR_4->size, VAR_2);

        if (VAR_4->props.ip) {    

            stw_be_p(VAR_4->data+VAR_2+2, VAR_4->size - VAR_2);

            stw_be_p(VAR_4->data+VAR_2+4,

                     lduw_be_p(VAR_4->data + VAR_2 + 4) + VAR_1);

        } else {         

            stw_be_p(VAR_4->data+VAR_2+4, VAR_4->size - VAR_2);

        }

        VAR_2 = VAR_4->props.tucss;

        len = VAR_4->size - VAR_2;

        DBGOUT(TXSUM, "tcp %d tucss %d len %d\n", VAR_4->props.tcp, VAR_2, len);

        if (VAR_4->props.tcp) {

            VAR_3 = VAR_1 * VAR_4->props.mss;

            stl_be_p(VAR_4->data+VAR_2+4, ldl_be_p(VAR_4->data+VAR_2+4)+VAR_3); 

            if (VAR_4->props.paylen - VAR_3 > VAR_4->props.mss) {

                VAR_4->data[VAR_2 + 13] &= ~9;    

            } else if (VAR_1) {

                e1000x_inc_reg_if_not_full(VAR_0->mac_reg, TSCTC);

            }

        } else    

            stw_be_p(VAR_4->data+VAR_2+4, len);

        if (VAR_4->props.sum_needed & E1000_TXD_POPTS_TXSM) {

            unsigned int VAR_5;

            

            void *VAR_6 = VAR_4->data + VAR_4->props.tucso;



            VAR_5 = lduw_be_p(VAR_6) + len;

            VAR_5 = (VAR_5 >> 16) + (VAR_5 & 0xffff);

            stw_be_p(VAR_6, VAR_5);

        }

        VAR_4->tso_frames++;

    }



    if (VAR_4->props.sum_needed & E1000_TXD_POPTS_TXSM) {

        putsum(VAR_4->data, VAR_4->size, VAR_4->props.tucso,

               VAR_4->props.tucss, VAR_4->props.tucse);

    }

    if (VAR_4->props.sum_needed & E1000_TXD_POPTS_IXSM) {

        putsum(VAR_4->data, VAR_4->size, VAR_4->props.ipcso,

               VAR_4->props.ipcss, VAR_4->props.ipcse);

    }

    if (VAR_4->vlan_needed) {

        memmove(VAR_4->vlan, VAR_4->data, 4);

        memmove(VAR_4->data, VAR_4->data + 4, 8);

        memcpy(VAR_4->data + 8, VAR_4->vlan_header, 4);

        e1000_send_packet(VAR_0, VAR_4->vlan, VAR_4->size + 4);

    } else {

        e1000_send_packet(VAR_0, VAR_4->data, VAR_4->size);

    }



    e1000x_inc_reg_if_not_full(VAR_0->mac_reg, TPT);

    e1000x_grow_8reg_if_not_full(VAR_0->mac_reg, TOTL, VAR_0->tx.size);

    VAR_0->mac_reg[GPTC] = VAR_0->mac_reg[TPT];

    VAR_0->mac_reg[GOTCL] = VAR_0->mac_reg[TOTL];

    VAR_0->mac_reg[GOTCH] = VAR_0->mac_reg[TOTH];

}

FUNC_0(E1000State *VAR_0)
{ uint16_t len; unsigned int VAR_1 = VAR_0->tx.tso_frames, VAR_2, VAR_3; struct e1000_tx *VAR_4 = &VAR_0->tx; if (VAR_4->props.tse && VAR_4->props.cptse) { VAR_2 = VAR_4->props.ipcss; DBGOUT(TXSUM, "VAR_1 %d size %d ipcss %d\n",
VAR_1, VAR_4->size, VAR_2); if (VAR_4->props.ip) { stw_be_p(VAR_4->data+VAR_2+2, VAR_4->size - VAR_2); stw_be_p(VAR_4->data+VAR_2+4,
lduw_be_p(VAR_4->data + VAR_2 + 4) + VAR_1); } else { stw_be_p(VAR_4->data+VAR_2+4, VAR_4->size - VAR_2); } VAR_2 = VAR_4->props.tucss; len = VAR_4->size - VAR_2; DBGOUT(TXSUM, "tcp %d tucss %d len %d\n", VAR_4->props.tcp, VAR_2, len); if (VAR_4->props.tcp) { VAR_3 = VAR_1 * VAR_4->props.mss; stl_be_p(VAR_4->data+VAR_2+4, ldl_be_p(VAR_4->data+VAR_2+4)+VAR_3); if (VAR_4->props.paylen - VAR_3 > VAR_4->props.mss) { VAR_4->data[VAR_2 + 13] &= ~9; } else if (VAR_1) { e1000x_inc_reg_if_not_full(VAR_0->mac_reg, TSCTC); } } else stw_be_p(VAR_4->data+VAR_2+4, len); if (VAR_4->props.sum_needed & E1000_TXD_POPTS_TXSM) { unsigned int VAR_5; void *VAR_6 = VAR_4->data + VAR_4->props.tucso; VAR_5 = lduw_be_p(VAR_6) + len; VAR_5 = (VAR_5 >> 16) + (VAR_5 & 0xffff); stw_be_p(VAR_6, VAR_5); } VAR_4->tso_frames++; } if (VAR_4->props.sum_needed & E1000_TXD_POPTS_TXSM) { putsum(VAR_4->data, VAR_4->size, VAR_4->props.tucso,
VAR_4->props.tucss, VAR_4->props.tucse); } if (VAR_4->props.sum_needed & E1000_TXD_POPTS_IXSM) { putsum(VAR_4->data, VAR_4->size, VAR_4->props.ipcso,
VAR_4->props.ipcss, VAR_4->props.ipcse); } if (VAR_4->vlan_needed) { memmove(VAR_4->vlan, VAR_4->data, 4); memmove(VAR_4->data, VAR_4->data + 4, 8); memcpy(VAR_4->data + 8, VAR_4->vlan_header, 4); e1000_send_packet(VAR_0, VAR_4->vlan, VAR_4->size + 4); } else { e1000_send_packet(VAR_0, VAR_4->data, VAR_4->size); } e1000x_inc_reg_if_not_full(VAR_0->mac_reg, TPT); e1000x_grow_8reg_if_not_full(VAR_0->mac_reg, TOTL, VAR_0->tx.size); VAR_0->mac_reg[GPTC] = VAR_0->mac_reg[TPT]; VAR_0->mac_reg[GOTCL] = VAR_0->mac_reg[TOTL]; VAR_0->mac_reg[GOTCH] = VAR_0->mac_reg[TOTH]; }