cachepc-qemu

Fork of AMDESE/qemu with changes for cachepc side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-qemu
Log | Files | Refs | Submodules | LICENSE | sfeed.txt

pcnet.c (55664B)


      1/*
      2 * QEMU AMD PC-Net II (Am79C970A) emulation
      3 *
      4 * Copyright (c) 2004 Antony T Curtis
      5 *
      6 * Permission is hereby granted, free of charge, to any person obtaining a copy
      7 * of this software and associated documentation files (the "Software"), to deal
      8 * in the Software without restriction, including without limitation the rights
      9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
     10 * copies of the Software, and to permit persons to whom the Software is
     11 * furnished to do so, subject to the following conditions:
     12 *
     13 * The above copyright notice and this permission notice shall be included in
     14 * all copies or substantial portions of the Software.
     15 *
     16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
     19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
     21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
     22 * THE SOFTWARE.
     23 */
     24
     25/* This software was written to be compatible with the specification:
     26 * AMD Am79C970A PCnet-PCI II Ethernet Controller Data-Sheet
     27 * AMD Publication# 19436  Rev:E  Amendment/0  Issue Date: June 2000
     28 */
     29
     30/*
     31 * On Sparc32, this is the Lance (Am7990) part of chip STP2000 (Master I/O), also
     32 * produced as NCR89C100. See
     33 * http://www.ibiblio.org/pub/historic-linux/early-ports/Sparc/NCR/NCR89C100.txt
     34 * and
     35 * http://www.ibiblio.org/pub/historic-linux/early-ports/Sparc/NCR/NCR92C990.txt
     36 */
     37
     38#include "qemu/osdep.h"
     39#include "qemu/log.h"
     40#include "hw/irq.h"
     41#include "hw/qdev-properties.h"
     42#include "migration/vmstate.h"
     43#include "net/net.h"
     44#include "net/eth.h"
     45#include "qemu/timer.h"
     46#include "trace.h"
     47
     48#include "pcnet.h"
     49
     50//#define PCNET_DEBUG
     51//#define PCNET_DEBUG_IO
     52//#define PCNET_DEBUG_BCR
     53//#define PCNET_DEBUG_CSR
     54//#define PCNET_DEBUG_RMD
     55//#define PCNET_DEBUG_TMD
     56//#define PCNET_DEBUG_MATCH
     57
     58
     59struct qemu_ether_header {
     60    uint8_t ether_dhost[6];
     61    uint8_t ether_shost[6];
     62    uint16_t ether_type;
     63};
     64
     65#define CSR_INIT(S)      !!(((S)->csr[0])&0x0001)
     66#define CSR_STRT(S)      !!(((S)->csr[0])&0x0002)
     67#define CSR_STOP(S)      !!(((S)->csr[0])&0x0004)
     68#define CSR_TDMD(S)      !!(((S)->csr[0])&0x0008)
     69#define CSR_TXON(S)      !!(((S)->csr[0])&0x0010)
     70#define CSR_RXON(S)      !!(((S)->csr[0])&0x0020)
     71#define CSR_INEA(S)      !!(((S)->csr[0])&0x0040)
     72#define CSR_BSWP(S)      !!(((S)->csr[3])&0x0004)
     73#define CSR_LAPPEN(S)    !!(((S)->csr[3])&0x0020)
     74#define CSR_DXSUFLO(S)   !!(((S)->csr[3])&0x0040)
     75#define CSR_ASTRP_RCV(S) !!(((S)->csr[4])&0x0800)
     76#define CSR_DPOLL(S)     !!(((S)->csr[4])&0x1000)
     77#define CSR_SPND(S)      !!(((S)->csr[5])&0x0001)
     78#define CSR_LTINTEN(S)   !!(((S)->csr[5])&0x4000)
     79#define CSR_TOKINTD(S)   !!(((S)->csr[5])&0x8000)
     80#define CSR_DRX(S)       !!(((S)->csr[15])&0x0001)
     81#define CSR_DTX(S)       !!(((S)->csr[15])&0x0002)
     82#define CSR_LOOP(S)      !!(((S)->csr[15])&0x0004)
     83#define CSR_DXMTFCS(S)   !!(((S)->csr[15])&0x0008)
     84#define CSR_INTL(S)      !!(((S)->csr[15])&0x0040)
     85#define CSR_DRCVPA(S)    !!(((S)->csr[15])&0x2000)
     86#define CSR_DRCVBC(S)    !!(((S)->csr[15])&0x4000)
     87#define CSR_PROM(S)      !!(((S)->csr[15])&0x8000)
     88
     89#define CSR_CRBC(S)      ((S)->csr[40])
     90#define CSR_CRST(S)      ((S)->csr[41])
     91#define CSR_CXBC(S)      ((S)->csr[42])
     92#define CSR_CXST(S)      ((S)->csr[43])
     93#define CSR_NRBC(S)      ((S)->csr[44])
     94#define CSR_NRST(S)      ((S)->csr[45])
     95#define CSR_POLL(S)      ((S)->csr[46])
     96#define CSR_PINT(S)      ((S)->csr[47])
     97#define CSR_RCVRC(S)     ((S)->csr[72])
     98#define CSR_XMTRC(S)     ((S)->csr[74])
     99#define CSR_RCVRL(S)     ((S)->csr[76])
    100#define CSR_XMTRL(S)     ((S)->csr[78])
    101#define CSR_MISSC(S)     ((S)->csr[112])
    102
    103#define CSR_IADR(S)      ((S)->csr[ 1] | ((uint32_t)(S)->csr[ 2] << 16))
    104#define CSR_CRBA(S)      ((S)->csr[18] | ((uint32_t)(S)->csr[19] << 16))
    105#define CSR_CXBA(S)      ((S)->csr[20] | ((uint32_t)(S)->csr[21] << 16))
    106#define CSR_NRBA(S)      ((S)->csr[22] | ((uint32_t)(S)->csr[23] << 16))
    107#define CSR_BADR(S)      ((S)->csr[24] | ((uint32_t)(S)->csr[25] << 16))
    108#define CSR_NRDA(S)      ((S)->csr[26] | ((uint32_t)(S)->csr[27] << 16))
    109#define CSR_CRDA(S)      ((S)->csr[28] | ((uint32_t)(S)->csr[29] << 16))
    110#define CSR_BADX(S)      ((S)->csr[30] | ((uint32_t)(S)->csr[31] << 16))
    111#define CSR_NXDA(S)      ((S)->csr[32] | ((uint32_t)(S)->csr[33] << 16))
    112#define CSR_CXDA(S)      ((S)->csr[34] | ((uint32_t)(S)->csr[35] << 16))
    113#define CSR_NNRD(S)      ((S)->csr[36] | ((uint32_t)(S)->csr[37] << 16))
    114#define CSR_NNXD(S)      ((S)->csr[38] | ((uint32_t)(S)->csr[39] << 16))
    115#define CSR_PXDA(S)      ((S)->csr[60] | ((uint32_t)(S)->csr[61] << 16))
    116#define CSR_NXBA(S)      ((S)->csr[64] | ((uint32_t)(S)->csr[65] << 16))
    117
    118#define PHYSADDR(S,A) \
    119  (BCR_SSIZE32(S) ? (A) : (A) | ((0xff00 & (uint32_t)(S)->csr[2])<<16))
    120
    121struct pcnet_initblk16 {
    122    uint16_t mode;
    123    uint16_t padr[3];
    124    uint16_t ladrf[4];
    125    uint32_t rdra;
    126    uint32_t tdra;
    127};
    128
    129struct pcnet_initblk32 {
    130    uint16_t mode;
    131    uint8_t rlen;
    132    uint8_t tlen;
    133    uint16_t padr[3];
    134    uint16_t _res;
    135    uint16_t ladrf[4];
    136    uint32_t rdra;
    137    uint32_t tdra;
    138};
    139
    140struct pcnet_TMD {
    141    uint32_t tbadr;
    142    int16_t length;
    143    int16_t status;
    144    uint32_t misc;
    145    uint32_t res;
    146};
    147
    148#define TMDL_BCNT_MASK  0x0fff
    149#define TMDL_BCNT_SH    0
    150#define TMDL_ONES_MASK  0xf000
    151#define TMDL_ONES_SH    12
    152
    153#define TMDS_BPE_MASK   0x0080
    154#define TMDS_BPE_SH     7
    155#define TMDS_ENP_MASK   0x0100
    156#define TMDS_ENP_SH     8
    157#define TMDS_STP_MASK   0x0200
    158#define TMDS_STP_SH     9
    159#define TMDS_DEF_MASK   0x0400
    160#define TMDS_DEF_SH     10
    161#define TMDS_ONE_MASK   0x0800
    162#define TMDS_ONE_SH     11
    163#define TMDS_LTINT_MASK 0x1000
    164#define TMDS_LTINT_SH   12
    165#define TMDS_NOFCS_MASK 0x2000
    166#define TMDS_NOFCS_SH   13
    167#define TMDS_ADDFCS_MASK TMDS_NOFCS_MASK
    168#define TMDS_ADDFCS_SH  TMDS_NOFCS_SH
    169#define TMDS_ERR_MASK   0x4000
    170#define TMDS_ERR_SH     14
    171#define TMDS_OWN_MASK   0x8000
    172#define TMDS_OWN_SH     15
    173
    174#define TMDM_TRC_MASK   0x0000000f
    175#define TMDM_TRC_SH     0
    176#define TMDM_TDR_MASK   0x03ff0000
    177#define TMDM_TDR_SH     16
    178#define TMDM_RTRY_MASK  0x04000000
    179#define TMDM_RTRY_SH    26
    180#define TMDM_LCAR_MASK  0x08000000
    181#define TMDM_LCAR_SH    27
    182#define TMDM_LCOL_MASK  0x10000000
    183#define TMDM_LCOL_SH    28
    184#define TMDM_EXDEF_MASK 0x20000000
    185#define TMDM_EXDEF_SH   29
    186#define TMDM_UFLO_MASK  0x40000000
    187#define TMDM_UFLO_SH    30
    188#define TMDM_BUFF_MASK  0x80000000
    189#define TMDM_BUFF_SH    31
    190
    191struct pcnet_RMD {
    192    uint32_t rbadr;
    193    int16_t buf_length;
    194    int16_t status;
    195    uint32_t msg_length;
    196    uint32_t res;
    197};
    198
    199#define RMDL_BCNT_MASK  0x0fff
    200#define RMDL_BCNT_SH    0
    201#define RMDL_ONES_MASK  0xf000
    202#define RMDL_ONES_SH    12
    203
    204#define RMDS_BAM_MASK   0x0010
    205#define RMDS_BAM_SH     4
    206#define RMDS_LFAM_MASK  0x0020
    207#define RMDS_LFAM_SH    5
    208#define RMDS_PAM_MASK   0x0040
    209#define RMDS_PAM_SH     6
    210#define RMDS_BPE_MASK   0x0080
    211#define RMDS_BPE_SH     7
    212#define RMDS_ENP_MASK   0x0100
    213#define RMDS_ENP_SH     8
    214#define RMDS_STP_MASK   0x0200
    215#define RMDS_STP_SH     9
    216#define RMDS_BUFF_MASK  0x0400
    217#define RMDS_BUFF_SH    10
    218#define RMDS_CRC_MASK   0x0800
    219#define RMDS_CRC_SH     11
    220#define RMDS_OFLO_MASK  0x1000
    221#define RMDS_OFLO_SH    12
    222#define RMDS_FRAM_MASK  0x2000
    223#define RMDS_FRAM_SH    13
    224#define RMDS_ERR_MASK   0x4000
    225#define RMDS_ERR_SH     14
    226#define RMDS_OWN_MASK   0x8000
    227#define RMDS_OWN_SH     15
    228
    229#define RMDM_MCNT_MASK  0x00000fff
    230#define RMDM_MCNT_SH    0
    231#define RMDM_ZEROS_MASK 0x0000f000
    232#define RMDM_ZEROS_SH   12
    233#define RMDM_RPC_MASK   0x00ff0000
    234#define RMDM_RPC_SH     16
    235#define RMDM_RCC_MASK   0xff000000
    236#define RMDM_RCC_SH     24
    237
    238#define SET_FIELD(regp, name, field, value)             \
    239  (*(regp) = (*(regp) & ~(name ## _ ## field ## _MASK)) \
    240             | ((value) << name ## _ ## field ## _SH))
    241
    242#define GET_FIELD(reg, name, field)                     \
    243  (((reg) & name ## _ ## field ## _MASK) >> name ## _ ## field ## _SH)
    244
    245#define PRINT_TMD(T) printf(                            \
    246        "TMD0 : TBADR=0x%08x\n"                         \
    247        "TMD1 : OWN=%d, ERR=%d, FCS=%d, LTI=%d, "       \
    248        "ONE=%d, DEF=%d, STP=%d, ENP=%d,\n"             \
    249        "       BPE=%d, BCNT=%d\n"                      \
    250        "TMD2 : BUF=%d, UFL=%d, EXD=%d, LCO=%d, "       \
    251        "LCA=%d, RTR=%d,\n"                             \
    252        "       TDR=%d, TRC=%d\n",                      \
    253        (T)->tbadr,                                     \
    254        GET_FIELD((T)->status, TMDS, OWN),              \
    255        GET_FIELD((T)->status, TMDS, ERR),              \
    256        GET_FIELD((T)->status, TMDS, NOFCS),            \
    257        GET_FIELD((T)->status, TMDS, LTINT),            \
    258        GET_FIELD((T)->status, TMDS, ONE),              \
    259        GET_FIELD((T)->status, TMDS, DEF),              \
    260        GET_FIELD((T)->status, TMDS, STP),              \
    261        GET_FIELD((T)->status, TMDS, ENP),              \
    262        GET_FIELD((T)->status, TMDS, BPE),              \
    263        4096-GET_FIELD((T)->length, TMDL, BCNT),        \
    264        GET_FIELD((T)->misc, TMDM, BUFF),               \
    265        GET_FIELD((T)->misc, TMDM, UFLO),               \
    266        GET_FIELD((T)->misc, TMDM, EXDEF),              \
    267        GET_FIELD((T)->misc, TMDM, LCOL),               \
    268        GET_FIELD((T)->misc, TMDM, LCAR),               \
    269        GET_FIELD((T)->misc, TMDM, RTRY),               \
    270        GET_FIELD((T)->misc, TMDM, TDR),                \
    271        GET_FIELD((T)->misc, TMDM, TRC))
    272
    273#define PRINT_RMD(R) printf(                            \
    274        "RMD0 : RBADR=0x%08x\n"                         \
    275        "RMD1 : OWN=%d, ERR=%d, FRAM=%d, OFLO=%d, "     \
    276        "CRC=%d, BUFF=%d, STP=%d, ENP=%d,\n       "     \
    277        "BPE=%d, PAM=%d, LAFM=%d, BAM=%d, ONES=%d, BCNT=%d\n" \
    278        "RMD2 : RCC=%d, RPC=%d, MCNT=%d, ZEROS=%d\n",   \
    279        (R)->rbadr,                                     \
    280        GET_FIELD((R)->status, RMDS, OWN),              \
    281        GET_FIELD((R)->status, RMDS, ERR),              \
    282        GET_FIELD((R)->status, RMDS, FRAM),             \
    283        GET_FIELD((R)->status, RMDS, OFLO),             \
    284        GET_FIELD((R)->status, RMDS, CRC),              \
    285        GET_FIELD((R)->status, RMDS, BUFF),             \
    286        GET_FIELD((R)->status, RMDS, STP),              \
    287        GET_FIELD((R)->status, RMDS, ENP),              \
    288        GET_FIELD((R)->status, RMDS, BPE),              \
    289        GET_FIELD((R)->status, RMDS, PAM),              \
    290        GET_FIELD((R)->status, RMDS, LFAM),             \
    291        GET_FIELD((R)->status, RMDS, BAM),              \
    292        GET_FIELD((R)->buf_length, RMDL, ONES),         \
    293        4096-GET_FIELD((R)->buf_length, RMDL, BCNT),    \
    294        GET_FIELD((R)->msg_length, RMDM, RCC),          \
    295        GET_FIELD((R)->msg_length, RMDM, RPC),          \
    296        GET_FIELD((R)->msg_length, RMDM, MCNT),         \
    297        GET_FIELD((R)->msg_length, RMDM, ZEROS))
    298
    299static inline void pcnet_tmd_load(PCNetState *s, struct pcnet_TMD *tmd,
    300                                  hwaddr addr)
    301{
    302    if (!BCR_SSIZE32(s)) {
    303        struct {
    304            uint32_t tbadr;
    305            int16_t length;
    306            int16_t status;
    307        } xda;
    308        s->phys_mem_read(s->dma_opaque, addr, (void *)&xda, sizeof(xda), 0);
    309        tmd->tbadr = le32_to_cpu(xda.tbadr) & 0xffffff;
    310        tmd->length = le16_to_cpu(xda.length);
    311        tmd->status = (le32_to_cpu(xda.tbadr) >> 16) & 0xff00;
    312        tmd->misc = le16_to_cpu(xda.status) << 16;
    313        tmd->res = 0;
    314    } else {
    315        s->phys_mem_read(s->dma_opaque, addr, (void *)tmd, sizeof(*tmd), 0);
    316        le32_to_cpus(&tmd->tbadr);
    317        le16_to_cpus((uint16_t *)&tmd->length);
    318        le16_to_cpus((uint16_t *)&tmd->status);
    319        le32_to_cpus(&tmd->misc);
    320        le32_to_cpus(&tmd->res);
    321        if (BCR_SWSTYLE(s) == 3) {
    322            uint32_t tmp = tmd->tbadr;
    323            tmd->tbadr = tmd->misc;
    324            tmd->misc = tmp;
    325        }
    326    }
    327}
    328
    329static inline void pcnet_tmd_store(PCNetState *s, const struct pcnet_TMD *tmd,
    330                                   hwaddr addr)
    331{
    332    if (!BCR_SSIZE32(s)) {
    333        struct {
    334            uint32_t tbadr;
    335            int16_t length;
    336            int16_t status;
    337        } xda;
    338        xda.tbadr = cpu_to_le32((tmd->tbadr & 0xffffff) |
    339                                ((tmd->status & 0xff00) << 16));
    340        xda.length = cpu_to_le16(tmd->length);
    341        xda.status = cpu_to_le16(tmd->misc >> 16);
    342        s->phys_mem_write(s->dma_opaque, addr, (void *)&xda, sizeof(xda), 0);
    343    } else {
    344        struct {
    345            uint32_t tbadr;
    346            int16_t length;
    347            int16_t status;
    348            uint32_t misc;
    349            uint32_t res;
    350        } xda;
    351        xda.tbadr = cpu_to_le32(tmd->tbadr);
    352        xda.length = cpu_to_le16(tmd->length);
    353        xda.status = cpu_to_le16(tmd->status);
    354        xda.misc = cpu_to_le32(tmd->misc);
    355        xda.res = cpu_to_le32(tmd->res);
    356        if (BCR_SWSTYLE(s) == 3) {
    357            uint32_t tmp = xda.tbadr;
    358            xda.tbadr = xda.misc;
    359            xda.misc = tmp;
    360        }
    361        s->phys_mem_write(s->dma_opaque, addr, (void *)&xda, sizeof(xda), 0);
    362    }
    363}
    364
    365static inline void pcnet_rmd_load(PCNetState *s, struct pcnet_RMD *rmd,
    366                                  hwaddr addr)
    367{
    368    if (!BCR_SSIZE32(s)) {
    369        struct {
    370            uint32_t rbadr;
    371            int16_t buf_length;
    372            int16_t msg_length;
    373	} rda;
    374        s->phys_mem_read(s->dma_opaque, addr, (void *)&rda, sizeof(rda), 0);
    375        rmd->rbadr = le32_to_cpu(rda.rbadr) & 0xffffff;
    376        rmd->buf_length = le16_to_cpu(rda.buf_length);
    377        rmd->status = (le32_to_cpu(rda.rbadr) >> 16) & 0xff00;
    378        rmd->msg_length = le16_to_cpu(rda.msg_length);
    379        rmd->res = 0;
    380    } else {
    381        s->phys_mem_read(s->dma_opaque, addr, (void *)rmd, sizeof(*rmd), 0);
    382        le32_to_cpus(&rmd->rbadr);
    383        le16_to_cpus((uint16_t *)&rmd->buf_length);
    384        le16_to_cpus((uint16_t *)&rmd->status);
    385        le32_to_cpus(&rmd->msg_length);
    386        le32_to_cpus(&rmd->res);
    387        if (BCR_SWSTYLE(s) == 3) {
    388            uint32_t tmp = rmd->rbadr;
    389            rmd->rbadr = rmd->msg_length;
    390            rmd->msg_length = tmp;
    391        }
    392    }
    393}
    394
    395static inline void pcnet_rmd_store(PCNetState *s, struct pcnet_RMD *rmd,
    396                                   hwaddr addr)
    397{
    398    if (!BCR_SSIZE32(s)) {
    399        struct {
    400            uint32_t rbadr;
    401            int16_t buf_length;
    402            int16_t msg_length;
    403        } rda;
    404        rda.rbadr = cpu_to_le32((rmd->rbadr & 0xffffff) |
    405                                ((rmd->status & 0xff00) << 16));
    406        rda.buf_length = cpu_to_le16(rmd->buf_length);
    407        rda.msg_length = cpu_to_le16(rmd->msg_length);
    408        s->phys_mem_write(s->dma_opaque, addr, (void *)&rda, sizeof(rda), 0);
    409    } else {
    410        struct {
    411            uint32_t rbadr;
    412            int16_t buf_length;
    413            int16_t status;
    414            uint32_t msg_length;
    415            uint32_t res;
    416        } rda;
    417        rda.rbadr = cpu_to_le32(rmd->rbadr);
    418        rda.buf_length = cpu_to_le16(rmd->buf_length);
    419        rda.status = cpu_to_le16(rmd->status);
    420        rda.msg_length = cpu_to_le32(rmd->msg_length);
    421        rda.res = cpu_to_le32(rmd->res);
    422        if (BCR_SWSTYLE(s) == 3) {
    423            uint32_t tmp = rda.rbadr;
    424            rda.rbadr = rda.msg_length;
    425            rda.msg_length = tmp;
    426        }
    427        s->phys_mem_write(s->dma_opaque, addr, (void *)&rda, sizeof(rda), 0);
    428    }
    429}
    430
    431
    432#define TMDLOAD(TMD,ADDR) pcnet_tmd_load(s,TMD,ADDR)
    433
    434#define TMDSTORE(TMD,ADDR) pcnet_tmd_store(s,TMD,ADDR)
    435
    436#define RMDLOAD(RMD,ADDR) pcnet_rmd_load(s,RMD,ADDR)
    437
    438#define RMDSTORE(RMD,ADDR) pcnet_rmd_store(s,RMD,ADDR)
    439
    440#if 1
    441
    442#define CHECK_RMD(ADDR,RES) do {                \
    443    struct pcnet_RMD rmd;                       \
    444    RMDLOAD(&rmd,(ADDR));                       \
    445    (RES) |= (GET_FIELD(rmd.buf_length, RMDL, ONES) != 15) \
    446          || (GET_FIELD(rmd.msg_length, RMDM, ZEROS) != 0); \
    447} while (0)
    448
    449#define CHECK_TMD(ADDR,RES) do {                \
    450    struct pcnet_TMD tmd;                       \
    451    TMDLOAD(&tmd,(ADDR));                       \
    452    (RES) |= (GET_FIELD(tmd.length, TMDL, ONES) != 15); \
    453} while (0)
    454
    455#else
    456
    457#define CHECK_RMD(ADDR,RES) do {                \
    458    switch (BCR_SWSTYLE(s)) {                   \
    459    case 0x00:                                  \
    460        {                                       \
    461            uint16_t rda[4];                    \
    462            s->phys_mem_read(s->dma_opaque, (ADDR), \
    463                (void *)&rda[0], sizeof(rda), 0); \
    464            (RES) |= (rda[2] & 0xf000)!=0xf000; \
    465            (RES) |= (rda[3] & 0xf000)!=0x0000; \
    466        }                                       \
    467        break;                                  \
    468    case 0x01:                                  \
    469    case 0x02:                                  \
    470        {                                       \
    471            uint32_t rda[4];                    \
    472            s->phys_mem_read(s->dma_opaque, (ADDR), \
    473                (void *)&rda[0], sizeof(rda), 0); \
    474            (RES) |= (rda[1] & 0x0000f000L)!=0x0000f000L; \
    475            (RES) |= (rda[2] & 0x0000f000L)!=0x00000000L; \
    476        }                                       \
    477        break;                                  \
    478    case 0x03:                                  \
    479        {                                       \
    480            uint32_t rda[4];                    \
    481            s->phys_mem_read(s->dma_opaque, (ADDR), \
    482                (void *)&rda[0], sizeof(rda), 0); \
    483            (RES) |= (rda[0] & 0x0000f000L)!=0x00000000L; \
    484            (RES) |= (rda[1] & 0x0000f000L)!=0x0000f000L; \
    485        }                                       \
    486        break;                                  \
    487    }                                           \
    488} while (0)
    489
    490#define CHECK_TMD(ADDR,RES) do {                \
    491    switch (BCR_SWSTYLE(s)) {                   \
    492    case 0x00:                                  \
    493        {                                       \
    494            uint16_t xda[4];                    \
    495            s->phys_mem_read(s->dma_opaque, (ADDR), \
    496                (void *)&xda[0], sizeof(xda), 0); \
    497            (RES) |= (xda[2] & 0xf000)!=0xf000; \
    498        }                                       \
    499        break;                                  \
    500    case 0x01:                                  \
    501    case 0x02:                                  \
    502    case 0x03:                                  \
    503        {                                       \
    504            uint32_t xda[4];                    \
    505            s->phys_mem_read(s->dma_opaque, (ADDR), \
    506                (void *)&xda[0], sizeof(xda), 0); \
    507            (RES) |= (xda[1] & 0x0000f000L)!=0x0000f000L; \
    508        }                                       \
    509        break;                                  \
    510    }                                           \
    511} while (0)
    512
    513#endif
    514
    515#define PRINT_PKTHDR(BUF) do {                  \
    516    struct qemu_ether_header *hdr = (void *)(BUF); \
    517    printf("packet dhost=%02x:%02x:%02x:%02x:%02x:%02x, " \
    518           "shost=%02x:%02x:%02x:%02x:%02x:%02x, " \
    519           "type=0x%04x\n",                     \
    520           hdr->ether_dhost[0],hdr->ether_dhost[1],hdr->ether_dhost[2], \
    521           hdr->ether_dhost[3],hdr->ether_dhost[4],hdr->ether_dhost[5], \
    522           hdr->ether_shost[0],hdr->ether_shost[1],hdr->ether_shost[2], \
    523           hdr->ether_shost[3],hdr->ether_shost[4],hdr->ether_shost[5], \
    524           be16_to_cpu(hdr->ether_type));       \
    525} while (0)
    526
    527#define CRC(crc, ch)	 (crc = (crc >> 8) ^ crctab[(crc ^ (ch)) & 0xff])
    528
    529/* generated using the AUTODIN II polynomial
    530 *	x^32 + x^26 + x^23 + x^22 + x^16 +
    531 *	x^12 + x^11 + x^10 + x^8 + x^7 + x^5 + x^4 + x^2 + x^1 + 1
    532 */
    533static const uint32_t crctab[256] = {
    534	0x00000000, 0x77073096, 0xee0e612c, 0x990951ba,
    535	0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3,
    536	0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
    537	0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91,
    538	0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
    539	0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
    540	0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec,
    541	0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5,
    542	0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
    543	0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
    544	0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940,
    545	0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
    546	0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116,
    547	0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f,
    548	0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
    549	0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d,
    550	0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a,
    551	0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
    552	0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818,
    553	0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
    554	0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
    555	0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457,
    556	0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c,
    557	0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
    558	0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
    559	0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb,
    560	0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
    561	0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9,
    562	0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086,
    563	0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
    564	0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4,
    565	0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad,
    566	0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
    567	0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683,
    568	0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
    569	0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
    570	0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe,
    571	0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7,
    572	0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
    573	0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
    574	0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252,
    575	0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
    576	0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60,
    577	0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79,
    578	0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
    579	0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f,
    580	0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04,
    581	0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
    582	0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a,
    583	0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
    584	0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
    585	0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21,
    586	0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e,
    587	0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
    588	0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
    589	0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45,
    590	0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
    591	0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db,
    592	0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0,
    593	0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
    594	0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6,
    595	0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf,
    596	0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
    597	0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d,
    598};
    599
    600static inline int padr_match(PCNetState *s, const uint8_t *buf, int size)
    601{
    602    struct qemu_ether_header *hdr = (void *)buf;
    603    uint8_t padr[6] = {
    604        s->csr[12] & 0xff, s->csr[12] >> 8,
    605        s->csr[13] & 0xff, s->csr[13] >> 8,
    606        s->csr[14] & 0xff, s->csr[14] >> 8
    607    };
    608    int result = (!CSR_DRCVPA(s)) && !memcmp(hdr->ether_dhost, padr, 6);
    609#ifdef PCNET_DEBUG_MATCH
    610    printf("packet dhost=%02x:%02x:%02x:%02x:%02x:%02x, "
    611           "padr=%02x:%02x:%02x:%02x:%02x:%02x\n",
    612           hdr->ether_dhost[0],hdr->ether_dhost[1],hdr->ether_dhost[2],
    613           hdr->ether_dhost[3],hdr->ether_dhost[4],hdr->ether_dhost[5],
    614           padr[0],padr[1],padr[2],padr[3],padr[4],padr[5]);
    615    printf("padr_match result=%d\n", result);
    616#endif
    617    return result;
    618}
    619
    620static inline int padr_bcast(PCNetState *s, const uint8_t *buf, int size)
    621{
    622    static const uint8_t BCAST[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
    623    struct qemu_ether_header *hdr = (void *)buf;
    624    int result = !CSR_DRCVBC(s) && !memcmp(hdr->ether_dhost, BCAST, 6);
    625#ifdef PCNET_DEBUG_MATCH
    626    printf("padr_bcast result=%d\n", result);
    627#endif
    628    return result;
    629}
    630
    631static inline int ladr_match(PCNetState *s, const uint8_t *buf, int size)
    632{
    633    struct qemu_ether_header *hdr = (void *)buf;
    634    if ((*(hdr->ether_dhost)&0x01) &&
    635        ((uint64_t *)&s->csr[8])[0] != 0LL) {
    636        uint8_t ladr[8] = {
    637            s->csr[8] & 0xff, s->csr[8] >> 8,
    638            s->csr[9] & 0xff, s->csr[9] >> 8,
    639            s->csr[10] & 0xff, s->csr[10] >> 8,
    640            s->csr[11] & 0xff, s->csr[11] >> 8
    641        };
    642        int index = net_crc32_le(hdr->ether_dhost, ETH_ALEN) >> 26;
    643        return !!(ladr[index >> 3] & (1 << (index & 7)));
    644    }
    645    return 0;
    646}
    647
    648static inline hwaddr pcnet_rdra_addr(PCNetState *s, int idx)
    649{
    650    while (idx < 1) {
    651        idx += CSR_RCVRL(s);
    652    }
    653    return s->rdra + ((CSR_RCVRL(s) - idx) * (BCR_SWSTYLE(s) ? 16 : 8));
    654}
    655
    656static inline int64_t pcnet_get_next_poll_time(PCNetState *s, int64_t current_time)
    657{
    658    int64_t next_time = current_time +
    659                        (65536 - (CSR_SPND(s) ? 0 : CSR_POLL(s))) * 30;
    660
    661    if (next_time <= current_time) {
    662        next_time = current_time + 1;
    663    }
    664    return next_time;
    665}
    666
    667static void pcnet_poll(PCNetState *s);
    668static void pcnet_poll_timer(void *opaque);
    669
    670static uint32_t pcnet_csr_readw(PCNetState *s, uint32_t rap);
    671static void pcnet_csr_writew(PCNetState *s, uint32_t rap, uint32_t new_value);
    672static void pcnet_bcr_writew(PCNetState *s, uint32_t rap, uint32_t val);
    673
    674static void pcnet_s_reset(PCNetState *s)
    675{
    676    trace_pcnet_s_reset(s);
    677
    678    s->rdra = 0;
    679    s->tdra = 0;
    680    s->rap = 0;
    681
    682    s->bcr[BCR_BSBC] &= ~0x0080;
    683
    684    s->csr[0]   = 0x0004;
    685    s->csr[3]   = 0x0000;
    686    s->csr[4]   = 0x0115;
    687    s->csr[5]   = 0x0000;
    688    s->csr[6]   = 0x0000;
    689    s->csr[8]   = 0;
    690    s->csr[9]   = 0;
    691    s->csr[10]  = 0;
    692    s->csr[11]  = 0;
    693    s->csr[12]  = le16_to_cpu(((uint16_t *)&s->prom[0])[0]);
    694    s->csr[13]  = le16_to_cpu(((uint16_t *)&s->prom[0])[1]);
    695    s->csr[14]  = le16_to_cpu(((uint16_t *)&s->prom[0])[2]);
    696    s->csr[15] &= 0x21c4;
    697    s->csr[72]  = 1;
    698    s->csr[74]  = 1;
    699    s->csr[76]  = 1;
    700    s->csr[78]  = 1;
    701    s->csr[80]  = 0x1410;
    702    s->csr[88]  = 0x1003;
    703    s->csr[89]  = 0x0262;
    704    s->csr[94]  = 0x0000;
    705    s->csr[100] = 0x0200;
    706    s->csr[103] = 0x0105;
    707    s->csr[112] = 0x0000;
    708    s->csr[114] = 0x0000;
    709    s->csr[122] = 0x0000;
    710    s->csr[124] = 0x0000;
    711
    712    s->tx_busy = 0;
    713}
    714
    715static void pcnet_update_irq(PCNetState *s)
    716{
    717    int isr = 0;
    718    s->csr[0] &= ~0x0080;
    719
    720#if 1
    721    if (((s->csr[0] & ~s->csr[3]) & 0x5f00) ||
    722        (((s->csr[4]>>1) & ~s->csr[4]) & 0x0115) ||
    723        (((s->csr[5]>>1) & s->csr[5]) & 0x0048))
    724#else
    725    if ((!(s->csr[3] & 0x4000) && !!(s->csr[0] & 0x4000)) /* BABL */ ||
    726        (!(s->csr[3] & 0x1000) && !!(s->csr[0] & 0x1000)) /* MISS */ ||
    727        (!(s->csr[3] & 0x0100) && !!(s->csr[0] & 0x0100)) /* IDON */ ||
    728        (!(s->csr[3] & 0x0200) && !!(s->csr[0] & 0x0200)) /* TINT */ ||
    729        (!(s->csr[3] & 0x0400) && !!(s->csr[0] & 0x0400)) /* RINT */ ||
    730        (!(s->csr[3] & 0x0800) && !!(s->csr[0] & 0x0800)) /* MERR */ ||
    731        (!(s->csr[4] & 0x0001) && !!(s->csr[4] & 0x0002)) /* JAB */ ||
    732        (!(s->csr[4] & 0x0004) && !!(s->csr[4] & 0x0008)) /* TXSTRT */ ||
    733        (!(s->csr[4] & 0x0010) && !!(s->csr[4] & 0x0020)) /* RCVO */ ||
    734        (!(s->csr[4] & 0x0100) && !!(s->csr[4] & 0x0200)) /* MFCO */ ||
    735        (!!(s->csr[5] & 0x0040) && !!(s->csr[5] & 0x0080)) /* EXDINT */ ||
    736        (!!(s->csr[5] & 0x0008) && !!(s->csr[5] & 0x0010)) /* MPINT */)
    737#endif
    738    {
    739
    740        isr = CSR_INEA(s);
    741        s->csr[0] |= 0x0080;
    742    }
    743
    744    if (!!(s->csr[4] & 0x0080) && CSR_INEA(s)) { /* UINT */
    745        s->csr[4] &= ~0x0080;
    746        s->csr[4] |= 0x0040;
    747        s->csr[0] |= 0x0080;
    748        isr = 1;
    749        trace_pcnet_user_int(s);
    750    }
    751
    752#if 1
    753    if (((s->csr[5]>>1) & s->csr[5]) & 0x0500)
    754#else
    755    if ((!!(s->csr[5] & 0x0400) && !!(s->csr[5] & 0x0800)) /* SINT */ ||
    756        (!!(s->csr[5] & 0x0100) && !!(s->csr[5] & 0x0200)) /* SLPINT */ )
    757#endif
    758    {
    759        isr = 1;
    760        s->csr[0] |= 0x0080;
    761    }
    762
    763    if (isr != s->isr) {
    764        trace_pcnet_isr_change(s, isr, s->isr);
    765    }
    766    qemu_set_irq(s->irq, isr);
    767    s->isr = isr;
    768}
    769
    770static void pcnet_init(PCNetState *s)
    771{
    772    int rlen, tlen;
    773    uint16_t padr[3], ladrf[4], mode;
    774    uint32_t rdra, tdra;
    775
    776    trace_pcnet_init(s, PHYSADDR(s, CSR_IADR(s)));
    777
    778    if (BCR_SSIZE32(s)) {
    779        struct pcnet_initblk32 initblk;
    780        s->phys_mem_read(s->dma_opaque, PHYSADDR(s,CSR_IADR(s)),
    781                (uint8_t *)&initblk, sizeof(initblk), 0);
    782        mode = le16_to_cpu(initblk.mode);
    783        rlen = initblk.rlen >> 4;
    784        tlen = initblk.tlen >> 4;
    785        ladrf[0] = le16_to_cpu(initblk.ladrf[0]);
    786        ladrf[1] = le16_to_cpu(initblk.ladrf[1]);
    787        ladrf[2] = le16_to_cpu(initblk.ladrf[2]);
    788        ladrf[3] = le16_to_cpu(initblk.ladrf[3]);
    789        padr[0] = le16_to_cpu(initblk.padr[0]);
    790        padr[1] = le16_to_cpu(initblk.padr[1]);
    791        padr[2] = le16_to_cpu(initblk.padr[2]);
    792        rdra = le32_to_cpu(initblk.rdra);
    793        tdra = le32_to_cpu(initblk.tdra);
    794    } else {
    795        struct pcnet_initblk16 initblk;
    796        s->phys_mem_read(s->dma_opaque, PHYSADDR(s,CSR_IADR(s)),
    797                (uint8_t *)&initblk, sizeof(initblk), 0);
    798        mode = le16_to_cpu(initblk.mode);
    799        ladrf[0] = le16_to_cpu(initblk.ladrf[0]);
    800        ladrf[1] = le16_to_cpu(initblk.ladrf[1]);
    801        ladrf[2] = le16_to_cpu(initblk.ladrf[2]);
    802        ladrf[3] = le16_to_cpu(initblk.ladrf[3]);
    803        padr[0] = le16_to_cpu(initblk.padr[0]);
    804        padr[1] = le16_to_cpu(initblk.padr[1]);
    805        padr[2] = le16_to_cpu(initblk.padr[2]);
    806        rdra = le32_to_cpu(initblk.rdra);
    807        tdra = le32_to_cpu(initblk.tdra);
    808        rlen = rdra >> 29;
    809        tlen = tdra >> 29;
    810        rdra &= 0x00ffffff;
    811        tdra &= 0x00ffffff;
    812    }
    813
    814    trace_pcnet_rlen_tlen(s, rlen, tlen);
    815
    816    CSR_RCVRL(s) = (rlen < 9) ? (1 << rlen) : 512;
    817    CSR_XMTRL(s) = (tlen < 9) ? (1 << tlen) : 512;
    818    s->csr[ 6] = (tlen << 12) | (rlen << 8);
    819    s->csr[15] = mode;
    820    s->csr[ 8] = ladrf[0];
    821    s->csr[ 9] = ladrf[1];
    822    s->csr[10] = ladrf[2];
    823    s->csr[11] = ladrf[3];
    824    s->csr[12] = padr[0];
    825    s->csr[13] = padr[1];
    826    s->csr[14] = padr[2];
    827    s->rdra = PHYSADDR(s, rdra);
    828    s->tdra = PHYSADDR(s, tdra);
    829
    830    CSR_RCVRC(s) = CSR_RCVRL(s);
    831    CSR_XMTRC(s) = CSR_XMTRL(s);
    832
    833    trace_pcnet_ss32_rdra_tdra(s, BCR_SSIZE32(s),
    834                               s->rdra, CSR_RCVRL(s), s->tdra, CSR_XMTRL(s));
    835
    836    s->csr[0] |= 0x0101;
    837    s->csr[0] &= ~0x0004;       /* clear STOP bit */
    838
    839    qemu_flush_queued_packets(qemu_get_queue(s->nic));
    840}
    841
    842static void pcnet_start(PCNetState *s)
    843{
    844#ifdef PCNET_DEBUG
    845    printf("pcnet_start\n");
    846#endif
    847
    848    if (!CSR_DTX(s)) {
    849        s->csr[0] |= 0x0010;    /* set TXON */
    850    }
    851    if (!CSR_DRX(s)) {
    852        s->csr[0] |= 0x0020;    /* set RXON */
    853    }
    854    s->csr[0] &= ~0x0004;       /* clear STOP bit */
    855    s->csr[0] |= 0x0002;
    856    pcnet_poll_timer(s);
    857
    858    qemu_flush_queued_packets(qemu_get_queue(s->nic));
    859}
    860
    861static void pcnet_stop(PCNetState *s)
    862{
    863#ifdef PCNET_DEBUG
    864    printf("pcnet_stop\n");
    865#endif
    866    s->csr[0] &= ~0xffeb;
    867    s->csr[0] |= 0x0014;
    868    s->csr[4] &= ~0x02c2;
    869    s->csr[5] &= ~0x0011;
    870    pcnet_poll_timer(s);
    871}
    872
    873static void pcnet_rdte_poll(PCNetState *s)
    874{
    875    s->csr[28] = s->csr[29] = 0;
    876    if (s->rdra) {
    877        int bad = 0;
    878#if 1
    879        hwaddr crda = pcnet_rdra_addr(s, CSR_RCVRC(s));
    880        hwaddr nrda = pcnet_rdra_addr(s, -1 + CSR_RCVRC(s));
    881        hwaddr nnrd = pcnet_rdra_addr(s, -2 + CSR_RCVRC(s));
    882#else
    883        hwaddr crda = s->rdra +
    884            (CSR_RCVRL(s) - CSR_RCVRC(s)) *
    885            (BCR_SWSTYLE(s) ? 16 : 8 );
    886        int nrdc = CSR_RCVRC(s)<=1 ? CSR_RCVRL(s) : CSR_RCVRC(s)-1;
    887        hwaddr nrda = s->rdra +
    888            (CSR_RCVRL(s) - nrdc) *
    889            (BCR_SWSTYLE(s) ? 16 : 8 );
    890        int nnrc = nrdc<=1 ? CSR_RCVRL(s) : nrdc-1;
    891        hwaddr nnrd = s->rdra +
    892            (CSR_RCVRL(s) - nnrc) *
    893            (BCR_SWSTYLE(s) ? 16 : 8 );
    894#endif
    895
    896        CHECK_RMD(crda, bad);
    897        if (!bad) {
    898            CHECK_RMD(nrda, bad);
    899            if (bad || (nrda == crda)) nrda = 0;
    900            CHECK_RMD(nnrd, bad);
    901            if (bad || (nnrd == crda)) nnrd = 0;
    902
    903            s->csr[28] = crda & 0xffff;
    904            s->csr[29] = crda >> 16;
    905            s->csr[26] = nrda & 0xffff;
    906            s->csr[27] = nrda >> 16;
    907            s->csr[36] = nnrd & 0xffff;
    908            s->csr[37] = nnrd >> 16;
    909#ifdef PCNET_DEBUG
    910            if (bad) {
    911                printf("pcnet: BAD RMD RECORDS AFTER 0x" TARGET_FMT_plx "\n",
    912                       crda);
    913            }
    914        } else {
    915            printf("pcnet: BAD RMD RDA=0x" TARGET_FMT_plx "\n", crda);
    916#endif
    917        }
    918    }
    919
    920    if (CSR_CRDA(s)) {
    921        struct pcnet_RMD rmd;
    922        RMDLOAD(&rmd, PHYSADDR(s,CSR_CRDA(s)));
    923        CSR_CRBC(s) = GET_FIELD(rmd.buf_length, RMDL, BCNT);
    924        CSR_CRST(s) = rmd.status;
    925#ifdef PCNET_DEBUG_RMD_X
    926        printf("CRDA=0x%08x CRST=0x%04x RCVRC=%d RMDL=0x%04x RMDS=0x%04x RMDM=0x%08x\n",
    927                PHYSADDR(s,CSR_CRDA(s)), CSR_CRST(s), CSR_RCVRC(s),
    928                rmd.buf_length, rmd.status, rmd.msg_length);
    929        PRINT_RMD(&rmd);
    930#endif
    931    } else {
    932        CSR_CRBC(s) = CSR_CRST(s) = 0;
    933    }
    934
    935    if (CSR_NRDA(s)) {
    936        struct pcnet_RMD rmd;
    937        RMDLOAD(&rmd, PHYSADDR(s,CSR_NRDA(s)));
    938        CSR_NRBC(s) = GET_FIELD(rmd.buf_length, RMDL, BCNT);
    939        CSR_NRST(s) = rmd.status;
    940    } else {
    941        CSR_NRBC(s) = CSR_NRST(s) = 0;
    942    }
    943
    944}
    945
    946static int pcnet_tdte_poll(PCNetState *s)
    947{
    948    s->csr[34] = s->csr[35] = 0;
    949    if (s->tdra) {
    950        hwaddr cxda = s->tdra +
    951            (CSR_XMTRL(s) - CSR_XMTRC(s)) *
    952            (BCR_SWSTYLE(s) ? 16 : 8);
    953        int bad = 0;
    954        CHECK_TMD(cxda, bad);
    955        if (!bad) {
    956            if (CSR_CXDA(s) != cxda) {
    957                s->csr[60] = s->csr[34];
    958                s->csr[61] = s->csr[35];
    959                s->csr[62] = CSR_CXBC(s);
    960                s->csr[63] = CSR_CXST(s);
    961            }
    962            s->csr[34] = cxda & 0xffff;
    963            s->csr[35] = cxda >> 16;
    964#ifdef PCNET_DEBUG_X
    965            printf("pcnet: BAD TMD XDA=0x%08x\n", cxda);
    966#endif
    967        }
    968    }
    969
    970    if (CSR_CXDA(s)) {
    971        struct pcnet_TMD tmd;
    972
    973        TMDLOAD(&tmd, PHYSADDR(s,CSR_CXDA(s)));
    974
    975        CSR_CXBC(s) = GET_FIELD(tmd.length, TMDL, BCNT);
    976        CSR_CXST(s) = tmd.status;
    977    } else {
    978        CSR_CXBC(s) = CSR_CXST(s) = 0;
    979    }
    980
    981    return !!(CSR_CXST(s) & 0x8000);
    982}
    983
    984#define MIN_BUF_SIZE 60
    985
    986ssize_t pcnet_receive(NetClientState *nc, const uint8_t *buf, size_t size_)
    987{
    988    PCNetState *s = qemu_get_nic_opaque(nc);
    989    int is_padr = 0, is_bcast = 0, is_ladr = 0;
    990    uint8_t buf1[60];
    991    int remaining;
    992    int crc_err = 0;
    993    size_t size = size_;
    994
    995    if (CSR_DRX(s) || CSR_STOP(s) || CSR_SPND(s) || !size ||
    996        (CSR_LOOP(s) && !s->looptest)) {
    997        return -1;
    998    }
    999#ifdef PCNET_DEBUG
   1000    printf("pcnet_receive size=%zu\n", size);
   1001#endif
   1002
   1003    /* if too small buffer, then expand it */
   1004    if (size < MIN_BUF_SIZE) {
   1005        memcpy(buf1, buf, size);
   1006        memset(buf1 + size, 0, MIN_BUF_SIZE - size);
   1007        buf = buf1;
   1008        size = MIN_BUF_SIZE;
   1009    }
   1010
   1011    if (CSR_PROM(s)
   1012        || (is_padr=padr_match(s, buf, size))
   1013        || (is_bcast=padr_bcast(s, buf, size))
   1014        || (is_ladr=ladr_match(s, buf, size))) {
   1015
   1016        pcnet_rdte_poll(s);
   1017
   1018        if (!(CSR_CRST(s) & 0x8000) && s->rdra) {
   1019            struct pcnet_RMD rmd;
   1020            int rcvrc = CSR_RCVRC(s)-1,i;
   1021            hwaddr nrda;
   1022            for (i = CSR_RCVRL(s)-1; i > 0; i--, rcvrc--) {
   1023                if (rcvrc <= 1)
   1024                    rcvrc = CSR_RCVRL(s);
   1025                nrda = s->rdra +
   1026                    (CSR_RCVRL(s) - rcvrc) *
   1027                    (BCR_SWSTYLE(s) ? 16 : 8 );
   1028                RMDLOAD(&rmd, nrda);
   1029                if (GET_FIELD(rmd.status, RMDS, OWN)) {
   1030#ifdef PCNET_DEBUG_RMD
   1031                    printf("pcnet - scan buffer: RCVRC=%d PREV_RCVRC=%d\n",
   1032                                rcvrc, CSR_RCVRC(s));
   1033#endif
   1034                    CSR_RCVRC(s) = rcvrc;
   1035                    pcnet_rdte_poll(s);
   1036                    break;
   1037                }
   1038            }
   1039        }
   1040
   1041        if (!(CSR_CRST(s) & 0x8000)) {
   1042#ifdef PCNET_DEBUG_RMD
   1043            printf("pcnet - no buffer: RCVRC=%d\n", CSR_RCVRC(s));
   1044#endif
   1045            s->csr[0] |= 0x1000; /* Set MISS flag */
   1046            CSR_MISSC(s)++;
   1047        } else {
   1048            uint8_t *src = s->buffer;
   1049            hwaddr crda = CSR_CRDA(s);
   1050            struct pcnet_RMD rmd;
   1051            int pktcount = 0;
   1052
   1053            if (!s->looptest) {
   1054                if (size > 4092) {
   1055#ifdef PCNET_DEBUG_RMD
   1056                    fprintf(stderr, "pcnet: truncates rx packet.\n");
   1057#endif
   1058                    size = 4092;
   1059                }
   1060                memcpy(src, buf, size);
   1061                /* no need to compute the CRC */
   1062                src[size] = 0;
   1063                src[size + 1] = 0;
   1064                src[size + 2] = 0;
   1065                src[size + 3] = 0;
   1066                size += 4;
   1067            } else if (s->looptest == PCNET_LOOPTEST_CRC ||
   1068                       !CSR_DXMTFCS(s) || size < MIN_BUF_SIZE+4) {
   1069                uint32_t fcs = ~0;
   1070                uint8_t *p = src;
   1071
   1072                while (p != &src[size])
   1073                    CRC(fcs, *p++);
   1074                *(uint32_t *)p = htonl(fcs);
   1075                size += 4;
   1076            } else {
   1077                uint32_t fcs = ~0;
   1078                uint8_t *p = src;
   1079
   1080                while (p != &src[size])
   1081                    CRC(fcs, *p++);
   1082                crc_err = (*(uint32_t *)p != htonl(fcs));
   1083            }
   1084
   1085#ifdef PCNET_DEBUG_MATCH
   1086            PRINT_PKTHDR(buf);
   1087#endif
   1088
   1089            RMDLOAD(&rmd, PHYSADDR(s,crda));
   1090            /*if (!CSR_LAPPEN(s))*/
   1091                SET_FIELD(&rmd.status, RMDS, STP, 1);
   1092
   1093#define PCNET_RECV_STORE() do {                                 \
   1094    int count = MIN(4096 - GET_FIELD(rmd.buf_length, RMDL, BCNT),remaining); \
   1095    hwaddr rbadr = PHYSADDR(s, rmd.rbadr);          \
   1096    s->phys_mem_write(s->dma_opaque, rbadr, src, count, CSR_BSWP(s)); \
   1097    src += count; remaining -= count;                           \
   1098    SET_FIELD(&rmd.status, RMDS, OWN, 0);                       \
   1099    RMDSTORE(&rmd, PHYSADDR(s,crda));                           \
   1100    pktcount++;                                                 \
   1101} while (0)
   1102
   1103            remaining = size;
   1104            PCNET_RECV_STORE();
   1105            if ((remaining > 0) && CSR_NRDA(s)) {
   1106                hwaddr nrda = CSR_NRDA(s);
   1107#ifdef PCNET_DEBUG_RMD
   1108                PRINT_RMD(&rmd);
   1109#endif
   1110                RMDLOAD(&rmd, PHYSADDR(s,nrda));
   1111                if (GET_FIELD(rmd.status, RMDS, OWN)) {
   1112                    crda = nrda;
   1113                    PCNET_RECV_STORE();
   1114#ifdef PCNET_DEBUG_RMD
   1115                    PRINT_RMD(&rmd);
   1116#endif
   1117                    if ((remaining > 0) && (nrda=CSR_NNRD(s))) {
   1118                        RMDLOAD(&rmd, PHYSADDR(s,nrda));
   1119                        if (GET_FIELD(rmd.status, RMDS, OWN)) {
   1120                            crda = nrda;
   1121                            PCNET_RECV_STORE();
   1122                        }
   1123                    }
   1124                }
   1125            }
   1126
   1127#undef PCNET_RECV_STORE
   1128
   1129            RMDLOAD(&rmd, PHYSADDR(s,crda));
   1130            if (remaining == 0) {
   1131                SET_FIELD(&rmd.msg_length, RMDM, MCNT, size);
   1132                SET_FIELD(&rmd.status, RMDS, ENP, 1);
   1133                SET_FIELD(&rmd.status, RMDS, PAM, !CSR_PROM(s) && is_padr);
   1134                SET_FIELD(&rmd.status, RMDS, LFAM, !CSR_PROM(s) && is_ladr);
   1135                SET_FIELD(&rmd.status, RMDS, BAM, !CSR_PROM(s) && is_bcast);
   1136                if (crc_err) {
   1137                    SET_FIELD(&rmd.status, RMDS, CRC, 1);
   1138                    SET_FIELD(&rmd.status, RMDS, ERR, 1);
   1139                }
   1140            } else {
   1141                SET_FIELD(&rmd.status, RMDS, OFLO, 1);
   1142                SET_FIELD(&rmd.status, RMDS, BUFF, 1);
   1143                SET_FIELD(&rmd.status, RMDS, ERR, 1);
   1144            }
   1145            RMDSTORE(&rmd, PHYSADDR(s,crda));
   1146            s->csr[0] |= 0x0400;
   1147
   1148#ifdef PCNET_DEBUG
   1149            printf("RCVRC=%d CRDA=0x%08x BLKS=%d\n",
   1150                CSR_RCVRC(s), PHYSADDR(s,CSR_CRDA(s)), pktcount);
   1151#endif
   1152#ifdef PCNET_DEBUG_RMD
   1153            PRINT_RMD(&rmd);
   1154#endif
   1155
   1156            while (pktcount--) {
   1157                if (CSR_RCVRC(s) <= 1) {
   1158                    CSR_RCVRC(s) = CSR_RCVRL(s);
   1159                } else {
   1160                    CSR_RCVRC(s)--;
   1161                }
   1162            }
   1163
   1164            pcnet_rdte_poll(s);
   1165
   1166        }
   1167    }
   1168
   1169    pcnet_poll(s);
   1170    pcnet_update_irq(s);
   1171
   1172    return size_;
   1173}
   1174
   1175void pcnet_set_link_status(NetClientState *nc)
   1176{
   1177    PCNetState *d = qemu_get_nic_opaque(nc);
   1178
   1179    d->lnkst = nc->link_down ? 0 : 0x40;
   1180}
   1181
   1182static void pcnet_transmit(PCNetState *s)
   1183{
   1184    hwaddr xmit_cxda = 0;
   1185    int count = CSR_XMTRL(s)-1;
   1186    int add_crc = 0;
   1187    int bcnt;
   1188    s->xmit_pos = -1;
   1189
   1190    if (!CSR_TXON(s)) {
   1191        s->csr[0] &= ~0x0008;
   1192        return;
   1193    }
   1194
   1195    s->tx_busy = 1;
   1196
   1197txagain:
   1198    if (pcnet_tdte_poll(s)) {
   1199        struct pcnet_TMD tmd;
   1200
   1201        TMDLOAD(&tmd, PHYSADDR(s,CSR_CXDA(s)));
   1202
   1203#ifdef PCNET_DEBUG_TMD
   1204        printf("  TMDLOAD 0x%08x\n", PHYSADDR(s,CSR_CXDA(s)));
   1205        PRINT_TMD(&tmd);
   1206#endif
   1207        if (GET_FIELD(tmd.status, TMDS, STP)) {
   1208            s->xmit_pos = 0;
   1209            xmit_cxda = PHYSADDR(s,CSR_CXDA(s));
   1210            if (BCR_SWSTYLE(s) != 1)
   1211                add_crc = GET_FIELD(tmd.status, TMDS, ADDFCS);
   1212        }
   1213        if (s->lnkst == 0 &&
   1214            (!CSR_LOOP(s) || (!CSR_INTL(s) && !BCR_TMAULOOP(s)))) {
   1215            SET_FIELD(&tmd.misc, TMDM, LCAR, 1);
   1216            SET_FIELD(&tmd.status, TMDS, ERR, 1);
   1217            SET_FIELD(&tmd.status, TMDS, OWN, 0);
   1218            s->csr[0] |= 0xa000; /* ERR | CERR */
   1219            s->xmit_pos = -1;
   1220            goto txdone;
   1221        }
   1222
   1223        if (s->xmit_pos < 0) {
   1224            goto txdone;
   1225        }
   1226
   1227        bcnt = 4096 - GET_FIELD(tmd.length, TMDL, BCNT);
   1228
   1229        /* if multi-tmd packet outsizes s->buffer then skip it silently.
   1230         * Note: this is not what real hw does.
   1231         * Last four bytes of s->buffer are used to store CRC FCS code.
   1232         */
   1233        if (s->xmit_pos + bcnt > sizeof(s->buffer) - 4) {
   1234            s->xmit_pos = -1;
   1235            goto txdone;
   1236        }
   1237
   1238        s->phys_mem_read(s->dma_opaque, PHYSADDR(s, tmd.tbadr),
   1239                         s->buffer + s->xmit_pos, bcnt, CSR_BSWP(s));
   1240        s->xmit_pos += bcnt;
   1241
   1242        if (!GET_FIELD(tmd.status, TMDS, ENP)) {
   1243            goto txdone;
   1244        }
   1245
   1246#ifdef PCNET_DEBUG
   1247        printf("pcnet_transmit size=%d\n", s->xmit_pos);
   1248#endif
   1249        if (CSR_LOOP(s)) {
   1250            if (BCR_SWSTYLE(s) == 1)
   1251                add_crc = !GET_FIELD(tmd.status, TMDS, NOFCS);
   1252            s->looptest = add_crc ? PCNET_LOOPTEST_CRC : PCNET_LOOPTEST_NOCRC;
   1253            qemu_receive_packet(qemu_get_queue(s->nic), s->buffer, s->xmit_pos);
   1254            s->looptest = 0;
   1255        } else {
   1256            if (s->nic) {
   1257                qemu_send_packet(qemu_get_queue(s->nic), s->buffer,
   1258                                 s->xmit_pos);
   1259            }
   1260        }
   1261
   1262        s->csr[0] &= ~0x0008;   /* clear TDMD */
   1263        s->csr[4] |= 0x0004;    /* set TXSTRT */
   1264        s->xmit_pos = -1;
   1265
   1266txdone:
   1267        SET_FIELD(&tmd.status, TMDS, OWN, 0);
   1268        TMDSTORE(&tmd, PHYSADDR(s,CSR_CXDA(s)));
   1269        if (!CSR_TOKINTD(s)
   1270            || (CSR_LTINTEN(s) && GET_FIELD(tmd.status, TMDS, LTINT))) {
   1271            s->csr[0] |= 0x0200;    /* set TINT */
   1272        }
   1273        if (CSR_XMTRC(s) <= 1) {
   1274            CSR_XMTRC(s) = CSR_XMTRL(s);
   1275        } else {
   1276            CSR_XMTRC(s)--;
   1277        }
   1278        if (count--) {
   1279            goto txagain;
   1280        }
   1281    } else if (s->xmit_pos >= 0) {
   1282        struct pcnet_TMD tmd;
   1283        TMDLOAD(&tmd, xmit_cxda);
   1284        SET_FIELD(&tmd.misc, TMDM, BUFF, 1);
   1285        SET_FIELD(&tmd.misc, TMDM, UFLO, 1);
   1286        SET_FIELD(&tmd.status, TMDS, ERR, 1);
   1287        SET_FIELD(&tmd.status, TMDS, OWN, 0);
   1288        TMDSTORE(&tmd, xmit_cxda);
   1289        s->csr[0] |= 0x0200;    /* set TINT */
   1290        if (!CSR_DXSUFLO(s)) {
   1291            s->csr[0] &= ~0x0010;
   1292        } else if (count--) {
   1293            goto txagain;
   1294        }
   1295    }
   1296
   1297    s->tx_busy = 0;
   1298}
   1299
   1300static void pcnet_poll(PCNetState *s)
   1301{
   1302    if (CSR_RXON(s)) {
   1303        pcnet_rdte_poll(s);
   1304    }
   1305
   1306    if (CSR_TDMD(s) || (CSR_TXON(s) && !CSR_DPOLL(s) && pcnet_tdte_poll(s))) {
   1307        /* prevent recursion */
   1308        if (s->tx_busy) {
   1309            return;
   1310        }
   1311        pcnet_transmit(s);
   1312    }
   1313}
   1314
   1315static void pcnet_poll_timer(void *opaque)
   1316{
   1317    PCNetState *s = opaque;
   1318
   1319    timer_del(s->poll_timer);
   1320
   1321    if (CSR_TDMD(s)) {
   1322        pcnet_transmit(s);
   1323    }
   1324
   1325    pcnet_update_irq(s);
   1326
   1327    if (!CSR_STOP(s) && !CSR_SPND(s) && !CSR_DPOLL(s)) {
   1328        uint64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) * 33;
   1329        if (!s->timer || !now) {
   1330            s->timer = now;
   1331        } else {
   1332            uint64_t t = now - s->timer + CSR_POLL(s);
   1333            if (t > 0xffffLL) {
   1334                pcnet_poll(s);
   1335                CSR_POLL(s) = CSR_PINT(s);
   1336            } else {
   1337                CSR_POLL(s) = t;
   1338            }
   1339        }
   1340        timer_mod(s->poll_timer,
   1341            pcnet_get_next_poll_time(s,qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL)));
   1342    }
   1343}
   1344
   1345
   1346static void pcnet_csr_writew(PCNetState *s, uint32_t rap, uint32_t new_value)
   1347{
   1348    uint16_t val = new_value;
   1349#ifdef PCNET_DEBUG_CSR
   1350    printf("pcnet_csr_writew rap=%d val=0x%04x\n", rap, val);
   1351#endif
   1352    switch (rap) {
   1353    case 0:
   1354        s->csr[0] &= ~(val & 0x7f00); /* Clear any interrupt flags */
   1355
   1356        s->csr[0] = (s->csr[0] & ~0x0040) | (val & 0x0048);
   1357
   1358        val = (val & 0x007f) | (s->csr[0] & 0x7f00);
   1359
   1360        /* IFF STOP, STRT and INIT are set, clear STRT and INIT */
   1361        if ((val & 7) == 7) {
   1362            val &= ~3;
   1363        }
   1364        if (!CSR_STOP(s) && (val & 4)) {
   1365            pcnet_stop(s);
   1366        }
   1367        if (!CSR_INIT(s) && (val & 1)) {
   1368            pcnet_init(s);
   1369        }
   1370        if (!CSR_STRT(s) && (val & 2)) {
   1371            pcnet_start(s);
   1372        }
   1373        if (CSR_TDMD(s)) {
   1374            pcnet_transmit(s);
   1375        }
   1376        return;
   1377    case 1:
   1378    case 2:
   1379    case 8:
   1380    case 9:
   1381    case 10:
   1382    case 11:
   1383    case 12:
   1384    case 13:
   1385    case 14:
   1386    case 15:
   1387    case 18: /* CRBAL */
   1388    case 19: /* CRBAU */
   1389    case 20: /* CXBAL */
   1390    case 21: /* CXBAU */
   1391    case 22: /* NRBAU */
   1392    case 23: /* NRBAU */
   1393    case 24:
   1394    case 25:
   1395    case 26:
   1396    case 27:
   1397    case 28:
   1398    case 29:
   1399    case 30:
   1400    case 31:
   1401    case 32:
   1402    case 33:
   1403    case 34:
   1404    case 35:
   1405    case 36:
   1406    case 37:
   1407    case 38:
   1408    case 39:
   1409    case 40: /* CRBC */
   1410    case 41:
   1411    case 42: /* CXBC */
   1412    case 43:
   1413    case 44:
   1414    case 45:
   1415    case 46: /* POLL */
   1416    case 47: /* POLLINT */
   1417    case 72:
   1418    case 74:
   1419        break;
   1420    case 76: /* RCVRL */
   1421    case 78: /* XMTRL */
   1422        val = (val > 0) ? val : 512;
   1423        break;
   1424    case 112:
   1425        if (CSR_STOP(s) || CSR_SPND(s)) {
   1426            break;
   1427        }
   1428        return;
   1429    case 3:
   1430        break;
   1431    case 4:
   1432        s->csr[4] &= ~(val & 0x026a);
   1433        val &= ~0x026a; val |= s->csr[4] & 0x026a;
   1434        break;
   1435    case 5:
   1436        s->csr[5] &= ~(val & 0x0a90);
   1437        val &= ~0x0a90; val |= s->csr[5] & 0x0a90;
   1438        break;
   1439    case 16:
   1440        pcnet_csr_writew(s,1,val);
   1441        return;
   1442    case 17:
   1443        pcnet_csr_writew(s,2,val);
   1444        return;
   1445    case 58:
   1446        pcnet_bcr_writew(s,BCR_SWS,val);
   1447        break;
   1448    default:
   1449        return;
   1450    }
   1451    s->csr[rap] = val;
   1452}
   1453
   1454static uint32_t pcnet_csr_readw(PCNetState *s, uint32_t rap)
   1455{
   1456    uint32_t val;
   1457    switch (rap) {
   1458    case 0:
   1459        pcnet_update_irq(s);
   1460        val = s->csr[0];
   1461        val |= (val & 0x7800) ? 0x8000 : 0;
   1462        break;
   1463    case 16:
   1464        return pcnet_csr_readw(s,1);
   1465    case 17:
   1466        return pcnet_csr_readw(s,2);
   1467    case 58:
   1468        return pcnet_bcr_readw(s,BCR_SWS);
   1469    case 88:
   1470        val = s->csr[89];
   1471        val <<= 16;
   1472        val |= s->csr[88];
   1473        break;
   1474    default:
   1475        val = s->csr[rap];
   1476    }
   1477#ifdef PCNET_DEBUG_CSR
   1478    printf("pcnet_csr_readw rap=%d val=0x%04x\n", rap, val);
   1479#endif
   1480    return val;
   1481}
   1482
   1483static void pcnet_bcr_writew(PCNetState *s, uint32_t rap, uint32_t val)
   1484{
   1485    rap &= 127;
   1486#ifdef PCNET_DEBUG_BCR
   1487    printf("pcnet_bcr_writew rap=%d val=0x%04x\n", rap, val);
   1488#endif
   1489    switch (rap) {
   1490    case BCR_SWS:
   1491        if (!(CSR_STOP(s) || CSR_SPND(s)))
   1492            return;
   1493        val &= ~0x0300;
   1494        switch (val & 0x00ff) {
   1495        case 0:
   1496            val |= 0x0200;
   1497            break;
   1498        case 1:
   1499            val |= 0x0100;
   1500            break;
   1501        case 2:
   1502        case 3:
   1503            val |= 0x0300;
   1504            break;
   1505        default:
   1506            qemu_log_mask(LOG_GUEST_ERROR, "pcnet: Bad SWSTYLE=0x%02x\n",
   1507                          val & 0xff);
   1508            val = 0x0200;
   1509            break;
   1510        }
   1511#ifdef PCNET_DEBUG
   1512       printf("BCR_SWS=0x%04x\n", val);
   1513#endif
   1514        /* fall through */
   1515    case BCR_LNKST:
   1516    case BCR_LED1:
   1517    case BCR_LED2:
   1518    case BCR_LED3:
   1519    case BCR_MC:
   1520    case BCR_FDC:
   1521    case BCR_BSBC:
   1522    case BCR_EECAS:
   1523    case BCR_PLAT:
   1524        s->bcr[rap] = val;
   1525        break;
   1526    default:
   1527        break;
   1528    }
   1529}
   1530
   1531uint32_t pcnet_bcr_readw(PCNetState *s, uint32_t rap)
   1532{
   1533    uint32_t val;
   1534    rap &= 127;
   1535    switch (rap) {
   1536    case BCR_LNKST:
   1537    case BCR_LED1:
   1538    case BCR_LED2:
   1539    case BCR_LED3:
   1540        val = s->bcr[rap] & ~0x8000;
   1541        val |= (val & 0x017f & s->lnkst) ? 0x8000 : 0;
   1542        break;
   1543    default:
   1544        val = rap < 32 ? s->bcr[rap] : 0;
   1545        break;
   1546    }
   1547#ifdef PCNET_DEBUG_BCR
   1548    printf("pcnet_bcr_readw rap=%d val=0x%04x\n", rap, val);
   1549#endif
   1550    return val;
   1551}
   1552
   1553void pcnet_h_reset(void *opaque)
   1554{
   1555    PCNetState *s = opaque;
   1556
   1557    s->bcr[BCR_MSRDA] = 0x0005;
   1558    s->bcr[BCR_MSWRA] = 0x0005;
   1559    s->bcr[BCR_MC   ] = 0x0002;
   1560    s->bcr[BCR_LNKST] = 0x00c0;
   1561    s->bcr[BCR_LED1 ] = 0x0084;
   1562    s->bcr[BCR_LED2 ] = 0x0088;
   1563    s->bcr[BCR_LED3 ] = 0x0090;
   1564    s->bcr[BCR_FDC  ] = 0x0000;
   1565    s->bcr[BCR_BSBC ] = 0x9001;
   1566    s->bcr[BCR_EECAS] = 0x0002;
   1567    s->bcr[BCR_SWS  ] = 0x0200;
   1568    s->bcr[BCR_PLAT ] = 0xff06;
   1569
   1570    pcnet_s_reset(s);
   1571    pcnet_update_irq(s);
   1572    pcnet_poll_timer(s);
   1573}
   1574
   1575void pcnet_ioport_writew(void *opaque, uint32_t addr, uint32_t val)
   1576{
   1577    PCNetState *s = opaque;
   1578    pcnet_poll_timer(s);
   1579#ifdef PCNET_DEBUG_IO
   1580    printf("pcnet_ioport_writew addr=0x%08x val=0x%04x\n", addr, val);
   1581#endif
   1582    if (!BCR_DWIO(s)) {
   1583        switch (addr & 0x0f) {
   1584        case 0x00: /* RDP */
   1585            pcnet_csr_writew(s, s->rap, val);
   1586            break;
   1587        case 0x02:
   1588            s->rap = val & 0x7f;
   1589            break;
   1590        case 0x06:
   1591            pcnet_bcr_writew(s, s->rap, val);
   1592            break;
   1593        }
   1594    }
   1595    pcnet_update_irq(s);
   1596}
   1597
   1598uint32_t pcnet_ioport_readw(void *opaque, uint32_t addr)
   1599{
   1600    PCNetState *s = opaque;
   1601    uint32_t val = -1;
   1602    pcnet_poll_timer(s);
   1603    if (!BCR_DWIO(s)) {
   1604        switch (addr & 0x0f) {
   1605        case 0x00: /* RDP */
   1606            val = pcnet_csr_readw(s, s->rap);
   1607            break;
   1608        case 0x02:
   1609            val = s->rap;
   1610            break;
   1611        case 0x04:
   1612            pcnet_s_reset(s);
   1613            val = 0;
   1614            break;
   1615        case 0x06:
   1616            val = pcnet_bcr_readw(s, s->rap);
   1617            break;
   1618        }
   1619    }
   1620    pcnet_update_irq(s);
   1621#ifdef PCNET_DEBUG_IO
   1622    printf("pcnet_ioport_readw addr=0x%08x val=0x%04x\n", addr, val & 0xffff);
   1623#endif
   1624    return val;
   1625}
   1626
   1627void pcnet_ioport_writel(void *opaque, uint32_t addr, uint32_t val)
   1628{
   1629    PCNetState *s = opaque;
   1630    pcnet_poll_timer(s);
   1631#ifdef PCNET_DEBUG_IO
   1632    printf("pcnet_ioport_writel addr=0x%08x val=0x%08x\n", addr, val);
   1633#endif
   1634    if (BCR_DWIO(s)) {
   1635        switch (addr & 0x0f) {
   1636        case 0x00: /* RDP */
   1637            pcnet_csr_writew(s, s->rap, val & 0xffff);
   1638            break;
   1639        case 0x04:
   1640            s->rap = val & 0x7f;
   1641            break;
   1642        case 0x0c:
   1643            pcnet_bcr_writew(s, s->rap, val & 0xffff);
   1644            break;
   1645        }
   1646    } else if ((addr & 0x0f) == 0) {
   1647        /* switch device to dword i/o mode */
   1648        pcnet_bcr_writew(s, BCR_BSBC, pcnet_bcr_readw(s, BCR_BSBC) | 0x0080);
   1649#ifdef PCNET_DEBUG_IO
   1650        printf("device switched into dword i/o mode\n");
   1651#endif
   1652    }
   1653    pcnet_update_irq(s);
   1654}
   1655
   1656uint32_t pcnet_ioport_readl(void *opaque, uint32_t addr)
   1657{
   1658    PCNetState *s = opaque;
   1659    uint32_t val = -1;
   1660    pcnet_poll_timer(s);
   1661    if (BCR_DWIO(s)) {
   1662        switch (addr & 0x0f) {
   1663        case 0x00: /* RDP */
   1664            val = pcnet_csr_readw(s, s->rap);
   1665            break;
   1666        case 0x04:
   1667            val = s->rap;
   1668            break;
   1669        case 0x08:
   1670            pcnet_s_reset(s);
   1671            val = 0;
   1672            break;
   1673        case 0x0c:
   1674            val = pcnet_bcr_readw(s, s->rap);
   1675            break;
   1676        }
   1677    }
   1678    pcnet_update_irq(s);
   1679#ifdef PCNET_DEBUG_IO
   1680    printf("pcnet_ioport_readl addr=0x%08x val=0x%08x\n", addr, val);
   1681#endif
   1682    return val;
   1683}
   1684
   1685static bool is_version_2(void *opaque, int version_id)
   1686{
   1687    return version_id == 2;
   1688}
   1689
   1690const VMStateDescription vmstate_pcnet = {
   1691    .name = "pcnet",
   1692    .version_id = 3,
   1693    .minimum_version_id = 2,
   1694    .fields = (VMStateField[]) {
   1695        VMSTATE_INT32(rap, PCNetState),
   1696        VMSTATE_INT32(isr, PCNetState),
   1697        VMSTATE_INT32(lnkst, PCNetState),
   1698        VMSTATE_UINT32(rdra, PCNetState),
   1699        VMSTATE_UINT32(tdra, PCNetState),
   1700        VMSTATE_BUFFER(prom, PCNetState),
   1701        VMSTATE_UINT16_ARRAY(csr, PCNetState, 128),
   1702        VMSTATE_UINT16_ARRAY(bcr, PCNetState, 32),
   1703        VMSTATE_UINT64(timer, PCNetState),
   1704        VMSTATE_INT32(xmit_pos, PCNetState),
   1705        VMSTATE_BUFFER(buffer, PCNetState),
   1706        VMSTATE_UNUSED_TEST(is_version_2, 4),
   1707        VMSTATE_INT32(tx_busy, PCNetState),
   1708        VMSTATE_TIMER_PTR(poll_timer, PCNetState),
   1709        VMSTATE_END_OF_LIST()
   1710    }
   1711};
   1712
   1713void pcnet_common_init(DeviceState *dev, PCNetState *s, NetClientInfo *info)
   1714{
   1715    int i;
   1716    uint16_t checksum;
   1717
   1718    s->poll_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, pcnet_poll_timer, s);
   1719
   1720    qemu_macaddr_default_if_unset(&s->conf.macaddr);
   1721    s->nic = qemu_new_nic(info, &s->conf, object_get_typename(OBJECT(dev)), dev->id, s);
   1722    qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a);
   1723
   1724    /* Initialize the PROM */
   1725
   1726    /*
   1727      Datasheet: http://pdfdata.datasheetsite.com/web/24528/AM79C970A.pdf
   1728      page 95
   1729    */
   1730    memcpy(s->prom, s->conf.macaddr.a, 6);
   1731    /* Reserved Location: must be 00h */
   1732    s->prom[6] = s->prom[7] = 0x00;
   1733    /* Reserved Location: must be 00h */
   1734    s->prom[8] = 0x00;
   1735    /* Hardware ID: must be 11h if compatibility to AMD drivers is desired */
   1736    s->prom[9] = 0x11;
   1737    /* User programmable space, init with 0 */
   1738    s->prom[10] = s->prom[11] = 0x00;
   1739    /* LSByte of two-byte checksum, which is the sum of bytes 00h-0Bh
   1740       and bytes 0Eh and 0Fh, must therefore be initialized with 0! */
   1741    s->prom[12] = s->prom[13] = 0x00;
   1742    /* Must be ASCII W (57h) if compatibility to AMD
   1743       driver software is desired */
   1744    s->prom[14] = s->prom[15] = 0x57;
   1745
   1746    for (i = 0, checksum = 0; i < 16; i++) {
   1747        checksum += s->prom[i];
   1748    }
   1749    *(uint16_t *)&s->prom[12] = cpu_to_le16(checksum);
   1750
   1751    s->lnkst = 0x40; /* initial link state: up */
   1752}