Annotation of qemu/hw/rtl8139.c, revision 1.1.1.2

1.1       root        1: /**
                      2:  * QEMU RTL8139 emulation
                      3:  * 
                      4:  * Copyright (c) 2006 Igor Kovalenko
                      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:  * Modifications:
                     25:  *  2006-Jan-28  Mark Malakanov :   TSAD and CSCR implementation (for Windows driver)
1.1.1.2 ! root       26:  * 
        !            27:  *  2006-Apr-28  Juergen Lock   :   EEPROM emulation changes for FreeBSD driver
        !            28:  *                                  HW revision ID changes for FreeBSD driver
        !            29:  * 
        !            30:  *  2006-Jul-01  Igor Kovalenko :   Implemented loopback mode for FreeBSD driver
        !            31:  *                                  Corrected packet transfer reassembly routine for 8139C+ mode
        !            32:  *                                  Rearranged debugging print statements
        !            33:  *                                  Implemented PCI timer interrupt (disabled by default)
        !            34:  *                                  Implemented Tally Counters, increased VM load/save version
        !            35:  *                                  Implemented IP/TCP/UDP checksum task offloading
        !            36:  *
        !            37:  *  2006-Jul-04  Igor Kovalenko :   Implemented TCP segmentation offloading
        !            38:  *                                  Fixed MTU=1500 for produced ethernet frames
        !            39:  *
        !            40:  *  2006-Jul-09  Igor Kovalenko :   Fixed TCP header length calculation while processing
        !            41:  *                                  segmentation offloading
        !            42:  *                                  Removed slirp.h dependency
        !            43:  *                                  Added rx/tx buffer reset when enabling rx/tx operation
1.1       root       44:  */
                     45: 
                     46: #include "vl.h"
                     47: 
                     48: /* debug RTL8139 card */
                     49: //#define DEBUG_RTL8139 1
                     50: 
1.1.1.2 ! root       51: #define PCI_FREQUENCY 33000000L
        !            52: 
1.1       root       53: /* debug RTL8139 card C+ mode only */
                     54: //#define DEBUG_RTL8139CP 1
                     55: 
                     56: /* RTL8139 provides frame CRC with received packet, this feature seems to be
                     57:    ignored by most drivers, disabled by default */
                     58: //#define RTL8139_CALCULATE_RXCRC 1
                     59: 
1.1.1.2 ! root       60: /* Uncomment to enable on-board timer interrupts */
        !            61: //#define RTL8139_ONBOARD_TIMER 1
1.1       root       62: 
                     63: #if defined(RTL8139_CALCULATE_RXCRC)
                     64: /* For crc32 */
                     65: #include <zlib.h>
                     66: #endif
                     67: 
                     68: #define SET_MASKED(input, mask, curr) \
                     69:     ( ( (input) & ~(mask) ) | ( (curr) & (mask) ) )
                     70: 
                     71: /* arg % size for size which is a power of 2 */
                     72: #define MOD2(input, size) \
                     73:     ( ( input ) & ( size - 1 )  )
                     74: 
1.1.1.2 ! root       75: #if defined (DEBUG_RTL8139)
        !            76: #  define DEBUG_PRINT(x) do { printf x ; } while (0)
        !            77: #else
        !            78: #  define DEBUG_PRINT(x)
        !            79: #endif
        !            80: 
1.1       root       81: /* Symbolic offsets to registers. */
                     82: enum RTL8139_registers {
                     83:     MAC0 = 0,        /* Ethernet hardware address. */
                     84:     MAR0 = 8,        /* Multicast filter. */
1.1.1.2 ! root       85:     TxStatus0 = 0x10,/* Transmit status (Four 32bit registers). C mode only */
        !            86:                      /* Dump Tally Conter control register(64bit). C+ mode only */
        !            87:     TxAddr0 = 0x20,  /* Tx descriptors (also four 32bit). */
1.1       root       88:     RxBuf = 0x30,
                     89:     ChipCmd = 0x37,
                     90:     RxBufPtr = 0x38,
                     91:     RxBufAddr = 0x3A,
                     92:     IntrMask = 0x3C,
                     93:     IntrStatus = 0x3E,
                     94:     TxConfig = 0x40,
                     95:     RxConfig = 0x44,
                     96:     Timer = 0x48,        /* A general-purpose counter. */
                     97:     RxMissed = 0x4C,    /* 24 bits valid, write clears. */
                     98:     Cfg9346 = 0x50,
                     99:     Config0 = 0x51,
                    100:     Config1 = 0x52,
                    101:     FlashReg = 0x54,
                    102:     MediaStatus = 0x58,
                    103:     Config3 = 0x59,
                    104:     Config4 = 0x5A,        /* absent on RTL-8139A */
                    105:     HltClk = 0x5B,
                    106:     MultiIntr = 0x5C,
                    107:     PCIRevisionID = 0x5E,
                    108:     TxSummary = 0x60, /* TSAD register. Transmit Status of All Descriptors*/
                    109:     BasicModeCtrl = 0x62,
                    110:     BasicModeStatus = 0x64,
                    111:     NWayAdvert = 0x66,
                    112:     NWayLPAR = 0x68,
                    113:     NWayExpansion = 0x6A,
                    114:     /* Undocumented registers, but required for proper operation. */
                    115:     FIFOTMS = 0x70,        /* FIFO Control and test. */
                    116:     CSCR = 0x74,        /* Chip Status and Configuration Register. */
                    117:     PARA78 = 0x78,
                    118:     PARA7c = 0x7c,        /* Magic transceiver parameter register. */
                    119:     Config5 = 0xD8,        /* absent on RTL-8139A */
                    120:     /* C+ mode */
                    121:     TxPoll        = 0xD9,    /* Tell chip to check Tx descriptors for work */
                    122:     RxMaxSize    = 0xDA, /* Max size of an Rx packet (8169 only) */
                    123:     CpCmd        = 0xE0, /* C+ Command register (C+ mode only) */
                    124:     IntrMitigate    = 0xE2,    /* rx/tx interrupt mitigation control */
                    125:     RxRingAddrLO    = 0xE4, /* 64-bit start addr of Rx ring */
                    126:     RxRingAddrHI    = 0xE8, /* 64-bit start addr of Rx ring */
                    127:     TxThresh    = 0xEC, /* Early Tx threshold */
                    128: };
                    129: 
                    130: enum ClearBitMasks {
                    131:     MultiIntrClear = 0xF000,
                    132:     ChipCmdClear = 0xE2,
                    133:     Config1Clear = (1<<7)|(1<<6)|(1<<3)|(1<<2)|(1<<1),
                    134: };
                    135: 
                    136: enum ChipCmdBits {
                    137:     CmdReset = 0x10,
                    138:     CmdRxEnb = 0x08,
                    139:     CmdTxEnb = 0x04,
                    140:     RxBufEmpty = 0x01,
                    141: };
                    142: 
                    143: /* C+ mode */
                    144: enum CplusCmdBits {
1.1.1.2 ! root      145:     CPlusRxVLAN   = 0x0040, /* enable receive VLAN detagging */
        !           146:     CPlusRxChkSum = 0x0020, /* enable receive checksum offloading */
        !           147:     CPlusRxEnb    = 0x0002,
        !           148:     CPlusTxEnb    = 0x0001,
1.1       root      149: };
                    150: 
                    151: /* Interrupt register bits, using my own meaningful names. */
                    152: enum IntrStatusBits {
                    153:     PCIErr = 0x8000,
                    154:     PCSTimeout = 0x4000,
                    155:     RxFIFOOver = 0x40,
                    156:     RxUnderrun = 0x20,
                    157:     RxOverflow = 0x10,
                    158:     TxErr = 0x08,
                    159:     TxOK = 0x04,
                    160:     RxErr = 0x02,
                    161:     RxOK = 0x01,
                    162: 
                    163:     RxAckBits = RxFIFOOver | RxOverflow | RxOK,
                    164: };
                    165: 
                    166: enum TxStatusBits {
                    167:     TxHostOwns = 0x2000,
                    168:     TxUnderrun = 0x4000,
                    169:     TxStatOK = 0x8000,
                    170:     TxOutOfWindow = 0x20000000,
                    171:     TxAborted = 0x40000000,
                    172:     TxCarrierLost = 0x80000000,
                    173: };
                    174: enum RxStatusBits {
                    175:     RxMulticast = 0x8000,
                    176:     RxPhysical = 0x4000,
                    177:     RxBroadcast = 0x2000,
                    178:     RxBadSymbol = 0x0020,
                    179:     RxRunt = 0x0010,
                    180:     RxTooLong = 0x0008,
                    181:     RxCRCErr = 0x0004,
                    182:     RxBadAlign = 0x0002,
                    183:     RxStatusOK = 0x0001,
                    184: };
                    185: 
                    186: /* Bits in RxConfig. */
                    187: enum rx_mode_bits {
                    188:     AcceptErr = 0x20,
                    189:     AcceptRunt = 0x10,
                    190:     AcceptBroadcast = 0x08,
                    191:     AcceptMulticast = 0x04,
                    192:     AcceptMyPhys = 0x02,
                    193:     AcceptAllPhys = 0x01,
                    194: };
                    195: 
                    196: /* Bits in TxConfig. */
                    197: enum tx_config_bits {
                    198: 
                    199:         /* Interframe Gap Time. Only TxIFG96 doesn't violate IEEE 802.3 */
                    200:         TxIFGShift = 24,
                    201:         TxIFG84 = (0 << TxIFGShift),    /* 8.4us / 840ns (10 / 100Mbps) */
                    202:         TxIFG88 = (1 << TxIFGShift),    /* 8.8us / 880ns (10 / 100Mbps) */
                    203:         TxIFG92 = (2 << TxIFGShift),    /* 9.2us / 920ns (10 / 100Mbps) */
                    204:         TxIFG96 = (3 << TxIFGShift),    /* 9.6us / 960ns (10 / 100Mbps) */
                    205: 
                    206:     TxLoopBack = (1 << 18) | (1 << 17), /* enable loopback test mode */
                    207:     TxCRC = (1 << 16),    /* DISABLE appending CRC to end of Tx packets */
                    208:     TxClearAbt = (1 << 0),    /* Clear abort (WO) */
                    209:     TxDMAShift = 8,        /* DMA burst value (0-7) is shifted this many bits */
                    210:     TxRetryShift = 4,    /* TXRR value (0-15) is shifted this many bits */
                    211: 
                    212:     TxVersionMask = 0x7C800000, /* mask out version bits 30-26, 23 */
                    213: };
                    214: 
                    215: 
                    216: /* Transmit Status of All Descriptors (TSAD) Register */
                    217: enum TSAD_bits {
                    218:  TSAD_TOK3 = 1<<15, // TOK bit of Descriptor 3
                    219:  TSAD_TOK2 = 1<<14, // TOK bit of Descriptor 2
                    220:  TSAD_TOK1 = 1<<13, // TOK bit of Descriptor 1
                    221:  TSAD_TOK0 = 1<<12, // TOK bit of Descriptor 0
                    222:  TSAD_TUN3 = 1<<11, // TUN bit of Descriptor 3
                    223:  TSAD_TUN2 = 1<<10, // TUN bit of Descriptor 2
                    224:  TSAD_TUN1 = 1<<9, // TUN bit of Descriptor 1
                    225:  TSAD_TUN0 = 1<<8, // TUN bit of Descriptor 0
                    226:  TSAD_TABT3 = 1<<07, // TABT bit of Descriptor 3
                    227:  TSAD_TABT2 = 1<<06, // TABT bit of Descriptor 2
                    228:  TSAD_TABT1 = 1<<05, // TABT bit of Descriptor 1
                    229:  TSAD_TABT0 = 1<<04, // TABT bit of Descriptor 0
                    230:  TSAD_OWN3 = 1<<03, // OWN bit of Descriptor 3
                    231:  TSAD_OWN2 = 1<<02, // OWN bit of Descriptor 2
                    232:  TSAD_OWN1 = 1<<01, // OWN bit of Descriptor 1
                    233:  TSAD_OWN0 = 1<<00, // OWN bit of Descriptor 0
                    234: };
                    235: 
                    236: 
                    237: /* Bits in Config1 */
                    238: enum Config1Bits {
                    239:     Cfg1_PM_Enable = 0x01,
                    240:     Cfg1_VPD_Enable = 0x02,
                    241:     Cfg1_PIO = 0x04,
                    242:     Cfg1_MMIO = 0x08,
                    243:     LWAKE = 0x10,        /* not on 8139, 8139A */
                    244:     Cfg1_Driver_Load = 0x20,
                    245:     Cfg1_LED0 = 0x40,
                    246:     Cfg1_LED1 = 0x80,
                    247:     SLEEP = (1 << 1),    /* only on 8139, 8139A */
                    248:     PWRDN = (1 << 0),    /* only on 8139, 8139A */
                    249: };
                    250: 
                    251: /* Bits in Config3 */
                    252: enum Config3Bits {
                    253:     Cfg3_FBtBEn    = (1 << 0), /* 1 = Fast Back to Back */
                    254:     Cfg3_FuncRegEn = (1 << 1), /* 1 = enable CardBus Function registers */
                    255:     Cfg3_CLKRUN_En = (1 << 2), /* 1 = enable CLKRUN */
                    256:     Cfg3_CardB_En  = (1 << 3), /* 1 = enable CardBus registers */
                    257:     Cfg3_LinkUp    = (1 << 4), /* 1 = wake up on link up */
                    258:     Cfg3_Magic     = (1 << 5), /* 1 = wake up on Magic Packet (tm) */
                    259:     Cfg3_PARM_En   = (1 << 6), /* 0 = software can set twister parameters */
                    260:     Cfg3_GNTSel    = (1 << 7), /* 1 = delay 1 clock from PCI GNT signal */
                    261: };
                    262: 
                    263: /* Bits in Config4 */
                    264: enum Config4Bits {
                    265:     LWPTN = (1 << 2),    /* not on 8139, 8139A */
                    266: };
                    267: 
                    268: /* Bits in Config5 */
                    269: enum Config5Bits {
                    270:     Cfg5_PME_STS     = (1 << 0), /* 1 = PCI reset resets PME_Status */
                    271:     Cfg5_LANWake     = (1 << 1), /* 1 = enable LANWake signal */
                    272:     Cfg5_LDPS        = (1 << 2), /* 0 = save power when link is down */
                    273:     Cfg5_FIFOAddrPtr = (1 << 3), /* Realtek internal SRAM testing */
                    274:     Cfg5_UWF         = (1 << 4), /* 1 = accept unicast wakeup frame */
                    275:     Cfg5_MWF         = (1 << 5), /* 1 = accept multicast wakeup frame */
                    276:     Cfg5_BWF         = (1 << 6), /* 1 = accept broadcast wakeup frame */
                    277: };
                    278: 
                    279: enum RxConfigBits {
                    280:     /* rx fifo threshold */
                    281:     RxCfgFIFOShift = 13,
                    282:     RxCfgFIFONone = (7 << RxCfgFIFOShift),
                    283: 
                    284:     /* Max DMA burst */
                    285:     RxCfgDMAShift = 8,
                    286:     RxCfgDMAUnlimited = (7 << RxCfgDMAShift),
                    287: 
                    288:     /* rx ring buffer length */
                    289:     RxCfgRcv8K = 0,
                    290:     RxCfgRcv16K = (1 << 11),
                    291:     RxCfgRcv32K = (1 << 12),
                    292:     RxCfgRcv64K = (1 << 11) | (1 << 12),
                    293: 
                    294:     /* Disable packet wrap at end of Rx buffer. (not possible with 64k) */
                    295:     RxNoWrap = (1 << 7),
                    296: };
                    297: 
                    298: /* Twister tuning parameters from RealTek.
                    299:    Completely undocumented, but required to tune bad links on some boards. */
                    300: /*
                    301: enum CSCRBits {
                    302:     CSCR_LinkOKBit = 0x0400,
                    303:     CSCR_LinkChangeBit = 0x0800,
                    304:     CSCR_LinkStatusBits = 0x0f000,
                    305:     CSCR_LinkDownOffCmd = 0x003c0,
                    306:     CSCR_LinkDownCmd = 0x0f3c0,
                    307: */
                    308: enum CSCRBits {
                    309:     CSCR_Testfun = 1<<15, /* 1 = Auto-neg speeds up internal timer, WO, def 0 */ 
                    310:     CSCR_LD  = 1<<9,  /* Active low TPI link disable signal. When low, TPI still transmits link pulses and TPI stays in good link state. def 1*/
                    311:     CSCR_HEART_BIT = 1<<8,  /* 1 = HEART BEAT enable, 0 = HEART BEAT disable. HEART BEAT function is only valid in 10Mbps mode. def 1*/
                    312:     CSCR_JBEN = 1<<7,  /* 1 = enable jabber function. 0 = disable jabber function, def 1*/
                    313:     CSCR_F_LINK_100 = 1<<6, /* Used to login force good link in 100Mbps for diagnostic purposes. 1 = DISABLE, 0 = ENABLE. def 1*/ 
                    314:     CSCR_F_Connect  = 1<<5,  /* Assertion of this bit forces the disconnect function to be bypassed. def 0*/
                    315:     CSCR_Con_status = 1<<3, /* This bit indicates the status of the connection. 1 = valid connected link detected; 0 = disconnected link detected. RO def 0*/
                    316:     CSCR_Con_status_En = 1<<2, /* Assertion of this bit configures LED1 pin to indicate connection status. def 0*/
                    317:     CSCR_PASS_SCR = 1<<0, /* Bypass Scramble, def 0*/
                    318: };
                    319: 
                    320: enum Cfg9346Bits {
                    321:     Cfg9346_Lock = 0x00,
                    322:     Cfg9346_Unlock = 0xC0,
                    323: };
                    324: 
                    325: typedef enum {
                    326:     CH_8139 = 0,
                    327:     CH_8139_K,
                    328:     CH_8139A,
                    329:     CH_8139A_G,
                    330:     CH_8139B,
                    331:     CH_8130,
                    332:     CH_8139C,
                    333:     CH_8100,
                    334:     CH_8100B_8139D,
                    335:     CH_8101,
                    336: } chip_t;
                    337: 
                    338: enum chip_flags {
                    339:     HasHltClk = (1 << 0),
                    340:     HasLWake = (1 << 1),
                    341: };
                    342: 
                    343: #define HW_REVID(b30, b29, b28, b27, b26, b23, b22) \
                    344:     (b30<<30 | b29<<29 | b28<<28 | b27<<27 | b26<<26 | b23<<23 | b22<<22)
                    345: #define HW_REVID_MASK    HW_REVID(1, 1, 1, 1, 1, 1, 1)
                    346: 
1.1.1.2 ! root      347: #define RTL8139_PCI_REVID_8139      0x10
        !           348: #define RTL8139_PCI_REVID_8139CPLUS 0x20
        !           349: 
        !           350: #define RTL8139_PCI_REVID           RTL8139_PCI_REVID_8139CPLUS
        !           351: 
1.1       root      352: /* Size is 64 * 16bit words */
                    353: #define EEPROM_9346_ADDR_BITS 6
                    354: #define EEPROM_9346_SIZE  (1 << EEPROM_9346_ADDR_BITS)
                    355: #define EEPROM_9346_ADDR_MASK (EEPROM_9346_SIZE - 1)
                    356: 
                    357: enum Chip9346Operation
                    358: {
                    359:     Chip9346_op_mask = 0xc0,          /* 10 zzzzzz */
                    360:     Chip9346_op_read = 0x80,          /* 10 AAAAAA */
                    361:     Chip9346_op_write = 0x40,         /* 01 AAAAAA D(15)..D(0) */
                    362:     Chip9346_op_ext_mask = 0xf0,      /* 11 zzzzzz */
                    363:     Chip9346_op_write_enable = 0x30,  /* 00 11zzzz */
                    364:     Chip9346_op_write_all = 0x10,     /* 00 01zzzz */
                    365:     Chip9346_op_write_disable = 0x00, /* 00 00zzzz */
                    366: };
                    367: 
                    368: enum Chip9346Mode
                    369: {
                    370:     Chip9346_none = 0,
                    371:     Chip9346_enter_command_mode,
                    372:     Chip9346_read_command,
                    373:     Chip9346_data_read,      /* from output register */
                    374:     Chip9346_data_write,     /* to input register, then to contents at specified address */
                    375:     Chip9346_data_write_all, /* to input register, then filling contents */
                    376: };
                    377: 
                    378: typedef struct EEprom9346
                    379: {
                    380:     uint16_t contents[EEPROM_9346_SIZE];
                    381:     int      mode;
                    382:     uint32_t tick;
                    383:     uint8_t  address;
                    384:     uint16_t input;
                    385:     uint16_t output;
                    386: 
                    387:     uint8_t eecs;
                    388:     uint8_t eesk;
                    389:     uint8_t eedi;
                    390:     uint8_t eedo;
                    391: } EEprom9346;
                    392: 
1.1.1.2 ! root      393: typedef struct RTL8139TallyCounters
        !           394: {
        !           395:     /* Tally counters */
        !           396:     uint64_t   TxOk;
        !           397:     uint64_t   RxOk;
        !           398:     uint64_t   TxERR;
        !           399:     uint32_t   RxERR;
        !           400:     uint16_t   MissPkt;
        !           401:     uint16_t   FAE;
        !           402:     uint32_t   Tx1Col;
        !           403:     uint32_t   TxMCol;
        !           404:     uint64_t   RxOkPhy;
        !           405:     uint64_t   RxOkBrd;
        !           406:     uint32_t   RxOkMul;
        !           407:     uint16_t   TxAbt;
        !           408:     uint16_t   TxUndrn;
        !           409: } RTL8139TallyCounters;
        !           410: 
        !           411: /* Clears all tally counters */
        !           412: static void RTL8139TallyCounters_clear(RTL8139TallyCounters* counters);
        !           413: 
        !           414: /* Writes tally counters to specified physical memory address */
        !           415: static void RTL8139TallyCounters_physical_memory_write(target_phys_addr_t tc_addr, RTL8139TallyCounters* counters);
        !           416: 
        !           417: /* Loads values of tally counters from VM state file */
        !           418: static void RTL8139TallyCounters_load(QEMUFile* f, RTL8139TallyCounters *tally_counters);
        !           419: 
        !           420: /* Saves values of tally counters to VM state file */
        !           421: static void RTL8139TallyCounters_save(QEMUFile* f, RTL8139TallyCounters *tally_counters);
        !           422: 
1.1       root      423: typedef struct RTL8139State {
                    424:     uint8_t phys[8]; /* mac address */
                    425:     uint8_t mult[8]; /* multicast mask array */
                    426: 
1.1.1.2 ! root      427:     uint32_t TxStatus[4]; /* TxStatus0 in C mode*/ /* also DTCCR[0] and DTCCR[1] in C+ mode */
1.1       root      428:     uint32_t TxAddr[4];   /* TxAddr0 */
                    429:     uint32_t RxBuf;       /* Receive buffer */
                    430:     uint32_t RxBufferSize;/* internal variable, receive ring buffer size in C mode */
                    431:     uint32_t RxBufPtr;
                    432:     uint32_t RxBufAddr;
                    433: 
                    434:     uint16_t IntrStatus;
                    435:     uint16_t IntrMask;
                    436: 
                    437:     uint32_t TxConfig;
                    438:     uint32_t RxConfig;
                    439:     uint32_t RxMissed;
                    440: 
                    441:     uint16_t CSCR;
                    442: 
                    443:     uint8_t  Cfg9346;
                    444:     uint8_t  Config0;
                    445:     uint8_t  Config1;
                    446:     uint8_t  Config3;
                    447:     uint8_t  Config4;
                    448:     uint8_t  Config5;
                    449: 
                    450:     uint8_t  clock_enabled;
                    451:     uint8_t  bChipCmdState;
                    452: 
                    453:     uint16_t MultiIntr;
                    454: 
                    455:     uint16_t BasicModeCtrl;
                    456:     uint16_t BasicModeStatus;
                    457:     uint16_t NWayAdvert;
                    458:     uint16_t NWayLPAR;
                    459:     uint16_t NWayExpansion;
                    460: 
                    461:     uint16_t CpCmd;
                    462:     uint8_t  TxThresh;
                    463: 
                    464:     int irq;
                    465:     PCIDevice *pci_dev;
                    466:     VLANClientState *vc;
                    467:     uint8_t macaddr[6];
                    468:     int rtl8139_mmio_io_addr;
                    469: 
                    470:     /* C ring mode */
                    471:     uint32_t   currTxDesc;
                    472: 
                    473:     /* C+ mode */
                    474:     uint32_t   currCPlusRxDesc;
                    475:     uint32_t   currCPlusTxDesc;
                    476: 
                    477:     uint32_t   RxRingAddrLO;
                    478:     uint32_t   RxRingAddrHI;
                    479: 
                    480:     EEprom9346 eeprom;
1.1.1.2 ! root      481: 
        !           482:     uint32_t   TCTR;
        !           483:     uint32_t   TimerInt;
        !           484:     int64_t    TCTR_base;
        !           485: 
        !           486:     /* Tally counters */
        !           487:     RTL8139TallyCounters tally_counters;
        !           488: 
        !           489:     /* Non-persistent data */
        !           490:     uint8_t   *cplus_txbuffer;
        !           491:     int        cplus_txbuffer_len;
        !           492:     int        cplus_txbuffer_offset;
        !           493: 
        !           494:     /* PCI interrupt timer */
        !           495:     QEMUTimer *timer;
        !           496: 
1.1       root      497: } RTL8139State;
                    498: 
                    499: void prom9346_decode_command(EEprom9346 *eeprom, uint8_t command)
                    500: {
1.1.1.2 ! root      501:     DEBUG_PRINT(("RTL8139: eeprom command 0x%02x\n", command));
1.1       root      502: 
                    503:     switch (command & Chip9346_op_mask)
                    504:     {
                    505:         case Chip9346_op_read:
                    506:         {
                    507:             eeprom->address = command & EEPROM_9346_ADDR_MASK;
                    508:             eeprom->output = eeprom->contents[eeprom->address];
                    509:             eeprom->eedo = 0;
                    510:             eeprom->tick = 0;
                    511:             eeprom->mode = Chip9346_data_read;
1.1.1.2 ! root      512:             DEBUG_PRINT(("RTL8139: eeprom read from address 0x%02x data=0x%04x\n",
        !           513:                    eeprom->address, eeprom->output));
1.1       root      514:         }
                    515:         break;
                    516: 
                    517:         case Chip9346_op_write:
                    518:         {
                    519:             eeprom->address = command & EEPROM_9346_ADDR_MASK;
                    520:             eeprom->input = 0;
                    521:             eeprom->tick = 0;
                    522:             eeprom->mode = Chip9346_none; /* Chip9346_data_write */
1.1.1.2 ! root      523:             DEBUG_PRINT(("RTL8139: eeprom begin write to address 0x%02x\n",
        !           524:                    eeprom->address));
1.1       root      525:         }
                    526:         break;
                    527:         default:
                    528:             eeprom->mode = Chip9346_none;
                    529:             switch (command & Chip9346_op_ext_mask)
                    530:             {
                    531:                 case Chip9346_op_write_enable:
1.1.1.2 ! root      532:                     DEBUG_PRINT(("RTL8139: eeprom write enabled\n"));
1.1       root      533:                     break;
                    534:                 case Chip9346_op_write_all:
1.1.1.2 ! root      535:                     DEBUG_PRINT(("RTL8139: eeprom begin write all\n"));
1.1       root      536:                     break;
                    537:                 case Chip9346_op_write_disable:
1.1.1.2 ! root      538:                     DEBUG_PRINT(("RTL8139: eeprom write disabled\n"));
1.1       root      539:                     break;
                    540:             }
                    541:             break;
                    542:     }
                    543: }
                    544: 
                    545: void prom9346_shift_clock(EEprom9346 *eeprom)
                    546: {
                    547:     int bit = eeprom->eedi?1:0;
                    548: 
                    549:     ++ eeprom->tick;
                    550: 
1.1.1.2 ! root      551:     DEBUG_PRINT(("eeprom: tick %d eedi=%d eedo=%d\n", eeprom->tick, eeprom->eedi, eeprom->eedo));
1.1       root      552: 
                    553:     switch (eeprom->mode)
                    554:     {
                    555:         case Chip9346_enter_command_mode:
                    556:             if (bit)
                    557:             {
                    558:                 eeprom->mode = Chip9346_read_command;
                    559:                 eeprom->tick = 0;
                    560:                 eeprom->input = 0;
1.1.1.2 ! root      561:                 DEBUG_PRINT(("eeprom: +++ synchronized, begin command read\n"));
1.1       root      562:             }
                    563:             break;
                    564: 
                    565:         case Chip9346_read_command:
                    566:             eeprom->input = (eeprom->input << 1) | (bit & 1);
                    567:             if (eeprom->tick == 8)
                    568:             {
                    569:                 prom9346_decode_command(eeprom, eeprom->input & 0xff);
                    570:             }
                    571:             break;
                    572: 
                    573:         case Chip9346_data_read:
                    574:             eeprom->eedo = (eeprom->output & 0x8000)?1:0;
                    575:             eeprom->output <<= 1;
                    576:             if (eeprom->tick == 16)
                    577:             {
1.1.1.2 ! root      578: #if 1
        !           579:         // the FreeBSD drivers (rl and re) don't explicitly toggle
        !           580:         // CS between reads (or does setting Cfg9346 to 0 count too?),
        !           581:         // so we need to enter wait-for-command state here
        !           582:                 eeprom->mode = Chip9346_enter_command_mode;
        !           583:                 eeprom->input = 0;
        !           584:                 eeprom->tick = 0;
        !           585: 
        !           586:                 DEBUG_PRINT(("eeprom: +++ end of read, awaiting next command\n"));
        !           587: #else
        !           588:         // original behaviour
1.1       root      589:                 ++eeprom->address;
                    590:                 eeprom->address &= EEPROM_9346_ADDR_MASK;
                    591:                 eeprom->output = eeprom->contents[eeprom->address];
                    592:                 eeprom->tick = 0;
                    593: 
1.1.1.2 ! root      594:                 DEBUG_PRINT(("eeprom: +++ read next address 0x%02x data=0x%04x\n",
        !           595:                        eeprom->address, eeprom->output));
1.1       root      596: #endif
                    597:             }
                    598:             break;
                    599: 
                    600:         case Chip9346_data_write:
                    601:             eeprom->input = (eeprom->input << 1) | (bit & 1);
                    602:             if (eeprom->tick == 16)
                    603:             {
1.1.1.2 ! root      604:                 DEBUG_PRINT(("RTL8139: eeprom write to address 0x%02x data=0x%04x\n",
        !           605:                        eeprom->address, eeprom->input));
        !           606: 
1.1       root      607:                 eeprom->contents[eeprom->address] = eeprom->input;
                    608:                 eeprom->mode = Chip9346_none; /* waiting for next command after CS cycle */
                    609:                 eeprom->tick = 0;
                    610:                 eeprom->input = 0;
                    611:             }
                    612:             break;
                    613: 
                    614:         case Chip9346_data_write_all:
                    615:             eeprom->input = (eeprom->input << 1) | (bit & 1);
                    616:             if (eeprom->tick == 16)
                    617:             {
                    618:                 int i;
                    619:                 for (i = 0; i < EEPROM_9346_SIZE; i++)
                    620:                 {
                    621:                     eeprom->contents[i] = eeprom->input;
                    622:                 }
1.1.1.2 ! root      623:                 DEBUG_PRINT(("RTL8139: eeprom filled with data=0x%04x\n",
        !           624:                        eeprom->input));
        !           625: 
1.1       root      626:                 eeprom->mode = Chip9346_enter_command_mode;
                    627:                 eeprom->tick = 0;
                    628:                 eeprom->input = 0;
                    629:             }
                    630:             break;
                    631: 
                    632:         default:
                    633:             break;
                    634:     }
                    635: }
                    636: 
                    637: int prom9346_get_wire(RTL8139State *s)
                    638: {
                    639:     EEprom9346 *eeprom = &s->eeprom;
                    640:     if (!eeprom->eecs)
                    641:         return 0;
                    642: 
                    643:     return eeprom->eedo;
                    644: }
                    645: 
                    646: void prom9346_set_wire(RTL8139State *s, int eecs, int eesk, int eedi)
                    647: {
                    648:     EEprom9346 *eeprom = &s->eeprom;
                    649:     uint8_t old_eecs = eeprom->eecs;
                    650:     uint8_t old_eesk = eeprom->eesk;
                    651: 
                    652:     eeprom->eecs = eecs;
                    653:     eeprom->eesk = eesk;
                    654:     eeprom->eedi = eedi;
                    655: 
1.1.1.2 ! root      656:     DEBUG_PRINT(("eeprom: +++ wires CS=%d SK=%d DI=%d DO=%d\n",
        !           657:                  eeprom->eecs, eeprom->eesk, eeprom->eedi, eeprom->eedo));
1.1       root      658: 
                    659:     if (!old_eecs && eecs)
                    660:     {
                    661:         /* Synchronize start */
                    662:         eeprom->tick = 0;
                    663:         eeprom->input = 0;
                    664:         eeprom->output = 0;
                    665:         eeprom->mode = Chip9346_enter_command_mode;
                    666: 
1.1.1.2 ! root      667:         DEBUG_PRINT(("=== eeprom: begin access, enter command mode\n"));
1.1       root      668:     }
                    669: 
                    670:     if (!eecs)
                    671:     {
1.1.1.2 ! root      672:         DEBUG_PRINT(("=== eeprom: end access\n"));
1.1       root      673:         return;
                    674:     }
                    675: 
                    676:     if (!old_eesk && eesk)
                    677:     {
                    678:         /* SK front rules */
                    679:         prom9346_shift_clock(eeprom);
                    680:     }
                    681: }
                    682: 
                    683: static void rtl8139_update_irq(RTL8139State *s)
                    684: {
                    685:     int isr;
                    686:     isr = (s->IntrStatus & s->IntrMask) & 0xffff;
1.1.1.2 ! root      687: 
        !           688:     DEBUG_PRINT(("RTL8139: Set IRQ line %d to %d (%04x %04x)\n",
        !           689:        s->irq, isr ? 1 : 0, s->IntrStatus, s->IntrMask));
        !           690: 
1.1       root      691:     if (s->irq == 16) {
                    692:         /* PCI irq */
                    693:         pci_set_irq(s->pci_dev, 0, (isr != 0));
                    694:     } else {
                    695:         /* ISA irq */
                    696:         pic_set_irq(s->irq, (isr != 0));
                    697:     }
                    698: }
                    699: 
                    700: #define POLYNOMIAL 0x04c11db6
                    701: 
                    702: /* From FreeBSD */
                    703: /* XXX: optimize */
                    704: static int compute_mcast_idx(const uint8_t *ep)
                    705: {
                    706:     uint32_t crc;
                    707:     int carry, i, j;
                    708:     uint8_t b;
                    709: 
                    710:     crc = 0xffffffff;
                    711:     for (i = 0; i < 6; i++) {
                    712:         b = *ep++;
                    713:         for (j = 0; j < 8; j++) {
                    714:             carry = ((crc & 0x80000000L) ? 1 : 0) ^ (b & 0x01);
                    715:             crc <<= 1;
                    716:             b >>= 1;
                    717:             if (carry)
                    718:                 crc = ((crc ^ POLYNOMIAL) | carry);
                    719:         }
                    720:     }
                    721:     return (crc >> 26);
                    722: }
                    723: 
                    724: static int rtl8139_RxWrap(RTL8139State *s)
                    725: {
                    726:     /* wrapping enabled; assume 1.5k more buffer space if size < 65536 */
                    727:     return (s->RxConfig & (1 << 7));
                    728: }
                    729: 
                    730: static int rtl8139_receiver_enabled(RTL8139State *s)
                    731: {
                    732:     return s->bChipCmdState & CmdRxEnb;
                    733: }
                    734: 
                    735: static int rtl8139_transmitter_enabled(RTL8139State *s)
                    736: {
                    737:     return s->bChipCmdState & CmdTxEnb;
                    738: }
                    739: 
                    740: static int rtl8139_cp_receiver_enabled(RTL8139State *s)
                    741: {
                    742:     return s->CpCmd & CPlusRxEnb;
                    743: }
                    744: 
                    745: static int rtl8139_cp_transmitter_enabled(RTL8139State *s)
                    746: {
                    747:     return s->CpCmd & CPlusTxEnb;
                    748: }
                    749: 
                    750: static void rtl8139_write_buffer(RTL8139State *s, const void *buf, int size)
                    751: {
                    752:     if (s->RxBufAddr + size > s->RxBufferSize)
                    753:     {
                    754:         int wrapped = MOD2(s->RxBufAddr + size, s->RxBufferSize);
                    755: 
                    756:         /* write packet data */
                    757:         if (wrapped && s->RxBufferSize < 65536 && !rtl8139_RxWrap(s))
                    758:         {
1.1.1.2 ! root      759:             DEBUG_PRINT((">>> RTL8139: rx packet wrapped in buffer at %d\n", size-wrapped));
1.1       root      760: 
                    761:             if (size > wrapped)
                    762:             {
                    763:                 cpu_physical_memory_write( s->RxBuf + s->RxBufAddr,
                    764:                                            buf, size-wrapped );
                    765:             }
                    766: 
                    767:             /* reset buffer pointer */
                    768:             s->RxBufAddr = 0;
                    769: 
                    770:             cpu_physical_memory_write( s->RxBuf + s->RxBufAddr,
                    771:                                        buf + (size-wrapped), wrapped );
                    772: 
                    773:             s->RxBufAddr = wrapped;
                    774: 
                    775:             return;
                    776:         }
                    777:     }
                    778: 
                    779:     /* non-wrapping path or overwrapping enabled */
                    780:     cpu_physical_memory_write( s->RxBuf + s->RxBufAddr, buf, size );
                    781: 
                    782:     s->RxBufAddr += size;
                    783: }
                    784: 
                    785: #define MIN_BUF_SIZE 60
                    786: static inline target_phys_addr_t rtl8139_addr64(uint32_t low, uint32_t high)
                    787: {
                    788: #if TARGET_PHYS_ADDR_BITS > 32
                    789:     return low | ((target_phys_addr_t)high << 32);
                    790: #else
                    791:     return low;
                    792: #endif
                    793: }
                    794: 
                    795: static int rtl8139_can_receive(void *opaque)
                    796: {
                    797:     RTL8139State *s = opaque;
                    798:     int avail;
                    799: 
                    800:     /* Recieve (drop) packets if card is disabled.  */
                    801:     if (!s->clock_enabled)
                    802:       return 1;
                    803:     if (!rtl8139_receiver_enabled(s))
                    804:       return 1;
                    805: 
                    806:     if (rtl8139_cp_receiver_enabled(s)) {
                    807:         /* ??? Flow control not implemented in c+ mode.
                    808:            This is a hack to work around slirp deficiencies anyway.  */
                    809:         return 1;
                    810:     } else {
                    811:         avail = MOD2(s->RxBufferSize + s->RxBufPtr - s->RxBufAddr,
                    812:                      s->RxBufferSize);
                    813:         return (avail == 0 || avail >= 1514);
                    814:     }
                    815: }
                    816: 
1.1.1.2 ! root      817: static void rtl8139_do_receive(void *opaque, const uint8_t *buf, int size, int do_interrupt)
1.1       root      818: {
                    819:     RTL8139State *s = opaque;
                    820: 
                    821:     uint32_t packet_header = 0;
                    822: 
                    823:     uint8_t buf1[60];
                    824:     static const uint8_t broadcast_macaddr[6] = 
                    825:         { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
                    826: 
1.1.1.2 ! root      827:     DEBUG_PRINT((">>> RTL8139: received len=%d\n", size));
1.1       root      828: 
                    829:     /* test if board clock is stopped */
                    830:     if (!s->clock_enabled)
                    831:     {
1.1.1.2 ! root      832:         DEBUG_PRINT(("RTL8139: stopped ==========================\n"));
1.1       root      833:         return;
                    834:     }
                    835: 
                    836:     /* first check if receiver is enabled */
                    837: 
                    838:     if (!rtl8139_receiver_enabled(s))
                    839:     {
1.1.1.2 ! root      840:         DEBUG_PRINT(("RTL8139: receiver disabled ================\n"));
1.1       root      841:         return;
                    842:     }
                    843: 
                    844:     /* XXX: check this */
                    845:     if (s->RxConfig & AcceptAllPhys) {
                    846:         /* promiscuous: receive all */
1.1.1.2 ! root      847:         DEBUG_PRINT((">>> RTL8139: packet received in promiscuous mode\n"));
1.1       root      848: 
                    849:     } else {
                    850:         if (!memcmp(buf,  broadcast_macaddr, 6)) {
                    851:             /* broadcast address */
                    852:             if (!(s->RxConfig & AcceptBroadcast))
                    853:             {
1.1.1.2 ! root      854:                 DEBUG_PRINT((">>> RTL8139: broadcast packet rejected\n"));
        !           855: 
        !           856:                 /* update tally counter */
        !           857:                 ++s->tally_counters.RxERR;
        !           858: 
1.1       root      859:                 return;
                    860:             }
                    861: 
                    862:             packet_header |= RxBroadcast;
                    863: 
1.1.1.2 ! root      864:             DEBUG_PRINT((">>> RTL8139: broadcast packet received\n"));
        !           865: 
        !           866:             /* update tally counter */
        !           867:             ++s->tally_counters.RxOkBrd;
        !           868: 
1.1       root      869:         } else if (buf[0] & 0x01) {
                    870:             /* multicast */
                    871:             if (!(s->RxConfig & AcceptMulticast))
                    872:             {
1.1.1.2 ! root      873:                 DEBUG_PRINT((">>> RTL8139: multicast packet rejected\n"));
        !           874: 
        !           875:                 /* update tally counter */
        !           876:                 ++s->tally_counters.RxERR;
        !           877: 
1.1       root      878:                 return;
                    879:             }
                    880: 
                    881:             int mcast_idx = compute_mcast_idx(buf);
                    882: 
                    883:             if (!(s->mult[mcast_idx >> 3] & (1 << (mcast_idx & 7))))
                    884:             {
1.1.1.2 ! root      885:                 DEBUG_PRINT((">>> RTL8139: multicast address mismatch\n"));
        !           886: 
        !           887:                 /* update tally counter */
        !           888:                 ++s->tally_counters.RxERR;
        !           889: 
1.1       root      890:                 return;
                    891:             }
                    892: 
                    893:             packet_header |= RxMulticast;
                    894: 
1.1.1.2 ! root      895:             DEBUG_PRINT((">>> RTL8139: multicast packet received\n"));
        !           896: 
        !           897:             /* update tally counter */
        !           898:             ++s->tally_counters.RxOkMul;
        !           899: 
1.1       root      900:         } else if (s->phys[0] == buf[0] &&
                    901:                    s->phys[1] == buf[1] &&                   
                    902:                    s->phys[2] == buf[2] &&            
                    903:                    s->phys[3] == buf[3] &&            
                    904:                    s->phys[4] == buf[4] &&            
                    905:                    s->phys[5] == buf[5]) {
                    906:             /* match */
                    907:             if (!(s->RxConfig & AcceptMyPhys))
                    908:             {
1.1.1.2 ! root      909:                 DEBUG_PRINT((">>> RTL8139: rejecting physical address matching packet\n"));
        !           910: 
        !           911:                 /* update tally counter */
        !           912:                 ++s->tally_counters.RxERR;
        !           913: 
1.1       root      914:                 return;
                    915:             }
                    916: 
                    917:             packet_header |= RxPhysical;
                    918: 
1.1.1.2 ! root      919:             DEBUG_PRINT((">>> RTL8139: physical address matching packet received\n"));
        !           920: 
        !           921:             /* update tally counter */
        !           922:             ++s->tally_counters.RxOkPhy;
1.1       root      923: 
                    924:         } else {
                    925: 
1.1.1.2 ! root      926:             DEBUG_PRINT((">>> RTL8139: unknown packet\n"));
        !           927: 
        !           928:             /* update tally counter */
        !           929:             ++s->tally_counters.RxERR;
        !           930: 
1.1       root      931:             return;
                    932:         }
                    933:     }
                    934: 
                    935:     /* if too small buffer, then expand it */
                    936:     if (size < MIN_BUF_SIZE) {
                    937:         memcpy(buf1, buf, size);
                    938:         memset(buf1 + size, 0, MIN_BUF_SIZE - size);
                    939:         buf = buf1;
                    940:         size = MIN_BUF_SIZE;
                    941:     }
                    942: 
                    943:     if (rtl8139_cp_receiver_enabled(s))
                    944:     {
1.1.1.2 ! root      945:         DEBUG_PRINT(("RTL8139: in C+ Rx mode ================\n"));
1.1       root      946: 
                    947:         /* begin C+ receiver mode */
                    948: 
                    949: /* w0 ownership flag */
                    950: #define CP_RX_OWN (1<<31)
                    951: /* w0 end of ring flag */
                    952: #define CP_RX_EOR (1<<30)
                    953: /* w0 bits 0...12 : buffer size */
                    954: #define CP_RX_BUFFER_SIZE_MASK ((1<<13) - 1)
                    955: /* w1 tag available flag */
                    956: #define CP_RX_TAVA (1<<16)
                    957: /* w1 bits 0...15 : VLAN tag */
                    958: #define CP_RX_VLAN_TAG_MASK ((1<<16) - 1)
                    959: /* w2 low  32bit of Rx buffer ptr */
                    960: /* w3 high 32bit of Rx buffer ptr */
                    961: 
                    962:         int descriptor = s->currCPlusRxDesc;
                    963:         target_phys_addr_t cplus_rx_ring_desc;
                    964: 
                    965:         cplus_rx_ring_desc = rtl8139_addr64(s->RxRingAddrLO, s->RxRingAddrHI);
                    966:         cplus_rx_ring_desc += 16 * descriptor;
                    967: 
1.1.1.2 ! root      968:         DEBUG_PRINT(("RTL8139: +++ C+ mode reading RX descriptor %d from host memory at %08x %08x = %016" PRIx64 "\n",
        !           969:                descriptor, s->RxRingAddrHI, s->RxRingAddrLO, (uint64_t)cplus_rx_ring_desc));
1.1       root      970: 
                    971:         uint32_t val, rxdw0,rxdw1,rxbufLO,rxbufHI;
                    972: 
                    973:         cpu_physical_memory_read(cplus_rx_ring_desc,    (uint8_t *)&val, 4);
                    974:         rxdw0 = le32_to_cpu(val);
                    975:         cpu_physical_memory_read(cplus_rx_ring_desc+4,  (uint8_t *)&val, 4);
                    976:         rxdw1 = le32_to_cpu(val);
                    977:         cpu_physical_memory_read(cplus_rx_ring_desc+8,  (uint8_t *)&val, 4);
                    978:         rxbufLO = le32_to_cpu(val);
                    979:         cpu_physical_memory_read(cplus_rx_ring_desc+12, (uint8_t *)&val, 4);
                    980:         rxbufHI = le32_to_cpu(val);
                    981: 
1.1.1.2 ! root      982:         DEBUG_PRINT(("RTL8139: +++ C+ mode RX descriptor %d %08x %08x %08x %08x\n",
1.1       root      983:                descriptor,
1.1.1.2 ! root      984:                rxdw0, rxdw1, rxbufLO, rxbufHI));
1.1       root      985: 
                    986:         if (!(rxdw0 & CP_RX_OWN))
                    987:         {
1.1.1.2 ! root      988:             DEBUG_PRINT(("RTL8139: C+ Rx mode : descriptor %d is owned by host\n", descriptor));
        !           989: 
1.1       root      990:             s->IntrStatus |= RxOverflow;
                    991:             ++s->RxMissed;
1.1.1.2 ! root      992: 
        !           993:             /* update tally counter */
        !           994:             ++s->tally_counters.RxERR;
        !           995:             ++s->tally_counters.MissPkt;
        !           996: 
1.1       root      997:             rtl8139_update_irq(s);
                    998:             return;
                    999:         }
                   1000: 
                   1001:         uint32_t rx_space = rxdw0 & CP_RX_BUFFER_SIZE_MASK;
                   1002: 
1.1.1.2 ! root     1003:         /* TODO: scatter the packet over available receive ring descriptors space */
        !          1004: 
1.1       root     1005:         if (size+4 > rx_space)
                   1006:         {
1.1.1.2 ! root     1007:             DEBUG_PRINT(("RTL8139: C+ Rx mode : descriptor %d size %d received %d + 4\n",
        !          1008:                    descriptor, rx_space, size));
        !          1009: 
1.1       root     1010:             s->IntrStatus |= RxOverflow;
                   1011:             ++s->RxMissed;
1.1.1.2 ! root     1012: 
        !          1013:             /* update tally counter */
        !          1014:             ++s->tally_counters.RxERR;
        !          1015:             ++s->tally_counters.MissPkt;
        !          1016: 
1.1       root     1017:             rtl8139_update_irq(s);
                   1018:             return;
                   1019:         }
                   1020: 
                   1021:         target_phys_addr_t rx_addr = rtl8139_addr64(rxbufLO, rxbufHI);
                   1022: 
                   1023:         /* receive/copy to target memory */
                   1024:         cpu_physical_memory_write( rx_addr, buf, size );
                   1025: 
1.1.1.2 ! root     1026:         if (s->CpCmd & CPlusRxChkSum)
        !          1027:         {
        !          1028:             /* do some packet checksumming */
        !          1029:         }
        !          1030: 
1.1       root     1031:         /* write checksum */
                   1032: #if defined (RTL8139_CALCULATE_RXCRC)
                   1033:         val = cpu_to_le32(crc32(~0, buf, size));
                   1034: #else
                   1035:         val = 0;
                   1036: #endif
                   1037:         cpu_physical_memory_write( rx_addr+size, (uint8_t *)&val, 4);
                   1038: 
                   1039: /* first segment of received packet flag */
                   1040: #define CP_RX_STATUS_FS (1<<29)
                   1041: /* last segment of received packet flag */
                   1042: #define CP_RX_STATUS_LS (1<<28)
                   1043: /* multicast packet flag */
                   1044: #define CP_RX_STATUS_MAR (1<<26)
                   1045: /* physical-matching packet flag */
                   1046: #define CP_RX_STATUS_PAM (1<<25)
                   1047: /* broadcast packet flag */
                   1048: #define CP_RX_STATUS_BAR (1<<24)
                   1049: /* runt packet flag */
                   1050: #define CP_RX_STATUS_RUNT (1<<19)
                   1051: /* crc error flag */
                   1052: #define CP_RX_STATUS_CRC (1<<18)
                   1053: /* IP checksum error flag */
                   1054: #define CP_RX_STATUS_IPF (1<<15)
                   1055: /* UDP checksum error flag */
                   1056: #define CP_RX_STATUS_UDPF (1<<14)
                   1057: /* TCP checksum error flag */
                   1058: #define CP_RX_STATUS_TCPF (1<<13)
                   1059: 
                   1060:         /* transfer ownership to target */
                   1061:         rxdw0 &= ~CP_RX_OWN;
                   1062: 
                   1063:         /* set first segment bit */
                   1064:         rxdw0 |= CP_RX_STATUS_FS;
                   1065: 
                   1066:         /* set last segment bit */
                   1067:         rxdw0 |= CP_RX_STATUS_LS;
                   1068: 
                   1069:         /* set received packet type flags */
                   1070:         if (packet_header & RxBroadcast)
                   1071:             rxdw0 |= CP_RX_STATUS_BAR;
                   1072:         if (packet_header & RxMulticast)
                   1073:             rxdw0 |= CP_RX_STATUS_MAR;
                   1074:         if (packet_header & RxPhysical)
                   1075:             rxdw0 |= CP_RX_STATUS_PAM;
                   1076: 
                   1077:         /* set received size */
                   1078:         rxdw0 &= ~CP_RX_BUFFER_SIZE_MASK;
                   1079:         rxdw0 |= (size+4);
                   1080: 
                   1081:         /* reset VLAN tag flag */
                   1082:         rxdw1 &= ~CP_RX_TAVA;
                   1083: 
                   1084:         /* update ring data */
                   1085:         val = cpu_to_le32(rxdw0);
                   1086:         cpu_physical_memory_write(cplus_rx_ring_desc,    (uint8_t *)&val, 4);
                   1087:         val = cpu_to_le32(rxdw1);
                   1088:         cpu_physical_memory_write(cplus_rx_ring_desc+4,  (uint8_t *)&val, 4);
                   1089: 
1.1.1.2 ! root     1090:         /* update tally counter */
        !          1091:         ++s->tally_counters.RxOk;
        !          1092: 
1.1       root     1093:         /* seek to next Rx descriptor */
                   1094:         if (rxdw0 & CP_RX_EOR)
                   1095:         {
                   1096:             s->currCPlusRxDesc = 0;
                   1097:         }
                   1098:         else
                   1099:         {
                   1100:             ++s->currCPlusRxDesc;
                   1101:         }
                   1102: 
1.1.1.2 ! root     1103:         DEBUG_PRINT(("RTL8139: done C+ Rx mode ----------------\n"));
1.1       root     1104: 
                   1105:     }
                   1106:     else
                   1107:     {
1.1.1.2 ! root     1108:         DEBUG_PRINT(("RTL8139: in ring Rx mode ================\n"));
        !          1109: 
1.1       root     1110:         /* begin ring receiver mode */
                   1111:         int avail = MOD2(s->RxBufferSize + s->RxBufPtr - s->RxBufAddr, s->RxBufferSize);
                   1112: 
                   1113:         /* if receiver buffer is empty then avail == 0 */
                   1114: 
                   1115:         if (avail != 0 && size + 8 >= avail)
                   1116:         {
1.1.1.2 ! root     1117:             DEBUG_PRINT(("rx overflow: rx buffer length %d head 0x%04x read 0x%04x === available 0x%04x need 0x%04x\n",
        !          1118:                    s->RxBufferSize, s->RxBufAddr, s->RxBufPtr, avail, size + 8));
        !          1119: 
1.1       root     1120:             s->IntrStatus |= RxOverflow;
                   1121:             ++s->RxMissed;
                   1122:             rtl8139_update_irq(s);
                   1123:             return;
                   1124:         }
                   1125: 
                   1126:         packet_header |= RxStatusOK;
                   1127: 
                   1128:         packet_header |= (((size+4) << 16) & 0xffff0000);
                   1129: 
                   1130:         /* write header */
                   1131:         uint32_t val = cpu_to_le32(packet_header);
                   1132: 
                   1133:         rtl8139_write_buffer(s, (uint8_t *)&val, 4);
                   1134: 
                   1135:         rtl8139_write_buffer(s, buf, size);
                   1136: 
                   1137:         /* write checksum */
                   1138: #if defined (RTL8139_CALCULATE_RXCRC)
                   1139:         val = cpu_to_le32(crc32(~0, buf, size));
                   1140: #else
                   1141:         val = 0;
                   1142: #endif
                   1143: 
                   1144:         rtl8139_write_buffer(s, (uint8_t *)&val, 4);
                   1145: 
                   1146:         /* correct buffer write pointer */
                   1147:         s->RxBufAddr = MOD2((s->RxBufAddr + 3) & ~0x3, s->RxBufferSize);
                   1148: 
                   1149:         /* now we can signal we have received something */
                   1150: 
1.1.1.2 ! root     1151:         DEBUG_PRINT(("   received: rx buffer length %d head 0x%04x read 0x%04x\n",
        !          1152:                s->RxBufferSize, s->RxBufAddr, s->RxBufPtr));
1.1       root     1153:     }
                   1154: 
                   1155:     s->IntrStatus |= RxOK;
1.1.1.2 ! root     1156: 
        !          1157:     if (do_interrupt)
        !          1158:     {
        !          1159:         rtl8139_update_irq(s);
        !          1160:     }
        !          1161: }
        !          1162: 
        !          1163: static void rtl8139_receive(void *opaque, const uint8_t *buf, int size)
        !          1164: {
        !          1165:     rtl8139_do_receive(opaque, buf, size, 1);
1.1       root     1166: }
                   1167: 
                   1168: static void rtl8139_reset_rxring(RTL8139State *s, uint32_t bufferSize)
                   1169: {
                   1170:     s->RxBufferSize = bufferSize;
                   1171:     s->RxBufPtr  = 0;
                   1172:     s->RxBufAddr = 0;
                   1173: }
                   1174: 
                   1175: static void rtl8139_reset(RTL8139State *s)
                   1176: {
                   1177:     int i;
                   1178: 
                   1179:     /* restore MAC address */
                   1180:     memcpy(s->phys, s->macaddr, 6);
                   1181: 
                   1182:     /* reset interrupt mask */
                   1183:     s->IntrStatus = 0;
                   1184:     s->IntrMask = 0;
                   1185: 
                   1186:     rtl8139_update_irq(s);
                   1187: 
                   1188:     /* prepare eeprom */
                   1189:     s->eeprom.contents[0] = 0x8129;
1.1.1.2 ! root     1190: #if 1
        !          1191:     // PCI vendor and device ID should be mirrored here
        !          1192:     s->eeprom.contents[1] = 0x10ec;
        !          1193:     s->eeprom.contents[2] = 0x8139;
        !          1194: #endif
1.1       root     1195:     memcpy(&s->eeprom.contents[7], s->macaddr, 6);
                   1196: 
                   1197:     /* mark all status registers as owned by host */
                   1198:     for (i = 0; i < 4; ++i)
                   1199:     {
                   1200:         s->TxStatus[i] = TxHostOwns;
                   1201:     }
                   1202: 
                   1203:     s->currTxDesc = 0;
                   1204:     s->currCPlusRxDesc = 0;
                   1205:     s->currCPlusTxDesc = 0;
                   1206: 
                   1207:     s->RxRingAddrLO = 0;
                   1208:     s->RxRingAddrHI = 0;
                   1209: 
                   1210:     s->RxBuf = 0;
                   1211: 
                   1212:     rtl8139_reset_rxring(s, 8192);
                   1213: 
                   1214:     /* ACK the reset */
                   1215:     s->TxConfig = 0;
                   1216: 
                   1217: #if 0
                   1218: //    s->TxConfig |= HW_REVID(1, 0, 0, 0, 0, 0, 0); // RTL-8139  HasHltClk
                   1219:     s->clock_enabled = 0;
                   1220: #else
1.1.1.2 ! root     1221:     s->TxConfig |= HW_REVID(1, 1, 1, 0, 1, 1, 0); // RTL-8139C+ HasLWake
1.1       root     1222:     s->clock_enabled = 1;
                   1223: #endif
                   1224: 
                   1225:     s->bChipCmdState = CmdReset; /* RxBufEmpty bit is calculated on read from ChipCmd */;
                   1226: 
                   1227:     /* set initial state data */
                   1228:     s->Config0 = 0x0; /* No boot ROM */
                   1229:     s->Config1 = 0xC; /* IO mapped and MEM mapped registers available */
                   1230:     s->Config3 = 0x1; /* fast back-to-back compatible */
                   1231:     s->Config5 = 0x0;
                   1232: 
                   1233:     s->CSCR = CSCR_F_LINK_100 | CSCR_HEART_BIT | CSCR_LD; 
                   1234: 
                   1235:     s->CpCmd   = 0x0; /* reset C+ mode */
                   1236: 
                   1237: //    s->BasicModeCtrl = 0x3100; // 100Mbps, full duplex, autonegotiation
                   1238: //    s->BasicModeCtrl = 0x2100; // 100Mbps, full duplex
                   1239:     s->BasicModeCtrl = 0x1000; // autonegotiation
                   1240: 
                   1241:     s->BasicModeStatus  = 0x7809;
                   1242:     //s->BasicModeStatus |= 0x0040; /* UTP medium */
                   1243:     s->BasicModeStatus |= 0x0020; /* autonegotiation completed */
                   1244:     s->BasicModeStatus |= 0x0004; /* link is up */
                   1245: 
                   1246:     s->NWayAdvert    = 0x05e1; /* all modes, full duplex */
                   1247:     s->NWayLPAR      = 0x05e1; /* all modes, full duplex */
                   1248:     s->NWayExpansion = 0x0001; /* autonegotiation supported */
1.1.1.2 ! root     1249: 
        !          1250:     /* also reset timer and disable timer interrupt */
        !          1251:     s->TCTR = 0;
        !          1252:     s->TimerInt = 0;
        !          1253:     s->TCTR_base = 0;
        !          1254: 
        !          1255:     /* reset tally counters */
        !          1256:     RTL8139TallyCounters_clear(&s->tally_counters);
        !          1257: }
        !          1258: 
        !          1259: void RTL8139TallyCounters_clear(RTL8139TallyCounters* counters)
        !          1260: {
        !          1261:     counters->TxOk = 0;
        !          1262:     counters->RxOk = 0;
        !          1263:     counters->TxERR = 0;
        !          1264:     counters->RxERR = 0;
        !          1265:     counters->MissPkt = 0;
        !          1266:     counters->FAE = 0;
        !          1267:     counters->Tx1Col = 0;
        !          1268:     counters->TxMCol = 0;
        !          1269:     counters->RxOkPhy = 0;
        !          1270:     counters->RxOkBrd = 0;
        !          1271:     counters->RxOkMul = 0;
        !          1272:     counters->TxAbt = 0;
        !          1273:     counters->TxUndrn = 0;
        !          1274: }
        !          1275: 
        !          1276: static void RTL8139TallyCounters_physical_memory_write(target_phys_addr_t tc_addr, RTL8139TallyCounters* tally_counters)
        !          1277: {
        !          1278:     uint16_t val16;
        !          1279:     uint32_t val32;
        !          1280:     uint64_t val64;
        !          1281: 
        !          1282:     val64 = cpu_to_le64(tally_counters->TxOk);
        !          1283:     cpu_physical_memory_write(tc_addr + 0,    (uint8_t *)&val64, 8);
        !          1284: 
        !          1285:     val64 = cpu_to_le64(tally_counters->RxOk);
        !          1286:     cpu_physical_memory_write(tc_addr + 8,    (uint8_t *)&val64, 8);
        !          1287: 
        !          1288:     val64 = cpu_to_le64(tally_counters->TxERR);
        !          1289:     cpu_physical_memory_write(tc_addr + 16,    (uint8_t *)&val64, 8);
        !          1290: 
        !          1291:     val32 = cpu_to_le32(tally_counters->RxERR);
        !          1292:     cpu_physical_memory_write(tc_addr + 24,    (uint8_t *)&val32, 4);
        !          1293: 
        !          1294:     val16 = cpu_to_le16(tally_counters->MissPkt);
        !          1295:     cpu_physical_memory_write(tc_addr + 28,    (uint8_t *)&val16, 2);
        !          1296: 
        !          1297:     val16 = cpu_to_le16(tally_counters->FAE);
        !          1298:     cpu_physical_memory_write(tc_addr + 30,    (uint8_t *)&val16, 2);
        !          1299: 
        !          1300:     val32 = cpu_to_le32(tally_counters->Tx1Col);
        !          1301:     cpu_physical_memory_write(tc_addr + 32,    (uint8_t *)&val32, 4);
        !          1302: 
        !          1303:     val32 = cpu_to_le32(tally_counters->TxMCol);
        !          1304:     cpu_physical_memory_write(tc_addr + 36,    (uint8_t *)&val32, 4);
        !          1305: 
        !          1306:     val64 = cpu_to_le64(tally_counters->RxOkPhy);
        !          1307:     cpu_physical_memory_write(tc_addr + 40,    (uint8_t *)&val64, 8);
        !          1308: 
        !          1309:     val64 = cpu_to_le64(tally_counters->RxOkBrd);
        !          1310:     cpu_physical_memory_write(tc_addr + 48,    (uint8_t *)&val64, 8);
        !          1311: 
        !          1312:     val32 = cpu_to_le32(tally_counters->RxOkMul);
        !          1313:     cpu_physical_memory_write(tc_addr + 56,    (uint8_t *)&val32, 4);
        !          1314: 
        !          1315:     val16 = cpu_to_le16(tally_counters->TxAbt);
        !          1316:     cpu_physical_memory_write(tc_addr + 60,    (uint8_t *)&val16, 2);
        !          1317: 
        !          1318:     val16 = cpu_to_le16(tally_counters->TxUndrn);
        !          1319:     cpu_physical_memory_write(tc_addr + 62,    (uint8_t *)&val16, 2);
        !          1320: }
        !          1321: 
        !          1322: /* Loads values of tally counters from VM state file */
        !          1323: static void RTL8139TallyCounters_load(QEMUFile* f, RTL8139TallyCounters *tally_counters)
        !          1324: {
        !          1325:     qemu_get_be64s(f, &tally_counters->TxOk);
        !          1326:     qemu_get_be64s(f, &tally_counters->RxOk);
        !          1327:     qemu_get_be64s(f, &tally_counters->TxERR);
        !          1328:     qemu_get_be32s(f, &tally_counters->RxERR);
        !          1329:     qemu_get_be16s(f, &tally_counters->MissPkt);
        !          1330:     qemu_get_be16s(f, &tally_counters->FAE);
        !          1331:     qemu_get_be32s(f, &tally_counters->Tx1Col);
        !          1332:     qemu_get_be32s(f, &tally_counters->TxMCol);
        !          1333:     qemu_get_be64s(f, &tally_counters->RxOkPhy);
        !          1334:     qemu_get_be64s(f, &tally_counters->RxOkBrd);
        !          1335:     qemu_get_be32s(f, &tally_counters->RxOkMul);
        !          1336:     qemu_get_be16s(f, &tally_counters->TxAbt);
        !          1337:     qemu_get_be16s(f, &tally_counters->TxUndrn);
        !          1338: }
        !          1339: 
        !          1340: /* Saves values of tally counters to VM state file */
        !          1341: static void RTL8139TallyCounters_save(QEMUFile* f, RTL8139TallyCounters *tally_counters)
        !          1342: {
        !          1343:     qemu_put_be64s(f, &tally_counters->TxOk);
        !          1344:     qemu_put_be64s(f, &tally_counters->RxOk);
        !          1345:     qemu_put_be64s(f, &tally_counters->TxERR);
        !          1346:     qemu_put_be32s(f, &tally_counters->RxERR);
        !          1347:     qemu_put_be16s(f, &tally_counters->MissPkt);
        !          1348:     qemu_put_be16s(f, &tally_counters->FAE);
        !          1349:     qemu_put_be32s(f, &tally_counters->Tx1Col);
        !          1350:     qemu_put_be32s(f, &tally_counters->TxMCol);
        !          1351:     qemu_put_be64s(f, &tally_counters->RxOkPhy);
        !          1352:     qemu_put_be64s(f, &tally_counters->RxOkBrd);
        !          1353:     qemu_put_be32s(f, &tally_counters->RxOkMul);
        !          1354:     qemu_put_be16s(f, &tally_counters->TxAbt);
        !          1355:     qemu_put_be16s(f, &tally_counters->TxUndrn);
1.1       root     1356: }
                   1357: 
                   1358: static void rtl8139_ChipCmd_write(RTL8139State *s, uint32_t val)
                   1359: {
                   1360:     val &= 0xff;
                   1361: 
1.1.1.2 ! root     1362:     DEBUG_PRINT(("RTL8139: ChipCmd write val=0x%08x\n", val));
1.1       root     1363: 
                   1364:     if (val & CmdReset)
                   1365:     {
1.1.1.2 ! root     1366:         DEBUG_PRINT(("RTL8139: ChipCmd reset\n"));
1.1       root     1367:         rtl8139_reset(s);
                   1368:     }
                   1369:     if (val & CmdRxEnb)
                   1370:     {
1.1.1.2 ! root     1371:         DEBUG_PRINT(("RTL8139: ChipCmd enable receiver\n"));
        !          1372: 
        !          1373:         s->currCPlusRxDesc = 0;
1.1       root     1374:     }
                   1375:     if (val & CmdTxEnb)
                   1376:     {
1.1.1.2 ! root     1377:         DEBUG_PRINT(("RTL8139: ChipCmd enable transmitter\n"));
        !          1378: 
        !          1379:         s->currCPlusTxDesc = 0;
1.1       root     1380:     }
                   1381: 
                   1382:     /* mask unwriteable bits */
                   1383:     val = SET_MASKED(val, 0xe3, s->bChipCmdState);
                   1384: 
                   1385:     /* Deassert reset pin before next read */
                   1386:     val &= ~CmdReset;
                   1387: 
                   1388:     s->bChipCmdState = val;
                   1389: }
                   1390: 
                   1391: static int rtl8139_RxBufferEmpty(RTL8139State *s)
                   1392: {
                   1393:     int unread = MOD2(s->RxBufferSize + s->RxBufAddr - s->RxBufPtr, s->RxBufferSize);
                   1394: 
                   1395:     if (unread != 0)
                   1396:     {
1.1.1.2 ! root     1397:         DEBUG_PRINT(("RTL8139: receiver buffer data available 0x%04x\n", unread));
1.1       root     1398:         return 0;
                   1399:     }
                   1400: 
1.1.1.2 ! root     1401:     DEBUG_PRINT(("RTL8139: receiver buffer is empty\n"));
1.1       root     1402: 
                   1403:     return 1;
                   1404: }
                   1405: 
                   1406: static uint32_t rtl8139_ChipCmd_read(RTL8139State *s)
                   1407: {
                   1408:     uint32_t ret = s->bChipCmdState;
                   1409: 
                   1410:     if (rtl8139_RxBufferEmpty(s))
                   1411:         ret |= RxBufEmpty;
                   1412: 
1.1.1.2 ! root     1413:     DEBUG_PRINT(("RTL8139: ChipCmd read val=0x%04x\n", ret));
1.1       root     1414: 
                   1415:     return ret;
                   1416: }
                   1417: 
                   1418: static void rtl8139_CpCmd_write(RTL8139State *s, uint32_t val)
                   1419: {
                   1420:     val &= 0xffff;
                   1421: 
1.1.1.2 ! root     1422:     DEBUG_PRINT(("RTL8139C+ command register write(w) val=0x%04x\n", val));
1.1       root     1423: 
                   1424:     /* mask unwriteable bits */
                   1425:     val = SET_MASKED(val, 0xff84, s->CpCmd);
                   1426: 
                   1427:     s->CpCmd = val;
                   1428: }
                   1429: 
                   1430: static uint32_t rtl8139_CpCmd_read(RTL8139State *s)
                   1431: {
                   1432:     uint32_t ret = s->CpCmd;
                   1433: 
1.1.1.2 ! root     1434:     DEBUG_PRINT(("RTL8139C+ command register read(w) val=0x%04x\n", ret));
        !          1435: 
        !          1436:     return ret;
        !          1437: }
        !          1438: 
        !          1439: static void rtl8139_IntrMitigate_write(RTL8139State *s, uint32_t val)
        !          1440: {
        !          1441:     DEBUG_PRINT(("RTL8139C+ IntrMitigate register write(w) val=0x%04x\n", val));
        !          1442: }
        !          1443: 
        !          1444: static uint32_t rtl8139_IntrMitigate_read(RTL8139State *s)
        !          1445: {
        !          1446:     uint32_t ret = 0;
        !          1447: 
        !          1448:     DEBUG_PRINT(("RTL8139C+ IntrMitigate register read(w) val=0x%04x\n", ret));
1.1       root     1449: 
                   1450:     return ret;
                   1451: }
                   1452: 
                   1453: int rtl8139_config_writeable(RTL8139State *s)
                   1454: {
                   1455:     if (s->Cfg9346 & Cfg9346_Unlock)
                   1456:     {
                   1457:         return 1;
                   1458:     }
                   1459: 
1.1.1.2 ! root     1460:     DEBUG_PRINT(("RTL8139: Configuration registers are write-protected\n"));
1.1       root     1461: 
                   1462:     return 0;
                   1463: }
                   1464: 
                   1465: static void rtl8139_BasicModeCtrl_write(RTL8139State *s, uint32_t val)
                   1466: {
                   1467:     val &= 0xffff;
                   1468: 
1.1.1.2 ! root     1469:     DEBUG_PRINT(("RTL8139: BasicModeCtrl register write(w) val=0x%04x\n", val));
1.1       root     1470: 
                   1471:     /* mask unwriteable bits */
                   1472:     uint32 mask = 0x4cff;
                   1473: 
                   1474:     if (1 || !rtl8139_config_writeable(s))
                   1475:     {
                   1476:         /* Speed setting and autonegotiation enable bits are read-only */
                   1477:         mask |= 0x3000;
                   1478:         /* Duplex mode setting is read-only */
                   1479:         mask |= 0x0100;
                   1480:     }
                   1481: 
                   1482:     val = SET_MASKED(val, mask, s->BasicModeCtrl);
                   1483: 
                   1484:     s->BasicModeCtrl = val;
                   1485: }
                   1486: 
                   1487: static uint32_t rtl8139_BasicModeCtrl_read(RTL8139State *s)
                   1488: {
                   1489:     uint32_t ret = s->BasicModeCtrl;
                   1490: 
1.1.1.2 ! root     1491:     DEBUG_PRINT(("RTL8139: BasicModeCtrl register read(w) val=0x%04x\n", ret));
1.1       root     1492: 
                   1493:     return ret;
                   1494: }
                   1495: 
                   1496: static void rtl8139_BasicModeStatus_write(RTL8139State *s, uint32_t val)
                   1497: {
                   1498:     val &= 0xffff;
                   1499: 
1.1.1.2 ! root     1500:     DEBUG_PRINT(("RTL8139: BasicModeStatus register write(w) val=0x%04x\n", val));
1.1       root     1501: 
                   1502:     /* mask unwriteable bits */
                   1503:     val = SET_MASKED(val, 0xff3f, s->BasicModeStatus);
                   1504: 
                   1505:     s->BasicModeStatus = val;
                   1506: }
                   1507: 
                   1508: static uint32_t rtl8139_BasicModeStatus_read(RTL8139State *s)
                   1509: {
                   1510:     uint32_t ret = s->BasicModeStatus;
                   1511: 
1.1.1.2 ! root     1512:     DEBUG_PRINT(("RTL8139: BasicModeStatus register read(w) val=0x%04x\n", ret));
1.1       root     1513: 
                   1514:     return ret;
                   1515: }
                   1516: 
                   1517: static void rtl8139_Cfg9346_write(RTL8139State *s, uint32_t val)
                   1518: {
                   1519:     val &= 0xff;
                   1520: 
1.1.1.2 ! root     1521:     DEBUG_PRINT(("RTL8139: Cfg9346 write val=0x%02x\n", val));
1.1       root     1522: 
                   1523:     /* mask unwriteable bits */
                   1524:     val = SET_MASKED(val, 0x31, s->Cfg9346);
                   1525: 
                   1526:     uint32_t opmode = val & 0xc0;
                   1527:     uint32_t eeprom_val = val & 0xf;
                   1528: 
                   1529:     if (opmode == 0x80) {
                   1530:         /* eeprom access */
                   1531:         int eecs = (eeprom_val & 0x08)?1:0;
                   1532:         int eesk = (eeprom_val & 0x04)?1:0;
                   1533:         int eedi = (eeprom_val & 0x02)?1:0;
                   1534:         prom9346_set_wire(s, eecs, eesk, eedi);
                   1535:     } else if (opmode == 0x40) {
                   1536:         /* Reset.  */
                   1537:         val = 0;
                   1538:         rtl8139_reset(s);
                   1539:     }
                   1540: 
                   1541:     s->Cfg9346 = val;
                   1542: }
                   1543: 
                   1544: static uint32_t rtl8139_Cfg9346_read(RTL8139State *s)
                   1545: {
                   1546:     uint32_t ret = s->Cfg9346;
                   1547: 
                   1548:     uint32_t opmode = ret & 0xc0;
                   1549: 
                   1550:     if (opmode == 0x80)
                   1551:     {
                   1552:         /* eeprom access */
                   1553:         int eedo = prom9346_get_wire(s);
                   1554:         if (eedo)
                   1555:         {
                   1556:             ret |=  0x01;
                   1557:         }
                   1558:         else
                   1559:         {
                   1560:             ret &= ~0x01;
                   1561:         }
                   1562:     }
                   1563: 
1.1.1.2 ! root     1564:     DEBUG_PRINT(("RTL8139: Cfg9346 read val=0x%02x\n", ret));
1.1       root     1565: 
                   1566:     return ret;
                   1567: }
                   1568: 
                   1569: static void rtl8139_Config0_write(RTL8139State *s, uint32_t val)
                   1570: {
                   1571:     val &= 0xff;
                   1572: 
1.1.1.2 ! root     1573:     DEBUG_PRINT(("RTL8139: Config0 write val=0x%02x\n", val));
1.1       root     1574: 
                   1575:     if (!rtl8139_config_writeable(s))
                   1576:         return;
                   1577: 
                   1578:     /* mask unwriteable bits */
                   1579:     val = SET_MASKED(val, 0xf8, s->Config0);
                   1580: 
                   1581:     s->Config0 = val;
                   1582: }
                   1583: 
                   1584: static uint32_t rtl8139_Config0_read(RTL8139State *s)
                   1585: {
                   1586:     uint32_t ret = s->Config0;
                   1587: 
1.1.1.2 ! root     1588:     DEBUG_PRINT(("RTL8139: Config0 read val=0x%02x\n", ret));
1.1       root     1589: 
                   1590:     return ret;
                   1591: }
                   1592: 
                   1593: static void rtl8139_Config1_write(RTL8139State *s, uint32_t val)
                   1594: {
                   1595:     val &= 0xff;
                   1596: 
1.1.1.2 ! root     1597:     DEBUG_PRINT(("RTL8139: Config1 write val=0x%02x\n", val));
1.1       root     1598: 
                   1599:     if (!rtl8139_config_writeable(s))
                   1600:         return;
                   1601: 
                   1602:     /* mask unwriteable bits */
                   1603:     val = SET_MASKED(val, 0xC, s->Config1);
                   1604: 
                   1605:     s->Config1 = val;
                   1606: }
                   1607: 
                   1608: static uint32_t rtl8139_Config1_read(RTL8139State *s)
                   1609: {
                   1610:     uint32_t ret = s->Config1;
                   1611: 
1.1.1.2 ! root     1612:     DEBUG_PRINT(("RTL8139: Config1 read val=0x%02x\n", ret));
1.1       root     1613: 
                   1614:     return ret;
                   1615: }
                   1616: 
                   1617: static void rtl8139_Config3_write(RTL8139State *s, uint32_t val)
                   1618: {
                   1619:     val &= 0xff;
                   1620: 
1.1.1.2 ! root     1621:     DEBUG_PRINT(("RTL8139: Config3 write val=0x%02x\n", val));
1.1       root     1622: 
                   1623:     if (!rtl8139_config_writeable(s))
                   1624:         return;
                   1625: 
                   1626:     /* mask unwriteable bits */
                   1627:     val = SET_MASKED(val, 0x8F, s->Config3);
                   1628: 
                   1629:     s->Config3 = val;
                   1630: }
                   1631: 
                   1632: static uint32_t rtl8139_Config3_read(RTL8139State *s)
                   1633: {
                   1634:     uint32_t ret = s->Config3;
                   1635: 
1.1.1.2 ! root     1636:     DEBUG_PRINT(("RTL8139: Config3 read val=0x%02x\n", ret));
1.1       root     1637: 
                   1638:     return ret;
                   1639: }
                   1640: 
                   1641: static void rtl8139_Config4_write(RTL8139State *s, uint32_t val)
                   1642: {
                   1643:     val &= 0xff;
                   1644: 
1.1.1.2 ! root     1645:     DEBUG_PRINT(("RTL8139: Config4 write val=0x%02x\n", val));
1.1       root     1646: 
                   1647:     if (!rtl8139_config_writeable(s))
                   1648:         return;
                   1649: 
                   1650:     /* mask unwriteable bits */
                   1651:     val = SET_MASKED(val, 0x0a, s->Config4);
                   1652: 
                   1653:     s->Config4 = val;
                   1654: }
                   1655: 
                   1656: static uint32_t rtl8139_Config4_read(RTL8139State *s)
                   1657: {
                   1658:     uint32_t ret = s->Config4;
                   1659: 
1.1.1.2 ! root     1660:     DEBUG_PRINT(("RTL8139: Config4 read val=0x%02x\n", ret));
1.1       root     1661: 
                   1662:     return ret;
                   1663: }
                   1664: 
                   1665: static void rtl8139_Config5_write(RTL8139State *s, uint32_t val)
                   1666: {
                   1667:     val &= 0xff;
                   1668: 
1.1.1.2 ! root     1669:     DEBUG_PRINT(("RTL8139: Config5 write val=0x%02x\n", val));
1.1       root     1670: 
                   1671:     /* mask unwriteable bits */
                   1672:     val = SET_MASKED(val, 0x80, s->Config5);
                   1673: 
                   1674:     s->Config5 = val;
                   1675: }
                   1676: 
                   1677: static uint32_t rtl8139_Config5_read(RTL8139State *s)
                   1678: {
                   1679:     uint32_t ret = s->Config5;
                   1680: 
1.1.1.2 ! root     1681:     DEBUG_PRINT(("RTL8139: Config5 read val=0x%02x\n", ret));
1.1       root     1682: 
                   1683:     return ret;
                   1684: }
                   1685: 
                   1686: static void rtl8139_TxConfig_write(RTL8139State *s, uint32_t val)
                   1687: {
                   1688:     if (!rtl8139_transmitter_enabled(s))
                   1689:     {
1.1.1.2 ! root     1690:         DEBUG_PRINT(("RTL8139: transmitter disabled; no TxConfig write val=0x%08x\n", val));
1.1       root     1691:         return;
                   1692:     }
                   1693: 
1.1.1.2 ! root     1694:     DEBUG_PRINT(("RTL8139: TxConfig write val=0x%08x\n", val));
1.1       root     1695: 
                   1696:     val = SET_MASKED(val, TxVersionMask | 0x8070f80f, s->TxConfig);
                   1697: 
                   1698:     s->TxConfig = val;
                   1699: }
                   1700: 
                   1701: static void rtl8139_TxConfig_writeb(RTL8139State *s, uint32_t val)
                   1702: {
1.1.1.2 ! root     1703:     DEBUG_PRINT(("RTL8139C TxConfig via write(b) val=0x%02x\n", val));
        !          1704: 
        !          1705:     uint32_t tc = s->TxConfig;
        !          1706:     tc &= 0xFFFFFF00;
        !          1707:     tc |= (val & 0x000000FF);
        !          1708:     rtl8139_TxConfig_write(s, tc);
1.1       root     1709: }
                   1710: 
                   1711: static uint32_t rtl8139_TxConfig_read(RTL8139State *s)
                   1712: {
                   1713:     uint32_t ret = s->TxConfig;
                   1714: 
1.1.1.2 ! root     1715:     DEBUG_PRINT(("RTL8139: TxConfig read val=0x%04x\n", ret));
1.1       root     1716: 
                   1717:     return ret;
                   1718: }
                   1719: 
                   1720: static void rtl8139_RxConfig_write(RTL8139State *s, uint32_t val)
                   1721: {
1.1.1.2 ! root     1722:     DEBUG_PRINT(("RTL8139: RxConfig write val=0x%08x\n", val));
1.1       root     1723: 
                   1724:     /* mask unwriteable bits */
                   1725:     val = SET_MASKED(val, 0xf0fc0040, s->RxConfig);
                   1726: 
                   1727:     s->RxConfig = val;
                   1728: 
                   1729:     /* reset buffer size and read/write pointers */
                   1730:     rtl8139_reset_rxring(s, 8192 << ((s->RxConfig >> 11) & 0x3));
                   1731: 
1.1.1.2 ! root     1732:     DEBUG_PRINT(("RTL8139: RxConfig write reset buffer size to %d\n", s->RxBufferSize));
1.1       root     1733: }
                   1734: 
                   1735: static uint32_t rtl8139_RxConfig_read(RTL8139State *s)
                   1736: {
                   1737:     uint32_t ret = s->RxConfig;
                   1738: 
1.1.1.2 ! root     1739:     DEBUG_PRINT(("RTL8139: RxConfig read val=0x%08x\n", ret));
1.1       root     1740: 
                   1741:     return ret;
                   1742: }
                   1743: 
1.1.1.2 ! root     1744: static void rtl8139_transfer_frame(RTL8139State *s, const uint8_t *buf, int size, int do_interrupt)
        !          1745: {
        !          1746:     if (!size)
        !          1747:     {
        !          1748:         DEBUG_PRINT(("RTL8139: +++ empty ethernet frame\n"));
        !          1749:         return;
        !          1750:     }
        !          1751: 
        !          1752:     if (TxLoopBack == (s->TxConfig & TxLoopBack))
        !          1753:     {
        !          1754:         DEBUG_PRINT(("RTL8139: +++ transmit loopback mode\n"));
        !          1755:         rtl8139_do_receive(s, buf, size, do_interrupt);
        !          1756:     }
        !          1757:     else
        !          1758:     {
        !          1759:         qemu_send_packet(s->vc, buf, size);
        !          1760:     }
        !          1761: }
        !          1762: 
1.1       root     1763: static int rtl8139_transmit_one(RTL8139State *s, int descriptor)
                   1764: {
                   1765:     if (!rtl8139_transmitter_enabled(s))
                   1766:     {
1.1.1.2 ! root     1767:         DEBUG_PRINT(("RTL8139: +++ cannot transmit from descriptor %d: transmitter disabled\n",
        !          1768:                      descriptor));
1.1       root     1769:         return 0;
                   1770:     }
                   1771: 
                   1772:     if (s->TxStatus[descriptor] & TxHostOwns)
                   1773:     {
1.1.1.2 ! root     1774:         DEBUG_PRINT(("RTL8139: +++ cannot transmit from descriptor %d: owned by host (%08x)\n",
        !          1775:                      descriptor, s->TxStatus[descriptor]));
1.1       root     1776:         return 0;
                   1777:     }
                   1778: 
1.1.1.2 ! root     1779:     DEBUG_PRINT(("RTL8139: +++ transmitting from descriptor %d\n", descriptor));
1.1       root     1780: 
                   1781:     int txsize = s->TxStatus[descriptor] & 0x1fff;
                   1782:     uint8_t txbuffer[0x2000];
                   1783: 
1.1.1.2 ! root     1784:     DEBUG_PRINT(("RTL8139: +++ transmit reading %d bytes from host memory at 0x%08x\n",
        !          1785:                  txsize, s->TxAddr[descriptor]));
1.1       root     1786: 
1.1.1.2 ! root     1787:     cpu_physical_memory_read(s->TxAddr[descriptor], txbuffer, txsize);
1.1       root     1788: 
                   1789:     /* Mark descriptor as transferred */
                   1790:     s->TxStatus[descriptor] |= TxHostOwns;
                   1791:     s->TxStatus[descriptor] |= TxStatOK;
                   1792: 
1.1.1.2 ! root     1793:     rtl8139_transfer_frame(s, txbuffer, txsize, 0);
        !          1794: 
        !          1795:     DEBUG_PRINT(("RTL8139: +++ transmitted %d bytes from descriptor %d\n", txsize, descriptor));
1.1       root     1796: 
                   1797:     /* update interrupt */
                   1798:     s->IntrStatus |= TxOK;
                   1799:     rtl8139_update_irq(s);
                   1800: 
                   1801:     return 1;
                   1802: }
                   1803: 
1.1.1.2 ! root     1804: /* structures and macros for task offloading */
        !          1805: typedef struct ip_header
        !          1806: {
        !          1807:     uint8_t  ip_ver_len;    /* version and header length */
        !          1808:     uint8_t  ip_tos;        /* type of service */
        !          1809:     uint16_t ip_len;        /* total length */
        !          1810:     uint16_t ip_id;         /* identification */
        !          1811:     uint16_t ip_off;        /* fragment offset field */
        !          1812:     uint8_t  ip_ttl;        /* time to live */
        !          1813:     uint8_t  ip_p;          /* protocol */
        !          1814:     uint16_t ip_sum;        /* checksum */
        !          1815:     uint32_t ip_src,ip_dst; /* source and dest address */
        !          1816: } ip_header;
        !          1817: 
        !          1818: #define IP_HEADER_VERSION_4 4
        !          1819: #define IP_HEADER_VERSION(ip) ((ip->ip_ver_len >> 4)&0xf)
        !          1820: #define IP_HEADER_LENGTH(ip) (((ip->ip_ver_len)&0xf) << 2)
        !          1821: 
        !          1822: typedef struct tcp_header
        !          1823: {
        !          1824:     uint16_t th_sport;         /* source port */
        !          1825:     uint16_t th_dport;         /* destination port */
        !          1826:     uint32_t th_seq;                   /* sequence number */
        !          1827:     uint32_t th_ack;                   /* acknowledgement number */
        !          1828:     uint16_t th_offset_flags; /* data offset, reserved 6 bits, TCP protocol flags */
        !          1829:     uint16_t th_win;                   /* window */
        !          1830:     uint16_t th_sum;                   /* checksum */
        !          1831:     uint16_t th_urp;                   /* urgent pointer */
        !          1832: } tcp_header;
        !          1833: 
        !          1834: typedef struct udp_header
        !          1835: {
        !          1836:     uint16_t uh_sport; /* source port */
        !          1837:     uint16_t uh_dport; /* destination port */
        !          1838:     uint16_t uh_ulen;  /* udp length */
        !          1839:     uint16_t uh_sum;   /* udp checksum */
        !          1840: } udp_header;
        !          1841: 
        !          1842: typedef struct ip_pseudo_header
        !          1843: {
        !          1844:     uint32_t ip_src;
        !          1845:     uint32_t ip_dst;
        !          1846:     uint8_t  zeros;
        !          1847:     uint8_t  ip_proto;
        !          1848:     uint16_t ip_payload;
        !          1849: } ip_pseudo_header;
        !          1850: 
        !          1851: #define IP_PROTO_TCP 6
        !          1852: #define IP_PROTO_UDP 17
        !          1853: 
        !          1854: #define TCP_HEADER_DATA_OFFSET(tcp) (((be16_to_cpu(tcp->th_offset_flags) >> 12)&0xf) << 2)
        !          1855: #define TCP_FLAGS_ONLY(flags) ((flags)&0x3f)
        !          1856: #define TCP_HEADER_FLAGS(tcp) TCP_FLAGS_ONLY(be16_to_cpu(tcp->th_offset_flags))
        !          1857: 
        !          1858: #define TCP_HEADER_CLEAR_FLAGS(tcp, off) ((tcp)->th_offset_flags &= cpu_to_be16(~TCP_FLAGS_ONLY(off)))
        !          1859: 
        !          1860: #define TCP_FLAG_FIN  0x01
        !          1861: #define TCP_FLAG_PUSH 0x08
        !          1862: 
        !          1863: /* produces ones' complement sum of data */
        !          1864: static uint16_t ones_complement_sum(uint8_t *data, size_t len)
        !          1865: {
        !          1866:     uint32_t result = 0;
        !          1867: 
        !          1868:     for (; len > 1; data+=2, len-=2)
        !          1869:     {
        !          1870:         result += *(uint16_t*)data;
        !          1871:     }
        !          1872: 
        !          1873:     /* add the remainder byte */
        !          1874:     if (len)
        !          1875:     {
        !          1876:         uint8_t odd[2] = {*data, 0};
        !          1877:         result += *(uint16_t*)odd;
        !          1878:     }
        !          1879: 
        !          1880:     while (result>>16)
        !          1881:         result = (result & 0xffff) + (result >> 16);
        !          1882: 
        !          1883:     return result;
        !          1884: }
        !          1885: 
        !          1886: static uint16_t ip_checksum(void *data, size_t len)
        !          1887: {
        !          1888:     return ~ones_complement_sum((uint8_t*)data, len);
        !          1889: }
        !          1890: 
1.1       root     1891: static int rtl8139_cplus_transmit_one(RTL8139State *s)
                   1892: {
                   1893:     if (!rtl8139_transmitter_enabled(s))
                   1894:     {
1.1.1.2 ! root     1895:         DEBUG_PRINT(("RTL8139: +++ C+ mode: transmitter disabled\n"));
1.1       root     1896:         return 0;
                   1897:     }
                   1898: 
                   1899:     if (!rtl8139_cp_transmitter_enabled(s))
                   1900:     {
1.1.1.2 ! root     1901:         DEBUG_PRINT(("RTL8139: +++ C+ mode: C+ transmitter disabled\n"));
1.1       root     1902:         return 0 ;
                   1903:     }
                   1904: 
                   1905:     int descriptor = s->currCPlusTxDesc;
                   1906: 
                   1907:     target_phys_addr_t cplus_tx_ring_desc =
                   1908:         rtl8139_addr64(s->TxAddr[0], s->TxAddr[1]);
                   1909: 
                   1910:     /* Normal priority ring */
                   1911:     cplus_tx_ring_desc += 16 * descriptor;
                   1912: 
1.1.1.2 ! root     1913:     DEBUG_PRINT(("RTL8139: +++ C+ mode reading TX descriptor %d from host memory at %08x0x%08x = 0x%8lx\n",
        !          1914:            descriptor, s->TxAddr[1], s->TxAddr[0], cplus_tx_ring_desc));
1.1       root     1915: 
                   1916:     uint32_t val, txdw0,txdw1,txbufLO,txbufHI;
                   1917: 
                   1918:     cpu_physical_memory_read(cplus_tx_ring_desc,    (uint8_t *)&val, 4);
                   1919:     txdw0 = le32_to_cpu(val);
                   1920:     cpu_physical_memory_read(cplus_tx_ring_desc+4,  (uint8_t *)&val, 4);
                   1921:     txdw1 = le32_to_cpu(val);
                   1922:     cpu_physical_memory_read(cplus_tx_ring_desc+8,  (uint8_t *)&val, 4);
                   1923:     txbufLO = le32_to_cpu(val);
                   1924:     cpu_physical_memory_read(cplus_tx_ring_desc+12, (uint8_t *)&val, 4);
                   1925:     txbufHI = le32_to_cpu(val);
                   1926: 
1.1.1.2 ! root     1927:     DEBUG_PRINT(("RTL8139: +++ C+ mode TX descriptor %d %08x %08x %08x %08x\n",
1.1       root     1928:            descriptor,
1.1.1.2 ! root     1929:            txdw0, txdw1, txbufLO, txbufHI));
1.1       root     1930: 
                   1931: /* w0 ownership flag */
                   1932: #define CP_TX_OWN (1<<31)
                   1933: /* w0 end of ring flag */
                   1934: #define CP_TX_EOR (1<<30)
                   1935: /* first segment of received packet flag */
                   1936: #define CP_TX_FS (1<<29)
                   1937: /* last segment of received packet flag */
                   1938: #define CP_TX_LS (1<<28)
                   1939: /* large send packet flag */
                   1940: #define CP_TX_LGSEN (1<<27)
1.1.1.2 ! root     1941: /* large send MSS mask, bits 16...25 */
        !          1942: #define CP_TC_LGSEN_MSS_MASK ((1 << 12) - 1)
        !          1943: 
1.1       root     1944: /* IP checksum offload flag */
                   1945: #define CP_TX_IPCS (1<<18)
                   1946: /* UDP checksum offload flag */
                   1947: #define CP_TX_UDPCS (1<<17)
                   1948: /* TCP checksum offload flag */
                   1949: #define CP_TX_TCPCS (1<<16)
                   1950: 
                   1951: /* w0 bits 0...15 : buffer size */
                   1952: #define CP_TX_BUFFER_SIZE (1<<16)
                   1953: #define CP_TX_BUFFER_SIZE_MASK (CP_TX_BUFFER_SIZE - 1)
                   1954: /* w1 tag available flag */
                   1955: #define CP_RX_TAGC (1<<17)
                   1956: /* w1 bits 0...15 : VLAN tag */
                   1957: #define CP_TX_VLAN_TAG_MASK ((1<<16) - 1)
                   1958: /* w2 low  32bit of Rx buffer ptr */
                   1959: /* w3 high 32bit of Rx buffer ptr */
                   1960: 
                   1961: /* set after transmission */
                   1962: /* FIFO underrun flag */
                   1963: #define CP_TX_STATUS_UNF (1<<25)
                   1964: /* transmit error summary flag, valid if set any of three below */
                   1965: #define CP_TX_STATUS_TES (1<<23)
                   1966: /* out-of-window collision flag */
                   1967: #define CP_TX_STATUS_OWC (1<<22)
                   1968: /* link failure flag */
                   1969: #define CP_TX_STATUS_LNKF (1<<21)
                   1970: /* excessive collisions flag */
                   1971: #define CP_TX_STATUS_EXC (1<<20)
                   1972: 
                   1973:     if (!(txdw0 & CP_TX_OWN))
                   1974:     {
1.1.1.2 ! root     1975:         DEBUG_PRINT(("RTL8139: C+ Tx mode : descriptor %d is owned by host\n", descriptor));
1.1       root     1976:         return 0 ;
                   1977:     }
                   1978: 
1.1.1.2 ! root     1979:     DEBUG_PRINT(("RTL8139: +++ C+ Tx mode : transmitting from descriptor %d\n", descriptor));
        !          1980: 
        !          1981:     if (txdw0 & CP_TX_FS)
        !          1982:     {
        !          1983:         DEBUG_PRINT(("RTL8139: +++ C+ Tx mode : descriptor %d is first segment descriptor\n", descriptor));
        !          1984: 
        !          1985:         /* reset internal buffer offset */
        !          1986:         s->cplus_txbuffer_offset = 0;
        !          1987:     }
1.1       root     1988: 
                   1989:     int txsize = txdw0 & CP_TX_BUFFER_SIZE_MASK;
                   1990:     target_phys_addr_t tx_addr = rtl8139_addr64(txbufLO, txbufHI);
                   1991: 
1.1.1.2 ! root     1992:     /* make sure we have enough space to assemble the packet */
        !          1993:     if (!s->cplus_txbuffer)
        !          1994:     {
        !          1995:         s->cplus_txbuffer_len = CP_TX_BUFFER_SIZE;
        !          1996:         s->cplus_txbuffer = malloc(s->cplus_txbuffer_len);
        !          1997:         s->cplus_txbuffer_offset = 0;
1.1       root     1998: 
1.1.1.2 ! root     1999:         DEBUG_PRINT(("RTL8139: +++ C+ mode transmission buffer allocated space %d\n", s->cplus_txbuffer_len));
        !          2000:     }
        !          2001: 
        !          2002:     while (s->cplus_txbuffer && s->cplus_txbuffer_offset + txsize >= s->cplus_txbuffer_len)
        !          2003:     {
        !          2004:         s->cplus_txbuffer_len += CP_TX_BUFFER_SIZE;
        !          2005:         s->cplus_txbuffer = realloc(s->cplus_txbuffer, s->cplus_txbuffer_len);
        !          2006: 
        !          2007:         DEBUG_PRINT(("RTL8139: +++ C+ mode transmission buffer space changed to %d\n", s->cplus_txbuffer_len));
        !          2008:     }
        !          2009: 
        !          2010:     if (!s->cplus_txbuffer)
        !          2011:     {
        !          2012:         /* out of memory */
        !          2013: 
        !          2014:         DEBUG_PRINT(("RTL8139: +++ C+ mode transmiter failed to reallocate %d bytes\n", s->cplus_txbuffer_len));
        !          2015: 
        !          2016:         /* update tally counter */
        !          2017:         ++s->tally_counters.TxERR;
        !          2018:         ++s->tally_counters.TxAbt;
        !          2019: 
        !          2020:         return 0;
        !          2021:     }
1.1       root     2022: 
1.1.1.2 ! root     2023:     /* append more data to the packet */
        !          2024: 
        !          2025:     DEBUG_PRINT(("RTL8139: +++ C+ mode transmit reading %d bytes from host memory at %016" PRIx64 " to offset %d\n",
        !          2026:                  txsize, (uint64_t)tx_addr, s->cplus_txbuffer_offset));
        !          2027: 
        !          2028:     cpu_physical_memory_read(tx_addr, s->cplus_txbuffer + s->cplus_txbuffer_offset, txsize);
        !          2029:     s->cplus_txbuffer_offset += txsize;
        !          2030: 
        !          2031:     /* seek to next Rx descriptor */
        !          2032:     if (txdw0 & CP_TX_EOR)
        !          2033:     {
        !          2034:         s->currCPlusTxDesc = 0;
        !          2035:     }
        !          2036:     else
        !          2037:     {
        !          2038:         ++s->currCPlusTxDesc;
        !          2039:         if (s->currCPlusTxDesc >= 64)
        !          2040:             s->currCPlusTxDesc = 0;
        !          2041:     }
1.1       root     2042: 
                   2043:     /* transfer ownership to target */
                   2044:     txdw0 &= ~CP_RX_OWN;
                   2045: 
                   2046:     /* reset error indicator bits */
                   2047:     txdw0 &= ~CP_TX_STATUS_UNF;
                   2048:     txdw0 &= ~CP_TX_STATUS_TES;
                   2049:     txdw0 &= ~CP_TX_STATUS_OWC;
                   2050:     txdw0 &= ~CP_TX_STATUS_LNKF;
                   2051:     txdw0 &= ~CP_TX_STATUS_EXC;
                   2052: 
                   2053:     /* update ring data */
                   2054:     val = cpu_to_le32(txdw0);
                   2055:     cpu_physical_memory_write(cplus_tx_ring_desc,    (uint8_t *)&val, 4);
                   2056: //    val = cpu_to_le32(txdw1);
                   2057: //    cpu_physical_memory_write(cplus_tx_ring_desc+4,  &val, 4);
                   2058: 
1.1.1.2 ! root     2059:     /* Now decide if descriptor being processed is holding the last segment of packet */
        !          2060:     if (txdw0 & CP_TX_LS)
1.1       root     2061:     {
1.1.1.2 ! root     2062:         DEBUG_PRINT(("RTL8139: +++ C+ Tx mode : descriptor %d is last segment descriptor\n", descriptor));
        !          2063: 
        !          2064:         /* can transfer fully assembled packet */
        !          2065: 
        !          2066:         uint8_t *saved_buffer  = s->cplus_txbuffer;
        !          2067:         int      saved_size    = s->cplus_txbuffer_offset;
        !          2068:         int      saved_buffer_len = s->cplus_txbuffer_len;
        !          2069: 
        !          2070:         /* reset the card space to protect from recursive call */
        !          2071:         s->cplus_txbuffer = NULL;
        !          2072:         s->cplus_txbuffer_offset = 0;
        !          2073:         s->cplus_txbuffer_len = 0;
        !          2074: 
        !          2075:         if (txdw0 & (CP_TX_IPCS | CP_TX_UDPCS | CP_TX_TCPCS | CP_TX_LGSEN))
        !          2076:         {
        !          2077:             DEBUG_PRINT(("RTL8139: +++ C+ mode offloaded task checksum\n"));
        !          2078: 
        !          2079:             #define ETH_P_IP   0x0800          /* Internet Protocol packet     */
        !          2080:             #define ETH_HLEN    14
        !          2081:             #define ETH_MTU     1500
        !          2082: 
        !          2083:             /* ip packet header */
        !          2084:             ip_header *ip = 0;
        !          2085:             int hlen = 0;
        !          2086:             uint8_t  ip_protocol = 0;
        !          2087:             uint16_t ip_data_len = 0;
        !          2088: 
        !          2089:             uint8_t *eth_payload_data = 0;
        !          2090:             size_t   eth_payload_len  = 0;
        !          2091: 
        !          2092:             int proto = be16_to_cpu(*(uint16_t *)(saved_buffer + 12));
        !          2093:             if (proto == ETH_P_IP)
        !          2094:             {
        !          2095:                 DEBUG_PRINT(("RTL8139: +++ C+ mode has IP packet\n"));
        !          2096: 
        !          2097:                 /* not aligned */
        !          2098:                 eth_payload_data = saved_buffer + ETH_HLEN;
        !          2099:                 eth_payload_len  = saved_size   - ETH_HLEN;
        !          2100: 
        !          2101:                 ip = (ip_header*)eth_payload_data;
        !          2102: 
        !          2103:                 if (IP_HEADER_VERSION(ip) != IP_HEADER_VERSION_4) {
        !          2104:                     DEBUG_PRINT(("RTL8139: +++ C+ mode packet has bad IP version %d expected %d\n", IP_HEADER_VERSION(ip), IP_HEADER_VERSION_4));
        !          2105:                     ip = NULL;
        !          2106:                 } else {
        !          2107:                     hlen = IP_HEADER_LENGTH(ip);
        !          2108:                     ip_protocol = ip->ip_p;
        !          2109:                     ip_data_len = be16_to_cpu(ip->ip_len) - hlen;
        !          2110:                 }
        !          2111:             }
        !          2112: 
        !          2113:             if (ip)
        !          2114:             {
        !          2115:                 if (txdw0 & CP_TX_IPCS)
        !          2116:                 {
        !          2117:                     DEBUG_PRINT(("RTL8139: +++ C+ mode need IP checksum\n"));
        !          2118: 
        !          2119:                     if (hlen<sizeof(ip_header) || hlen>eth_payload_len) {/* min header length */
        !          2120:                         /* bad packet header len */
        !          2121:                         /* or packet too short */
        !          2122:                     }
        !          2123:                     else
        !          2124:                     {
        !          2125:                         ip->ip_sum = 0;
        !          2126:                         ip->ip_sum = ip_checksum(ip, hlen);
        !          2127:                         DEBUG_PRINT(("RTL8139: +++ C+ mode IP header len=%d checksum=%04x\n", hlen, ip->ip_sum));
        !          2128:                     }
        !          2129:                 }
        !          2130: 
        !          2131:                 if ((txdw0 & CP_TX_LGSEN) && ip_protocol == IP_PROTO_TCP)
        !          2132:                 {
        !          2133: #if defined (DEBUG_RTL8139)
        !          2134:                     int large_send_mss = (txdw0 >> 16) & CP_TC_LGSEN_MSS_MASK;
        !          2135: #endif
        !          2136:                     DEBUG_PRINT(("RTL8139: +++ C+ mode offloaded task TSO MTU=%d IP data %d frame data %d specified MSS=%d\n",
        !          2137:                                  ETH_MTU, ip_data_len, saved_size - ETH_HLEN, large_send_mss));
        !          2138: 
        !          2139:                     int tcp_send_offset = 0;
        !          2140:                     int send_count = 0;
        !          2141: 
        !          2142:                     /* maximum IP header length is 60 bytes */
        !          2143:                     uint8_t saved_ip_header[60];
        !          2144: 
        !          2145:                     /* save IP header template; data area is used in tcp checksum calculation */
        !          2146:                     memcpy(saved_ip_header, eth_payload_data, hlen);
        !          2147: 
        !          2148:                     /* a placeholder for checksum calculation routine in tcp case */
        !          2149:                     uint8_t *data_to_checksum     = eth_payload_data + hlen - 12;
        !          2150:                     //                    size_t   data_to_checksum_len = eth_payload_len  - hlen + 12;
        !          2151: 
        !          2152:                     /* pointer to TCP header */
        !          2153:                     tcp_header *p_tcp_hdr = (tcp_header*)(eth_payload_data + hlen);
        !          2154: 
        !          2155:                     int tcp_hlen = TCP_HEADER_DATA_OFFSET(p_tcp_hdr);
        !          2156: 
        !          2157:                     /* ETH_MTU = ip header len + tcp header len + payload */
        !          2158:                     int tcp_data_len = ip_data_len - tcp_hlen;
        !          2159:                     int tcp_chunk_size = ETH_MTU - hlen - tcp_hlen;
        !          2160: 
        !          2161:                     DEBUG_PRINT(("RTL8139: +++ C+ mode TSO IP data len %d TCP hlen %d TCP data len %d TCP chunk size %d\n",
        !          2162:                                  ip_data_len, tcp_hlen, tcp_data_len, tcp_chunk_size));
        !          2163: 
        !          2164:                     /* note the cycle below overwrites IP header data,
        !          2165:                        but restores it from saved_ip_header before sending packet */
        !          2166: 
        !          2167:                     int is_last_frame = 0;
        !          2168: 
        !          2169:                     for (tcp_send_offset = 0; tcp_send_offset < tcp_data_len; tcp_send_offset += tcp_chunk_size)
        !          2170:                     {
        !          2171:                         uint16_t chunk_size = tcp_chunk_size;
        !          2172: 
        !          2173:                         /* check if this is the last frame */
        !          2174:                         if (tcp_send_offset + tcp_chunk_size >= tcp_data_len)
        !          2175:                         {
        !          2176:                             is_last_frame = 1;
        !          2177:                             chunk_size = tcp_data_len - tcp_send_offset;
        !          2178:                         }
        !          2179: 
        !          2180:                         DEBUG_PRINT(("RTL8139: +++ C+ mode TSO TCP seqno %08x\n", be32_to_cpu(p_tcp_hdr->th_seq)));
        !          2181: 
        !          2182:                         /* add 4 TCP pseudoheader fields */
        !          2183:                         /* copy IP source and destination fields */
        !          2184:                         memcpy(data_to_checksum, saved_ip_header + 12, 8);
        !          2185: 
        !          2186:                         DEBUG_PRINT(("RTL8139: +++ C+ mode TSO calculating TCP checksum for packet with %d bytes data\n", tcp_hlen + chunk_size));
        !          2187: 
        !          2188:                         if (tcp_send_offset)
        !          2189:                         {
        !          2190:                             memcpy((uint8_t*)p_tcp_hdr + tcp_hlen, (uint8_t*)p_tcp_hdr + tcp_hlen + tcp_send_offset, chunk_size);
        !          2191:                         }
        !          2192: 
        !          2193:                         /* keep PUSH and FIN flags only for the last frame */
        !          2194:                         if (!is_last_frame)
        !          2195:                         {
        !          2196:                             TCP_HEADER_CLEAR_FLAGS(p_tcp_hdr, TCP_FLAG_PUSH|TCP_FLAG_FIN);
        !          2197:                         }
        !          2198: 
        !          2199:                         /* recalculate TCP checksum */
        !          2200:                         ip_pseudo_header *p_tcpip_hdr = (ip_pseudo_header *)data_to_checksum;
        !          2201:                         p_tcpip_hdr->zeros      = 0;
        !          2202:                         p_tcpip_hdr->ip_proto   = IP_PROTO_TCP;
        !          2203:                         p_tcpip_hdr->ip_payload = cpu_to_be16(tcp_hlen + chunk_size);
        !          2204: 
        !          2205:                         p_tcp_hdr->th_sum = 0;
        !          2206: 
        !          2207:                         int tcp_checksum = ip_checksum(data_to_checksum, tcp_hlen + chunk_size + 12);
        !          2208:                         DEBUG_PRINT(("RTL8139: +++ C+ mode TSO TCP checksum %04x\n", tcp_checksum));
        !          2209: 
        !          2210:                         p_tcp_hdr->th_sum = tcp_checksum;
        !          2211: 
        !          2212:                         /* restore IP header */
        !          2213:                         memcpy(eth_payload_data, saved_ip_header, hlen);
        !          2214: 
        !          2215:                         /* set IP data length and recalculate IP checksum */
        !          2216:                         ip->ip_len = cpu_to_be16(hlen + tcp_hlen + chunk_size);
        !          2217: 
        !          2218:                         /* increment IP id for subsequent frames */
        !          2219:                         ip->ip_id = cpu_to_be16(tcp_send_offset/tcp_chunk_size + be16_to_cpu(ip->ip_id));
        !          2220: 
        !          2221:                         ip->ip_sum = 0;
        !          2222:                         ip->ip_sum = ip_checksum(eth_payload_data, hlen);
        !          2223:                         DEBUG_PRINT(("RTL8139: +++ C+ mode TSO IP header len=%d checksum=%04x\n", hlen, ip->ip_sum));
        !          2224: 
        !          2225:                         int tso_send_size = ETH_HLEN + hlen + tcp_hlen + chunk_size;
        !          2226:                         DEBUG_PRINT(("RTL8139: +++ C+ mode TSO transferring packet size %d\n", tso_send_size));
        !          2227:                         rtl8139_transfer_frame(s, saved_buffer, tso_send_size, 0);
        !          2228: 
        !          2229:                         /* add transferred count to TCP sequence number */
        !          2230:                         p_tcp_hdr->th_seq = cpu_to_be32(chunk_size + be32_to_cpu(p_tcp_hdr->th_seq));
        !          2231:                         ++send_count;
        !          2232:                     }
        !          2233: 
        !          2234:                     /* Stop sending this frame */
        !          2235:                     saved_size = 0;
        !          2236:                 }
        !          2237:                 else if (txdw0 & (CP_TX_TCPCS|CP_TX_UDPCS))
        !          2238:                 {
        !          2239:                     DEBUG_PRINT(("RTL8139: +++ C+ mode need TCP or UDP checksum\n"));
        !          2240: 
        !          2241:                     /* maximum IP header length is 60 bytes */
        !          2242:                     uint8_t saved_ip_header[60];
        !          2243:                     memcpy(saved_ip_header, eth_payload_data, hlen);
        !          2244: 
        !          2245:                     uint8_t *data_to_checksum     = eth_payload_data + hlen - 12;
        !          2246:                     //                    size_t   data_to_checksum_len = eth_payload_len  - hlen + 12;
        !          2247: 
        !          2248:                     /* add 4 TCP pseudoheader fields */
        !          2249:                     /* copy IP source and destination fields */
        !          2250:                     memcpy(data_to_checksum, saved_ip_header + 12, 8);
        !          2251: 
        !          2252:                     if ((txdw0 & CP_TX_TCPCS) && ip_protocol == IP_PROTO_TCP)
        !          2253:                     {
        !          2254:                         DEBUG_PRINT(("RTL8139: +++ C+ mode calculating TCP checksum for packet with %d bytes data\n", ip_data_len));
        !          2255: 
        !          2256:                         ip_pseudo_header *p_tcpip_hdr = (ip_pseudo_header *)data_to_checksum;
        !          2257:                         p_tcpip_hdr->zeros      = 0;
        !          2258:                         p_tcpip_hdr->ip_proto   = IP_PROTO_TCP;
        !          2259:                         p_tcpip_hdr->ip_payload = cpu_to_be16(ip_data_len);
        !          2260: 
        !          2261:                         tcp_header* p_tcp_hdr = (tcp_header *) (data_to_checksum+12);
        !          2262: 
        !          2263:                         p_tcp_hdr->th_sum = 0;
        !          2264: 
        !          2265:                         int tcp_checksum = ip_checksum(data_to_checksum, ip_data_len + 12);
        !          2266:                         DEBUG_PRINT(("RTL8139: +++ C+ mode TCP checksum %04x\n", tcp_checksum));
        !          2267: 
        !          2268:                         p_tcp_hdr->th_sum = tcp_checksum;
        !          2269:                     }
        !          2270:                     else if ((txdw0 & CP_TX_UDPCS) && ip_protocol == IP_PROTO_UDP)
        !          2271:                     {
        !          2272:                         DEBUG_PRINT(("RTL8139: +++ C+ mode calculating UDP checksum for packet with %d bytes data\n", ip_data_len));
        !          2273: 
        !          2274:                         ip_pseudo_header *p_udpip_hdr = (ip_pseudo_header *)data_to_checksum;
        !          2275:                         p_udpip_hdr->zeros      = 0;
        !          2276:                         p_udpip_hdr->ip_proto   = IP_PROTO_UDP;
        !          2277:                         p_udpip_hdr->ip_payload = cpu_to_be16(ip_data_len);
        !          2278: 
        !          2279:                         udp_header *p_udp_hdr = (udp_header *) (data_to_checksum+12);
        !          2280: 
        !          2281:                         p_udp_hdr->uh_sum = 0;
        !          2282: 
        !          2283:                         int udp_checksum = ip_checksum(data_to_checksum, ip_data_len + 12);
        !          2284:                         DEBUG_PRINT(("RTL8139: +++ C+ mode UDP checksum %04x\n", udp_checksum));
        !          2285: 
        !          2286:                         p_udp_hdr->uh_sum = udp_checksum;
        !          2287:                     }
        !          2288: 
        !          2289:                     /* restore IP header */
        !          2290:                     memcpy(eth_payload_data, saved_ip_header, hlen);
        !          2291:                 }
        !          2292:             }
        !          2293:         }
        !          2294: 
        !          2295:         /* update tally counter */
        !          2296:         ++s->tally_counters.TxOk;
        !          2297: 
        !          2298:         DEBUG_PRINT(("RTL8139: +++ C+ mode transmitting %d bytes packet\n", saved_size));
        !          2299: 
        !          2300:         rtl8139_transfer_frame(s, saved_buffer, saved_size, 1);
        !          2301: 
        !          2302:         /* restore card space if there was no recursion and reset offset */
        !          2303:         if (!s->cplus_txbuffer)
        !          2304:         {
        !          2305:             s->cplus_txbuffer        = saved_buffer;
        !          2306:             s->cplus_txbuffer_len    = saved_buffer_len;
        !          2307:             s->cplus_txbuffer_offset = 0;
        !          2308:         }
        !          2309:         else
        !          2310:         {
        !          2311:             free(saved_buffer);
        !          2312:         }
1.1       root     2313:     }
                   2314:     else
                   2315:     {
1.1.1.2 ! root     2316:         DEBUG_PRINT(("RTL8139: +++ C+ mode transmission continue to next descriptor\n"));
1.1       root     2317:     }
                   2318: 
                   2319:     return 1;
                   2320: }
                   2321: 
                   2322: static void rtl8139_cplus_transmit(RTL8139State *s)
                   2323: {
                   2324:     int txcount = 0;
                   2325: 
                   2326:     while (rtl8139_cplus_transmit_one(s))
                   2327:     {
                   2328:         ++txcount;
                   2329:     }
                   2330: 
                   2331:     /* Mark transfer completed */
                   2332:     if (!txcount)
                   2333:     {
1.1.1.2 ! root     2334:         DEBUG_PRINT(("RTL8139: C+ mode : transmitter queue stalled, current TxDesc = %d\n",
        !          2335:                      s->currCPlusTxDesc));
1.1       root     2336:     }
                   2337:     else
                   2338:     {
                   2339:         /* update interrupt status */
                   2340:         s->IntrStatus |= TxOK;
                   2341:         rtl8139_update_irq(s);
                   2342:     }
                   2343: }
                   2344: 
                   2345: static void rtl8139_transmit(RTL8139State *s)
                   2346: {
                   2347:     int descriptor = s->currTxDesc, txcount = 0;
                   2348: 
                   2349:     /*while*/
                   2350:     if (rtl8139_transmit_one(s, descriptor))
                   2351:     {
                   2352:         ++s->currTxDesc;
                   2353:         s->currTxDesc %= 4;
                   2354:         ++txcount;
                   2355:     }
                   2356: 
                   2357:     /* Mark transfer completed */
                   2358:     if (!txcount)
                   2359:     {
1.1.1.2 ! root     2360:         DEBUG_PRINT(("RTL8139: transmitter queue stalled, current TxDesc = %d\n", s->currTxDesc));
1.1       root     2361:     }
                   2362: }
                   2363: 
                   2364: static void rtl8139_TxStatus_write(RTL8139State *s, uint32_t txRegOffset, uint32_t val)
                   2365: {
                   2366: 
                   2367:     int descriptor = txRegOffset/4;
1.1.1.2 ! root     2368: 
        !          2369:     /* handle C+ transmit mode register configuration */
        !          2370: 
        !          2371:     if (rtl8139_cp_transmitter_enabled(s))
        !          2372:     {
        !          2373:         DEBUG_PRINT(("RTL8139C+ DTCCR write offset=0x%x val=0x%08x descriptor=%d\n", txRegOffset, val, descriptor));
        !          2374: 
        !          2375:         /* handle Dump Tally Counters command */
        !          2376:         s->TxStatus[descriptor] = val;
        !          2377: 
        !          2378:         if (descriptor == 0 && (val & 0x8))
        !          2379:         {
        !          2380:             target_phys_addr_t tc_addr = rtl8139_addr64(s->TxStatus[0] & ~0x3f, s->TxStatus[1]);
        !          2381: 
        !          2382:             /* dump tally counters to specified memory location */
        !          2383:             RTL8139TallyCounters_physical_memory_write( tc_addr, &s->tally_counters);
        !          2384: 
        !          2385:             /* mark dump completed */
        !          2386:             s->TxStatus[0] &= ~0x8;
        !          2387:         }
        !          2388: 
        !          2389:         return;
        !          2390:     }
        !          2391: 
        !          2392:     DEBUG_PRINT(("RTL8139: TxStatus write offset=0x%x val=0x%08x descriptor=%d\n", txRegOffset, val, descriptor));
1.1       root     2393: 
                   2394:     /* mask only reserved bits */
                   2395:     val &= ~0xff00c000; /* these bits are reset on write */
                   2396:     val = SET_MASKED(val, 0x00c00000, s->TxStatus[descriptor]);
                   2397: 
                   2398:     s->TxStatus[descriptor] = val;
                   2399: 
                   2400:     /* attempt to start transmission */
                   2401:     rtl8139_transmit(s);
                   2402: }
                   2403: 
                   2404: static uint32_t rtl8139_TxStatus_read(RTL8139State *s, uint32_t txRegOffset)
                   2405: {
                   2406:     uint32_t ret = s->TxStatus[txRegOffset/4];
                   2407: 
1.1.1.2 ! root     2408:     DEBUG_PRINT(("RTL8139: TxStatus read offset=0x%x val=0x%08x\n", txRegOffset, ret));
1.1       root     2409: 
                   2410:     return ret;
                   2411: }
                   2412: 
                   2413: static uint16_t rtl8139_TSAD_read(RTL8139State *s)
                   2414: {
                   2415:     uint16_t ret = 0;
                   2416: 
                   2417:     /* Simulate TSAD, it is read only anyway */
                   2418: 
                   2419:     ret = ((s->TxStatus[3] & TxStatOK  )?TSAD_TOK3:0)
                   2420:          |((s->TxStatus[2] & TxStatOK  )?TSAD_TOK2:0)
                   2421:          |((s->TxStatus[1] & TxStatOK  )?TSAD_TOK1:0)
                   2422:          |((s->TxStatus[0] & TxStatOK  )?TSAD_TOK0:0)
                   2423: 
                   2424:          |((s->TxStatus[3] & TxUnderrun)?TSAD_TUN3:0)
                   2425:          |((s->TxStatus[2] & TxUnderrun)?TSAD_TUN2:0)
                   2426:          |((s->TxStatus[1] & TxUnderrun)?TSAD_TUN1:0)
                   2427:          |((s->TxStatus[0] & TxUnderrun)?TSAD_TUN0:0)
                   2428:          
                   2429:          |((s->TxStatus[3] & TxAborted )?TSAD_TABT3:0)
                   2430:          |((s->TxStatus[2] & TxAborted )?TSAD_TABT2:0)
                   2431:          |((s->TxStatus[1] & TxAborted )?TSAD_TABT1:0)
                   2432:          |((s->TxStatus[0] & TxAborted )?TSAD_TABT0:0)
                   2433:          
                   2434:          |((s->TxStatus[3] & TxHostOwns )?TSAD_OWN3:0)
                   2435:          |((s->TxStatus[2] & TxHostOwns )?TSAD_OWN2:0)
                   2436:          |((s->TxStatus[1] & TxHostOwns )?TSAD_OWN1:0)
                   2437:          |((s->TxStatus[0] & TxHostOwns )?TSAD_OWN0:0) ;
                   2438:        
                   2439: 
1.1.1.2 ! root     2440:     DEBUG_PRINT(("RTL8139: TSAD read val=0x%04x\n", ret));
1.1       root     2441: 
                   2442:     return ret;
                   2443: }
                   2444: 
                   2445: static uint16_t rtl8139_CSCR_read(RTL8139State *s)
                   2446: {
                   2447:     uint16_t ret = s->CSCR;
                   2448: 
1.1.1.2 ! root     2449:     DEBUG_PRINT(("RTL8139: CSCR read val=0x%04x\n", ret));
1.1       root     2450: 
                   2451:     return ret;
                   2452: }
                   2453: 
                   2454: static void rtl8139_TxAddr_write(RTL8139State *s, uint32_t txAddrOffset, uint32_t val)
                   2455: {
1.1.1.2 ! root     2456:     DEBUG_PRINT(("RTL8139: TxAddr write offset=0x%x val=0x%08x\n", txAddrOffset, val));
1.1       root     2457: 
                   2458:     s->TxAddr[txAddrOffset/4] = le32_to_cpu(val);
                   2459: }
                   2460: 
                   2461: static uint32_t rtl8139_TxAddr_read(RTL8139State *s, uint32_t txAddrOffset)
                   2462: {
                   2463:     uint32_t ret = cpu_to_le32(s->TxAddr[txAddrOffset/4]);
                   2464: 
1.1.1.2 ! root     2465:     DEBUG_PRINT(("RTL8139: TxAddr read offset=0x%x val=0x%08x\n", txAddrOffset, ret));
1.1       root     2466: 
                   2467:     return ret;
                   2468: }
                   2469: 
                   2470: static void rtl8139_RxBufPtr_write(RTL8139State *s, uint32_t val)
                   2471: {
1.1.1.2 ! root     2472:     DEBUG_PRINT(("RTL8139: RxBufPtr write val=0x%04x\n", val));
1.1       root     2473: 
                   2474:     /* this value is off by 16 */
                   2475:     s->RxBufPtr = MOD2(val + 0x10, s->RxBufferSize);
                   2476: 
1.1.1.2 ! root     2477:     DEBUG_PRINT((" CAPR write: rx buffer length %d head 0x%04x read 0x%04x\n",
        !          2478:            s->RxBufferSize, s->RxBufAddr, s->RxBufPtr));
1.1       root     2479: }
                   2480: 
                   2481: static uint32_t rtl8139_RxBufPtr_read(RTL8139State *s)
                   2482: {
                   2483:     /* this value is off by 16 */
                   2484:     uint32_t ret = s->RxBufPtr - 0x10;
                   2485: 
1.1.1.2 ! root     2486:     DEBUG_PRINT(("RTL8139: RxBufPtr read val=0x%04x\n", ret));
        !          2487: 
        !          2488:     return ret;
        !          2489: }
        !          2490: 
        !          2491: static uint32_t rtl8139_RxBufAddr_read(RTL8139State *s)
        !          2492: {
        !          2493:     /* this value is NOT off by 16 */
        !          2494:     uint32_t ret = s->RxBufAddr;
        !          2495: 
        !          2496:     DEBUG_PRINT(("RTL8139: RxBufAddr read val=0x%04x\n", ret));
1.1       root     2497: 
                   2498:     return ret;
                   2499: }
                   2500: 
                   2501: static void rtl8139_RxBuf_write(RTL8139State *s, uint32_t val)
                   2502: {
1.1.1.2 ! root     2503:     DEBUG_PRINT(("RTL8139: RxBuf write val=0x%08x\n", val));
1.1       root     2504: 
                   2505:     s->RxBuf = val;
                   2506: 
                   2507:     /* may need to reset rxring here */
                   2508: }
                   2509: 
                   2510: static uint32_t rtl8139_RxBuf_read(RTL8139State *s)
                   2511: {
                   2512:     uint32_t ret = s->RxBuf;
                   2513: 
1.1.1.2 ! root     2514:     DEBUG_PRINT(("RTL8139: RxBuf read val=0x%08x\n", ret));
1.1       root     2515: 
                   2516:     return ret;
                   2517: }
                   2518: 
                   2519: static void rtl8139_IntrMask_write(RTL8139State *s, uint32_t val)
                   2520: {
1.1.1.2 ! root     2521:     DEBUG_PRINT(("RTL8139: IntrMask write(w) val=0x%04x\n", val));
1.1       root     2522: 
                   2523:     /* mask unwriteable bits */
                   2524:     val = SET_MASKED(val, 0x1e00, s->IntrMask);
                   2525: 
                   2526:     s->IntrMask = val;
                   2527: 
                   2528:     rtl8139_update_irq(s);
                   2529: }
                   2530: 
                   2531: static uint32_t rtl8139_IntrMask_read(RTL8139State *s)
                   2532: {
                   2533:     uint32_t ret = s->IntrMask;
                   2534: 
1.1.1.2 ! root     2535:     DEBUG_PRINT(("RTL8139: IntrMask read(w) val=0x%04x\n", ret));
1.1       root     2536: 
                   2537:     return ret;
                   2538: }
                   2539: 
                   2540: static void rtl8139_IntrStatus_write(RTL8139State *s, uint32_t val)
                   2541: {
1.1.1.2 ! root     2542:     DEBUG_PRINT(("RTL8139: IntrStatus write(w) val=0x%04x\n", val));
1.1       root     2543: 
                   2544: #if 0
                   2545: 
                   2546:     /* writing to ISR has no effect */
                   2547: 
                   2548:     return;
                   2549: 
                   2550: #else
                   2551:     uint16_t newStatus = s->IntrStatus & ~val;
                   2552: 
                   2553:     /* mask unwriteable bits */
                   2554:     newStatus = SET_MASKED(newStatus, 0x1e00, s->IntrStatus);
                   2555: 
                   2556:     /* writing 1 to interrupt status register bit clears it */
                   2557:     s->IntrStatus = 0;
                   2558:     rtl8139_update_irq(s);
                   2559: 
                   2560:     s->IntrStatus = newStatus;
                   2561:     rtl8139_update_irq(s);
                   2562: #endif
                   2563: }
                   2564: 
                   2565: static uint32_t rtl8139_IntrStatus_read(RTL8139State *s)
                   2566: {
                   2567:     uint32_t ret = s->IntrStatus;
                   2568: 
1.1.1.2 ! root     2569:     DEBUG_PRINT(("RTL8139: IntrStatus read(w) val=0x%04x\n", ret));
1.1       root     2570: 
                   2571: #if 0
                   2572: 
                   2573:     /* reading ISR clears all interrupts */
                   2574:     s->IntrStatus = 0;
                   2575: 
                   2576:     rtl8139_update_irq(s);
                   2577: 
                   2578: #endif
                   2579: 
                   2580:     return ret;
                   2581: }
                   2582: 
                   2583: static void rtl8139_MultiIntr_write(RTL8139State *s, uint32_t val)
                   2584: {
1.1.1.2 ! root     2585:     DEBUG_PRINT(("RTL8139: MultiIntr write(w) val=0x%04x\n", val));
1.1       root     2586: 
                   2587:     /* mask unwriteable bits */
                   2588:     val = SET_MASKED(val, 0xf000, s->MultiIntr);
                   2589: 
                   2590:     s->MultiIntr = val;
                   2591: }
                   2592: 
                   2593: static uint32_t rtl8139_MultiIntr_read(RTL8139State *s)
                   2594: {
                   2595:     uint32_t ret = s->MultiIntr;
                   2596: 
1.1.1.2 ! root     2597:     DEBUG_PRINT(("RTL8139: MultiIntr read(w) val=0x%04x\n", ret));
1.1       root     2598: 
                   2599:     return ret;
                   2600: }
                   2601: 
                   2602: static void rtl8139_io_writeb(void *opaque, uint8_t addr, uint32_t val)
                   2603: {
                   2604:     RTL8139State *s = opaque;
                   2605: 
                   2606:     addr &= 0xff;
                   2607: 
                   2608:     switch (addr)
                   2609:     {
                   2610:         case MAC0 ... MAC0+5:
                   2611:             s->phys[addr - MAC0] = val;
                   2612:             break;
                   2613:         case MAC0+6 ... MAC0+7:
                   2614:             /* reserved */
                   2615:             break;
                   2616:         case MAR0 ... MAR0+7:
                   2617:             s->mult[addr - MAR0] = val;
                   2618:             break;
                   2619:         case ChipCmd:
                   2620:             rtl8139_ChipCmd_write(s, val);
                   2621:             break;
                   2622:         case Cfg9346:
                   2623:             rtl8139_Cfg9346_write(s, val);
                   2624:             break;
                   2625:         case TxConfig: /* windows driver sometimes writes using byte-lenth call */
                   2626:             rtl8139_TxConfig_writeb(s, val);
                   2627:             break;
                   2628:         case Config0:
                   2629:             rtl8139_Config0_write(s, val);
                   2630:             break;
                   2631:         case Config1:
                   2632:             rtl8139_Config1_write(s, val);
                   2633:             break;
                   2634:         case Config3:
                   2635:             rtl8139_Config3_write(s, val);
                   2636:             break;
                   2637:         case Config4:
                   2638:             rtl8139_Config4_write(s, val);
                   2639:             break;
                   2640:         case Config5:
                   2641:             rtl8139_Config5_write(s, val);
                   2642:             break;
                   2643:         case MediaStatus:
                   2644:             /* ignore */
1.1.1.2 ! root     2645:             DEBUG_PRINT(("RTL8139: not implemented write(b) to MediaStatus val=0x%02x\n", val));
1.1       root     2646:             break;
                   2647: 
                   2648:         case HltClk:
1.1.1.2 ! root     2649:             DEBUG_PRINT(("RTL8139: HltClk write val=0x%08x\n", val));
1.1       root     2650:             if (val == 'R')
                   2651:             {
                   2652:                 s->clock_enabled = 1;
                   2653:             }
                   2654:             else if (val == 'H')
                   2655:             {
                   2656:                 s->clock_enabled = 0;
                   2657:             }
                   2658:             break;
                   2659: 
                   2660:         case TxThresh:
1.1.1.2 ! root     2661:             DEBUG_PRINT(("RTL8139C+ TxThresh write(b) val=0x%02x\n", val));
1.1       root     2662:             s->TxThresh = val;
                   2663:             break;
                   2664: 
                   2665:         case TxPoll:
1.1.1.2 ! root     2666:             DEBUG_PRINT(("RTL8139C+ TxPoll write(b) val=0x%02x\n", val));
1.1       root     2667:             if (val & (1 << 7))
                   2668:             {
1.1.1.2 ! root     2669:                 DEBUG_PRINT(("RTL8139C+ TxPoll high priority transmission (not implemented)\n"));
1.1       root     2670:                 //rtl8139_cplus_transmit(s);
                   2671:             }
                   2672:             if (val & (1 << 6))
                   2673:             {
1.1.1.2 ! root     2674:                 DEBUG_PRINT(("RTL8139C+ TxPoll normal priority transmission\n"));
1.1       root     2675:                 rtl8139_cplus_transmit(s);
                   2676:             }
                   2677: 
                   2678:             break;
                   2679: 
                   2680:         default:
1.1.1.2 ! root     2681:             DEBUG_PRINT(("RTL8139: not implemented write(b) addr=0x%x val=0x%02x\n", addr, val));
1.1       root     2682:             break;
                   2683:     }
                   2684: }
                   2685: 
                   2686: static void rtl8139_io_writew(void *opaque, uint8_t addr, uint32_t val)
                   2687: {
                   2688:     RTL8139State *s = opaque;
                   2689: 
                   2690:     addr &= 0xfe;
                   2691: 
                   2692:     switch (addr)
                   2693:     {
                   2694:         case IntrMask:
                   2695:             rtl8139_IntrMask_write(s, val);
                   2696:             break;
                   2697: 
                   2698:         case IntrStatus:
                   2699:             rtl8139_IntrStatus_write(s, val);
                   2700:             break;
                   2701: 
                   2702:         case MultiIntr:
                   2703:             rtl8139_MultiIntr_write(s, val);
                   2704:             break;
                   2705: 
                   2706:         case RxBufPtr:
                   2707:             rtl8139_RxBufPtr_write(s, val);
                   2708:             break;
                   2709: 
                   2710:         case BasicModeCtrl:
                   2711:             rtl8139_BasicModeCtrl_write(s, val);
                   2712:             break;
                   2713:         case BasicModeStatus:
                   2714:             rtl8139_BasicModeStatus_write(s, val);
                   2715:             break;
                   2716:         case NWayAdvert:
1.1.1.2 ! root     2717:             DEBUG_PRINT(("RTL8139: NWayAdvert write(w) val=0x%04x\n", val));
1.1       root     2718:             s->NWayAdvert = val;
                   2719:             break;
                   2720:         case NWayLPAR:
1.1.1.2 ! root     2721:             DEBUG_PRINT(("RTL8139: forbidden NWayLPAR write(w) val=0x%04x\n", val));
1.1       root     2722:             break;
                   2723:         case NWayExpansion:
1.1.1.2 ! root     2724:             DEBUG_PRINT(("RTL8139: NWayExpansion write(w) val=0x%04x\n", val));
1.1       root     2725:             s->NWayExpansion = val;
                   2726:             break;
                   2727: 
                   2728:         case CpCmd:
                   2729:             rtl8139_CpCmd_write(s, val);
                   2730:             break;
                   2731: 
1.1.1.2 ! root     2732:         case IntrMitigate:
        !          2733:             rtl8139_IntrMitigate_write(s, val);
        !          2734:             break;
        !          2735: 
1.1       root     2736:         default:
1.1.1.2 ! root     2737:             DEBUG_PRINT(("RTL8139: ioport write(w) addr=0x%x val=0x%04x via write(b)\n", addr, val));
1.1       root     2738: 
                   2739: #ifdef TARGET_WORDS_BIGENDIAN
                   2740:             rtl8139_io_writeb(opaque, addr, (val >> 8) & 0xff);
                   2741:             rtl8139_io_writeb(opaque, addr + 1, val & 0xff);
                   2742: #else
                   2743:             rtl8139_io_writeb(opaque, addr, val & 0xff);
                   2744:             rtl8139_io_writeb(opaque, addr + 1, (val >> 8) & 0xff);
                   2745: #endif
                   2746:             break;
                   2747:     }
                   2748: }
                   2749: 
                   2750: static void rtl8139_io_writel(void *opaque, uint8_t addr, uint32_t val)
                   2751: {
                   2752:     RTL8139State *s = opaque;
                   2753: 
                   2754:     addr &= 0xfc;
                   2755: 
                   2756:     switch (addr)
                   2757:     {
                   2758:         case RxMissed:
1.1.1.2 ! root     2759:             DEBUG_PRINT(("RTL8139: RxMissed clearing on write\n"));
1.1       root     2760:             s->RxMissed = 0;
                   2761:             break;
                   2762: 
                   2763:         case TxConfig:
                   2764:             rtl8139_TxConfig_write(s, val);
                   2765:             break;
                   2766: 
                   2767:         case RxConfig:
                   2768:             rtl8139_RxConfig_write(s, val);
                   2769:             break;
                   2770: 
                   2771:         case TxStatus0 ... TxStatus0+4*4-1:
                   2772:             rtl8139_TxStatus_write(s, addr-TxStatus0, val);
                   2773:             break;
                   2774: 
                   2775:         case TxAddr0 ... TxAddr0+4*4-1:
                   2776:             rtl8139_TxAddr_write(s, addr-TxAddr0, val);
                   2777:             break;
                   2778: 
                   2779:         case RxBuf:
                   2780:             rtl8139_RxBuf_write(s, val);
                   2781:             break;
                   2782: 
                   2783:         case RxRingAddrLO:
1.1.1.2 ! root     2784:             DEBUG_PRINT(("RTL8139: C+ RxRing low bits write val=0x%08x\n", val));
1.1       root     2785:             s->RxRingAddrLO = val;
                   2786:             break;
                   2787: 
                   2788:         case RxRingAddrHI:
1.1.1.2 ! root     2789:             DEBUG_PRINT(("RTL8139: C+ RxRing high bits write val=0x%08x\n", val));
1.1       root     2790:             s->RxRingAddrHI = val;
                   2791:             break;
                   2792: 
1.1.1.2 ! root     2793:         case Timer:
        !          2794:             DEBUG_PRINT(("RTL8139: TCTR Timer reset on write\n"));
        !          2795:             s->TCTR = 0;
        !          2796:             s->TCTR_base = qemu_get_clock(vm_clock);
        !          2797:             break;
        !          2798: 
        !          2799:         case FlashReg:
        !          2800:             DEBUG_PRINT(("RTL8139: FlashReg TimerInt write val=0x%08x\n", val));
        !          2801:             s->TimerInt = val;
        !          2802:             break;
        !          2803: 
1.1       root     2804:         default:
1.1.1.2 ! root     2805:             DEBUG_PRINT(("RTL8139: ioport write(l) addr=0x%x val=0x%08x via write(b)\n", addr, val));
1.1       root     2806: #ifdef TARGET_WORDS_BIGENDIAN
                   2807:             rtl8139_io_writeb(opaque, addr, (val >> 24) & 0xff);
                   2808:             rtl8139_io_writeb(opaque, addr + 1, (val >> 16) & 0xff);
                   2809:             rtl8139_io_writeb(opaque, addr + 2, (val >> 8) & 0xff);
                   2810:             rtl8139_io_writeb(opaque, addr + 3, val & 0xff);
                   2811: #else
                   2812:             rtl8139_io_writeb(opaque, addr, val & 0xff);
                   2813:             rtl8139_io_writeb(opaque, addr + 1, (val >> 8) & 0xff);
                   2814:             rtl8139_io_writeb(opaque, addr + 2, (val >> 16) & 0xff);
                   2815:             rtl8139_io_writeb(opaque, addr + 3, (val >> 24) & 0xff);
                   2816: #endif
                   2817:             break;
                   2818:     }
                   2819: }
                   2820: 
                   2821: static uint32_t rtl8139_io_readb(void *opaque, uint8_t addr)
                   2822: {
                   2823:     RTL8139State *s = opaque;
                   2824:     int ret;
                   2825: 
                   2826:     addr &= 0xff;
                   2827: 
                   2828:     switch (addr)
                   2829:     {
                   2830:         case MAC0 ... MAC0+5:
                   2831:             ret = s->phys[addr - MAC0];
                   2832:             break;
                   2833:         case MAC0+6 ... MAC0+7:
                   2834:             ret = 0;
                   2835:             break;
                   2836:         case MAR0 ... MAR0+7:
                   2837:             ret = s->mult[addr - MAR0];
                   2838:             break;
                   2839:         case ChipCmd:
                   2840:             ret = rtl8139_ChipCmd_read(s);
                   2841:             break;
                   2842:         case Cfg9346:
                   2843:             ret = rtl8139_Cfg9346_read(s);
                   2844:             break;
                   2845:         case Config0:
                   2846:             ret = rtl8139_Config0_read(s);
                   2847:             break;
                   2848:         case Config1:
                   2849:             ret = rtl8139_Config1_read(s);
                   2850:             break;
                   2851:         case Config3:
                   2852:             ret = rtl8139_Config3_read(s);
                   2853:             break;
                   2854:         case Config4:
                   2855:             ret = rtl8139_Config4_read(s);
                   2856:             break;
                   2857:         case Config5:
                   2858:             ret = rtl8139_Config5_read(s);
                   2859:             break;
                   2860: 
                   2861:         case MediaStatus:
                   2862:             ret = 0xd0;
1.1.1.2 ! root     2863:             DEBUG_PRINT(("RTL8139: MediaStatus read 0x%x\n", ret));
1.1       root     2864:             break;
                   2865: 
                   2866:         case HltClk:
                   2867:             ret = s->clock_enabled;
1.1.1.2 ! root     2868:             DEBUG_PRINT(("RTL8139: HltClk read 0x%x\n", ret));
1.1       root     2869:             break;
                   2870: 
                   2871:         case PCIRevisionID:
1.1.1.2 ! root     2872:             ret = RTL8139_PCI_REVID;
        !          2873:             DEBUG_PRINT(("RTL8139: PCI Revision ID read 0x%x\n", ret));
1.1       root     2874:             break;
                   2875: 
                   2876:         case TxThresh:
                   2877:             ret = s->TxThresh;
1.1.1.2 ! root     2878:             DEBUG_PRINT(("RTL8139C+ TxThresh read(b) val=0x%02x\n", ret));
1.1       root     2879:             break;
                   2880: 
                   2881:         case 0x43: /* Part of TxConfig register. Windows driver tries to read it */
                   2882:             ret = s->TxConfig >> 24;
1.1.1.2 ! root     2883:             DEBUG_PRINT(("RTL8139C TxConfig at 0x43 read(b) val=0x%02x\n", ret));
1.1       root     2884:             break;
                   2885: 
                   2886:         default:
1.1.1.2 ! root     2887:             DEBUG_PRINT(("RTL8139: not implemented read(b) addr=0x%x\n", addr));
1.1       root     2888:             ret = 0;
                   2889:             break;
                   2890:     }
                   2891: 
                   2892:     return ret;
                   2893: }
                   2894: 
                   2895: static uint32_t rtl8139_io_readw(void *opaque, uint8_t addr)
                   2896: {
                   2897:     RTL8139State *s = opaque;
                   2898:     uint32_t ret;
                   2899: 
                   2900:     addr &= 0xfe; /* mask lower bit */
                   2901: 
                   2902:     switch (addr)
                   2903:     {
                   2904:         case IntrMask:
                   2905:             ret = rtl8139_IntrMask_read(s);
                   2906:             break;
                   2907: 
                   2908:         case IntrStatus:
                   2909:             ret = rtl8139_IntrStatus_read(s);
                   2910:             break;
                   2911: 
                   2912:         case MultiIntr:
                   2913:             ret = rtl8139_MultiIntr_read(s);
                   2914:             break;
                   2915: 
                   2916:         case RxBufPtr:
                   2917:             ret = rtl8139_RxBufPtr_read(s);
                   2918:             break;
                   2919: 
1.1.1.2 ! root     2920:         case RxBufAddr:
        !          2921:             ret = rtl8139_RxBufAddr_read(s);
        !          2922:             break;
        !          2923: 
1.1       root     2924:         case BasicModeCtrl:
                   2925:             ret = rtl8139_BasicModeCtrl_read(s);
                   2926:             break;
                   2927:         case BasicModeStatus:
                   2928:             ret = rtl8139_BasicModeStatus_read(s);
                   2929:             break;
                   2930:         case NWayAdvert:
                   2931:             ret = s->NWayAdvert;
1.1.1.2 ! root     2932:             DEBUG_PRINT(("RTL8139: NWayAdvert read(w) val=0x%04x\n", ret));
1.1       root     2933:             break;
                   2934:         case NWayLPAR:
                   2935:             ret = s->NWayLPAR;
1.1.1.2 ! root     2936:             DEBUG_PRINT(("RTL8139: NWayLPAR read(w) val=0x%04x\n", ret));
1.1       root     2937:             break;
                   2938:         case NWayExpansion:
                   2939:             ret = s->NWayExpansion;
1.1.1.2 ! root     2940:             DEBUG_PRINT(("RTL8139: NWayExpansion read(w) val=0x%04x\n", ret));
1.1       root     2941:             break;
                   2942: 
                   2943:         case CpCmd:
                   2944:             ret = rtl8139_CpCmd_read(s);
                   2945:             break;
                   2946: 
1.1.1.2 ! root     2947:         case IntrMitigate:
        !          2948:             ret = rtl8139_IntrMitigate_read(s);
        !          2949:             break;
        !          2950: 
1.1       root     2951:         case TxSummary:
                   2952:             ret = rtl8139_TSAD_read(s);
                   2953:             break;
                   2954: 
                   2955:         case CSCR:
                   2956:             ret = rtl8139_CSCR_read(s);
                   2957:             break;
                   2958: 
                   2959:         default:
1.1.1.2 ! root     2960:             DEBUG_PRINT(("RTL8139: ioport read(w) addr=0x%x via read(b)\n", addr));
1.1       root     2961: 
                   2962: #ifdef TARGET_WORDS_BIGENDIAN
                   2963:             ret  = rtl8139_io_readb(opaque, addr) << 8;
                   2964:             ret |= rtl8139_io_readb(opaque, addr + 1);
                   2965: #else
                   2966:             ret  = rtl8139_io_readb(opaque, addr);
                   2967:             ret |= rtl8139_io_readb(opaque, addr + 1) << 8;
                   2968: #endif
                   2969: 
1.1.1.2 ! root     2970:             DEBUG_PRINT(("RTL8139: ioport read(w) addr=0x%x val=0x%04x\n", addr, ret));
1.1       root     2971:             break;
                   2972:     }
                   2973: 
                   2974:     return ret;
                   2975: }
                   2976: 
                   2977: static uint32_t rtl8139_io_readl(void *opaque, uint8_t addr)
                   2978: {
                   2979:     RTL8139State *s = opaque;
                   2980:     uint32_t ret;
                   2981: 
                   2982:     addr &= 0xfc; /* also mask low 2 bits */
                   2983: 
                   2984:     switch (addr)
                   2985:     {
                   2986:         case RxMissed:
                   2987:             ret = s->RxMissed;
                   2988: 
1.1.1.2 ! root     2989:             DEBUG_PRINT(("RTL8139: RxMissed read val=0x%08x\n", ret));
1.1       root     2990:             break;
                   2991: 
                   2992:         case TxConfig:
                   2993:             ret = rtl8139_TxConfig_read(s);
                   2994:             break;
                   2995: 
                   2996:         case RxConfig:
                   2997:             ret = rtl8139_RxConfig_read(s);
                   2998:             break;
                   2999: 
                   3000:         case TxStatus0 ... TxStatus0+4*4-1:
                   3001:             ret = rtl8139_TxStatus_read(s, addr-TxStatus0);
                   3002:             break;
                   3003: 
                   3004:         case TxAddr0 ... TxAddr0+4*4-1:
                   3005:             ret = rtl8139_TxAddr_read(s, addr-TxAddr0);
                   3006:             break;
                   3007: 
                   3008:         case RxBuf:
                   3009:             ret = rtl8139_RxBuf_read(s);
                   3010:             break;
                   3011: 
                   3012:         case RxRingAddrLO:
                   3013:             ret = s->RxRingAddrLO;
1.1.1.2 ! root     3014:             DEBUG_PRINT(("RTL8139: C+ RxRing low bits read val=0x%08x\n", ret));
1.1       root     3015:             break;
                   3016: 
                   3017:         case RxRingAddrHI:
                   3018:             ret = s->RxRingAddrHI;
1.1.1.2 ! root     3019:             DEBUG_PRINT(("RTL8139: C+ RxRing high bits read val=0x%08x\n", ret));
        !          3020:             break;
        !          3021: 
        !          3022:         case Timer:
        !          3023:             ret = s->TCTR;
        !          3024:             DEBUG_PRINT(("RTL8139: TCTR Timer read val=0x%08x\n", ret));
        !          3025:             break;
        !          3026: 
        !          3027:         case FlashReg:
        !          3028:             ret = s->TimerInt;
        !          3029:             DEBUG_PRINT(("RTL8139: FlashReg TimerInt read val=0x%08x\n", ret));
1.1       root     3030:             break;
                   3031: 
                   3032:         default:
1.1.1.2 ! root     3033:             DEBUG_PRINT(("RTL8139: ioport read(l) addr=0x%x via read(b)\n", addr));
1.1       root     3034: 
                   3035: #ifdef TARGET_WORDS_BIGENDIAN
                   3036:             ret  = rtl8139_io_readb(opaque, addr) << 24;
                   3037:             ret |= rtl8139_io_readb(opaque, addr + 1) << 16;
                   3038:             ret |= rtl8139_io_readb(opaque, addr + 2) << 8;
                   3039:             ret |= rtl8139_io_readb(opaque, addr + 3);
                   3040: #else
                   3041:             ret  = rtl8139_io_readb(opaque, addr);
                   3042:             ret |= rtl8139_io_readb(opaque, addr + 1) << 8;
                   3043:             ret |= rtl8139_io_readb(opaque, addr + 2) << 16;
                   3044:             ret |= rtl8139_io_readb(opaque, addr + 3) << 24;
                   3045: #endif
                   3046: 
1.1.1.2 ! root     3047:             DEBUG_PRINT(("RTL8139: read(l) addr=0x%x val=%08x\n", addr, ret));
1.1       root     3048:             break;
                   3049:     }
                   3050: 
                   3051:     return ret;
                   3052: }
                   3053: 
                   3054: /* */
                   3055: 
                   3056: static void rtl8139_ioport_writeb(void *opaque, uint32_t addr, uint32_t val)
                   3057: {
                   3058:     rtl8139_io_writeb(opaque, addr & 0xFF, val);
                   3059: }
                   3060: 
                   3061: static void rtl8139_ioport_writew(void *opaque, uint32_t addr, uint32_t val)
                   3062: {
                   3063:     rtl8139_io_writew(opaque, addr & 0xFF, val);
                   3064: }
                   3065: 
                   3066: static void rtl8139_ioport_writel(void *opaque, uint32_t addr, uint32_t val)
                   3067: {
                   3068:     rtl8139_io_writel(opaque, addr & 0xFF, val);
                   3069: }
                   3070: 
                   3071: static uint32_t rtl8139_ioport_readb(void *opaque, uint32_t addr)
                   3072: {
                   3073:     return rtl8139_io_readb(opaque, addr & 0xFF);
                   3074: }
                   3075: 
                   3076: static uint32_t rtl8139_ioport_readw(void *opaque, uint32_t addr)
                   3077: {
                   3078:     return rtl8139_io_readw(opaque, addr & 0xFF);
                   3079: }
                   3080: 
                   3081: static uint32_t rtl8139_ioport_readl(void *opaque, uint32_t addr)
                   3082: {
                   3083:     return rtl8139_io_readl(opaque, addr & 0xFF);
                   3084: }
                   3085: 
                   3086: /* */
                   3087: 
                   3088: static void rtl8139_mmio_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
                   3089: {
                   3090:     rtl8139_io_writeb(opaque, addr & 0xFF, val);
                   3091: }
                   3092: 
                   3093: static void rtl8139_mmio_writew(void *opaque, target_phys_addr_t addr, uint32_t val)
                   3094: {
                   3095:     rtl8139_io_writew(opaque, addr & 0xFF, val);
                   3096: }
                   3097: 
                   3098: static void rtl8139_mmio_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
                   3099: {
                   3100:     rtl8139_io_writel(opaque, addr & 0xFF, val);
                   3101: }
                   3102: 
                   3103: static uint32_t rtl8139_mmio_readb(void *opaque, target_phys_addr_t addr)
                   3104: {
                   3105:     return rtl8139_io_readb(opaque, addr & 0xFF);
                   3106: }
                   3107: 
                   3108: static uint32_t rtl8139_mmio_readw(void *opaque, target_phys_addr_t addr)
                   3109: {
                   3110:     return rtl8139_io_readw(opaque, addr & 0xFF);
                   3111: }
                   3112: 
                   3113: static uint32_t rtl8139_mmio_readl(void *opaque, target_phys_addr_t addr)
                   3114: {
                   3115:     return rtl8139_io_readl(opaque, addr & 0xFF);
                   3116: }
                   3117: 
                   3118: /* */
                   3119: 
                   3120: static void rtl8139_save(QEMUFile* f,void* opaque)
                   3121: {
                   3122:     RTL8139State* s=(RTL8139State*)opaque;
                   3123:     int i;
                   3124: 
                   3125:     qemu_put_buffer(f, s->phys, 6);
                   3126:     qemu_put_buffer(f, s->mult, 8);
                   3127: 
                   3128:     for (i=0; i<4; ++i)
                   3129:     {
                   3130:         qemu_put_be32s(f, &s->TxStatus[i]); /* TxStatus0 */
                   3131:     }
                   3132:     for (i=0; i<4; ++i)
                   3133:     {
                   3134:         qemu_put_be32s(f, &s->TxAddr[i]); /* TxAddr0 */
                   3135:     }
                   3136: 
                   3137:     qemu_put_be32s(f, &s->RxBuf); /* Receive buffer */
                   3138:     qemu_put_be32s(f, &s->RxBufferSize);/* internal variable, receive ring buffer size in C mode */
                   3139:     qemu_put_be32s(f, &s->RxBufPtr);
                   3140:     qemu_put_be32s(f, &s->RxBufAddr);
                   3141: 
                   3142:     qemu_put_be16s(f, &s->IntrStatus);
                   3143:     qemu_put_be16s(f, &s->IntrMask);
                   3144: 
                   3145:     qemu_put_be32s(f, &s->TxConfig);
                   3146:     qemu_put_be32s(f, &s->RxConfig);
                   3147:     qemu_put_be32s(f, &s->RxMissed);
                   3148:     qemu_put_be16s(f, &s->CSCR);
                   3149: 
                   3150:     qemu_put_8s(f, &s->Cfg9346);
                   3151:     qemu_put_8s(f, &s->Config0);
                   3152:     qemu_put_8s(f, &s->Config1);
                   3153:     qemu_put_8s(f, &s->Config3);
                   3154:     qemu_put_8s(f, &s->Config4);
                   3155:     qemu_put_8s(f, &s->Config5);
                   3156: 
                   3157:     qemu_put_8s(f, &s->clock_enabled);
                   3158:     qemu_put_8s(f, &s->bChipCmdState);
                   3159: 
                   3160:     qemu_put_be16s(f, &s->MultiIntr);
                   3161: 
                   3162:     qemu_put_be16s(f, &s->BasicModeCtrl);
                   3163:     qemu_put_be16s(f, &s->BasicModeStatus);
                   3164:     qemu_put_be16s(f, &s->NWayAdvert);
                   3165:     qemu_put_be16s(f, &s->NWayLPAR);
                   3166:     qemu_put_be16s(f, &s->NWayExpansion);
                   3167: 
                   3168:     qemu_put_be16s(f, &s->CpCmd);
                   3169:     qemu_put_8s(f, &s->TxThresh);
                   3170: 
                   3171:     qemu_put_be32s(f, &s->irq);
                   3172:     qemu_put_buffer(f, s->macaddr, 6);
                   3173:     qemu_put_be32s(f, &s->rtl8139_mmio_io_addr);
                   3174: 
                   3175:     qemu_put_be32s(f, &s->currTxDesc);
                   3176:     qemu_put_be32s(f, &s->currCPlusRxDesc);
                   3177:     qemu_put_be32s(f, &s->currCPlusTxDesc);
                   3178:     qemu_put_be32s(f, &s->RxRingAddrLO);
                   3179:     qemu_put_be32s(f, &s->RxRingAddrHI);
                   3180: 
                   3181:     for (i=0; i<EEPROM_9346_SIZE; ++i)
                   3182:     {
                   3183:         qemu_put_be16s(f, &s->eeprom.contents[i]);
                   3184:     }
                   3185:     qemu_put_be32s(f, &s->eeprom.mode);
                   3186:     qemu_put_be32s(f, &s->eeprom.tick);
                   3187:     qemu_put_8s(f, &s->eeprom.address);
                   3188:     qemu_put_be16s(f, &s->eeprom.input);
                   3189:     qemu_put_be16s(f, &s->eeprom.output);
                   3190: 
                   3191:     qemu_put_8s(f, &s->eeprom.eecs);
                   3192:     qemu_put_8s(f, &s->eeprom.eesk);
                   3193:     qemu_put_8s(f, &s->eeprom.eedi);
                   3194:     qemu_put_8s(f, &s->eeprom.eedo);
1.1.1.2 ! root     3195: 
        !          3196:     qemu_put_be32s(f, &s->TCTR);
        !          3197:     qemu_put_be32s(f, &s->TimerInt);
        !          3198:     qemu_put_be64s(f, &s->TCTR_base);
        !          3199: 
        !          3200:     RTL8139TallyCounters_save(f, &s->tally_counters);
1.1       root     3201: }
                   3202: 
                   3203: static int rtl8139_load(QEMUFile* f,void* opaque,int version_id)
                   3204: {
                   3205:     RTL8139State* s=(RTL8139State*)opaque;
                   3206:     int i;
                   3207: 
1.1.1.2 ! root     3208:     /* just 2 versions for now */
        !          3209:     if (version_id > 2)
1.1       root     3210:             return -EINVAL;
                   3211: 
1.1.1.2 ! root     3212:     /* saved since version 1 */
1.1       root     3213:     qemu_get_buffer(f, s->phys, 6);
                   3214:     qemu_get_buffer(f, s->mult, 8);
                   3215: 
                   3216:     for (i=0; i<4; ++i)
                   3217:     {
                   3218:         qemu_get_be32s(f, &s->TxStatus[i]); /* TxStatus0 */
                   3219:     }
                   3220:     for (i=0; i<4; ++i)
                   3221:     {
                   3222:         qemu_get_be32s(f, &s->TxAddr[i]); /* TxAddr0 */
                   3223:     }
                   3224: 
                   3225:     qemu_get_be32s(f, &s->RxBuf); /* Receive buffer */
                   3226:     qemu_get_be32s(f, &s->RxBufferSize);/* internal variable, receive ring buffer size in C mode */
                   3227:     qemu_get_be32s(f, &s->RxBufPtr);
                   3228:     qemu_get_be32s(f, &s->RxBufAddr);
                   3229: 
                   3230:     qemu_get_be16s(f, &s->IntrStatus);
                   3231:     qemu_get_be16s(f, &s->IntrMask);
                   3232: 
                   3233:     qemu_get_be32s(f, &s->TxConfig);
                   3234:     qemu_get_be32s(f, &s->RxConfig);
                   3235:     qemu_get_be32s(f, &s->RxMissed);
                   3236:     qemu_get_be16s(f, &s->CSCR);
                   3237: 
                   3238:     qemu_get_8s(f, &s->Cfg9346);
                   3239:     qemu_get_8s(f, &s->Config0);
                   3240:     qemu_get_8s(f, &s->Config1);
                   3241:     qemu_get_8s(f, &s->Config3);
                   3242:     qemu_get_8s(f, &s->Config4);
                   3243:     qemu_get_8s(f, &s->Config5);
                   3244: 
                   3245:     qemu_get_8s(f, &s->clock_enabled);
                   3246:     qemu_get_8s(f, &s->bChipCmdState);
                   3247: 
                   3248:     qemu_get_be16s(f, &s->MultiIntr);
                   3249: 
                   3250:     qemu_get_be16s(f, &s->BasicModeCtrl);
                   3251:     qemu_get_be16s(f, &s->BasicModeStatus);
                   3252:     qemu_get_be16s(f, &s->NWayAdvert);
                   3253:     qemu_get_be16s(f, &s->NWayLPAR);
                   3254:     qemu_get_be16s(f, &s->NWayExpansion);
                   3255: 
                   3256:     qemu_get_be16s(f, &s->CpCmd);
                   3257:     qemu_get_8s(f, &s->TxThresh);
                   3258: 
                   3259:     qemu_get_be32s(f, &s->irq);
                   3260:     qemu_get_buffer(f, s->macaddr, 6);
                   3261:     qemu_get_be32s(f, &s->rtl8139_mmio_io_addr);
                   3262: 
                   3263:     qemu_get_be32s(f, &s->currTxDesc);
                   3264:     qemu_get_be32s(f, &s->currCPlusRxDesc);
                   3265:     qemu_get_be32s(f, &s->currCPlusTxDesc);
                   3266:     qemu_get_be32s(f, &s->RxRingAddrLO);
                   3267:     qemu_get_be32s(f, &s->RxRingAddrHI);
                   3268: 
                   3269:     for (i=0; i<EEPROM_9346_SIZE; ++i)
                   3270:     {
                   3271:         qemu_get_be16s(f, &s->eeprom.contents[i]);
                   3272:     }
                   3273:     qemu_get_be32s(f, &s->eeprom.mode);
                   3274:     qemu_get_be32s(f, &s->eeprom.tick);
                   3275:     qemu_get_8s(f, &s->eeprom.address);
                   3276:     qemu_get_be16s(f, &s->eeprom.input);
                   3277:     qemu_get_be16s(f, &s->eeprom.output);
                   3278: 
                   3279:     qemu_get_8s(f, &s->eeprom.eecs);
                   3280:     qemu_get_8s(f, &s->eeprom.eesk);
                   3281:     qemu_get_8s(f, &s->eeprom.eedi);
                   3282:     qemu_get_8s(f, &s->eeprom.eedo);
                   3283: 
1.1.1.2 ! root     3284:     /* saved since version 2 */
        !          3285:     if (version_id >= 2)
        !          3286:     {
        !          3287:         qemu_get_be32s(f, &s->TCTR);
        !          3288:         qemu_get_be32s(f, &s->TimerInt);
        !          3289:         qemu_get_be64s(f, &s->TCTR_base);
        !          3290: 
        !          3291:         RTL8139TallyCounters_load(f, &s->tally_counters);
        !          3292:     }
        !          3293:     else
        !          3294:     {
        !          3295:         /* not saved, use default */
        !          3296:         s->TCTR = 0;
        !          3297:         s->TimerInt = 0;
        !          3298:         s->TCTR_base = 0;
        !          3299: 
        !          3300:         RTL8139TallyCounters_clear(&s->tally_counters);
        !          3301:     }
        !          3302: 
1.1       root     3303:     return 0;
                   3304: }
                   3305: 
                   3306: /***********************************************************/
                   3307: /* PCI RTL8139 definitions */
                   3308: 
                   3309: typedef struct PCIRTL8139State {
                   3310:     PCIDevice dev;
                   3311:     RTL8139State rtl8139;
                   3312: } PCIRTL8139State;
                   3313: 
                   3314: static void rtl8139_mmio_map(PCIDevice *pci_dev, int region_num, 
                   3315:                        uint32_t addr, uint32_t size, int type)
                   3316: {
                   3317:     PCIRTL8139State *d = (PCIRTL8139State *)pci_dev;
                   3318:     RTL8139State *s = &d->rtl8139;
                   3319: 
                   3320:     cpu_register_physical_memory(addr + 0, 0x100, s->rtl8139_mmio_io_addr);
                   3321: }
                   3322: 
                   3323: static void rtl8139_ioport_map(PCIDevice *pci_dev, int region_num, 
                   3324:                        uint32_t addr, uint32_t size, int type)
                   3325: {
                   3326:     PCIRTL8139State *d = (PCIRTL8139State *)pci_dev;
                   3327:     RTL8139State *s = &d->rtl8139;
                   3328: 
                   3329:     register_ioport_write(addr, 0x100, 1, rtl8139_ioport_writeb, s);
                   3330:     register_ioport_read( addr, 0x100, 1, rtl8139_ioport_readb,  s);
                   3331: 
                   3332:     register_ioport_write(addr, 0x100, 2, rtl8139_ioport_writew, s);
                   3333:     register_ioport_read( addr, 0x100, 2, rtl8139_ioport_readw,  s);
                   3334: 
                   3335:     register_ioport_write(addr, 0x100, 4, rtl8139_ioport_writel, s);
                   3336:     register_ioport_read( addr, 0x100, 4, rtl8139_ioport_readl,  s);
                   3337: }
                   3338: 
                   3339: static CPUReadMemoryFunc *rtl8139_mmio_read[3] = {
                   3340:     rtl8139_mmio_readb,
                   3341:     rtl8139_mmio_readw,
                   3342:     rtl8139_mmio_readl,
                   3343: };
                   3344: 
                   3345: static CPUWriteMemoryFunc *rtl8139_mmio_write[3] = {
                   3346:     rtl8139_mmio_writeb,
                   3347:     rtl8139_mmio_writew,
                   3348:     rtl8139_mmio_writel,
                   3349: };
                   3350: 
1.1.1.2 ! root     3351: static inline int64_t rtl8139_get_next_tctr_time(RTL8139State *s, int64_t current_time)
        !          3352: {
        !          3353:     int64_t next_time = current_time + 
        !          3354:         muldiv64(1, ticks_per_sec, PCI_FREQUENCY);
        !          3355:     if (next_time <= current_time)
        !          3356:         next_time = current_time + 1;
        !          3357:     return next_time;
        !          3358: }
        !          3359: 
        !          3360: #if RTL8139_ONBOARD_TIMER
        !          3361: static void rtl8139_timer(void *opaque)
        !          3362: {
        !          3363:     RTL8139State *s = opaque;
        !          3364: 
        !          3365:     int is_timeout = 0;
        !          3366: 
        !          3367:     int64_t  curr_time;
        !          3368:     uint32_t curr_tick;
        !          3369: 
        !          3370:     if (!s->clock_enabled)
        !          3371:     {
        !          3372:         DEBUG_PRINT(("RTL8139: >>> timer: clock is not running\n"));
        !          3373:         return;
        !          3374:     }
        !          3375: 
        !          3376:     curr_time = qemu_get_clock(vm_clock);
        !          3377: 
        !          3378:     curr_tick = muldiv64(curr_time - s->TCTR_base, PCI_FREQUENCY, ticks_per_sec);
        !          3379: 
        !          3380:     if (s->TimerInt && curr_tick >= s->TimerInt)
        !          3381:     {
        !          3382:         if (s->TCTR < s->TimerInt || curr_tick < s->TCTR)
        !          3383:         {
        !          3384:             is_timeout = 1;
        !          3385:         }
        !          3386:     }
        !          3387: 
        !          3388:     s->TCTR = curr_tick;
        !          3389: 
        !          3390: //  DEBUG_PRINT(("RTL8139: >>> timer: tick=%08u\n", s->TCTR));
        !          3391: 
        !          3392:     if (is_timeout)
        !          3393:     {
        !          3394:         DEBUG_PRINT(("RTL8139: >>> timer: timeout tick=%08u\n", s->TCTR));
        !          3395:         s->IntrStatus |= PCSTimeout;
        !          3396:         rtl8139_update_irq(s);
        !          3397:     }
        !          3398: 
        !          3399:     qemu_mod_timer(s->timer, 
        !          3400:         rtl8139_get_next_tctr_time(s,curr_time));
        !          3401: }
        !          3402: #endif /* RTL8139_ONBOARD_TIMER */
        !          3403: 
1.1       root     3404: void pci_rtl8139_init(PCIBus *bus, NICInfo *nd)
                   3405: {
                   3406:     PCIRTL8139State *d;
                   3407:     RTL8139State *s;
                   3408:     uint8_t *pci_conf;
                   3409:     
                   3410:     d = (PCIRTL8139State *)pci_register_device(bus,
                   3411:                                               "RTL8139", sizeof(PCIRTL8139State),
                   3412:                                               -1, 
                   3413:                                               NULL, NULL);
                   3414:     pci_conf = d->dev.config;
                   3415:     pci_conf[0x00] = 0xec; /* Realtek 8139 */
                   3416:     pci_conf[0x01] = 0x10;
                   3417:     pci_conf[0x02] = 0x39;
                   3418:     pci_conf[0x03] = 0x81;
                   3419:     pci_conf[0x04] = 0x05; /* command = I/O space, Bus Master */
1.1.1.2 ! root     3420:     pci_conf[0x08] = RTL8139_PCI_REVID; /* PCI revision ID; >=0x20 is for 8139C+ */
1.1       root     3421:     pci_conf[0x0a] = 0x00; /* ethernet network controller */
                   3422:     pci_conf[0x0b] = 0x02;
                   3423:     pci_conf[0x0e] = 0x00; /* header_type */
                   3424:     pci_conf[0x3d] = 1;    /* interrupt pin 0 */
                   3425:     pci_conf[0x34] = 0xdc;
                   3426: 
                   3427:     s = &d->rtl8139;
                   3428: 
                   3429:     /* I/O handler for memory-mapped I/O */
                   3430:     s->rtl8139_mmio_io_addr =
                   3431:     cpu_register_io_memory(0, rtl8139_mmio_read, rtl8139_mmio_write, s);
                   3432: 
                   3433:     pci_register_io_region(&d->dev, 0, 0x100, 
                   3434:                            PCI_ADDRESS_SPACE_IO,  rtl8139_ioport_map);
                   3435: 
                   3436:     pci_register_io_region(&d->dev, 1, 0x100, 
                   3437:                            PCI_ADDRESS_SPACE_MEM, rtl8139_mmio_map);
                   3438: 
                   3439:     s->irq = 16; /* PCI interrupt */
                   3440:     s->pci_dev = (PCIDevice *)d;
                   3441:     memcpy(s->macaddr, nd->macaddr, 6);
                   3442:     rtl8139_reset(s);
                   3443:     s->vc = qemu_new_vlan_client(nd->vlan, rtl8139_receive,
                   3444:                                  rtl8139_can_receive, s);
                   3445: 
                   3446:     snprintf(s->vc->info_str, sizeof(s->vc->info_str),
                   3447:              "rtl8139 pci macaddr=%02x:%02x:%02x:%02x:%02x:%02x",
                   3448:              s->macaddr[0],
                   3449:              s->macaddr[1],
                   3450:              s->macaddr[2],
                   3451:              s->macaddr[3],
                   3452:              s->macaddr[4],
                   3453:              s->macaddr[5]);
1.1.1.2 ! root     3454: 
        !          3455:     s->cplus_txbuffer = NULL;
        !          3456:     s->cplus_txbuffer_len = 0;
        !          3457:     s->cplus_txbuffer_offset = 0;
1.1       root     3458:              
                   3459:     /* XXX: instance number ? */
1.1.1.2 ! root     3460:     register_savevm("rtl8139", 0, 2, rtl8139_save, rtl8139_load, s);
1.1       root     3461:     register_savevm("rtl8139_pci", 0, 1, generic_pci_save, generic_pci_load, 
                   3462:                     &d->dev);
1.1.1.2 ! root     3463: 
        !          3464: #if RTL8139_ONBOARD_TIMER
        !          3465:     s->timer = qemu_new_timer(vm_clock, rtl8139_timer, s);
        !          3466: 
        !          3467:     qemu_mod_timer(s->timer, 
        !          3468:         rtl8139_get_next_tctr_time(s,qemu_get_clock(vm_clock)));
        !          3469: #endif /* RTL8139_ONBOARD_TIMER */
1.1       root     3470: }
1.1.1.2 ! root     3471: 

unix.superglobalmegacorp.com