symbian-qemu-0.9.1-12/qemu-symbian-svp/hw/pcnet.c
changeset 1 2fb8b9db1c86
equal deleted inserted replaced
0:ffa851df0825 1:2fb8b9db1c86
       
     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 "hw.h"
       
    39 #include "pci.h"
       
    40 #include "net.h"
       
    41 #include "qemu-timer.h"
       
    42 #include "qemu_socket.h"
       
    43 
       
    44 //#define PCNET_DEBUG
       
    45 //#define PCNET_DEBUG_IO
       
    46 //#define PCNET_DEBUG_BCR
       
    47 //#define PCNET_DEBUG_CSR
       
    48 //#define PCNET_DEBUG_RMD
       
    49 //#define PCNET_DEBUG_TMD
       
    50 //#define PCNET_DEBUG_MATCH
       
    51 
       
    52 
       
    53 #define PCNET_IOPORT_SIZE       0x20
       
    54 #define PCNET_PNPMMIO_SIZE      0x20
       
    55 
       
    56 #define PCNET_LOOPTEST_CRC	1
       
    57 #define PCNET_LOOPTEST_NOCRC	2
       
    58 
       
    59 
       
    60 typedef struct PCNetState_st PCNetState;
       
    61 
       
    62 struct PCNetState_st {
       
    63     PCIDevice dev;
       
    64     PCIDevice *pci_dev;
       
    65     VLANClientState *vc;
       
    66     NICInfo *nd;
       
    67     QEMUTimer *poll_timer;
       
    68     int mmio_index, rap, isr, lnkst;
       
    69     uint32_t rdra, tdra;
       
    70     uint8_t prom[16];
       
    71     uint16_t csr[128];
       
    72     uint16_t bcr[32];
       
    73     uint64_t timer;
       
    74     int xmit_pos, recv_pos;
       
    75     uint8_t buffer[4096];
       
    76     int tx_busy;
       
    77     qemu_irq irq;
       
    78     void (*phys_mem_read)(void *dma_opaque, target_phys_addr_t addr,
       
    79                          uint8_t *buf, int len, int do_bswap);
       
    80     void (*phys_mem_write)(void *dma_opaque, target_phys_addr_t addr,
       
    81                           uint8_t *buf, int len, int do_bswap);
       
    82     void *dma_opaque;
       
    83     int looptest;
       
    84 };
       
    85 
       
    86 struct qemu_ether_header {
       
    87     uint8_t ether_dhost[6];
       
    88     uint8_t ether_shost[6];
       
    89     uint16_t ether_type;
       
    90 };
       
    91 
       
    92 /* BUS CONFIGURATION REGISTERS */
       
    93 #define BCR_MSRDA    0
       
    94 #define BCR_MSWRA    1
       
    95 #define BCR_MC       2
       
    96 #define BCR_LNKST    4
       
    97 #define BCR_LED1     5
       
    98 #define BCR_LED2     6
       
    99 #define BCR_LED3     7
       
   100 #define BCR_FDC      9
       
   101 #define BCR_BSBC     18
       
   102 #define BCR_EECAS    19
       
   103 #define BCR_SWS      20
       
   104 #define BCR_PLAT     22
       
   105 
       
   106 #define BCR_DWIO(S)      !!((S)->bcr[BCR_BSBC] & 0x0080)
       
   107 #define BCR_SSIZE32(S)   !!((S)->bcr[BCR_SWS ] & 0x0100)
       
   108 #define BCR_SWSTYLE(S)     ((S)->bcr[BCR_SWS ] & 0x00FF)
       
   109 
       
   110 #define CSR_INIT(S)      !!(((S)->csr[0])&0x0001)
       
   111 #define CSR_STRT(S)      !!(((S)->csr[0])&0x0002)
       
   112 #define CSR_STOP(S)      !!(((S)->csr[0])&0x0004)
       
   113 #define CSR_TDMD(S)      !!(((S)->csr[0])&0x0008)
       
   114 #define CSR_TXON(S)      !!(((S)->csr[0])&0x0010)
       
   115 #define CSR_RXON(S)      !!(((S)->csr[0])&0x0020)
       
   116 #define CSR_INEA(S)      !!(((S)->csr[0])&0x0040)
       
   117 #define CSR_BSWP(S)      !!(((S)->csr[3])&0x0004)
       
   118 #define CSR_LAPPEN(S)    !!(((S)->csr[3])&0x0020)
       
   119 #define CSR_DXSUFLO(S)   !!(((S)->csr[3])&0x0040)
       
   120 #define CSR_ASTRP_RCV(S) !!(((S)->csr[4])&0x0800)
       
   121 #define CSR_DPOLL(S)     !!(((S)->csr[4])&0x1000)
       
   122 #define CSR_SPND(S)      !!(((S)->csr[5])&0x0001)
       
   123 #define CSR_LTINTEN(S)   !!(((S)->csr[5])&0x4000)
       
   124 #define CSR_TOKINTD(S)   !!(((S)->csr[5])&0x8000)
       
   125 #define CSR_DRX(S)       !!(((S)->csr[15])&0x0001)
       
   126 #define CSR_DTX(S)       !!(((S)->csr[15])&0x0002)
       
   127 #define CSR_LOOP(S)      !!(((S)->csr[15])&0x0004)
       
   128 #define CSR_DXMTFCS(S)   !!(((S)->csr[15])&0x0008)
       
   129 #define CSR_DRCVPA(S)    !!(((S)->csr[15])&0x2000)
       
   130 #define CSR_DRCVBC(S)    !!(((S)->csr[15])&0x4000)
       
   131 #define CSR_PROM(S)      !!(((S)->csr[15])&0x8000)
       
   132 
       
   133 #define CSR_CRBC(S)      ((S)->csr[40])
       
   134 #define CSR_CRST(S)      ((S)->csr[41])
       
   135 #define CSR_CXBC(S)      ((S)->csr[42])
       
   136 #define CSR_CXST(S)      ((S)->csr[43])
       
   137 #define CSR_NRBC(S)      ((S)->csr[44])
       
   138 #define CSR_NRST(S)      ((S)->csr[45])
       
   139 #define CSR_POLL(S)      ((S)->csr[46])
       
   140 #define CSR_PINT(S)      ((S)->csr[47])
       
   141 #define CSR_RCVRC(S)     ((S)->csr[72])
       
   142 #define CSR_XMTRC(S)     ((S)->csr[74])
       
   143 #define CSR_RCVRL(S)     ((S)->csr[76])
       
   144 #define CSR_XMTRL(S)     ((S)->csr[78])
       
   145 #define CSR_MISSC(S)     ((S)->csr[112])
       
   146 
       
   147 #define CSR_IADR(S)      ((S)->csr[ 1] | ((S)->csr[ 2] << 16))
       
   148 #define CSR_CRBA(S)      ((S)->csr[18] | ((S)->csr[19] << 16))
       
   149 #define CSR_CXBA(S)      ((S)->csr[20] | ((S)->csr[21] << 16))
       
   150 #define CSR_NRBA(S)      ((S)->csr[22] | ((S)->csr[23] << 16))
       
   151 #define CSR_BADR(S)      ((S)->csr[24] | ((S)->csr[25] << 16))
       
   152 #define CSR_NRDA(S)      ((S)->csr[26] | ((S)->csr[27] << 16))
       
   153 #define CSR_CRDA(S)      ((S)->csr[28] | ((S)->csr[29] << 16))
       
   154 #define CSR_BADX(S)      ((S)->csr[30] | ((S)->csr[31] << 16))
       
   155 #define CSR_NXDA(S)      ((S)->csr[32] | ((S)->csr[33] << 16))
       
   156 #define CSR_CXDA(S)      ((S)->csr[34] | ((S)->csr[35] << 16))
       
   157 #define CSR_NNRD(S)      ((S)->csr[36] | ((S)->csr[37] << 16))
       
   158 #define CSR_NNXD(S)      ((S)->csr[38] | ((S)->csr[39] << 16))
       
   159 #define CSR_PXDA(S)      ((S)->csr[60] | ((S)->csr[61] << 16))
       
   160 #define CSR_NXBA(S)      ((S)->csr[64] | ((S)->csr[65] << 16))
       
   161 
       
   162 #define PHYSADDR(S,A) \
       
   163   (BCR_SSIZE32(S) ? (A) : (A) | ((0xff00 & (uint32_t)(s)->csr[2])<<16))
       
   164 
       
   165 struct pcnet_initblk16 {
       
   166     uint16_t mode;
       
   167     uint16_t padr[3];
       
   168     uint16_t ladrf[4];
       
   169     uint32_t rdra;
       
   170     uint32_t tdra;
       
   171 };
       
   172 
       
   173 struct pcnet_initblk32 {
       
   174     uint16_t mode;
       
   175     uint8_t rlen;
       
   176     uint8_t tlen;
       
   177     uint16_t padr[3];
       
   178     uint16_t _res;
       
   179     uint16_t ladrf[4];
       
   180     uint32_t rdra;
       
   181     uint32_t tdra;
       
   182 };
       
   183 
       
   184 struct pcnet_TMD {
       
   185     uint32_t tbadr;
       
   186     int16_t length;
       
   187     int16_t status;
       
   188     uint32_t misc;
       
   189     uint32_t res;
       
   190 };
       
   191 
       
   192 #define TMDL_BCNT_MASK  0x0fff
       
   193 #define TMDL_BCNT_SH    0
       
   194 #define TMDL_ONES_MASK  0xf000
       
   195 #define TMDL_ONES_SH    12
       
   196 
       
   197 #define TMDS_BPE_MASK   0x0080
       
   198 #define TMDS_BPE_SH     7
       
   199 #define TMDS_ENP_MASK   0x0100
       
   200 #define TMDS_ENP_SH     8
       
   201 #define TMDS_STP_MASK   0x0200
       
   202 #define TMDS_STP_SH     9
       
   203 #define TMDS_DEF_MASK   0x0400
       
   204 #define TMDS_DEF_SH     10
       
   205 #define TMDS_ONE_MASK   0x0800
       
   206 #define TMDS_ONE_SH     11
       
   207 #define TMDS_LTINT_MASK 0x1000
       
   208 #define TMDS_LTINT_SH   12
       
   209 #define TMDS_NOFCS_MASK 0x2000
       
   210 #define TMDS_NOFCS_SH   13
       
   211 #define TMDS_ADDFCS_MASK TMDS_NOFCS_MASK
       
   212 #define TMDS_ADDFCS_SH  TMDS_NOFCS_SH
       
   213 #define TMDS_ERR_MASK   0x4000
       
   214 #define TMDS_ERR_SH     14
       
   215 #define TMDS_OWN_MASK   0x8000
       
   216 #define TMDS_OWN_SH     15
       
   217 
       
   218 #define TMDM_TRC_MASK   0x0000000f
       
   219 #define TMDM_TRC_SH     0
       
   220 #define TMDM_TDR_MASK   0x03ff0000
       
   221 #define TMDM_TDR_SH     16
       
   222 #define TMDM_RTRY_MASK  0x04000000
       
   223 #define TMDM_RTRY_SH    26
       
   224 #define TMDM_LCAR_MASK  0x08000000
       
   225 #define TMDM_LCAR_SH    27
       
   226 #define TMDM_LCOL_MASK  0x10000000
       
   227 #define TMDM_LCOL_SH    28
       
   228 #define TMDM_EXDEF_MASK 0x20000000
       
   229 #define TMDM_EXDEF_SH   29
       
   230 #define TMDM_UFLO_MASK  0x40000000
       
   231 #define TMDM_UFLO_SH    30
       
   232 #define TMDM_BUFF_MASK  0x80000000
       
   233 #define TMDM_BUFF_SH    31
       
   234 
       
   235 struct pcnet_RMD {
       
   236     uint32_t rbadr;
       
   237     int16_t buf_length;
       
   238     int16_t status;
       
   239     uint32_t msg_length;
       
   240     uint32_t res;
       
   241 };
       
   242 
       
   243 #define RMDL_BCNT_MASK  0x0fff
       
   244 #define RMDL_BCNT_SH    0
       
   245 #define RMDL_ONES_MASK  0xf000
       
   246 #define RMDL_ONES_SH    12
       
   247 
       
   248 #define RMDS_BAM_MASK   0x0010
       
   249 #define RMDS_BAM_SH     4
       
   250 #define RMDS_LFAM_MASK  0x0020
       
   251 #define RMDS_LFAM_SH    5
       
   252 #define RMDS_PAM_MASK   0x0040
       
   253 #define RMDS_PAM_SH     6
       
   254 #define RMDS_BPE_MASK   0x0080
       
   255 #define RMDS_BPE_SH     7
       
   256 #define RMDS_ENP_MASK   0x0100
       
   257 #define RMDS_ENP_SH     8
       
   258 #define RMDS_STP_MASK   0x0200
       
   259 #define RMDS_STP_SH     9
       
   260 #define RMDS_BUFF_MASK  0x0400
       
   261 #define RMDS_BUFF_SH    10
       
   262 #define RMDS_CRC_MASK   0x0800
       
   263 #define RMDS_CRC_SH     11
       
   264 #define RMDS_OFLO_MASK  0x1000
       
   265 #define RMDS_OFLO_SH    12
       
   266 #define RMDS_FRAM_MASK  0x2000
       
   267 #define RMDS_FRAM_SH    13
       
   268 #define RMDS_ERR_MASK   0x4000
       
   269 #define RMDS_ERR_SH     14
       
   270 #define RMDS_OWN_MASK   0x8000
       
   271 #define RMDS_OWN_SH     15
       
   272 
       
   273 #define RMDM_MCNT_MASK  0x00000fff
       
   274 #define RMDM_MCNT_SH    0
       
   275 #define RMDM_ZEROS_MASK 0x0000f000
       
   276 #define RMDM_ZEROS_SH   12
       
   277 #define RMDM_RPC_MASK   0x00ff0000
       
   278 #define RMDM_RPC_SH     16
       
   279 #define RMDM_RCC_MASK   0xff000000
       
   280 #define RMDM_RCC_SH     24
       
   281 
       
   282 #define SET_FIELD(regp, name, field, value)             \
       
   283   (*(regp) = (*(regp) & ~(name ## _ ## field ## _MASK)) \
       
   284              | ((value) << name ## _ ## field ## _SH))
       
   285 
       
   286 #define GET_FIELD(reg, name, field)                     \
       
   287   (((reg) & name ## _ ## field ## _MASK) >> name ## _ ## field ## _SH)
       
   288 
       
   289 #define PRINT_TMD(T) printf(                            \
       
   290         "TMD0 : TBADR=0x%08x\n"                         \
       
   291         "TMD1 : OWN=%d, ERR=%d, FCS=%d, LTI=%d, "       \
       
   292         "ONE=%d, DEF=%d, STP=%d, ENP=%d,\n"             \
       
   293         "       BPE=%d, BCNT=%d\n"                      \
       
   294         "TMD2 : BUF=%d, UFL=%d, EXD=%d, LCO=%d, "       \
       
   295         "LCA=%d, RTR=%d,\n"                             \
       
   296         "       TDR=%d, TRC=%d\n",                      \
       
   297         (T)->tbadr,                                     \
       
   298         GET_FIELD((T)->status, TMDS, OWN),              \
       
   299         GET_FIELD((T)->status, TMDS, ERR),              \
       
   300         GET_FIELD((T)->status, TMDS, NOFCS),            \
       
   301         GET_FIELD((T)->status, TMDS, LTINT),            \
       
   302         GET_FIELD((T)->status, TMDS, ONE),              \
       
   303         GET_FIELD((T)->status, TMDS, DEF),              \
       
   304         GET_FIELD((T)->status, TMDS, STP),              \
       
   305         GET_FIELD((T)->status, TMDS, ENP),              \
       
   306         GET_FIELD((T)->status, TMDS, BPE),              \
       
   307         4096-GET_FIELD((T)->length, TMDL, BCNT),        \
       
   308         GET_FIELD((T)->misc, TMDM, BUFF),               \
       
   309         GET_FIELD((T)->misc, TMDM, UFLO),               \
       
   310         GET_FIELD((T)->misc, TMDM, EXDEF),              \
       
   311         GET_FIELD((T)->misc, TMDM, LCOL),               \
       
   312         GET_FIELD((T)->misc, TMDM, LCAR),               \
       
   313         GET_FIELD((T)->misc, TMDM, RTRY),               \
       
   314         GET_FIELD((T)->misc, TMDM, TDR),                \
       
   315         GET_FIELD((T)->misc, TMDM, TRC))
       
   316 
       
   317 #define PRINT_RMD(R) printf(                            \
       
   318         "RMD0 : RBADR=0x%08x\n"                         \
       
   319         "RMD1 : OWN=%d, ERR=%d, FRAM=%d, OFLO=%d, "     \
       
   320         "CRC=%d, BUFF=%d, STP=%d, ENP=%d,\n       "     \
       
   321         "BPE=%d, PAM=%d, LAFM=%d, BAM=%d, ONES=%d, BCNT=%d\n" \
       
   322         "RMD2 : RCC=%d, RPC=%d, MCNT=%d, ZEROS=%d\n",   \
       
   323         (R)->rbadr,                                     \
       
   324         GET_FIELD((R)->status, RMDS, OWN),              \
       
   325         GET_FIELD((R)->status, RMDS, ERR),              \
       
   326         GET_FIELD((R)->status, RMDS, FRAM),             \
       
   327         GET_FIELD((R)->status, RMDS, OFLO),             \
       
   328         GET_FIELD((R)->status, RMDS, CRC),              \
       
   329         GET_FIELD((R)->status, RMDS, BUFF),             \
       
   330         GET_FIELD((R)->status, RMDS, STP),              \
       
   331         GET_FIELD((R)->status, RMDS, ENP),              \
       
   332         GET_FIELD((R)->status, RMDS, BPE),              \
       
   333         GET_FIELD((R)->status, RMDS, PAM),              \
       
   334         GET_FIELD((R)->status, RMDS, LFAM),             \
       
   335         GET_FIELD((R)->status, RMDS, BAM),              \
       
   336         GET_FIELD((R)->buf_length, RMDL, ONES),         \
       
   337         4096-GET_FIELD((R)->buf_length, RMDL, BCNT),    \
       
   338         GET_FIELD((R)->msg_length, RMDM, RCC),          \
       
   339         GET_FIELD((R)->msg_length, RMDM, RPC),          \
       
   340         GET_FIELD((R)->msg_length, RMDM, MCNT),         \
       
   341         GET_FIELD((R)->msg_length, RMDM, ZEROS))
       
   342 
       
   343 static inline void pcnet_tmd_load(PCNetState *s, struct pcnet_TMD *tmd,
       
   344                                   target_phys_addr_t addr)
       
   345 {
       
   346     if (!BCR_SSIZE32(s)) {
       
   347         struct {
       
   348             uint32_t tbadr;
       
   349             int16_t length;
       
   350             int16_t status;
       
   351 	} xda;
       
   352         s->phys_mem_read(s->dma_opaque, addr, (void *)&xda, sizeof(xda), 0);
       
   353         tmd->tbadr = le32_to_cpu(xda.tbadr) & 0xffffff;
       
   354         tmd->length = le16_to_cpu(xda.length);
       
   355         tmd->status = (le32_to_cpu(xda.tbadr) >> 16) & 0xff00;
       
   356         tmd->misc = le16_to_cpu(xda.status) << 16;
       
   357         tmd->res = 0;
       
   358     } else {
       
   359         s->phys_mem_read(s->dma_opaque, addr, (void *)tmd, sizeof(*tmd), 0);
       
   360         le32_to_cpus(&tmd->tbadr);
       
   361         le16_to_cpus((uint16_t *)&tmd->length);
       
   362         le16_to_cpus((uint16_t *)&tmd->status);
       
   363         le32_to_cpus(&tmd->misc);
       
   364         le32_to_cpus(&tmd->res);
       
   365         if (BCR_SWSTYLE(s) == 3) {
       
   366             uint32_t tmp = tmd->tbadr;
       
   367             tmd->tbadr = tmd->misc;
       
   368             tmd->misc = tmp;
       
   369         }
       
   370     }
       
   371 }
       
   372 
       
   373 static inline void pcnet_tmd_store(PCNetState *s, const struct pcnet_TMD *tmd,
       
   374                                    target_phys_addr_t addr)
       
   375 {
       
   376     if (!BCR_SSIZE32(s)) {
       
   377         struct {
       
   378             uint32_t tbadr;
       
   379             int16_t length;
       
   380             int16_t status;
       
   381         } xda;
       
   382         xda.tbadr = cpu_to_le32((tmd->tbadr & 0xffffff) |
       
   383                                 ((tmd->status & 0xff00) << 16));
       
   384         xda.length = cpu_to_le16(tmd->length);
       
   385         xda.status = cpu_to_le16(tmd->misc >> 16);
       
   386         s->phys_mem_write(s->dma_opaque, addr, (void *)&xda, sizeof(xda), 0);
       
   387     } else {
       
   388         struct {
       
   389             uint32_t tbadr;
       
   390             int16_t length;
       
   391             int16_t status;
       
   392             uint32_t misc;
       
   393             uint32_t res;
       
   394         } xda;
       
   395         xda.tbadr = cpu_to_le32(tmd->tbadr);
       
   396         xda.length = cpu_to_le16(tmd->length);
       
   397         xda.status = cpu_to_le16(tmd->status);
       
   398         xda.misc = cpu_to_le32(tmd->misc);
       
   399         xda.res = cpu_to_le32(tmd->res);
       
   400         if (BCR_SWSTYLE(s) == 3) {
       
   401             uint32_t tmp = xda.tbadr;
       
   402             xda.tbadr = xda.misc;
       
   403             xda.misc = tmp;
       
   404         }
       
   405         s->phys_mem_write(s->dma_opaque, addr, (void *)&xda, sizeof(xda), 0);
       
   406     }
       
   407 }
       
   408 
       
   409 static inline void pcnet_rmd_load(PCNetState *s, struct pcnet_RMD *rmd,
       
   410                                   target_phys_addr_t addr)
       
   411 {
       
   412     if (!BCR_SSIZE32(s)) {
       
   413         struct {
       
   414             uint32_t rbadr;
       
   415             int16_t buf_length;
       
   416             int16_t msg_length;
       
   417 	} rda;
       
   418         s->phys_mem_read(s->dma_opaque, addr, (void *)&rda, sizeof(rda), 0);
       
   419         rmd->rbadr = le32_to_cpu(rda.rbadr) & 0xffffff;
       
   420         rmd->buf_length = le16_to_cpu(rda.buf_length);
       
   421         rmd->status = (le32_to_cpu(rda.rbadr) >> 16) & 0xff00;
       
   422         rmd->msg_length = le16_to_cpu(rda.msg_length);
       
   423         rmd->res = 0;
       
   424     } else {
       
   425         s->phys_mem_read(s->dma_opaque, addr, (void *)rmd, sizeof(*rmd), 0);
       
   426         le32_to_cpus(&rmd->rbadr);
       
   427         le16_to_cpus((uint16_t *)&rmd->buf_length);
       
   428         le16_to_cpus((uint16_t *)&rmd->status);
       
   429         le32_to_cpus(&rmd->msg_length);
       
   430         le32_to_cpus(&rmd->res);
       
   431         if (BCR_SWSTYLE(s) == 3) {
       
   432             uint32_t tmp = rmd->rbadr;
       
   433             rmd->rbadr = rmd->msg_length;
       
   434             rmd->msg_length = tmp;
       
   435         }
       
   436     }
       
   437 }
       
   438 
       
   439 static inline void pcnet_rmd_store(PCNetState *s, struct pcnet_RMD *rmd,
       
   440                                    target_phys_addr_t addr)
       
   441 {
       
   442     if (!BCR_SSIZE32(s)) {
       
   443         struct {
       
   444             uint32_t rbadr;
       
   445             int16_t buf_length;
       
   446             int16_t msg_length;
       
   447         } rda;
       
   448         rda.rbadr = cpu_to_le32((rmd->rbadr & 0xffffff) |
       
   449                                 ((rmd->status & 0xff00) << 16));
       
   450         rda.buf_length = cpu_to_le16(rmd->buf_length);
       
   451         rda.msg_length = cpu_to_le16(rmd->msg_length);
       
   452         s->phys_mem_write(s->dma_opaque, addr, (void *)&rda, sizeof(rda), 0);
       
   453     } else {
       
   454         struct {
       
   455             uint32_t rbadr;
       
   456             int16_t buf_length;
       
   457             int16_t status;
       
   458             uint32_t msg_length;
       
   459             uint32_t res;
       
   460         } rda;
       
   461         rda.rbadr = cpu_to_le32(rmd->rbadr);
       
   462         rda.buf_length = cpu_to_le16(rmd->buf_length);
       
   463         rda.status = cpu_to_le16(rmd->status);
       
   464         rda.msg_length = cpu_to_le32(rmd->msg_length);
       
   465         rda.res = cpu_to_le32(rmd->res);
       
   466         if (BCR_SWSTYLE(s) == 3) {
       
   467             uint32_t tmp = rda.rbadr;
       
   468             rda.rbadr = rda.msg_length;
       
   469             rda.msg_length = tmp;
       
   470         }
       
   471         s->phys_mem_write(s->dma_opaque, addr, (void *)&rda, sizeof(rda), 0);
       
   472     }
       
   473 }
       
   474 
       
   475 
       
   476 #define TMDLOAD(TMD,ADDR) pcnet_tmd_load(s,TMD,ADDR)
       
   477 
       
   478 #define TMDSTORE(TMD,ADDR) pcnet_tmd_store(s,TMD,ADDR)
       
   479 
       
   480 #define RMDLOAD(RMD,ADDR) pcnet_rmd_load(s,RMD,ADDR)
       
   481 
       
   482 #define RMDSTORE(RMD,ADDR) pcnet_rmd_store(s,RMD,ADDR)
       
   483 
       
   484 #if 1
       
   485 
       
   486 #define CHECK_RMD(ADDR,RES) do {                \
       
   487     struct pcnet_RMD rmd;                       \
       
   488     RMDLOAD(&rmd,(ADDR));                       \
       
   489     (RES) |= (GET_FIELD(rmd.buf_length, RMDL, ONES) != 15) \
       
   490           || (GET_FIELD(rmd.msg_length, RMDM, ZEROS) != 0); \
       
   491 } while (0)
       
   492 
       
   493 #define CHECK_TMD(ADDR,RES) do {                \
       
   494     struct pcnet_TMD tmd;                       \
       
   495     TMDLOAD(&tmd,(ADDR));                       \
       
   496     (RES) |= (GET_FIELD(tmd.length, TMDL, ONES) != 15); \
       
   497 } while (0)
       
   498 
       
   499 #else
       
   500 
       
   501 #define CHECK_RMD(ADDR,RES) do {                \
       
   502     switch (BCR_SWSTYLE(s)) {                   \
       
   503     case 0x00:                                  \
       
   504         do {                                    \
       
   505             uint16_t rda[4];                    \
       
   506             s->phys_mem_read(s->dma_opaque, (ADDR), \
       
   507                 (void *)&rda[0], sizeof(rda), 0); \
       
   508             (RES) |= (rda[2] & 0xf000)!=0xf000; \
       
   509             (RES) |= (rda[3] & 0xf000)!=0x0000; \
       
   510         } while (0);                            \
       
   511         break;                                  \
       
   512     case 0x01:                                  \
       
   513     case 0x02:                                  \
       
   514         do {                                    \
       
   515             uint32_t rda[4];                    \
       
   516             s->phys_mem_read(s->dma_opaque, (ADDR), \
       
   517                 (void *)&rda[0], sizeof(rda), 0); \
       
   518             (RES) |= (rda[1] & 0x0000f000L)!=0x0000f000L; \
       
   519             (RES) |= (rda[2] & 0x0000f000L)!=0x00000000L; \
       
   520         } while (0);                            \
       
   521         break;                                  \
       
   522     case 0x03:                                  \
       
   523         do {                                    \
       
   524             uint32_t rda[4];                    \
       
   525             s->phys_mem_read(s->dma_opaque, (ADDR), \
       
   526                 (void *)&rda[0], sizeof(rda), 0); \
       
   527             (RES) |= (rda[0] & 0x0000f000L)!=0x00000000L; \
       
   528             (RES) |= (rda[1] & 0x0000f000L)!=0x0000f000L; \
       
   529         } while (0);                            \
       
   530         break;                                  \
       
   531     }                                           \
       
   532 } while (0)
       
   533 
       
   534 #define CHECK_TMD(ADDR,RES) do {                \
       
   535     switch (BCR_SWSTYLE(s)) {                   \
       
   536     case 0x00:                                  \
       
   537         do {                                    \
       
   538             uint16_t xda[4];                    \
       
   539             s->phys_mem_read(s->dma_opaque, (ADDR), \
       
   540                 (void *)&xda[0], sizeof(xda), 0); \
       
   541             (RES) |= (xda[2] & 0xf000)!=0xf000; \
       
   542         } while (0);                            \
       
   543         break;                                  \
       
   544     case 0x01:                                  \
       
   545     case 0x02:                                  \
       
   546     case 0x03:                                  \
       
   547         do {                                    \
       
   548             uint32_t xda[4];                    \
       
   549             s->phys_mem_read(s->dma_opaque, (ADDR), \
       
   550                 (void *)&xda[0], sizeof(xda), 0); \
       
   551             (RES) |= (xda[1] & 0x0000f000L)!=0x0000f000L; \
       
   552         } while (0);                            \
       
   553         break;                                  \
       
   554     }                                           \
       
   555 } while (0)
       
   556 
       
   557 #endif
       
   558 
       
   559 #define PRINT_PKTHDR(BUF) do {                  \
       
   560     struct qemu_ether_header *hdr = (void *)(BUF); \
       
   561     printf("packet dhost=%02x:%02x:%02x:%02x:%02x:%02x, " \
       
   562            "shost=%02x:%02x:%02x:%02x:%02x:%02x, " \
       
   563            "type=0x%04x\n",                     \
       
   564            hdr->ether_dhost[0],hdr->ether_dhost[1],hdr->ether_dhost[2], \
       
   565            hdr->ether_dhost[3],hdr->ether_dhost[4],hdr->ether_dhost[5], \
       
   566            hdr->ether_shost[0],hdr->ether_shost[1],hdr->ether_shost[2], \
       
   567            hdr->ether_shost[3],hdr->ether_shost[4],hdr->ether_shost[5], \
       
   568            be16_to_cpu(hdr->ether_type));       \
       
   569 } while (0)
       
   570 
       
   571 #define MULTICAST_FILTER_LEN 8
       
   572 
       
   573 static inline uint32_t lnc_mchash(const uint8_t *ether_addr)
       
   574 {
       
   575 #define LNC_POLYNOMIAL          0xEDB88320UL
       
   576     uint32_t crc = 0xFFFFFFFF;
       
   577     int idx, bit;
       
   578     uint8_t data;
       
   579 
       
   580     for (idx = 0; idx < 6; idx++) {
       
   581         for (data = *ether_addr++, bit = 0; bit < MULTICAST_FILTER_LEN; bit++) {
       
   582             crc = (crc >> 1) ^ (((crc ^ data) & 1) ? LNC_POLYNOMIAL : 0);
       
   583             data >>= 1;
       
   584         }
       
   585     }
       
   586     return crc;
       
   587 #undef LNC_POLYNOMIAL
       
   588 }
       
   589 
       
   590 #define CRC(crc, ch)	 (crc = (crc >> 8) ^ crctab[(crc ^ (ch)) & 0xff])
       
   591 
       
   592 /* generated using the AUTODIN II polynomial
       
   593  *	x^32 + x^26 + x^23 + x^22 + x^16 +
       
   594  *	x^12 + x^11 + x^10 + x^8 + x^7 + x^5 + x^4 + x^2 + x^1 + 1
       
   595  */
       
   596 static const uint32_t crctab[256] = {
       
   597 	0x00000000, 0x77073096, 0xee0e612c, 0x990951ba,
       
   598 	0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3,
       
   599 	0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
       
   600 	0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91,
       
   601 	0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
       
   602 	0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
       
   603 	0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec,
       
   604 	0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5,
       
   605 	0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
       
   606 	0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
       
   607 	0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940,
       
   608 	0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
       
   609 	0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116,
       
   610 	0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f,
       
   611 	0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
       
   612 	0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d,
       
   613 	0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a,
       
   614 	0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
       
   615 	0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818,
       
   616 	0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
       
   617 	0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
       
   618 	0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457,
       
   619 	0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c,
       
   620 	0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
       
   621 	0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
       
   622 	0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb,
       
   623 	0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
       
   624 	0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9,
       
   625 	0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086,
       
   626 	0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
       
   627 	0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4,
       
   628 	0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad,
       
   629 	0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
       
   630 	0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683,
       
   631 	0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
       
   632 	0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
       
   633 	0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe,
       
   634 	0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7,
       
   635 	0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
       
   636 	0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
       
   637 	0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252,
       
   638 	0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
       
   639 	0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60,
       
   640 	0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79,
       
   641 	0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
       
   642 	0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f,
       
   643 	0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04,
       
   644 	0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
       
   645 	0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a,
       
   646 	0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
       
   647 	0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
       
   648 	0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21,
       
   649 	0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e,
       
   650 	0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
       
   651 	0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
       
   652 	0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45,
       
   653 	0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
       
   654 	0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db,
       
   655 	0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0,
       
   656 	0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
       
   657 	0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6,
       
   658 	0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf,
       
   659 	0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
       
   660 	0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d,
       
   661 };
       
   662 
       
   663 static inline int padr_match(PCNetState *s, const uint8_t *buf, int size)
       
   664 {
       
   665     struct qemu_ether_header *hdr = (void *)buf;
       
   666     uint8_t padr[6] = {
       
   667         s->csr[12] & 0xff, s->csr[12] >> 8,
       
   668         s->csr[13] & 0xff, s->csr[13] >> 8,
       
   669         s->csr[14] & 0xff, s->csr[14] >> 8
       
   670     };
       
   671     int result = (!CSR_DRCVPA(s)) && !memcmp(hdr->ether_dhost, padr, 6);
       
   672 #ifdef PCNET_DEBUG_MATCH
       
   673     printf("packet dhost=%02x:%02x:%02x:%02x:%02x:%02x, "
       
   674            "padr=%02x:%02x:%02x:%02x:%02x:%02x\n",
       
   675            hdr->ether_dhost[0],hdr->ether_dhost[1],hdr->ether_dhost[2],
       
   676            hdr->ether_dhost[3],hdr->ether_dhost[4],hdr->ether_dhost[5],
       
   677            padr[0],padr[1],padr[2],padr[3],padr[4],padr[5]);
       
   678     printf("padr_match result=%d\n", result);
       
   679 #endif
       
   680     return result;
       
   681 }
       
   682 
       
   683 static inline int padr_bcast(PCNetState *s, const uint8_t *buf, int size)
       
   684 {
       
   685     static const uint8_t BCAST[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
       
   686     struct qemu_ether_header *hdr = (void *)buf;
       
   687     int result = !CSR_DRCVBC(s) && !memcmp(hdr->ether_dhost, BCAST, 6);
       
   688 #ifdef PCNET_DEBUG_MATCH
       
   689     printf("padr_bcast result=%d\n", result);
       
   690 #endif
       
   691     return result;
       
   692 }
       
   693 
       
   694 static inline int ladr_match(PCNetState *s, const uint8_t *buf, int size)
       
   695 {
       
   696     struct qemu_ether_header *hdr = (void *)buf;
       
   697     if ((*(hdr->ether_dhost)&0x01) &&
       
   698         ((uint64_t *)&s->csr[8])[0] != 0LL) {
       
   699         uint8_t ladr[8] = {
       
   700             s->csr[8] & 0xff, s->csr[8] >> 8,
       
   701             s->csr[9] & 0xff, s->csr[9] >> 8,
       
   702             s->csr[10] & 0xff, s->csr[10] >> 8,
       
   703             s->csr[11] & 0xff, s->csr[11] >> 8
       
   704         };
       
   705         int index = lnc_mchash(hdr->ether_dhost) >> 26;
       
   706         return !!(ladr[index >> 3] & (1 << (index & 7)));
       
   707     }
       
   708     return 0;
       
   709 }
       
   710 
       
   711 static inline target_phys_addr_t pcnet_rdra_addr(PCNetState *s, int idx)
       
   712 {
       
   713     while (idx < 1) idx += CSR_RCVRL(s);
       
   714     return s->rdra + ((CSR_RCVRL(s) - idx) * (BCR_SWSTYLE(s) ? 16 : 8));
       
   715 }
       
   716 
       
   717 static inline int64_t pcnet_get_next_poll_time(PCNetState *s, int64_t current_time)
       
   718 {
       
   719     int64_t next_time = current_time +
       
   720         muldiv64(65536 - (CSR_SPND(s) ? 0 : CSR_POLL(s)),
       
   721                  ticks_per_sec, 33000000L);
       
   722     if (next_time <= current_time)
       
   723         next_time = current_time + 1;
       
   724     return next_time;
       
   725 }
       
   726 
       
   727 static void pcnet_poll(PCNetState *s);
       
   728 static void pcnet_poll_timer(void *opaque);
       
   729 
       
   730 static uint32_t pcnet_csr_readw(PCNetState *s, uint32_t rap);
       
   731 static void pcnet_csr_writew(PCNetState *s, uint32_t rap, uint32_t new_value);
       
   732 static void pcnet_bcr_writew(PCNetState *s, uint32_t rap, uint32_t val);
       
   733 static uint32_t pcnet_bcr_readw(PCNetState *s, uint32_t rap);
       
   734 
       
   735 static void pcnet_s_reset(PCNetState *s)
       
   736 {
       
   737 #ifdef PCNET_DEBUG
       
   738     printf("pcnet_s_reset\n");
       
   739 #endif
       
   740 
       
   741     s->lnkst = 0x40;
       
   742     s->rdra = 0;
       
   743     s->tdra = 0;
       
   744     s->rap = 0;
       
   745 
       
   746     s->bcr[BCR_BSBC] &= ~0x0080;
       
   747 
       
   748     s->csr[0]   = 0x0004;
       
   749     s->csr[3]   = 0x0000;
       
   750     s->csr[4]   = 0x0115;
       
   751     s->csr[5]   = 0x0000;
       
   752     s->csr[6]   = 0x0000;
       
   753     s->csr[8]   = 0;
       
   754     s->csr[9]   = 0;
       
   755     s->csr[10]  = 0;
       
   756     s->csr[11]  = 0;
       
   757     s->csr[12]  = le16_to_cpu(((uint16_t *)&s->prom[0])[0]);
       
   758     s->csr[13]  = le16_to_cpu(((uint16_t *)&s->prom[0])[1]);
       
   759     s->csr[14]  = le16_to_cpu(((uint16_t *)&s->prom[0])[2]);
       
   760     s->csr[15] &= 0x21c4;
       
   761     s->csr[72]  = 1;
       
   762     s->csr[74]  = 1;
       
   763     s->csr[76]  = 1;
       
   764     s->csr[78]  = 1;
       
   765     s->csr[80]  = 0x1410;
       
   766     s->csr[88]  = 0x1003;
       
   767     s->csr[89]  = 0x0262;
       
   768     s->csr[94]  = 0x0000;
       
   769     s->csr[100] = 0x0200;
       
   770     s->csr[103] = 0x0105;
       
   771     s->csr[103] = 0x0105;
       
   772     s->csr[112] = 0x0000;
       
   773     s->csr[114] = 0x0000;
       
   774     s->csr[122] = 0x0000;
       
   775     s->csr[124] = 0x0000;
       
   776 
       
   777     s->tx_busy = 0;
       
   778 }
       
   779 
       
   780 static void pcnet_update_irq(PCNetState *s)
       
   781 {
       
   782     int isr = 0;
       
   783     s->csr[0] &= ~0x0080;
       
   784 
       
   785 #if 1
       
   786     if (((s->csr[0] & ~s->csr[3]) & 0x5f00) ||
       
   787         (((s->csr[4]>>1) & ~s->csr[4]) & 0x0115) ||
       
   788         (((s->csr[5]>>1) & s->csr[5]) & 0x0048))
       
   789 #else
       
   790     if ((!(s->csr[3] & 0x4000) && !!(s->csr[0] & 0x4000)) /* BABL */ ||
       
   791         (!(s->csr[3] & 0x1000) && !!(s->csr[0] & 0x1000)) /* MISS */ ||
       
   792         (!(s->csr[3] & 0x0100) && !!(s->csr[0] & 0x0100)) /* IDON */ ||
       
   793         (!(s->csr[3] & 0x0200) && !!(s->csr[0] & 0x0200)) /* TINT */ ||
       
   794         (!(s->csr[3] & 0x0400) && !!(s->csr[0] & 0x0400)) /* RINT */ ||
       
   795         (!(s->csr[3] & 0x0800) && !!(s->csr[0] & 0x0800)) /* MERR */ ||
       
   796         (!(s->csr[4] & 0x0001) && !!(s->csr[4] & 0x0002)) /* JAB */ ||
       
   797         (!(s->csr[4] & 0x0004) && !!(s->csr[4] & 0x0008)) /* TXSTRT */ ||
       
   798         (!(s->csr[4] & 0x0010) && !!(s->csr[4] & 0x0020)) /* RCVO */ ||
       
   799         (!(s->csr[4] & 0x0100) && !!(s->csr[4] & 0x0200)) /* MFCO */ ||
       
   800         (!!(s->csr[5] & 0x0040) && !!(s->csr[5] & 0x0080)) /* EXDINT */ ||
       
   801         (!!(s->csr[5] & 0x0008) && !!(s->csr[5] & 0x0010)) /* MPINT */)
       
   802 #endif
       
   803     {
       
   804 
       
   805         isr = CSR_INEA(s);
       
   806         s->csr[0] |= 0x0080;
       
   807     }
       
   808 
       
   809     if (!!(s->csr[4] & 0x0080) && CSR_INEA(s)) { /* UINT */
       
   810         s->csr[4] &= ~0x0080;
       
   811         s->csr[4] |= 0x0040;
       
   812         s->csr[0] |= 0x0080;
       
   813         isr = 1;
       
   814 #ifdef PCNET_DEBUG
       
   815         printf("pcnet user int\n");
       
   816 #endif
       
   817     }
       
   818 
       
   819 #if 1
       
   820     if (((s->csr[5]>>1) & s->csr[5]) & 0x0500)
       
   821 #else
       
   822     if ((!!(s->csr[5] & 0x0400) && !!(s->csr[5] & 0x0800)) /* SINT */ ||
       
   823         (!!(s->csr[5] & 0x0100) && !!(s->csr[5] & 0x0200)) /* SLPINT */ )
       
   824 #endif
       
   825     {
       
   826         isr = 1;
       
   827         s->csr[0] |= 0x0080;
       
   828     }
       
   829 
       
   830     if (isr != s->isr) {
       
   831 #ifdef PCNET_DEBUG
       
   832         printf("pcnet: INTA=%d\n", isr);
       
   833 #endif
       
   834     }
       
   835     qemu_set_irq(s->irq, isr);
       
   836     s->isr = isr;
       
   837 }
       
   838 
       
   839 static void pcnet_init(PCNetState *s)
       
   840 {
       
   841     int rlen, tlen;
       
   842     uint16_t padr[3], ladrf[4], mode;
       
   843     uint32_t rdra, tdra;
       
   844 
       
   845 #ifdef PCNET_DEBUG
       
   846     printf("pcnet_init init_addr=0x%08x\n", PHYSADDR(s,CSR_IADR(s)));
       
   847 #endif
       
   848 
       
   849     if (BCR_SSIZE32(s)) {
       
   850         struct pcnet_initblk32 initblk;
       
   851         s->phys_mem_read(s->dma_opaque, PHYSADDR(s,CSR_IADR(s)),
       
   852                 (uint8_t *)&initblk, sizeof(initblk), 0);
       
   853         mode = le16_to_cpu(initblk.mode);
       
   854         rlen = initblk.rlen >> 4;
       
   855         tlen = initblk.tlen >> 4;
       
   856 	ladrf[0] = le16_to_cpu(initblk.ladrf[0]);
       
   857 	ladrf[1] = le16_to_cpu(initblk.ladrf[1]);
       
   858 	ladrf[2] = le16_to_cpu(initblk.ladrf[2]);
       
   859 	ladrf[3] = le16_to_cpu(initblk.ladrf[3]);
       
   860 	padr[0] = le16_to_cpu(initblk.padr[0]);
       
   861 	padr[1] = le16_to_cpu(initblk.padr[1]);
       
   862 	padr[2] = le16_to_cpu(initblk.padr[2]);
       
   863         rdra = le32_to_cpu(initblk.rdra);
       
   864         tdra = le32_to_cpu(initblk.tdra);
       
   865     } else {
       
   866         struct pcnet_initblk16 initblk;
       
   867         s->phys_mem_read(s->dma_opaque, PHYSADDR(s,CSR_IADR(s)),
       
   868                 (uint8_t *)&initblk, sizeof(initblk), 0);
       
   869         mode = le16_to_cpu(initblk.mode);
       
   870 	ladrf[0] = le16_to_cpu(initblk.ladrf[0]);
       
   871 	ladrf[1] = le16_to_cpu(initblk.ladrf[1]);
       
   872 	ladrf[2] = le16_to_cpu(initblk.ladrf[2]);
       
   873 	ladrf[3] = le16_to_cpu(initblk.ladrf[3]);
       
   874 	padr[0] = le16_to_cpu(initblk.padr[0]);
       
   875 	padr[1] = le16_to_cpu(initblk.padr[1]);
       
   876 	padr[2] = le16_to_cpu(initblk.padr[2]);
       
   877         rdra = le32_to_cpu(initblk.rdra);
       
   878         tdra = le32_to_cpu(initblk.tdra);
       
   879         rlen = rdra >> 29;
       
   880         tlen = tdra >> 29;
       
   881         rdra &= 0x00ffffff;
       
   882         tdra &= 0x00ffffff;
       
   883     }
       
   884 
       
   885 #if defined(PCNET_DEBUG)
       
   886     printf("rlen=%d tlen=%d\n", rlen, tlen);
       
   887 #endif
       
   888 
       
   889     CSR_RCVRL(s) = (rlen < 9) ? (1 << rlen) : 512;
       
   890     CSR_XMTRL(s) = (tlen < 9) ? (1 << tlen) : 512;
       
   891     s->csr[ 6] = (tlen << 12) | (rlen << 8);
       
   892     s->csr[15] = mode;
       
   893     s->csr[ 8] = ladrf[0];
       
   894     s->csr[ 9] = ladrf[1];
       
   895     s->csr[10] = ladrf[2];
       
   896     s->csr[11] = ladrf[3];
       
   897     s->csr[12] = padr[0];
       
   898     s->csr[13] = padr[1];
       
   899     s->csr[14] = padr[2];
       
   900     s->rdra = PHYSADDR(s, rdra);
       
   901     s->tdra = PHYSADDR(s, tdra);
       
   902 
       
   903     CSR_RCVRC(s) = CSR_RCVRL(s);
       
   904     CSR_XMTRC(s) = CSR_XMTRL(s);
       
   905 
       
   906 #ifdef PCNET_DEBUG
       
   907     printf("pcnet ss32=%d rdra=0x%08x[%d] tdra=0x%08x[%d]\n",
       
   908         BCR_SSIZE32(s),
       
   909         s->rdra, CSR_RCVRL(s), s->tdra, CSR_XMTRL(s));
       
   910 #endif
       
   911 
       
   912     s->csr[0] |= 0x0101;
       
   913     s->csr[0] &= ~0x0004;       /* clear STOP bit */
       
   914 }
       
   915 
       
   916 static void pcnet_start(PCNetState *s)
       
   917 {
       
   918 #ifdef PCNET_DEBUG
       
   919     printf("pcnet_start\n");
       
   920 #endif
       
   921 
       
   922     if (!CSR_DTX(s))
       
   923         s->csr[0] |= 0x0010;    /* set TXON */
       
   924 
       
   925     if (!CSR_DRX(s))
       
   926         s->csr[0] |= 0x0020;    /* set RXON */
       
   927 
       
   928     s->csr[0] &= ~0x0004;       /* clear STOP bit */
       
   929     s->csr[0] |= 0x0002;
       
   930 }
       
   931 
       
   932 static void pcnet_stop(PCNetState *s)
       
   933 {
       
   934 #ifdef PCNET_DEBUG
       
   935     printf("pcnet_stop\n");
       
   936 #endif
       
   937     s->csr[0] &= ~0x7feb;
       
   938     s->csr[0] |= 0x0014;
       
   939     s->csr[4] &= ~0x02c2;
       
   940     s->csr[5] &= ~0x0011;
       
   941     pcnet_poll_timer(s);
       
   942 }
       
   943 
       
   944 static void pcnet_rdte_poll(PCNetState *s)
       
   945 {
       
   946     s->csr[28] = s->csr[29] = 0;
       
   947     if (s->rdra) {
       
   948         int bad = 0;
       
   949 #if 1
       
   950         target_phys_addr_t crda = pcnet_rdra_addr(s, CSR_RCVRC(s));
       
   951         target_phys_addr_t nrda = pcnet_rdra_addr(s, -1 + CSR_RCVRC(s));
       
   952         target_phys_addr_t nnrd = pcnet_rdra_addr(s, -2 + CSR_RCVRC(s));
       
   953 #else
       
   954         target_phys_addr_t crda = s->rdra +
       
   955             (CSR_RCVRL(s) - CSR_RCVRC(s)) *
       
   956             (BCR_SWSTYLE(s) ? 16 : 8 );
       
   957         int nrdc = CSR_RCVRC(s)<=1 ? CSR_RCVRL(s) : CSR_RCVRC(s)-1;
       
   958         target_phys_addr_t nrda = s->rdra +
       
   959             (CSR_RCVRL(s) - nrdc) *
       
   960             (BCR_SWSTYLE(s) ? 16 : 8 );
       
   961         int nnrc = nrdc<=1 ? CSR_RCVRL(s) : nrdc-1;
       
   962         target_phys_addr_t nnrd = s->rdra +
       
   963             (CSR_RCVRL(s) - nnrc) *
       
   964             (BCR_SWSTYLE(s) ? 16 : 8 );
       
   965 #endif
       
   966 
       
   967         CHECK_RMD(PHYSADDR(s,crda), bad);
       
   968         if (!bad) {
       
   969             CHECK_RMD(PHYSADDR(s,nrda), bad);
       
   970             if (bad || (nrda == crda)) nrda = 0;
       
   971             CHECK_RMD(PHYSADDR(s,nnrd), bad);
       
   972             if (bad || (nnrd == crda)) nnrd = 0;
       
   973 
       
   974             s->csr[28] = crda & 0xffff;
       
   975             s->csr[29] = crda >> 16;
       
   976             s->csr[26] = nrda & 0xffff;
       
   977             s->csr[27] = nrda >> 16;
       
   978             s->csr[36] = nnrd & 0xffff;
       
   979             s->csr[37] = nnrd >> 16;
       
   980 #ifdef PCNET_DEBUG
       
   981             if (bad) {
       
   982                 printf("pcnet: BAD RMD RECORDS AFTER 0x" TARGET_FMT_plx "\n",
       
   983                        PHYSADDR(s,crda));
       
   984             }
       
   985         } else {
       
   986             printf("pcnet: BAD RMD RDA=0x" TARGET_FMT_plx "\n",
       
   987                    PHYSADDR(s,crda));
       
   988 #endif
       
   989         }
       
   990     }
       
   991 
       
   992     if (CSR_CRDA(s)) {
       
   993         struct pcnet_RMD rmd;
       
   994         RMDLOAD(&rmd, PHYSADDR(s,CSR_CRDA(s)));
       
   995         CSR_CRBC(s) = GET_FIELD(rmd.buf_length, RMDL, BCNT);
       
   996         CSR_CRST(s) = rmd.status;
       
   997 #ifdef PCNET_DEBUG_RMD_X
       
   998         printf("CRDA=0x%08x CRST=0x%04x RCVRC=%d RMDL=0x%04x RMDS=0x%04x RMDM=0x%08x\n",
       
   999                 PHYSADDR(s,CSR_CRDA(s)), CSR_CRST(s), CSR_RCVRC(s),
       
  1000                 rmd.buf_length, rmd.status, rmd.msg_length);
       
  1001         PRINT_RMD(&rmd);
       
  1002 #endif
       
  1003     } else {
       
  1004         CSR_CRBC(s) = CSR_CRST(s) = 0;
       
  1005     }
       
  1006 
       
  1007     if (CSR_NRDA(s)) {
       
  1008         struct pcnet_RMD rmd;
       
  1009         RMDLOAD(&rmd, PHYSADDR(s,CSR_NRDA(s)));
       
  1010         CSR_NRBC(s) = GET_FIELD(rmd.buf_length, RMDL, BCNT);
       
  1011         CSR_NRST(s) = rmd.status;
       
  1012     } else {
       
  1013         CSR_NRBC(s) = CSR_NRST(s) = 0;
       
  1014     }
       
  1015 
       
  1016 }
       
  1017 
       
  1018 static int pcnet_tdte_poll(PCNetState *s)
       
  1019 {
       
  1020     s->csr[34] = s->csr[35] = 0;
       
  1021     if (s->tdra) {
       
  1022         target_phys_addr_t cxda = s->tdra +
       
  1023             (CSR_XMTRL(s) - CSR_XMTRC(s)) *
       
  1024             (BCR_SWSTYLE(s) ? 16 : 8);
       
  1025         int bad = 0;
       
  1026         CHECK_TMD(PHYSADDR(s, cxda),bad);
       
  1027         if (!bad) {
       
  1028             if (CSR_CXDA(s) != cxda) {
       
  1029                 s->csr[60] = s->csr[34];
       
  1030                 s->csr[61] = s->csr[35];
       
  1031                 s->csr[62] = CSR_CXBC(s);
       
  1032                 s->csr[63] = CSR_CXST(s);
       
  1033             }
       
  1034             s->csr[34] = cxda & 0xffff;
       
  1035             s->csr[35] = cxda >> 16;
       
  1036 #ifdef PCNET_DEBUG_X
       
  1037             printf("pcnet: BAD TMD XDA=0x%08x\n", PHYSADDR(s,cxda));
       
  1038 #endif
       
  1039         }
       
  1040     }
       
  1041 
       
  1042     if (CSR_CXDA(s)) {
       
  1043         struct pcnet_TMD tmd;
       
  1044 
       
  1045         TMDLOAD(&tmd, PHYSADDR(s,CSR_CXDA(s)));
       
  1046 
       
  1047         CSR_CXBC(s) = GET_FIELD(tmd.length, TMDL, BCNT);
       
  1048         CSR_CXST(s) = tmd.status;
       
  1049     } else {
       
  1050         CSR_CXBC(s) = CSR_CXST(s) = 0;
       
  1051     }
       
  1052 
       
  1053     return !!(CSR_CXST(s) & 0x8000);
       
  1054 }
       
  1055 
       
  1056 static int pcnet_can_receive(void *opaque)
       
  1057 {
       
  1058     PCNetState *s = opaque;
       
  1059     if (CSR_STOP(s) || CSR_SPND(s))
       
  1060         return 0;
       
  1061 
       
  1062     if (s->recv_pos > 0)
       
  1063         return 0;
       
  1064 
       
  1065     return sizeof(s->buffer)-16;
       
  1066 }
       
  1067 
       
  1068 #define MIN_BUF_SIZE 60
       
  1069 
       
  1070 static void pcnet_receive(void *opaque, const uint8_t *buf, int size)
       
  1071 {
       
  1072     PCNetState *s = opaque;
       
  1073     int is_padr = 0, is_bcast = 0, is_ladr = 0;
       
  1074     uint8_t buf1[60];
       
  1075     int remaining;
       
  1076     int crc_err = 0;
       
  1077 
       
  1078     if (CSR_DRX(s) || CSR_STOP(s) || CSR_SPND(s) || !size)
       
  1079         return;
       
  1080 
       
  1081 #ifdef PCNET_DEBUG
       
  1082     printf("pcnet_receive size=%d\n", size);
       
  1083 #endif
       
  1084 
       
  1085     /* if too small buffer, then expand it */
       
  1086     if (size < MIN_BUF_SIZE) {
       
  1087         memcpy(buf1, buf, size);
       
  1088         memset(buf1 + size, 0, MIN_BUF_SIZE - size);
       
  1089         buf = buf1;
       
  1090         size = MIN_BUF_SIZE;
       
  1091     }
       
  1092 
       
  1093     if (CSR_PROM(s)
       
  1094         || (is_padr=padr_match(s, buf, size))
       
  1095         || (is_bcast=padr_bcast(s, buf, size))
       
  1096         || (is_ladr=ladr_match(s, buf, size))) {
       
  1097 
       
  1098         pcnet_rdte_poll(s);
       
  1099 
       
  1100         if (!(CSR_CRST(s) & 0x8000) && s->rdra) {
       
  1101             struct pcnet_RMD rmd;
       
  1102             int rcvrc = CSR_RCVRC(s)-1,i;
       
  1103             target_phys_addr_t nrda;
       
  1104             for (i = CSR_RCVRL(s)-1; i > 0; i--, rcvrc--) {
       
  1105                 if (rcvrc <= 1)
       
  1106                     rcvrc = CSR_RCVRL(s);
       
  1107                 nrda = s->rdra +
       
  1108                     (CSR_RCVRL(s) - rcvrc) *
       
  1109                     (BCR_SWSTYLE(s) ? 16 : 8 );
       
  1110                 RMDLOAD(&rmd, PHYSADDR(s,nrda));
       
  1111                 if (GET_FIELD(rmd.status, RMDS, OWN)) {
       
  1112 #ifdef PCNET_DEBUG_RMD
       
  1113                     printf("pcnet - scan buffer: RCVRC=%d PREV_RCVRC=%d\n",
       
  1114                                 rcvrc, CSR_RCVRC(s));
       
  1115 #endif
       
  1116                     CSR_RCVRC(s) = rcvrc;
       
  1117                     pcnet_rdte_poll(s);
       
  1118                     break;
       
  1119                 }
       
  1120             }
       
  1121         }
       
  1122 
       
  1123         if (!(CSR_CRST(s) & 0x8000)) {
       
  1124 #ifdef PCNET_DEBUG_RMD
       
  1125             printf("pcnet - no buffer: RCVRC=%d\n", CSR_RCVRC(s));
       
  1126 #endif
       
  1127             s->csr[0] |= 0x1000; /* Set MISS flag */
       
  1128             CSR_MISSC(s)++;
       
  1129         } else {
       
  1130             uint8_t *src = s->buffer;
       
  1131             target_phys_addr_t crda = CSR_CRDA(s);
       
  1132             struct pcnet_RMD rmd;
       
  1133             int pktcount = 0;
       
  1134 
       
  1135             if (!s->looptest) {
       
  1136                 memcpy(src, buf, size);
       
  1137                 /* no need to compute the CRC */
       
  1138                 src[size] = 0;
       
  1139                 src[size + 1] = 0;
       
  1140                 src[size + 2] = 0;
       
  1141                 src[size + 3] = 0;
       
  1142                 size += 4;
       
  1143             } else if (s->looptest == PCNET_LOOPTEST_CRC ||
       
  1144                        !CSR_DXMTFCS(s) || size < MIN_BUF_SIZE+4) {
       
  1145                 uint32_t fcs = ~0;
       
  1146                 uint8_t *p = src;
       
  1147 
       
  1148                 while (p != &src[size])
       
  1149                     CRC(fcs, *p++);
       
  1150                 *(uint32_t *)p = htonl(fcs);
       
  1151                 size += 4;
       
  1152             } else {
       
  1153                 uint32_t fcs = ~0;
       
  1154                 uint8_t *p = src;
       
  1155 
       
  1156                 while (p != &src[size-4])
       
  1157                     CRC(fcs, *p++);
       
  1158                 crc_err = (*(uint32_t *)p != htonl(fcs));
       
  1159             }
       
  1160 
       
  1161 #ifdef PCNET_DEBUG_MATCH
       
  1162             PRINT_PKTHDR(buf);
       
  1163 #endif
       
  1164 
       
  1165             RMDLOAD(&rmd, PHYSADDR(s,crda));
       
  1166             /*if (!CSR_LAPPEN(s))*/
       
  1167                 SET_FIELD(&rmd.status, RMDS, STP, 1);
       
  1168 
       
  1169 #define PCNET_RECV_STORE() do {                                 \
       
  1170     int count = MIN(4096 - GET_FIELD(rmd.buf_length, RMDL, BCNT),remaining); \
       
  1171     target_phys_addr_t rbadr = PHYSADDR(s, rmd.rbadr);          \
       
  1172     s->phys_mem_write(s->dma_opaque, rbadr, src, count, CSR_BSWP(s)); \
       
  1173     src += count; remaining -= count;                           \
       
  1174     SET_FIELD(&rmd.status, RMDS, OWN, 0);                       \
       
  1175     RMDSTORE(&rmd, PHYSADDR(s,crda));                           \
       
  1176     pktcount++;                                                 \
       
  1177 } while (0)
       
  1178 
       
  1179             remaining = size;
       
  1180             PCNET_RECV_STORE();
       
  1181             if ((remaining > 0) && CSR_NRDA(s)) {
       
  1182                 target_phys_addr_t nrda = CSR_NRDA(s);
       
  1183 #ifdef PCNET_DEBUG_RMD
       
  1184                 PRINT_RMD(&rmd);
       
  1185 #endif
       
  1186                 RMDLOAD(&rmd, PHYSADDR(s,nrda));
       
  1187                 if (GET_FIELD(rmd.status, RMDS, OWN)) {
       
  1188                     crda = nrda;
       
  1189                     PCNET_RECV_STORE();
       
  1190 #ifdef PCNET_DEBUG_RMD
       
  1191                     PRINT_RMD(&rmd);
       
  1192 #endif
       
  1193                     if ((remaining > 0) && (nrda=CSR_NNRD(s))) {
       
  1194                         RMDLOAD(&rmd, PHYSADDR(s,nrda));
       
  1195                         if (GET_FIELD(rmd.status, RMDS, OWN)) {
       
  1196                             crda = nrda;
       
  1197                             PCNET_RECV_STORE();
       
  1198                         }
       
  1199                     }
       
  1200                 }
       
  1201             }
       
  1202 
       
  1203 #undef PCNET_RECV_STORE
       
  1204 
       
  1205             RMDLOAD(&rmd, PHYSADDR(s,crda));
       
  1206             if (remaining == 0) {
       
  1207                 SET_FIELD(&rmd.msg_length, RMDM, MCNT, size);
       
  1208                 SET_FIELD(&rmd.status, RMDS, ENP, 1);
       
  1209                 SET_FIELD(&rmd.status, RMDS, PAM, !CSR_PROM(s) && is_padr);
       
  1210                 SET_FIELD(&rmd.status, RMDS, LFAM, !CSR_PROM(s) && is_ladr);
       
  1211                 SET_FIELD(&rmd.status, RMDS, BAM, !CSR_PROM(s) && is_bcast);
       
  1212                 if (crc_err) {
       
  1213                     SET_FIELD(&rmd.status, RMDS, CRC, 1);
       
  1214                     SET_FIELD(&rmd.status, RMDS, ERR, 1);
       
  1215                 }
       
  1216             } else {
       
  1217                 SET_FIELD(&rmd.status, RMDS, OFLO, 1);
       
  1218                 SET_FIELD(&rmd.status, RMDS, BUFF, 1);
       
  1219                 SET_FIELD(&rmd.status, RMDS, ERR, 1);
       
  1220             }
       
  1221             RMDSTORE(&rmd, PHYSADDR(s,crda));
       
  1222             s->csr[0] |= 0x0400;
       
  1223 
       
  1224 #ifdef PCNET_DEBUG
       
  1225             printf("RCVRC=%d CRDA=0x%08x BLKS=%d\n",
       
  1226                 CSR_RCVRC(s), PHYSADDR(s,CSR_CRDA(s)), pktcount);
       
  1227 #endif
       
  1228 #ifdef PCNET_DEBUG_RMD
       
  1229             PRINT_RMD(&rmd);
       
  1230 #endif
       
  1231 
       
  1232             while (pktcount--) {
       
  1233                 if (CSR_RCVRC(s) <= 1)
       
  1234                     CSR_RCVRC(s) = CSR_RCVRL(s);
       
  1235                 else
       
  1236                     CSR_RCVRC(s)--;
       
  1237             }
       
  1238 
       
  1239             pcnet_rdte_poll(s);
       
  1240 
       
  1241         }
       
  1242     }
       
  1243 
       
  1244     pcnet_poll(s);
       
  1245     pcnet_update_irq(s);
       
  1246 }
       
  1247 
       
  1248 static void pcnet_transmit(PCNetState *s)
       
  1249 {
       
  1250     target_phys_addr_t xmit_cxda = 0;
       
  1251     int count = CSR_XMTRL(s)-1;
       
  1252     int add_crc = 0;
       
  1253 
       
  1254     s->xmit_pos = -1;
       
  1255 
       
  1256     if (!CSR_TXON(s)) {
       
  1257         s->csr[0] &= ~0x0008;
       
  1258         return;
       
  1259     }
       
  1260 
       
  1261     s->tx_busy = 1;
       
  1262 
       
  1263     txagain:
       
  1264     if (pcnet_tdte_poll(s)) {
       
  1265         struct pcnet_TMD tmd;
       
  1266 
       
  1267         TMDLOAD(&tmd, PHYSADDR(s,CSR_CXDA(s)));
       
  1268 
       
  1269 #ifdef PCNET_DEBUG_TMD
       
  1270         printf("  TMDLOAD 0x%08x\n", PHYSADDR(s,CSR_CXDA(s)));
       
  1271         PRINT_TMD(&tmd);
       
  1272 #endif
       
  1273         if (GET_FIELD(tmd.status, TMDS, STP)) {
       
  1274             s->xmit_pos = 0;
       
  1275             xmit_cxda = PHYSADDR(s,CSR_CXDA(s));
       
  1276             if (BCR_SWSTYLE(s) != 1)
       
  1277                 add_crc = GET_FIELD(tmd.status, TMDS, ADDFCS);
       
  1278         }
       
  1279         if (!GET_FIELD(tmd.status, TMDS, ENP)) {
       
  1280             int bcnt = 4096 - GET_FIELD(tmd.length, TMDL, BCNT);
       
  1281             s->phys_mem_read(s->dma_opaque, PHYSADDR(s, tmd.tbadr),
       
  1282                              s->buffer + s->xmit_pos, bcnt, CSR_BSWP(s));
       
  1283             s->xmit_pos += bcnt;
       
  1284         } else if (s->xmit_pos >= 0) {
       
  1285             int bcnt = 4096 - GET_FIELD(tmd.length, TMDL, BCNT);
       
  1286             s->phys_mem_read(s->dma_opaque, PHYSADDR(s, tmd.tbadr),
       
  1287                              s->buffer + s->xmit_pos, bcnt, CSR_BSWP(s));
       
  1288             s->xmit_pos += bcnt;
       
  1289 #ifdef PCNET_DEBUG
       
  1290             printf("pcnet_transmit size=%d\n", s->xmit_pos);
       
  1291 #endif
       
  1292             if (CSR_LOOP(s)) {
       
  1293                 if (BCR_SWSTYLE(s) == 1)
       
  1294                     add_crc = !GET_FIELD(tmd.status, TMDS, NOFCS);
       
  1295                 s->looptest = add_crc ? PCNET_LOOPTEST_CRC : PCNET_LOOPTEST_NOCRC;
       
  1296                 pcnet_receive(s, s->buffer, s->xmit_pos);
       
  1297                 s->looptest = 0;
       
  1298             } else
       
  1299                 if (s->vc)
       
  1300                     qemu_send_packet(s->vc, s->buffer, s->xmit_pos);
       
  1301 
       
  1302             s->csr[0] &= ~0x0008;   /* clear TDMD */
       
  1303             s->csr[4] |= 0x0004;    /* set TXSTRT */
       
  1304             s->xmit_pos = -1;
       
  1305         }
       
  1306 
       
  1307         SET_FIELD(&tmd.status, TMDS, OWN, 0);
       
  1308         TMDSTORE(&tmd, PHYSADDR(s,CSR_CXDA(s)));
       
  1309         if (!CSR_TOKINTD(s) || (CSR_LTINTEN(s) && GET_FIELD(tmd.status, TMDS, LTINT)))
       
  1310             s->csr[0] |= 0x0200;    /* set TINT */
       
  1311 
       
  1312         if (CSR_XMTRC(s)<=1)
       
  1313             CSR_XMTRC(s) = CSR_XMTRL(s);
       
  1314         else
       
  1315             CSR_XMTRC(s)--;
       
  1316         if (count--)
       
  1317             goto txagain;
       
  1318 
       
  1319     } else
       
  1320     if (s->xmit_pos >= 0) {
       
  1321         struct pcnet_TMD tmd;
       
  1322         TMDLOAD(&tmd, PHYSADDR(s,xmit_cxda));
       
  1323         SET_FIELD(&tmd.misc, TMDM, BUFF, 1);
       
  1324         SET_FIELD(&tmd.misc, TMDM, UFLO, 1);
       
  1325         SET_FIELD(&tmd.status, TMDS, ERR, 1);
       
  1326         SET_FIELD(&tmd.status, TMDS, OWN, 0);
       
  1327         TMDSTORE(&tmd, PHYSADDR(s,xmit_cxda));
       
  1328         s->csr[0] |= 0x0200;    /* set TINT */
       
  1329         if (!CSR_DXSUFLO(s)) {
       
  1330             s->csr[0] &= ~0x0010;
       
  1331         } else
       
  1332         if (count--)
       
  1333           goto txagain;
       
  1334     }
       
  1335 
       
  1336     s->tx_busy = 0;
       
  1337 }
       
  1338 
       
  1339 static void pcnet_poll(PCNetState *s)
       
  1340 {
       
  1341     if (CSR_RXON(s)) {
       
  1342         pcnet_rdte_poll(s);
       
  1343     }
       
  1344 
       
  1345     if (CSR_TDMD(s) ||
       
  1346         (CSR_TXON(s) && !CSR_DPOLL(s) && pcnet_tdte_poll(s)))
       
  1347     {
       
  1348         /* prevent recursion */
       
  1349         if (s->tx_busy)
       
  1350             return;
       
  1351 
       
  1352         pcnet_transmit(s);
       
  1353     }
       
  1354 }
       
  1355 
       
  1356 static void pcnet_poll_timer(void *opaque)
       
  1357 {
       
  1358     PCNetState *s = opaque;
       
  1359 
       
  1360     qemu_del_timer(s->poll_timer);
       
  1361 
       
  1362     if (CSR_TDMD(s)) {
       
  1363         pcnet_transmit(s);
       
  1364     }
       
  1365 
       
  1366     pcnet_update_irq(s);
       
  1367 
       
  1368     if (!CSR_STOP(s) && !CSR_SPND(s) && !CSR_DPOLL(s)) {
       
  1369         uint64_t now = qemu_get_clock(vm_clock) * 33;
       
  1370         if (!s->timer || !now)
       
  1371             s->timer = now;
       
  1372         else {
       
  1373             uint64_t t = now - s->timer + CSR_POLL(s);
       
  1374             if (t > 0xffffLL) {
       
  1375                 pcnet_poll(s);
       
  1376                 CSR_POLL(s) = CSR_PINT(s);
       
  1377             } else
       
  1378                 CSR_POLL(s) = t;
       
  1379         }
       
  1380         qemu_mod_timer(s->poll_timer,
       
  1381             pcnet_get_next_poll_time(s,qemu_get_clock(vm_clock)));
       
  1382     }
       
  1383 }
       
  1384 
       
  1385 
       
  1386 static void pcnet_csr_writew(PCNetState *s, uint32_t rap, uint32_t new_value)
       
  1387 {
       
  1388     uint16_t val = new_value;
       
  1389 #ifdef PCNET_DEBUG_CSR
       
  1390     printf("pcnet_csr_writew rap=%d val=0x%04x\n", rap, val);
       
  1391 #endif
       
  1392     switch (rap) {
       
  1393     case 0:
       
  1394         s->csr[0] &= ~(val & 0x7f00); /* Clear any interrupt flags */
       
  1395 
       
  1396         s->csr[0] = (s->csr[0] & ~0x0040) | (val & 0x0048);
       
  1397 
       
  1398         val = (val & 0x007f) | (s->csr[0] & 0x7f00);
       
  1399 
       
  1400         /* IFF STOP, STRT and INIT are set, clear STRT and INIT */
       
  1401         if ((val&7) == 7)
       
  1402           val &= ~3;
       
  1403 
       
  1404         if (!CSR_STOP(s) && (val & 4))
       
  1405             pcnet_stop(s);
       
  1406 
       
  1407         if (!CSR_INIT(s) && (val & 1))
       
  1408             pcnet_init(s);
       
  1409 
       
  1410         if (!CSR_STRT(s) && (val & 2))
       
  1411             pcnet_start(s);
       
  1412 
       
  1413         if (CSR_TDMD(s))
       
  1414             pcnet_transmit(s);
       
  1415 
       
  1416         return;
       
  1417     case 1:
       
  1418     case 2:
       
  1419     case 8:
       
  1420     case 9:
       
  1421     case 10:
       
  1422     case 11:
       
  1423     case 12:
       
  1424     case 13:
       
  1425     case 14:
       
  1426     case 15:
       
  1427     case 18: /* CRBAL */
       
  1428     case 19: /* CRBAU */
       
  1429     case 20: /* CXBAL */
       
  1430     case 21: /* CXBAU */
       
  1431     case 22: /* NRBAU */
       
  1432     case 23: /* NRBAU */
       
  1433     case 24:
       
  1434     case 25:
       
  1435     case 26:
       
  1436     case 27:
       
  1437     case 28:
       
  1438     case 29:
       
  1439     case 30:
       
  1440     case 31:
       
  1441     case 32:
       
  1442     case 33:
       
  1443     case 34:
       
  1444     case 35:
       
  1445     case 36:
       
  1446     case 37:
       
  1447     case 38:
       
  1448     case 39:
       
  1449     case 40: /* CRBC */
       
  1450     case 41:
       
  1451     case 42: /* CXBC */
       
  1452     case 43:
       
  1453     case 44:
       
  1454     case 45:
       
  1455     case 46: /* POLL */
       
  1456     case 47: /* POLLINT */
       
  1457     case 72:
       
  1458     case 74:
       
  1459     case 76: /* RCVRL */
       
  1460     case 78: /* XMTRL */
       
  1461     case 112:
       
  1462        if (CSR_STOP(s) || CSR_SPND(s))
       
  1463            break;
       
  1464        return;
       
  1465     case 3:
       
  1466         break;
       
  1467     case 4:
       
  1468         s->csr[4] &= ~(val & 0x026a);
       
  1469         val &= ~0x026a; val |= s->csr[4] & 0x026a;
       
  1470         break;
       
  1471     case 5:
       
  1472         s->csr[5] &= ~(val & 0x0a90);
       
  1473         val &= ~0x0a90; val |= s->csr[5] & 0x0a90;
       
  1474         break;
       
  1475     case 16:
       
  1476         pcnet_csr_writew(s,1,val);
       
  1477         return;
       
  1478     case 17:
       
  1479         pcnet_csr_writew(s,2,val);
       
  1480         return;
       
  1481     case 58:
       
  1482         pcnet_bcr_writew(s,BCR_SWS,val);
       
  1483         break;
       
  1484     default:
       
  1485         return;
       
  1486     }
       
  1487     s->csr[rap] = val;
       
  1488 }
       
  1489 
       
  1490 static uint32_t pcnet_csr_readw(PCNetState *s, uint32_t rap)
       
  1491 {
       
  1492     uint32_t val;
       
  1493     switch (rap) {
       
  1494     case 0:
       
  1495         pcnet_update_irq(s);
       
  1496         val = s->csr[0];
       
  1497         val |= (val & 0x7800) ? 0x8000 : 0;
       
  1498         break;
       
  1499     case 16:
       
  1500         return pcnet_csr_readw(s,1);
       
  1501     case 17:
       
  1502         return pcnet_csr_readw(s,2);
       
  1503     case 58:
       
  1504         return pcnet_bcr_readw(s,BCR_SWS);
       
  1505     case 88:
       
  1506         val = s->csr[89];
       
  1507         val <<= 16;
       
  1508         val |= s->csr[88];
       
  1509         break;
       
  1510     default:
       
  1511         val = s->csr[rap];
       
  1512     }
       
  1513 #ifdef PCNET_DEBUG_CSR
       
  1514     printf("pcnet_csr_readw rap=%d val=0x%04x\n", rap, val);
       
  1515 #endif
       
  1516     return val;
       
  1517 }
       
  1518 
       
  1519 static void pcnet_bcr_writew(PCNetState *s, uint32_t rap, uint32_t val)
       
  1520 {
       
  1521     rap &= 127;
       
  1522 #ifdef PCNET_DEBUG_BCR
       
  1523     printf("pcnet_bcr_writew rap=%d val=0x%04x\n", rap, val);
       
  1524 #endif
       
  1525     switch (rap) {
       
  1526     case BCR_SWS:
       
  1527         if (!(CSR_STOP(s) || CSR_SPND(s)))
       
  1528             return;
       
  1529         val &= ~0x0300;
       
  1530         switch (val & 0x00ff) {
       
  1531         case 0:
       
  1532             val |= 0x0200;
       
  1533             break;
       
  1534         case 1:
       
  1535             val |= 0x0100;
       
  1536             break;
       
  1537         case 2:
       
  1538         case 3:
       
  1539             val |= 0x0300;
       
  1540             break;
       
  1541         default:
       
  1542             printf("Bad SWSTYLE=0x%02x\n", val & 0xff);
       
  1543             val = 0x0200;
       
  1544             break;
       
  1545         }
       
  1546 #ifdef PCNET_DEBUG
       
  1547        printf("BCR_SWS=0x%04x\n", val);
       
  1548 #endif
       
  1549     case BCR_LNKST:
       
  1550     case BCR_LED1:
       
  1551     case BCR_LED2:
       
  1552     case BCR_LED3:
       
  1553     case BCR_MC:
       
  1554     case BCR_FDC:
       
  1555     case BCR_BSBC:
       
  1556     case BCR_EECAS:
       
  1557     case BCR_PLAT:
       
  1558         s->bcr[rap] = val;
       
  1559         break;
       
  1560     default:
       
  1561         break;
       
  1562     }
       
  1563 }
       
  1564 
       
  1565 static uint32_t pcnet_bcr_readw(PCNetState *s, uint32_t rap)
       
  1566 {
       
  1567     uint32_t val;
       
  1568     rap &= 127;
       
  1569     switch (rap) {
       
  1570     case BCR_LNKST:
       
  1571     case BCR_LED1:
       
  1572     case BCR_LED2:
       
  1573     case BCR_LED3:
       
  1574         val = s->bcr[rap] & ~0x8000;
       
  1575         val |= (val & 0x017f & s->lnkst) ? 0x8000 : 0;
       
  1576         break;
       
  1577     default:
       
  1578         val = rap < 32 ? s->bcr[rap] : 0;
       
  1579         break;
       
  1580     }
       
  1581 #ifdef PCNET_DEBUG_BCR
       
  1582     printf("pcnet_bcr_readw rap=%d val=0x%04x\n", rap, val);
       
  1583 #endif
       
  1584     return val;
       
  1585 }
       
  1586 
       
  1587 static void pcnet_h_reset(void *opaque)
       
  1588 {
       
  1589     PCNetState *s = opaque;
       
  1590     int i;
       
  1591     uint16_t checksum;
       
  1592 
       
  1593     /* Initialize the PROM */
       
  1594 
       
  1595     if (s->nd)
       
  1596         memcpy(s->prom, s->nd->macaddr, 6);
       
  1597     s->prom[12] = s->prom[13] = 0x00;
       
  1598     s->prom[14] = s->prom[15] = 0x57;
       
  1599 
       
  1600     for (i = 0,checksum = 0; i < 16; i++)
       
  1601         checksum += s->prom[i];
       
  1602     *(uint16_t *)&s->prom[12] = cpu_to_le16(checksum);
       
  1603 
       
  1604 
       
  1605     s->bcr[BCR_MSRDA] = 0x0005;
       
  1606     s->bcr[BCR_MSWRA] = 0x0005;
       
  1607     s->bcr[BCR_MC   ] = 0x0002;
       
  1608     s->bcr[BCR_LNKST] = 0x00c0;
       
  1609     s->bcr[BCR_LED1 ] = 0x0084;
       
  1610     s->bcr[BCR_LED2 ] = 0x0088;
       
  1611     s->bcr[BCR_LED3 ] = 0x0090;
       
  1612     s->bcr[BCR_FDC  ] = 0x0000;
       
  1613     s->bcr[BCR_BSBC ] = 0x9001;
       
  1614     s->bcr[BCR_EECAS] = 0x0002;
       
  1615     s->bcr[BCR_SWS  ] = 0x0200;
       
  1616     s->bcr[BCR_PLAT ] = 0xff06;
       
  1617 
       
  1618     pcnet_s_reset(s);
       
  1619 }
       
  1620 
       
  1621 static void pcnet_aprom_writeb(void *opaque, uint32_t addr, uint32_t val)
       
  1622 {
       
  1623     PCNetState *s = opaque;
       
  1624 #ifdef PCNET_DEBUG
       
  1625     printf("pcnet_aprom_writeb addr=0x%08x val=0x%02x\n", addr, val);
       
  1626 #endif
       
  1627     /* Check APROMWE bit to enable write access */
       
  1628     if (pcnet_bcr_readw(s,2) & 0x80)
       
  1629         s->prom[addr & 15] = val;
       
  1630 }
       
  1631 
       
  1632 static uint32_t pcnet_aprom_readb(void *opaque, uint32_t addr)
       
  1633 {
       
  1634     PCNetState *s = opaque;
       
  1635     uint32_t val = s->prom[addr &= 15];
       
  1636 #ifdef PCNET_DEBUG
       
  1637     printf("pcnet_aprom_readb addr=0x%08x val=0x%02x\n", addr, val);
       
  1638 #endif
       
  1639     return val;
       
  1640 }
       
  1641 
       
  1642 static void pcnet_ioport_writew(void *opaque, uint32_t addr, uint32_t val)
       
  1643 {
       
  1644     PCNetState *s = opaque;
       
  1645     pcnet_poll_timer(s);
       
  1646 #ifdef PCNET_DEBUG_IO
       
  1647     printf("pcnet_ioport_writew addr=0x%08x val=0x%04x\n", addr, val);
       
  1648 #endif
       
  1649     if (!BCR_DWIO(s)) {
       
  1650         switch (addr & 0x0f) {
       
  1651         case 0x00: /* RDP */
       
  1652             pcnet_csr_writew(s, s->rap, val);
       
  1653             break;
       
  1654         case 0x02:
       
  1655             s->rap = val & 0x7f;
       
  1656             break;
       
  1657         case 0x06:
       
  1658             pcnet_bcr_writew(s, s->rap, val);
       
  1659             break;
       
  1660         }
       
  1661     }
       
  1662     pcnet_update_irq(s);
       
  1663 }
       
  1664 
       
  1665 static uint32_t pcnet_ioport_readw(void *opaque, uint32_t addr)
       
  1666 {
       
  1667     PCNetState *s = opaque;
       
  1668     uint32_t val = -1;
       
  1669     pcnet_poll_timer(s);
       
  1670     if (!BCR_DWIO(s)) {
       
  1671         switch (addr & 0x0f) {
       
  1672         case 0x00: /* RDP */
       
  1673             val = pcnet_csr_readw(s, s->rap);
       
  1674             break;
       
  1675         case 0x02:
       
  1676             val = s->rap;
       
  1677             break;
       
  1678         case 0x04:
       
  1679             pcnet_s_reset(s);
       
  1680             val = 0;
       
  1681             break;
       
  1682         case 0x06:
       
  1683             val = pcnet_bcr_readw(s, s->rap);
       
  1684             break;
       
  1685         }
       
  1686     }
       
  1687     pcnet_update_irq(s);
       
  1688 #ifdef PCNET_DEBUG_IO
       
  1689     printf("pcnet_ioport_readw addr=0x%08x val=0x%04x\n", addr, val & 0xffff);
       
  1690 #endif
       
  1691     return val;
       
  1692 }
       
  1693 
       
  1694 static void pcnet_ioport_writel(void *opaque, uint32_t addr, uint32_t val)
       
  1695 {
       
  1696     PCNetState *s = opaque;
       
  1697     pcnet_poll_timer(s);
       
  1698 #ifdef PCNET_DEBUG_IO
       
  1699     printf("pcnet_ioport_writel addr=0x%08x val=0x%08x\n", addr, val);
       
  1700 #endif
       
  1701     if (BCR_DWIO(s)) {
       
  1702         switch (addr & 0x0f) {
       
  1703         case 0x00: /* RDP */
       
  1704             pcnet_csr_writew(s, s->rap, val & 0xffff);
       
  1705             break;
       
  1706         case 0x04:
       
  1707             s->rap = val & 0x7f;
       
  1708             break;
       
  1709         case 0x0c:
       
  1710             pcnet_bcr_writew(s, s->rap, val & 0xffff);
       
  1711             break;
       
  1712         }
       
  1713     } else
       
  1714     if ((addr & 0x0f) == 0) {
       
  1715         /* switch device to dword i/o mode */
       
  1716         pcnet_bcr_writew(s, BCR_BSBC, pcnet_bcr_readw(s, BCR_BSBC) | 0x0080);
       
  1717 #ifdef PCNET_DEBUG_IO
       
  1718         printf("device switched into dword i/o mode\n");
       
  1719 #endif
       
  1720     }
       
  1721     pcnet_update_irq(s);
       
  1722 }
       
  1723 
       
  1724 static uint32_t pcnet_ioport_readl(void *opaque, uint32_t addr)
       
  1725 {
       
  1726     PCNetState *s = opaque;
       
  1727     uint32_t val = -1;
       
  1728     pcnet_poll_timer(s);
       
  1729     if (BCR_DWIO(s)) {
       
  1730         switch (addr & 0x0f) {
       
  1731         case 0x00: /* RDP */
       
  1732             val = pcnet_csr_readw(s, s->rap);
       
  1733             break;
       
  1734         case 0x04:
       
  1735             val = s->rap;
       
  1736             break;
       
  1737         case 0x08:
       
  1738             pcnet_s_reset(s);
       
  1739             val = 0;
       
  1740             break;
       
  1741         case 0x0c:
       
  1742             val = pcnet_bcr_readw(s, s->rap);
       
  1743             break;
       
  1744         }
       
  1745     }
       
  1746     pcnet_update_irq(s);
       
  1747 #ifdef PCNET_DEBUG_IO
       
  1748     printf("pcnet_ioport_readl addr=0x%08x val=0x%08x\n", addr, val);
       
  1749 #endif
       
  1750     return val;
       
  1751 }
       
  1752 
       
  1753 static void pcnet_ioport_map(PCIDevice *pci_dev, int region_num,
       
  1754                              uint32_t addr, uint32_t size, int type)
       
  1755 {
       
  1756     PCNetState *d = (PCNetState *)pci_dev;
       
  1757 
       
  1758 #ifdef PCNET_DEBUG_IO
       
  1759     printf("pcnet_ioport_map addr=0x%04x size=0x%04x\n", addr, size);
       
  1760 #endif
       
  1761 
       
  1762     register_ioport_write(addr, 16, 1, pcnet_aprom_writeb, d);
       
  1763     register_ioport_read(addr, 16, 1, pcnet_aprom_readb, d);
       
  1764 
       
  1765     register_ioport_write(addr + 0x10, 0x10, 2, pcnet_ioport_writew, d);
       
  1766     register_ioport_read(addr + 0x10, 0x10, 2, pcnet_ioport_readw, d);
       
  1767     register_ioport_write(addr + 0x10, 0x10, 4, pcnet_ioport_writel, d);
       
  1768     register_ioport_read(addr + 0x10, 0x10, 4, pcnet_ioport_readl, d);
       
  1769 }
       
  1770 
       
  1771 static void pcnet_mmio_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
       
  1772 {
       
  1773     PCNetState *d = opaque;
       
  1774 #ifdef PCNET_DEBUG_IO
       
  1775     printf("pcnet_mmio_writeb addr=0x" TARGET_FMT_plx" val=0x%02x\n", addr,
       
  1776            val);
       
  1777 #endif
       
  1778     if (!(addr & 0x10))
       
  1779         pcnet_aprom_writeb(d, addr & 0x0f, val);
       
  1780 }
       
  1781 
       
  1782 static uint32_t pcnet_mmio_readb(void *opaque, target_phys_addr_t addr)
       
  1783 {
       
  1784     PCNetState *d = opaque;
       
  1785     uint32_t val = -1;
       
  1786     if (!(addr & 0x10))
       
  1787         val = pcnet_aprom_readb(d, addr & 0x0f);
       
  1788 #ifdef PCNET_DEBUG_IO
       
  1789     printf("pcnet_mmio_readb addr=0x" TARGET_FMT_plx " val=0x%02x\n", addr,
       
  1790            val & 0xff);
       
  1791 #endif
       
  1792     return val;
       
  1793 }
       
  1794 
       
  1795 static void pcnet_mmio_writew(void *opaque, target_phys_addr_t addr, uint32_t val)
       
  1796 {
       
  1797     PCNetState *d = opaque;
       
  1798 #ifdef PCNET_DEBUG_IO
       
  1799     printf("pcnet_mmio_writew addr=0x" TARGET_FMT_plx " val=0x%04x\n", addr,
       
  1800            val);
       
  1801 #endif
       
  1802     if (addr & 0x10)
       
  1803         pcnet_ioport_writew(d, addr & 0x0f, val);
       
  1804     else {
       
  1805         addr &= 0x0f;
       
  1806         pcnet_aprom_writeb(d, addr, val & 0xff);
       
  1807         pcnet_aprom_writeb(d, addr+1, (val & 0xff00) >> 8);
       
  1808     }
       
  1809 }
       
  1810 
       
  1811 static uint32_t pcnet_mmio_readw(void *opaque, target_phys_addr_t addr)
       
  1812 {
       
  1813     PCNetState *d = opaque;
       
  1814     uint32_t val = -1;
       
  1815     if (addr & 0x10)
       
  1816         val = pcnet_ioport_readw(d, addr & 0x0f);
       
  1817     else {
       
  1818         addr &= 0x0f;
       
  1819         val = pcnet_aprom_readb(d, addr+1);
       
  1820         val <<= 8;
       
  1821         val |= pcnet_aprom_readb(d, addr);
       
  1822     }
       
  1823 #ifdef PCNET_DEBUG_IO
       
  1824     printf("pcnet_mmio_readw addr=0x" TARGET_FMT_plx" val = 0x%04x\n", addr,
       
  1825            val & 0xffff);
       
  1826 #endif
       
  1827     return val;
       
  1828 }
       
  1829 
       
  1830 static void pcnet_mmio_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
       
  1831 {
       
  1832     PCNetState *d = opaque;
       
  1833 #ifdef PCNET_DEBUG_IO
       
  1834     printf("pcnet_mmio_writel addr=0x" TARGET_FMT_plx" val=0x%08x\n", addr,
       
  1835            val);
       
  1836 #endif
       
  1837     if (addr & 0x10)
       
  1838         pcnet_ioport_writel(d, addr & 0x0f, val);
       
  1839     else {
       
  1840         addr &= 0x0f;
       
  1841         pcnet_aprom_writeb(d, addr, val & 0xff);
       
  1842         pcnet_aprom_writeb(d, addr+1, (val & 0xff00) >> 8);
       
  1843         pcnet_aprom_writeb(d, addr+2, (val & 0xff0000) >> 16);
       
  1844         pcnet_aprom_writeb(d, addr+3, (val & 0xff000000) >> 24);
       
  1845     }
       
  1846 }
       
  1847 
       
  1848 static uint32_t pcnet_mmio_readl(void *opaque, target_phys_addr_t addr)
       
  1849 {
       
  1850     PCNetState *d = opaque;
       
  1851     uint32_t val;
       
  1852     if (addr & 0x10)
       
  1853         val = pcnet_ioport_readl(d, addr & 0x0f);
       
  1854     else {
       
  1855         addr &= 0x0f;
       
  1856         val = pcnet_aprom_readb(d, addr+3);
       
  1857         val <<= 8;
       
  1858         val |= pcnet_aprom_readb(d, addr+2);
       
  1859         val <<= 8;
       
  1860         val |= pcnet_aprom_readb(d, addr+1);
       
  1861         val <<= 8;
       
  1862         val |= pcnet_aprom_readb(d, addr);
       
  1863     }
       
  1864 #ifdef PCNET_DEBUG_IO
       
  1865     printf("pcnet_mmio_readl addr=0x" TARGET_FMT_plx " val=0x%08x\n", addr,
       
  1866            val);
       
  1867 #endif
       
  1868     return val;
       
  1869 }
       
  1870 
       
  1871 
       
  1872 static void pcnet_save(QEMUFile *f, void *opaque)
       
  1873 {
       
  1874     PCNetState *s = opaque;
       
  1875     unsigned int i;
       
  1876 
       
  1877     if (s->pci_dev)
       
  1878         pci_device_save(s->pci_dev, f);
       
  1879 
       
  1880     qemu_put_sbe32(f, s->rap);
       
  1881     qemu_put_sbe32(f, s->isr);
       
  1882     qemu_put_sbe32(f, s->lnkst);
       
  1883     qemu_put_be32s(f, &s->rdra);
       
  1884     qemu_put_be32s(f, &s->tdra);
       
  1885     qemu_put_buffer(f, s->prom, 16);
       
  1886     for (i = 0; i < 128; i++)
       
  1887         qemu_put_be16s(f, &s->csr[i]);
       
  1888     for (i = 0; i < 32; i++)
       
  1889         qemu_put_be16s(f, &s->bcr[i]);
       
  1890     qemu_put_be64s(f, &s->timer);
       
  1891     qemu_put_sbe32(f, s->xmit_pos);
       
  1892     qemu_put_sbe32(f, s->recv_pos);
       
  1893     qemu_put_buffer(f, s->buffer, 4096);
       
  1894     qemu_put_sbe32(f, s->tx_busy);
       
  1895     qemu_put_timer(f, s->poll_timer);
       
  1896 }
       
  1897 
       
  1898 static int pcnet_load(QEMUFile *f, void *opaque, int version_id)
       
  1899 {
       
  1900     PCNetState *s = opaque;
       
  1901     int i, ret;
       
  1902 
       
  1903     if (version_id != 2)
       
  1904         return -EINVAL;
       
  1905 
       
  1906     if (s->pci_dev) {
       
  1907         ret = pci_device_load(s->pci_dev, f);
       
  1908         if (ret < 0)
       
  1909             return ret;
       
  1910     }
       
  1911 
       
  1912     qemu_get_sbe32s(f, &s->rap);
       
  1913     qemu_get_sbe32s(f, &s->isr);
       
  1914     qemu_get_sbe32s(f, &s->lnkst);
       
  1915     qemu_get_be32s(f, &s->rdra);
       
  1916     qemu_get_be32s(f, &s->tdra);
       
  1917     qemu_get_buffer(f, s->prom, 16);
       
  1918     for (i = 0; i < 128; i++)
       
  1919         qemu_get_be16s(f, &s->csr[i]);
       
  1920     for (i = 0; i < 32; i++)
       
  1921         qemu_get_be16s(f, &s->bcr[i]);
       
  1922     qemu_get_be64s(f, &s->timer);
       
  1923     qemu_get_sbe32s(f, &s->xmit_pos);
       
  1924     qemu_get_sbe32s(f, &s->recv_pos);
       
  1925     qemu_get_buffer(f, s->buffer, 4096);
       
  1926     qemu_get_sbe32s(f, &s->tx_busy);
       
  1927     qemu_get_timer(f, s->poll_timer);
       
  1928 
       
  1929     return 0;
       
  1930 }
       
  1931 
       
  1932 static void pcnet_common_init(PCNetState *d, NICInfo *nd, const char *info_str)
       
  1933 {
       
  1934     d->poll_timer = qemu_new_timer(vm_clock, pcnet_poll_timer, d);
       
  1935 
       
  1936     d->nd = nd;
       
  1937 
       
  1938     if (nd && nd->vlan) {
       
  1939         d->vc = qemu_new_vlan_client(nd->vlan, pcnet_receive,
       
  1940                                      pcnet_can_receive, d);
       
  1941 
       
  1942         snprintf(d->vc->info_str, sizeof(d->vc->info_str),
       
  1943                  "pcnet macaddr=%02x:%02x:%02x:%02x:%02x:%02x",
       
  1944                  d->nd->macaddr[0],
       
  1945                  d->nd->macaddr[1],
       
  1946                  d->nd->macaddr[2],
       
  1947                  d->nd->macaddr[3],
       
  1948                  d->nd->macaddr[4],
       
  1949                  d->nd->macaddr[5]);
       
  1950     } else {
       
  1951         d->vc = NULL;
       
  1952     }
       
  1953     pcnet_h_reset(d);
       
  1954     register_savevm("pcnet", -1, 2, pcnet_save, pcnet_load, d);
       
  1955 }
       
  1956 
       
  1957 /* PCI interface */
       
  1958 
       
  1959 static CPUWriteMemoryFunc *pcnet_mmio_write[] = {
       
  1960     (CPUWriteMemoryFunc *)&pcnet_mmio_writeb,
       
  1961     (CPUWriteMemoryFunc *)&pcnet_mmio_writew,
       
  1962     (CPUWriteMemoryFunc *)&pcnet_mmio_writel
       
  1963 };
       
  1964 
       
  1965 static CPUReadMemoryFunc *pcnet_mmio_read[] = {
       
  1966     (CPUReadMemoryFunc *)&pcnet_mmio_readb,
       
  1967     (CPUReadMemoryFunc *)&pcnet_mmio_readw,
       
  1968     (CPUReadMemoryFunc *)&pcnet_mmio_readl
       
  1969 };
       
  1970 
       
  1971 static void pcnet_mmio_map(PCIDevice *pci_dev, int region_num,
       
  1972                             uint32_t addr, uint32_t size, int type)
       
  1973 {
       
  1974     PCNetState *d = (PCNetState *)pci_dev;
       
  1975 
       
  1976 #ifdef PCNET_DEBUG_IO
       
  1977     printf("pcnet_mmio_map addr=0x%08x 0x%08x\n", addr, size);
       
  1978 #endif
       
  1979 
       
  1980     cpu_register_physical_memory(addr, PCNET_PNPMMIO_SIZE, d->mmio_index);
       
  1981 }
       
  1982 
       
  1983 static void pci_physical_memory_write(void *dma_opaque, target_phys_addr_t addr,
       
  1984                                       uint8_t *buf, int len, int do_bswap)
       
  1985 {
       
  1986     cpu_physical_memory_write(addr, buf, len);
       
  1987 }
       
  1988 
       
  1989 static void pci_physical_memory_read(void *dma_opaque, target_phys_addr_t addr,
       
  1990                                      uint8_t *buf, int len, int do_bswap)
       
  1991 {
       
  1992     cpu_physical_memory_read(addr, buf, len);
       
  1993 }
       
  1994 
       
  1995 void pci_pcnet_init(PCIBus *bus, NICInfo *nd, int devfn)
       
  1996 {
       
  1997     PCNetState *d;
       
  1998     uint8_t *pci_conf;
       
  1999 
       
  2000 #if 0
       
  2001     printf("sizeof(RMD)=%d, sizeof(TMD)=%d\n",
       
  2002         sizeof(struct pcnet_RMD), sizeof(struct pcnet_TMD));
       
  2003 #endif
       
  2004 
       
  2005     d = (PCNetState *)pci_register_device(bus, "PCNet", sizeof(PCNetState),
       
  2006                                           devfn, NULL, NULL);
       
  2007 
       
  2008     pci_conf = d->dev.config;
       
  2009 
       
  2010     *(uint16_t *)&pci_conf[0x00] = cpu_to_le16(0x1022);
       
  2011     *(uint16_t *)&pci_conf[0x02] = cpu_to_le16(0x2000);
       
  2012     *(uint16_t *)&pci_conf[0x04] = cpu_to_le16(0x0007);
       
  2013     *(uint16_t *)&pci_conf[0x06] = cpu_to_le16(0x0280);
       
  2014     pci_conf[0x08] = 0x10;
       
  2015     pci_conf[0x09] = 0x00;
       
  2016     pci_conf[0x0a] = 0x00; // ethernet network controller
       
  2017     pci_conf[0x0b] = 0x02;
       
  2018     pci_conf[0x0e] = 0x00; // header_type
       
  2019 
       
  2020     *(uint32_t *)&pci_conf[0x10] = cpu_to_le32(0x00000001);
       
  2021     *(uint32_t *)&pci_conf[0x14] = cpu_to_le32(0x00000000);
       
  2022 
       
  2023     pci_conf[0x3d] = 1; // interrupt pin 0
       
  2024     pci_conf[0x3e] = 0x06;
       
  2025     pci_conf[0x3f] = 0xff;
       
  2026 
       
  2027     /* Handler for memory-mapped I/O */
       
  2028     d->mmio_index =
       
  2029       cpu_register_io_memory(0, pcnet_mmio_read, pcnet_mmio_write, d);
       
  2030 
       
  2031     pci_register_io_region((PCIDevice *)d, 0, PCNET_IOPORT_SIZE,
       
  2032                            PCI_ADDRESS_SPACE_IO, pcnet_ioport_map);
       
  2033 
       
  2034     pci_register_io_region((PCIDevice *)d, 1, PCNET_PNPMMIO_SIZE,
       
  2035                            PCI_ADDRESS_SPACE_MEM, pcnet_mmio_map);
       
  2036 
       
  2037     d->irq = d->dev.irq[0];
       
  2038     d->phys_mem_read = pci_physical_memory_read;
       
  2039     d->phys_mem_write = pci_physical_memory_write;
       
  2040     d->pci_dev = &d->dev;
       
  2041 
       
  2042     pcnet_common_init(d, nd, "pcnet");
       
  2043 }
       
  2044 
       
  2045 /* SPARC32 interface */
       
  2046 
       
  2047 #if defined (TARGET_SPARC) && !defined(TARGET_SPARC64) // Avoid compile failure
       
  2048 #include "sun4m.h"
       
  2049 
       
  2050 static void parent_lance_reset(void *opaque, int irq, int level)
       
  2051 {
       
  2052     if (level)
       
  2053         pcnet_h_reset(opaque);
       
  2054 }
       
  2055 
       
  2056 static void lance_mem_writew(void *opaque, target_phys_addr_t addr,
       
  2057                              uint32_t val)
       
  2058 {
       
  2059 #ifdef PCNET_DEBUG_IO
       
  2060     printf("lance_mem_writew addr=" TARGET_FMT_plx " val=0x%04x\n", addr,
       
  2061            val & 0xffff);
       
  2062 #endif
       
  2063     pcnet_ioport_writew(opaque, addr, val & 0xffff);
       
  2064 }
       
  2065 
       
  2066 static uint32_t lance_mem_readw(void *opaque, target_phys_addr_t addr)
       
  2067 {
       
  2068     uint32_t val;
       
  2069 
       
  2070     val = pcnet_ioport_readw(opaque, addr);
       
  2071 #ifdef PCNET_DEBUG_IO
       
  2072     printf("lance_mem_readw addr=" TARGET_FMT_plx " val = 0x%04x\n", addr,
       
  2073            val & 0xffff);
       
  2074 #endif
       
  2075 
       
  2076     return val & 0xffff;
       
  2077 }
       
  2078 
       
  2079 static CPUReadMemoryFunc *lance_mem_read[3] = {
       
  2080     NULL,
       
  2081     lance_mem_readw,
       
  2082     NULL,
       
  2083 };
       
  2084 
       
  2085 static CPUWriteMemoryFunc *lance_mem_write[3] = {
       
  2086     NULL,
       
  2087     lance_mem_writew,
       
  2088     NULL,
       
  2089 };
       
  2090 
       
  2091 void lance_init(NICInfo *nd, target_phys_addr_t leaddr, void *dma_opaque,
       
  2092                 qemu_irq irq, qemu_irq *reset)
       
  2093 {
       
  2094     PCNetState *d;
       
  2095     int lance_io_memory;
       
  2096 
       
  2097     d = qemu_mallocz(sizeof(PCNetState));
       
  2098     if (!d)
       
  2099         return;
       
  2100 
       
  2101     lance_io_memory =
       
  2102         cpu_register_io_memory(0, lance_mem_read, lance_mem_write, d);
       
  2103 
       
  2104     d->dma_opaque = dma_opaque;
       
  2105 
       
  2106     *reset = *qemu_allocate_irqs(parent_lance_reset, d, 1);
       
  2107 
       
  2108     cpu_register_physical_memory(leaddr, 4, lance_io_memory);
       
  2109 
       
  2110     d->irq = irq;
       
  2111     d->phys_mem_read = ledma_memory_read;
       
  2112     d->phys_mem_write = ledma_memory_write;
       
  2113 
       
  2114     pcnet_common_init(d, nd, "lance");
       
  2115 }
       
  2116 #endif /* TARGET_SPARC */