qemu

FORK: QEMU emulator
git clone https://git.neptards.moe/neptards/qemu.git
Log | Files | Refs | Submodules | LICENSE

pcnet.c (55872B)


      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 
     59 struct 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 
    121 struct 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 
    129 struct 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 
    140 struct 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 
    191 struct 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 
    299 static 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 
    329 static 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 
    365 static 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 
    395 static 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  */
    533 static 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 
    600 static 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 
    620 static 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 
    631 static 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 
    648 static 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 
    656 static 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 
    667 static void pcnet_poll(PCNetState *s);
    668 static void pcnet_poll_timer(void *opaque);
    669 
    670 static uint32_t pcnet_csr_readw(PCNetState *s, uint32_t rap);
    671 static void pcnet_csr_writew(PCNetState *s, uint32_t rap, uint32_t new_value);
    672 static void pcnet_bcr_writew(PCNetState *s, uint32_t rap, uint32_t val);
    673 
    674 static 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 
    715 static 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 
    770 static 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 
    842 static 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 
    861 static 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 
    873 static 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 
    946 static 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 
    986 ssize_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 
   1175 void 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 
   1182 static 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 
   1197 txagain:
   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 
   1266 txdone:
   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 
   1300 static 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 
   1315 static 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 
   1346 static 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 
   1454 static 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 
   1483 static 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 
   1531 uint32_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 
   1553 void 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 
   1575 void 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 
   1598 uint32_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 
   1627 void 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 
   1656 uint32_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 
   1685 static bool is_version_2(void *opaque, int version_id)
   1686 {
   1687     return version_id == 2;
   1688 }
   1689 
   1690 const 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 
   1713 void 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 }