Annotation of qemu/hw/cadence_gem.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * QEMU Xilinx GEM emulation
                      3:  *
                      4:  * Copyright (c) 2011 Xilinx, Inc.
                      5:  *
                      6:  * Permission is hereby granted, free of charge, to any person obtaining a copy
                      7:  * of this software and associated documentation files (the "Software"), to deal
                      8:  * in the Software without restriction, including without limitation the rights
                      9:  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
                     10:  * copies of the Software, and to permit persons to whom the Software is
                     11:  * furnished to do so, subject to the following conditions:
                     12:  *
                     13:  * The above copyright notice and this permission notice shall be included in
                     14:  * all copies or substantial portions of the Software.
                     15:  *
                     16:  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
                     17:  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
                     18:  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
                     19:  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
                     20:  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
                     21:  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
                     22:  * THE SOFTWARE.
                     23:  */
                     24: 
                     25: #include <zlib.h> /* For crc32 */
                     26: 
                     27: #include "sysbus.h"
                     28: #include "net.h"
                     29: #include "net/checksum.h"
                     30: 
                     31: #ifdef CADENCE_GEM_ERR_DEBUG
                     32: #define DB_PRINT(...) do { \
                     33:     fprintf(stderr,  ": %s: ", __func__); \
                     34:     fprintf(stderr, ## __VA_ARGS__); \
                     35:     } while (0);
                     36: #else
                     37:     #define DB_PRINT(...)
                     38: #endif
                     39: 
                     40: #define GEM_NWCTRL        (0x00000000/4) /* Network Control reg */
                     41: #define GEM_NWCFG         (0x00000004/4) /* Network Config reg */
                     42: #define GEM_NWSTATUS      (0x00000008/4) /* Network Status reg */
                     43: #define GEM_USERIO        (0x0000000C/4) /* User IO reg */
                     44: #define GEM_DMACFG        (0x00000010/4) /* DMA Control reg */
                     45: #define GEM_TXSTATUS      (0x00000014/4) /* TX Status reg */
                     46: #define GEM_RXQBASE       (0x00000018/4) /* RX Q Base address reg */
                     47: #define GEM_TXQBASE       (0x0000001C/4) /* TX Q Base address reg */
                     48: #define GEM_RXSTATUS      (0x00000020/4) /* RX Status reg */
                     49: #define GEM_ISR           (0x00000024/4) /* Interrupt Status reg */
                     50: #define GEM_IER           (0x00000028/4) /* Interrupt Enable reg */
                     51: #define GEM_IDR           (0x0000002C/4) /* Interrupt Disable reg */
                     52: #define GEM_IMR           (0x00000030/4) /* Interrupt Mask reg */
                     53: #define GEM_PHYMNTNC      (0x00000034/4) /* Phy Maintaince reg */
                     54: #define GEM_RXPAUSE       (0x00000038/4) /* RX Pause Time reg */
                     55: #define GEM_TXPAUSE       (0x0000003C/4) /* TX Pause Time reg */
                     56: #define GEM_TXPARTIALSF   (0x00000040/4) /* TX Partial Store and Forward */
                     57: #define GEM_RXPARTIALSF   (0x00000044/4) /* RX Partial Store and Forward */
                     58: #define GEM_HASHLO        (0x00000080/4) /* Hash Low address reg */
                     59: #define GEM_HASHHI        (0x00000084/4) /* Hash High address reg */
                     60: #define GEM_SPADDR1LO     (0x00000088/4) /* Specific addr 1 low reg */
                     61: #define GEM_SPADDR1HI     (0x0000008C/4) /* Specific addr 1 high reg */
                     62: #define GEM_SPADDR2LO     (0x00000090/4) /* Specific addr 2 low reg */
                     63: #define GEM_SPADDR2HI     (0x00000094/4) /* Specific addr 2 high reg */
                     64: #define GEM_SPADDR3LO     (0x00000098/4) /* Specific addr 3 low reg */
                     65: #define GEM_SPADDR3HI     (0x0000009C/4) /* Specific addr 3 high reg */
                     66: #define GEM_SPADDR4LO     (0x000000A0/4) /* Specific addr 4 low reg */
                     67: #define GEM_SPADDR4HI     (0x000000A4/4) /* Specific addr 4 high reg */
                     68: #define GEM_TIDMATCH1     (0x000000A8/4) /* Type ID1 Match reg */
                     69: #define GEM_TIDMATCH2     (0x000000AC/4) /* Type ID2 Match reg */
                     70: #define GEM_TIDMATCH3     (0x000000B0/4) /* Type ID3 Match reg */
                     71: #define GEM_TIDMATCH4     (0x000000B4/4) /* Type ID4 Match reg */
                     72: #define GEM_WOLAN         (0x000000B8/4) /* Wake on LAN reg */
                     73: #define GEM_IPGSTRETCH    (0x000000BC/4) /* IPG Stretch reg */
                     74: #define GEM_SVLAN         (0x000000C0/4) /* Stacked VLAN reg */
                     75: #define GEM_MODID         (0x000000FC/4) /* Module ID reg */
                     76: #define GEM_OCTTXLO       (0x00000100/4) /* Octects transmitted Low reg */
                     77: #define GEM_OCTTXHI       (0x00000104/4) /* Octects transmitted High reg */
                     78: #define GEM_TXCNT         (0x00000108/4) /* Error-free Frames transmitted */
                     79: #define GEM_TXBCNT        (0x0000010C/4) /* Error-free Broadcast Frames */
                     80: #define GEM_TXMCNT        (0x00000110/4) /* Error-free Multicast Frame */
                     81: #define GEM_TXPAUSECNT    (0x00000114/4) /* Pause Frames Transmitted */
                     82: #define GEM_TX64CNT       (0x00000118/4) /* Error-free 64 TX */
                     83: #define GEM_TX65CNT       (0x0000011C/4) /* Error-free 65-127 TX */
                     84: #define GEM_TX128CNT      (0x00000120/4) /* Error-free 128-255 TX */
                     85: #define GEM_TX256CNT      (0x00000124/4) /* Error-free 256-511 */
                     86: #define GEM_TX512CNT      (0x00000128/4) /* Error-free 512-1023 TX */
                     87: #define GEM_TX1024CNT     (0x0000012C/4) /* Error-free 1024-1518 TX */
                     88: #define GEM_TX1519CNT     (0x00000130/4) /* Error-free larger than 1519 TX */
                     89: #define GEM_TXURUNCNT     (0x00000134/4) /* TX under run error counter */
                     90: #define GEM_SINGLECOLLCNT (0x00000138/4) /* Single Collision Frames */
                     91: #define GEM_MULTCOLLCNT   (0x0000013C/4) /* Multiple Collision Frames */
                     92: #define GEM_EXCESSCOLLCNT (0x00000140/4) /* Excessive Collision Frames */
                     93: #define GEM_LATECOLLCNT   (0x00000144/4) /* Late Collision Frames */
                     94: #define GEM_DEFERTXCNT    (0x00000148/4) /* Deferred Transmission Frames */
                     95: #define GEM_CSENSECNT     (0x0000014C/4) /* Carrier Sense Error Counter */
                     96: #define GEM_OCTRXLO       (0x00000150/4) /* Octects Received register Low */
                     97: #define GEM_OCTRXHI       (0x00000154/4) /* Octects Received register High */
                     98: #define GEM_RXCNT         (0x00000158/4) /* Error-free Frames Received */
                     99: #define GEM_RXBROADCNT    (0x0000015C/4) /* Error-free Broadcast Frames RX */
                    100: #define GEM_RXMULTICNT    (0x00000160/4) /* Error-free Multicast Frames RX */
                    101: #define GEM_RXPAUSECNT    (0x00000164/4) /* Pause Frames Received Counter */
                    102: #define GEM_RX64CNT       (0x00000168/4) /* Error-free 64 byte Frames RX */
                    103: #define GEM_RX65CNT       (0x0000016C/4) /* Error-free 65-127B Frames RX */
                    104: #define GEM_RX128CNT      (0x00000170/4) /* Error-free 128-255B Frames RX */
                    105: #define GEM_RX256CNT      (0x00000174/4) /* Error-free 256-512B Frames RX */
                    106: #define GEM_RX512CNT      (0x00000178/4) /* Error-free 512-1023B Frames RX */
                    107: #define GEM_RX1024CNT     (0x0000017C/4) /* Error-free 1024-1518B Frames RX */
                    108: #define GEM_RX1519CNT     (0x00000180/4) /* Error-free 1519-max Frames RX */
                    109: #define GEM_RXUNDERCNT    (0x00000184/4) /* Undersize Frames Received */
                    110: #define GEM_RXOVERCNT     (0x00000188/4) /* Oversize Frames Received */
                    111: #define GEM_RXJABCNT      (0x0000018C/4) /* Jabbers Received Counter */
                    112: #define GEM_RXFCSCNT      (0x00000190/4) /* Frame Check seq. Error Counter */
                    113: #define GEM_RXLENERRCNT   (0x00000194/4) /* Length Field Error Counter */
                    114: #define GEM_RXSYMERRCNT   (0x00000198/4) /* Symbol Error Counter */
                    115: #define GEM_RXALIGNERRCNT (0x0000019C/4) /* Alignment Error Counter */
                    116: #define GEM_RXRSCERRCNT   (0x000001A0/4) /* Receive Resource Error Counter */
                    117: #define GEM_RXORUNCNT     (0x000001A4/4) /* Receive Overrun Counter */
                    118: #define GEM_RXIPCSERRCNT  (0x000001A8/4) /* IP header Checksum Error Counter */
                    119: #define GEM_RXTCPCCNT     (0x000001AC/4) /* TCP Checksum Error Counter */
                    120: #define GEM_RXUDPCCNT     (0x000001B0/4) /* UDP Checksum Error Counter */
                    121: 
                    122: #define GEM_1588S         (0x000001D0/4) /* 1588 Timer Seconds */
                    123: #define GEM_1588NS        (0x000001D4/4) /* 1588 Timer Nanoseconds */
                    124: #define GEM_1588ADJ       (0x000001D8/4) /* 1588 Timer Adjust */
                    125: #define GEM_1588INC       (0x000001DC/4) /* 1588 Timer Increment */
                    126: #define GEM_PTPETXS       (0x000001E0/4) /* PTP Event Frame Transmitted (s) */
                    127: #define GEM_PTPETXNS      (0x000001E4/4) /* PTP Event Frame Transmitted (ns) */
                    128: #define GEM_PTPERXS       (0x000001E8/4) /* PTP Event Frame Received (s) */
                    129: #define GEM_PTPERXNS      (0x000001EC/4) /* PTP Event Frame Received (ns) */
                    130: #define GEM_PTPPTXS       (0x000001E0/4) /* PTP Peer Frame Transmitted (s) */
                    131: #define GEM_PTPPTXNS      (0x000001E4/4) /* PTP Peer Frame Transmitted (ns) */
                    132: #define GEM_PTPPRXS       (0x000001E8/4) /* PTP Peer Frame Received (s) */
                    133: #define GEM_PTPPRXNS      (0x000001EC/4) /* PTP Peer Frame Received (ns) */
                    134: 
                    135: /* Design Configuration Registers */
                    136: #define GEM_DESCONF       (0x00000280/4)
                    137: #define GEM_DESCONF2      (0x00000284/4)
                    138: #define GEM_DESCONF3      (0x00000288/4)
                    139: #define GEM_DESCONF4      (0x0000028C/4)
                    140: #define GEM_DESCONF5      (0x00000290/4)
                    141: #define GEM_DESCONF6      (0x00000294/4)
                    142: #define GEM_DESCONF7      (0x00000298/4)
                    143: 
                    144: #define GEM_MAXREG        (0x00000640/4) /* Last valid GEM address */
                    145: 
                    146: /*****************************************/
                    147: #define GEM_NWCTRL_TXSTART     0x00000200 /* Transmit Enable */
                    148: #define GEM_NWCTRL_TXENA       0x00000008 /* Transmit Enable */
                    149: #define GEM_NWCTRL_RXENA       0x00000004 /* Receive Enable */
                    150: #define GEM_NWCTRL_LOCALLOOP   0x00000002 /* Local Loopback */
                    151: 
                    152: #define GEM_NWCFG_STRIP_FCS    0x00020000 /* Strip FCS field */
                    153: #define GEM_NWCFG_LERR_DISC    0x00010000 /* Discard RX frames with lenth err */
                    154: #define GEM_NWCFG_BUFF_OFST_M  0x0000C000 /* Receive buffer offset mask */
                    155: #define GEM_NWCFG_BUFF_OFST_S  14         /* Receive buffer offset shift */
                    156: #define GEM_NWCFG_UCAST_HASH   0x00000080 /* accept unicast if hash match */
                    157: #define GEM_NWCFG_MCAST_HASH   0x00000040 /* accept multicast if hash match */
                    158: #define GEM_NWCFG_BCAST_REJ    0x00000020 /* Reject broadcast packets */
                    159: #define GEM_NWCFG_PROMISC      0x00000010 /* Accept all packets */
                    160: 
                    161: #define GEM_DMACFG_RBUFSZ_M    0x007F0000 /* DMA RX Buffer Size mask */
                    162: #define GEM_DMACFG_RBUFSZ_S    16         /* DMA RX Buffer Size shift */
                    163: #define GEM_DMACFG_RBUFSZ_MUL  64         /* DMA RX Buffer Size multiplier */
                    164: #define GEM_DMACFG_TXCSUM_OFFL 0x00000800 /* Transmit checksum offload */
                    165: 
                    166: #define GEM_TXSTATUS_TXCMPL    0x00000020 /* Transmit Complete */
                    167: #define GEM_TXSTATUS_USED      0x00000001 /* sw owned descriptor encountered */
                    168: 
                    169: #define GEM_RXSTATUS_FRMRCVD   0x00000002 /* Frame received */
                    170: #define GEM_RXSTATUS_NOBUF     0x00000001 /* Buffer unavailable */
                    171: 
                    172: /* GEM_ISR GEM_IER GEM_IDR GEM_IMR */
                    173: #define GEM_INT_TXCMPL        0x00000080 /* Transmit Complete */
                    174: #define GEM_INT_TXUSED         0x00000008
                    175: #define GEM_INT_RXUSED         0x00000004
                    176: #define GEM_INT_RXCMPL        0x00000002
                    177: 
                    178: #define GEM_PHYMNTNC_OP_R      0x20000000 /* read operation */
                    179: #define GEM_PHYMNTNC_OP_W      0x10000000 /* write operation */
                    180: #define GEM_PHYMNTNC_ADDR      0x0F800000 /* Address bits */
                    181: #define GEM_PHYMNTNC_ADDR_SHFT 23
                    182: #define GEM_PHYMNTNC_REG       0x007C0000 /* register bits */
                    183: #define GEM_PHYMNTNC_REG_SHIFT 18
                    184: 
                    185: /* Marvell PHY definitions */
                    186: #define BOARD_PHY_ADDRESS    23 /* PHY address we will emulate a device at */
                    187: 
                    188: #define PHY_REG_CONTROL      0
                    189: #define PHY_REG_STATUS       1
                    190: #define PHY_REG_PHYID1       2
                    191: #define PHY_REG_PHYID2       3
                    192: #define PHY_REG_ANEGADV      4
                    193: #define PHY_REG_LINKPABIL    5
                    194: #define PHY_REG_ANEGEXP      6
                    195: #define PHY_REG_NEXTP        7
                    196: #define PHY_REG_LINKPNEXTP   8
                    197: #define PHY_REG_100BTCTRL    9
                    198: #define PHY_REG_1000BTSTAT   10
                    199: #define PHY_REG_EXTSTAT      15
                    200: #define PHY_REG_PHYSPCFC_CTL 16
                    201: #define PHY_REG_PHYSPCFC_ST  17
                    202: #define PHY_REG_INT_EN       18
                    203: #define PHY_REG_INT_ST       19
                    204: #define PHY_REG_EXT_PHYSPCFC_CTL  20
                    205: #define PHY_REG_RXERR        21
                    206: #define PHY_REG_EACD         22
                    207: #define PHY_REG_LED          24
                    208: #define PHY_REG_LED_OVRD     25
                    209: #define PHY_REG_EXT_PHYSPCFC_CTL2 26
                    210: #define PHY_REG_EXT_PHYSPCFC_ST   27
                    211: #define PHY_REG_CABLE_DIAG   28
                    212: 
                    213: #define PHY_REG_CONTROL_RST  0x8000
                    214: #define PHY_REG_CONTROL_LOOP 0x4000
                    215: #define PHY_REG_CONTROL_ANEG 0x1000
                    216: 
                    217: #define PHY_REG_STATUS_LINK     0x0004
                    218: #define PHY_REG_STATUS_ANEGCMPL 0x0020
                    219: 
                    220: #define PHY_REG_INT_ST_ANEGCMPL 0x0800
                    221: #define PHY_REG_INT_ST_LINKC    0x0400
                    222: #define PHY_REG_INT_ST_ENERGY   0x0010
                    223: 
                    224: /***********************************************************************/
                    225: #define GEM_RX_REJECT  1
                    226: #define GEM_RX_ACCEPT  0
                    227: 
                    228: /***********************************************************************/
                    229: 
                    230: #define DESC_1_USED 0x80000000
                    231: #define DESC_1_LENGTH 0x00001FFF
                    232: 
                    233: #define DESC_1_TX_WRAP 0x40000000
                    234: #define DESC_1_TX_LAST 0x00008000
                    235: 
                    236: #define DESC_0_RX_WRAP 0x00000002
                    237: #define DESC_0_RX_OWNERSHIP 0x00000001
                    238: 
                    239: #define DESC_1_RX_SOF 0x00004000
                    240: #define DESC_1_RX_EOF 0x00008000
                    241: 
                    242: static inline unsigned tx_desc_get_buffer(unsigned *desc)
                    243: {
                    244:     return desc[0];
                    245: }
                    246: 
                    247: static inline unsigned tx_desc_get_used(unsigned *desc)
                    248: {
                    249:     return (desc[1] & DESC_1_USED) ? 1 : 0;
                    250: }
                    251: 
                    252: static inline void tx_desc_set_used(unsigned *desc)
                    253: {
                    254:     desc[1] |= DESC_1_USED;
                    255: }
                    256: 
                    257: static inline unsigned tx_desc_get_wrap(unsigned *desc)
                    258: {
                    259:     return (desc[1] & DESC_1_TX_WRAP) ? 1 : 0;
                    260: }
                    261: 
                    262: static inline unsigned tx_desc_get_last(unsigned *desc)
                    263: {
                    264:     return (desc[1] & DESC_1_TX_LAST) ? 1 : 0;
                    265: }
                    266: 
                    267: static inline unsigned tx_desc_get_length(unsigned *desc)
                    268: {
                    269:     return desc[1] & DESC_1_LENGTH;
                    270: }
                    271: 
                    272: static inline void print_gem_tx_desc(unsigned *desc)
                    273: {
                    274:     DB_PRINT("TXDESC:\n");
                    275:     DB_PRINT("bufaddr: 0x%08x\n", *desc);
                    276:     DB_PRINT("used_hw: %d\n", tx_desc_get_used(desc));
                    277:     DB_PRINT("wrap:    %d\n", tx_desc_get_wrap(desc));
                    278:     DB_PRINT("last:    %d\n", tx_desc_get_last(desc));
                    279:     DB_PRINT("length:  %d\n", tx_desc_get_length(desc));
                    280: }
                    281: 
                    282: static inline unsigned rx_desc_get_buffer(unsigned *desc)
                    283: {
                    284:     return desc[0] & ~0x3UL;
                    285: }
                    286: 
                    287: static inline unsigned rx_desc_get_wrap(unsigned *desc)
                    288: {
                    289:     return desc[0] & DESC_0_RX_WRAP ? 1 : 0;
                    290: }
                    291: 
                    292: static inline unsigned rx_desc_get_ownership(unsigned *desc)
                    293: {
                    294:     return desc[0] & DESC_0_RX_OWNERSHIP ? 1 : 0;
                    295: }
                    296: 
                    297: static inline void rx_desc_set_ownership(unsigned *desc)
                    298: {
                    299:     desc[0] |= DESC_0_RX_OWNERSHIP;
                    300: }
                    301: 
                    302: static inline void rx_desc_set_sof(unsigned *desc)
                    303: {
                    304:     desc[1] |= DESC_1_RX_SOF;
                    305: }
                    306: 
                    307: static inline void rx_desc_set_eof(unsigned *desc)
                    308: {
                    309:     desc[1] |= DESC_1_RX_EOF;
                    310: }
                    311: 
                    312: static inline void rx_desc_set_length(unsigned *desc, unsigned len)
                    313: {
                    314:     desc[1] &= ~DESC_1_LENGTH;
                    315:     desc[1] |= len;
                    316: }
                    317: 
                    318: typedef struct {
                    319:     SysBusDevice busdev;
                    320:     MemoryRegion iomem;
                    321:     NICState *nic;
                    322:     NICConf conf;
                    323:     qemu_irq irq;
                    324: 
                    325:     /* GEM registers backing store */
                    326:     uint32_t regs[GEM_MAXREG];
                    327:     /* Mask of register bits which are write only */
                    328:     uint32_t regs_wo[GEM_MAXREG];
                    329:     /* Mask of register bits which are read only */
                    330:     uint32_t regs_ro[GEM_MAXREG];
                    331:     /* Mask of register bits which are clear on read */
                    332:     uint32_t regs_rtc[GEM_MAXREG];
                    333:     /* Mask of register bits which are write 1 to clear */
                    334:     uint32_t regs_w1c[GEM_MAXREG];
                    335: 
                    336:     /* PHY registers backing store */
                    337:     uint16_t phy_regs[32];
                    338: 
                    339:     uint8_t phy_loop; /* Are we in phy loopback? */
                    340: 
                    341:     /* The current DMA descriptor pointers */
                    342:     target_phys_addr_t rx_desc_addr;
                    343:     target_phys_addr_t tx_desc_addr;
                    344: 
                    345: } GemState;
                    346: 
                    347: /* The broadcast MAC address: 0xFFFFFFFFFFFF */
                    348: const uint8_t broadcast_addr[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
                    349: 
                    350: /*
                    351:  * gem_init_register_masks:
                    352:  * One time initialization.
                    353:  * Set masks to identify which register bits have magical clear properties
                    354:  */
                    355: static void gem_init_register_masks(GemState *s)
                    356: {
                    357:     /* Mask of register bits which are read only*/
                    358:     memset(&s->regs_ro[0], 0, sizeof(s->regs_ro));
                    359:     s->regs_ro[GEM_NWCTRL]   = 0xFFF80000;
                    360:     s->regs_ro[GEM_NWSTATUS] = 0xFFFFFFFF;
                    361:     s->regs_ro[GEM_DMACFG]   = 0xFE00F000;
                    362:     s->regs_ro[GEM_TXSTATUS] = 0xFFFFFE08;
                    363:     s->regs_ro[GEM_RXQBASE]  = 0x00000003;
                    364:     s->regs_ro[GEM_TXQBASE]  = 0x00000003;
                    365:     s->regs_ro[GEM_RXSTATUS] = 0xFFFFFFF0;
                    366:     s->regs_ro[GEM_ISR]      = 0xFFFFFFFF;
                    367:     s->regs_ro[GEM_IMR]      = 0xFFFFFFFF;
                    368:     s->regs_ro[GEM_MODID]    = 0xFFFFFFFF;
                    369: 
                    370:     /* Mask of register bits which are clear on read */
                    371:     memset(&s->regs_rtc[0], 0, sizeof(s->regs_rtc));
                    372:     s->regs_rtc[GEM_ISR]      = 0xFFFFFFFF;
                    373: 
                    374:     /* Mask of register bits which are write 1 to clear */
                    375:     memset(&s->regs_w1c[0], 0, sizeof(s->regs_w1c));
                    376:     s->regs_w1c[GEM_TXSTATUS] = 0x000001F7;
                    377:     s->regs_w1c[GEM_RXSTATUS] = 0x0000000F;
                    378: 
                    379:     /* Mask of register bits which are write only */
                    380:     memset(&s->regs_wo[0], 0, sizeof(s->regs_wo));
                    381:     s->regs_wo[GEM_NWCTRL]   = 0x00073E60;
                    382:     s->regs_wo[GEM_IER]      = 0x07FFFFFF;
                    383:     s->regs_wo[GEM_IDR]      = 0x07FFFFFF;
                    384: }
                    385: 
                    386: /*
                    387:  * phy_update_link:
                    388:  * Make the emulated PHY link state match the QEMU "interface" state.
                    389:  */
                    390: static void phy_update_link(GemState *s)
                    391: {
                    392:     DB_PRINT("down %d\n", s->nic->nc.link_down);
                    393: 
                    394:     /* Autonegotiation status mirrors link status.  */
                    395:     if (s->nic->nc.link_down) {
                    396:         s->phy_regs[PHY_REG_STATUS] &= ~(PHY_REG_STATUS_ANEGCMPL |
                    397:                                          PHY_REG_STATUS_LINK);
                    398:         s->phy_regs[PHY_REG_INT_ST] |= PHY_REG_INT_ST_LINKC;
                    399:     } else {
                    400:         s->phy_regs[PHY_REG_STATUS] |= (PHY_REG_STATUS_ANEGCMPL |
                    401:                                          PHY_REG_STATUS_LINK);
                    402:         s->phy_regs[PHY_REG_INT_ST] |= (PHY_REG_INT_ST_LINKC |
                    403:                                         PHY_REG_INT_ST_ANEGCMPL |
                    404:                                         PHY_REG_INT_ST_ENERGY);
                    405:     }
                    406: }
                    407: 
                    408: static int gem_can_receive(VLANClientState *nc)
                    409: {
                    410:     GemState *s;
                    411: 
                    412:     s = DO_UPCAST(NICState, nc, nc)->opaque;
                    413: 
                    414:     DB_PRINT("\n");
                    415: 
                    416:     /* Do nothing if receive is not enabled. */
                    417:     if (!(s->regs[GEM_NWCTRL] & GEM_NWCTRL_RXENA)) {
                    418:         return 0;
                    419:     }
                    420: 
                    421:     return 1;
                    422: }
                    423: 
                    424: /*
                    425:  * gem_update_int_status:
                    426:  * Raise or lower interrupt based on current status.
                    427:  */
                    428: static void gem_update_int_status(GemState *s)
                    429: {
                    430:     uint32_t new_interrupts = 0;
                    431:     /* Packet transmitted ? */
                    432:     if (s->regs[GEM_TXSTATUS] & GEM_TXSTATUS_TXCMPL) {
                    433:         new_interrupts |= GEM_INT_TXCMPL;
                    434:     }
                    435:     /* End of TX ring ? */
                    436:     if (s->regs[GEM_TXSTATUS] & GEM_TXSTATUS_USED) {
                    437:         new_interrupts |= GEM_INT_TXUSED;
                    438:     }
                    439: 
                    440:     /* Frame received ? */
                    441:     if (s->regs[GEM_RXSTATUS] & GEM_RXSTATUS_FRMRCVD) {
                    442:         new_interrupts |= GEM_INT_RXCMPL;
                    443:     }
                    444:     /* RX ring full ? */
                    445:     if (s->regs[GEM_RXSTATUS] & GEM_RXSTATUS_NOBUF) {
                    446:         new_interrupts |= GEM_INT_RXUSED;
                    447:     }
                    448: 
                    449:     s->regs[GEM_ISR] |= new_interrupts & ~(s->regs[GEM_IMR]);
                    450: 
                    451:     if (s->regs[GEM_ISR]) {
                    452:         DB_PRINT("asserting int. (0x%08x)\n", s->regs[GEM_ISR]);
                    453:         qemu_set_irq(s->irq, 1);
                    454:     } else {
                    455:         qemu_set_irq(s->irq, 0);
                    456:     }
                    457: }
                    458: 
                    459: /*
                    460:  * gem_receive_updatestats:
                    461:  * Increment receive statistics.
                    462:  */
                    463: static void gem_receive_updatestats(GemState *s, const uint8_t *packet,
                    464:                                     unsigned bytes)
                    465: {
                    466:     uint64_t octets;
                    467: 
                    468:     /* Total octets (bytes) received */
                    469:     octets = ((uint64_t)(s->regs[GEM_OCTRXLO]) << 32) |
                    470:              s->regs[GEM_OCTRXHI];
                    471:     octets += bytes;
                    472:     s->regs[GEM_OCTRXLO] = octets >> 32;
                    473:     s->regs[GEM_OCTRXHI] = octets;
                    474: 
                    475:     /* Error-free Frames received */
                    476:     s->regs[GEM_RXCNT]++;
                    477: 
                    478:     /* Error-free Broadcast Frames counter */
                    479:     if (!memcmp(packet, broadcast_addr, 6)) {
                    480:         s->regs[GEM_RXBROADCNT]++;
                    481:     }
                    482: 
                    483:     /* Error-free Multicast Frames counter */
                    484:     if (packet[0] == 0x01) {
                    485:         s->regs[GEM_RXMULTICNT]++;
                    486:     }
                    487: 
                    488:     if (bytes <= 64) {
                    489:         s->regs[GEM_RX64CNT]++;
                    490:     } else if (bytes <= 127) {
                    491:         s->regs[GEM_RX65CNT]++;
                    492:     } else if (bytes <= 255) {
                    493:         s->regs[GEM_RX128CNT]++;
                    494:     } else if (bytes <= 511) {
                    495:         s->regs[GEM_RX256CNT]++;
                    496:     } else if (bytes <= 1023) {
                    497:         s->regs[GEM_RX512CNT]++;
                    498:     } else if (bytes <= 1518) {
                    499:         s->regs[GEM_RX1024CNT]++;
                    500:     } else {
                    501:         s->regs[GEM_RX1519CNT]++;
                    502:     }
                    503: }
                    504: 
                    505: /*
                    506:  * Get the MAC Address bit from the specified position
                    507:  */
                    508: static unsigned get_bit(const uint8_t *mac, unsigned bit)
                    509: {
                    510:     unsigned byte;
                    511: 
                    512:     byte = mac[bit / 8];
                    513:     byte >>= (bit & 0x7);
                    514:     byte &= 1;
                    515: 
                    516:     return byte;
                    517: }
                    518: 
                    519: /*
                    520:  * Calculate a GEM MAC Address hash index
                    521:  */
                    522: static unsigned calc_mac_hash(const uint8_t *mac)
                    523: {
                    524:     int index_bit, mac_bit;
                    525:     unsigned hash_index;
                    526: 
                    527:     hash_index = 0;
                    528:     mac_bit = 5;
                    529:     for (index_bit = 5; index_bit >= 0; index_bit--) {
                    530:         hash_index |= (get_bit(mac,  mac_bit) ^
                    531:                                get_bit(mac, mac_bit + 6) ^
                    532:                                get_bit(mac, mac_bit + 12) ^
                    533:                                get_bit(mac, mac_bit + 18) ^
                    534:                                get_bit(mac, mac_bit + 24) ^
                    535:                                get_bit(mac, mac_bit + 30) ^
                    536:                                get_bit(mac, mac_bit + 36) ^
                    537:                                get_bit(mac, mac_bit + 42)) << index_bit;
                    538:         mac_bit--;
                    539:     }
                    540: 
                    541:     return hash_index;
                    542: }
                    543: 
                    544: /*
                    545:  * gem_mac_address_filter:
                    546:  * Accept or reject this destination address?
                    547:  * Returns:
                    548:  * GEM_RX_REJECT: reject
                    549:  * GEM_RX_ACCEPT: accept
                    550:  */
                    551: static int gem_mac_address_filter(GemState *s, const uint8_t *packet)
                    552: {
                    553:     uint8_t *gem_spaddr;
                    554:     int i;
                    555: 
                    556:     /* Promiscuous mode? */
                    557:     if (s->regs[GEM_NWCFG] & GEM_NWCFG_PROMISC) {
                    558:         return GEM_RX_ACCEPT;
                    559:     }
                    560: 
                    561:     if (!memcmp(packet, broadcast_addr, 6)) {
                    562:         /* Reject broadcast packets? */
                    563:         if (s->regs[GEM_NWCFG] & GEM_NWCFG_BCAST_REJ) {
                    564:             return GEM_RX_REJECT;
                    565:         }
                    566:         return GEM_RX_ACCEPT;
                    567:     }
                    568: 
                    569:     /* Accept packets -w- hash match? */
                    570:     if ((packet[0] == 0x01 && (s->regs[GEM_NWCFG] & GEM_NWCFG_MCAST_HASH)) ||
                    571:         (packet[0] != 0x01 && (s->regs[GEM_NWCFG] & GEM_NWCFG_UCAST_HASH))) {
                    572:         unsigned hash_index;
                    573: 
                    574:         hash_index = calc_mac_hash(packet);
                    575:         if (hash_index < 32) {
                    576:             if (s->regs[GEM_HASHLO] & (1<<hash_index)) {
                    577:                 return GEM_RX_ACCEPT;
                    578:             }
                    579:         } else {
                    580:             hash_index -= 32;
                    581:             if (s->regs[GEM_HASHHI] & (1<<hash_index)) {
                    582:                 return GEM_RX_ACCEPT;
                    583:             }
                    584:         }
                    585:     }
                    586: 
                    587:     /* Check all 4 specific addresses */
                    588:     gem_spaddr = (uint8_t *)&(s->regs[GEM_SPADDR1LO]);
                    589:     for (i = 0; i < 4; i++) {
                    590:         if (!memcmp(packet, gem_spaddr, 6)) {
                    591:             return GEM_RX_ACCEPT;
                    592:         }
                    593: 
                    594:         gem_spaddr += 8;
                    595:     }
                    596: 
                    597:     /* No address match; reject the packet */
                    598:     return GEM_RX_REJECT;
                    599: }
                    600: 
                    601: /*
                    602:  * gem_receive:
                    603:  * Fit a packet handed to us by QEMU into the receive descriptor ring.
                    604:  */
                    605: static ssize_t gem_receive(VLANClientState *nc, const uint8_t *buf, size_t size)
                    606: {
                    607:     unsigned    desc[2];
                    608:     target_phys_addr_t packet_desc_addr, last_desc_addr;
                    609:     GemState *s;
                    610:     unsigned   rxbufsize, bytes_to_copy;
                    611:     unsigned   rxbuf_offset;
                    612:     uint8_t    rxbuf[2048];
                    613:     uint8_t   *rxbuf_ptr;
                    614: 
                    615:     s = DO_UPCAST(NICState, nc, nc)->opaque;
                    616: 
                    617:     /* Do nothing if receive is not enabled. */
                    618:     if (!(s->regs[GEM_NWCTRL] & GEM_NWCTRL_RXENA)) {
                    619:         return -1;
                    620:     }
                    621: 
                    622:     /* Is this destination MAC address "for us" ? */
                    623:     if (gem_mac_address_filter(s, buf) == GEM_RX_REJECT) {
                    624:         return -1;
                    625:     }
                    626: 
                    627:     /* Discard packets with receive length error enabled ? */
                    628:     if (s->regs[GEM_NWCFG] & GEM_NWCFG_LERR_DISC) {
                    629:         unsigned type_len;
                    630: 
                    631:         /* Fish the ethertype / length field out of the RX packet */
                    632:         type_len = buf[12] << 8 | buf[13];
                    633:         /* It is a length field, not an ethertype */
                    634:         if (type_len < 0x600) {
                    635:             if (size < type_len) {
                    636:                 /* discard */
                    637:                 return -1;
                    638:             }
                    639:         }
                    640:     }
                    641: 
                    642:     /*
                    643:      * Determine configured receive buffer offset (probably 0)
                    644:      */
                    645:     rxbuf_offset = (s->regs[GEM_NWCFG] & GEM_NWCFG_BUFF_OFST_M) >>
                    646:                    GEM_NWCFG_BUFF_OFST_S;
                    647: 
                    648:     /* The configure size of each receive buffer.  Determines how many
                    649:      * buffers needed to hold this packet.
                    650:      */
                    651:     rxbufsize = ((s->regs[GEM_DMACFG] & GEM_DMACFG_RBUFSZ_M) >>
                    652:                  GEM_DMACFG_RBUFSZ_S) * GEM_DMACFG_RBUFSZ_MUL;
                    653:     bytes_to_copy = size;
                    654: 
                    655:     /* Strip of FCS field ? (usually yes) */
                    656:     if (s->regs[GEM_NWCFG] & GEM_NWCFG_STRIP_FCS) {
                    657:         rxbuf_ptr = (void *)buf;
                    658:     } else {
                    659:         unsigned crc_val;
                    660:         int      crc_offset;
                    661: 
                    662:         /* The application wants the FCS field, which QEMU does not provide.
                    663:          * We must try and caclculate one.
                    664:          */
                    665: 
                    666:         memcpy(rxbuf, buf, size);
                    667:         memset(rxbuf + size, 0, sizeof(rxbuf - size));
                    668:         rxbuf_ptr = rxbuf;
                    669:         crc_val = cpu_to_le32(crc32(0, rxbuf, MAX(size, 60)));
                    670:         if (size < 60) {
                    671:             crc_offset = 60;
                    672:         } else {
                    673:             crc_offset = size;
                    674:         }
                    675:         memcpy(rxbuf + crc_offset, &crc_val, sizeof(crc_val));
                    676: 
                    677:         bytes_to_copy += 4;
                    678:         size += 4;
                    679:     }
                    680: 
                    681:     /* Pad to minimum length */
                    682:     if (size < 64) {
                    683:         size = 64;
                    684:     }
                    685: 
                    686:     DB_PRINT("config bufsize: %d packet size: %ld\n", rxbufsize, size);
                    687: 
                    688:     packet_desc_addr = s->rx_desc_addr;
                    689:     while (1) {
                    690:         DB_PRINT("read descriptor 0x%x\n", packet_desc_addr);
                    691:         /* read current descriptor */
                    692:         cpu_physical_memory_read(packet_desc_addr,
                    693:                                  (uint8_t *)&desc[0], sizeof(desc));
                    694: 
                    695:         /* Descriptor owned by software ? */
                    696:         if (rx_desc_get_ownership(desc) == 1) {
                    697:             DB_PRINT("descriptor 0x%x owned by sw.\n", packet_desc_addr);
                    698:             s->regs[GEM_RXSTATUS] |= GEM_RXSTATUS_NOBUF;
                    699:             /* Handle interrupt consequences */
                    700:             gem_update_int_status(s);
                    701:             return -1;
                    702:         }
                    703: 
                    704:         DB_PRINT("copy %d bytes to 0x%x\n", MIN(bytes_to_copy, rxbufsize),
                    705:                 rx_desc_get_buffer(desc));
                    706: 
                    707:         /*
                    708:          * Let's have QEMU lend a helping hand.
                    709:          */
                    710:         if (rx_desc_get_buffer(desc) == 0) {
                    711:             DB_PRINT("Invalid RX buffer (NULL) for descriptor 0x%x\n",
                    712:                        packet_desc_addr);
                    713:             break;
                    714:         }
                    715: 
                    716:         /* Copy packet data to emulated DMA buffer */
                    717:         cpu_physical_memory_write(rx_desc_get_buffer(desc) + rxbuf_offset,
                    718:                                   rxbuf_ptr, MIN(bytes_to_copy, rxbufsize));
                    719:         bytes_to_copy -= MIN(bytes_to_copy, rxbufsize);
                    720:         rxbuf_ptr += MIN(bytes_to_copy, rxbufsize);
                    721:         if (bytes_to_copy == 0) {
                    722:             break;
                    723:         }
                    724: 
                    725:         /* Next descriptor */
                    726:         if (rx_desc_get_wrap(desc)) {
                    727:             packet_desc_addr = s->regs[GEM_RXQBASE];
                    728:         } else {
                    729:             packet_desc_addr += 8;
                    730:         }
                    731:     }
                    732: 
                    733:     DB_PRINT("set length: %ld, EOF on descriptor 0x%x\n", size,
                    734:             (unsigned)packet_desc_addr);
                    735: 
                    736:     /* Update last descriptor with EOF and total length */
                    737:     rx_desc_set_eof(desc);
                    738:     rx_desc_set_length(desc, size);
                    739:     cpu_physical_memory_write(packet_desc_addr,
                    740:                               (uint8_t *)&desc[0], sizeof(desc));
                    741: 
                    742:     /* Advance RX packet descriptor Q */
                    743:     last_desc_addr = packet_desc_addr;
                    744:     packet_desc_addr = s->rx_desc_addr;
                    745:     s->rx_desc_addr = last_desc_addr;
                    746:     if (rx_desc_get_wrap(desc)) {
                    747:         s->rx_desc_addr = s->regs[GEM_RXQBASE];
                    748:     } else {
                    749:         s->rx_desc_addr += 8;
                    750:     }
                    751: 
                    752:     DB_PRINT("set SOF, OWN on descriptor 0x%08x\n", packet_desc_addr);
                    753: 
                    754:     /* Count it */
                    755:     gem_receive_updatestats(s, buf, size);
                    756: 
                    757:     /* Update first descriptor (which could also be the last) */
                    758:     /* read descriptor */
                    759:     cpu_physical_memory_read(packet_desc_addr,
                    760:                              (uint8_t *)&desc[0], sizeof(desc));
                    761:     rx_desc_set_sof(desc);
                    762:     rx_desc_set_ownership(desc);
                    763:     cpu_physical_memory_write(packet_desc_addr,
                    764:                               (uint8_t *)&desc[0], sizeof(desc));
                    765: 
                    766:     s->regs[GEM_RXSTATUS] |= GEM_RXSTATUS_FRMRCVD;
                    767: 
                    768:     /* Handle interrupt consequences */
                    769:     gem_update_int_status(s);
                    770: 
                    771:     return size;
                    772: }
                    773: 
                    774: /*
                    775:  * gem_transmit_updatestats:
                    776:  * Increment transmit statistics.
                    777:  */
                    778: static void gem_transmit_updatestats(GemState *s, const uint8_t *packet,
                    779:                                      unsigned bytes)
                    780: {
                    781:     uint64_t octets;
                    782: 
                    783:     /* Total octets (bytes) transmitted */
                    784:     octets = ((uint64_t)(s->regs[GEM_OCTTXLO]) << 32) |
                    785:              s->regs[GEM_OCTTXHI];
                    786:     octets += bytes;
                    787:     s->regs[GEM_OCTTXLO] = octets >> 32;
                    788:     s->regs[GEM_OCTTXHI] = octets;
                    789: 
                    790:     /* Error-free Frames transmitted */
                    791:     s->regs[GEM_TXCNT]++;
                    792: 
                    793:     /* Error-free Broadcast Frames counter */
                    794:     if (!memcmp(packet, broadcast_addr, 6)) {
                    795:         s->regs[GEM_TXBCNT]++;
                    796:     }
                    797: 
                    798:     /* Error-free Multicast Frames counter */
                    799:     if (packet[0] == 0x01) {
                    800:         s->regs[GEM_TXMCNT]++;
                    801:     }
                    802: 
                    803:     if (bytes <= 64) {
                    804:         s->regs[GEM_TX64CNT]++;
                    805:     } else if (bytes <= 127) {
                    806:         s->regs[GEM_TX65CNT]++;
                    807:     } else if (bytes <= 255) {
                    808:         s->regs[GEM_TX128CNT]++;
                    809:     } else if (bytes <= 511) {
                    810:         s->regs[GEM_TX256CNT]++;
                    811:     } else if (bytes <= 1023) {
                    812:         s->regs[GEM_TX512CNT]++;
                    813:     } else if (bytes <= 1518) {
                    814:         s->regs[GEM_TX1024CNT]++;
                    815:     } else {
                    816:         s->regs[GEM_TX1519CNT]++;
                    817:     }
                    818: }
                    819: 
                    820: /*
                    821:  * gem_transmit:
                    822:  * Fish packets out of the descriptor ring and feed them to QEMU
                    823:  */
                    824: static void gem_transmit(GemState *s)
                    825: {
                    826:     unsigned    desc[2];
                    827:     target_phys_addr_t packet_desc_addr;
                    828:     uint8_t     tx_packet[2048];
                    829:     uint8_t     *p;
                    830:     unsigned    total_bytes;
                    831: 
                    832:     /* Do nothing if transmit is not enabled. */
                    833:     if (!(s->regs[GEM_NWCTRL] & GEM_NWCTRL_TXENA)) {
                    834:         return;
                    835:     }
                    836: 
                    837:     DB_PRINT("\n");
                    838: 
                    839:     /* The packet we will hand off to qemu.
                    840:      * Packets scattered across multiple descriptors are gathered to this
                    841:      * one contiguous buffer first.
                    842:      */
                    843:     p = tx_packet;
                    844:     total_bytes = 0;
                    845: 
                    846:     /* read current descriptor */
                    847:     packet_desc_addr = s->tx_desc_addr;
                    848:     cpu_physical_memory_read(packet_desc_addr,
                    849:                              (uint8_t *)&desc[0], sizeof(desc));
                    850:     /* Handle all descriptors owned by hardware */
                    851:     while (tx_desc_get_used(desc) == 0) {
                    852: 
                    853:         /* Do nothing if transmit is not enabled. */
                    854:         if (!(s->regs[GEM_NWCTRL] & GEM_NWCTRL_TXENA)) {
                    855:             return;
                    856:         }
                    857:         print_gem_tx_desc(desc);
                    858: 
                    859:         /* The real hardware would eat this (and possibly crash).
                    860:          * For QEMU let's lend a helping hand.
                    861:          */
                    862:         if ((tx_desc_get_buffer(desc) == 0) ||
                    863:             (tx_desc_get_length(desc) == 0)) {
                    864:             DB_PRINT("Invalid TX descriptor @ 0x%x\n", packet_desc_addr);
                    865:             break;
                    866:         }
                    867: 
                    868:         /* Gather this fragment of the packet from "dma memory" to our contig.
                    869:          * buffer.
                    870:          */
                    871:         cpu_physical_memory_read(tx_desc_get_buffer(desc), p,
                    872:                                  tx_desc_get_length(desc));
                    873:         p += tx_desc_get_length(desc);
                    874:         total_bytes += tx_desc_get_length(desc);
                    875: 
                    876:         /* Last descriptor for this packet; hand the whole thing off */
                    877:         if (tx_desc_get_last(desc)) {
                    878:             /* Modify the 1st descriptor of this packet to be owned by
                    879:              * the processor.
                    880:              */
                    881:             cpu_physical_memory_read(s->tx_desc_addr,
                    882:                                      (uint8_t *)&desc[0], sizeof(desc));
                    883:             tx_desc_set_used(desc);
                    884:             cpu_physical_memory_write(s->tx_desc_addr,
                    885:                                       (uint8_t *)&desc[0], sizeof(desc));
                    886:             /* Advance the hardare current descriptor past this packet */
                    887:             if (tx_desc_get_wrap(desc)) {
                    888:                 s->tx_desc_addr = s->regs[GEM_TXQBASE];
                    889:             } else {
                    890:                 s->tx_desc_addr = packet_desc_addr + 8;
                    891:             }
                    892:             DB_PRINT("TX descriptor next: 0x%08x\n", s->tx_desc_addr);
                    893: 
                    894:             s->regs[GEM_TXSTATUS] |= GEM_TXSTATUS_TXCMPL;
                    895: 
                    896:             /* Handle interrupt consequences */
                    897:             gem_update_int_status(s);
                    898: 
                    899:             /* Is checksum offload enabled? */
                    900:             if (s->regs[GEM_DMACFG] & GEM_DMACFG_TXCSUM_OFFL) {
                    901:                 net_checksum_calculate(tx_packet, total_bytes);
                    902:             }
                    903: 
                    904:             /* Update MAC statistics */
                    905:             gem_transmit_updatestats(s, tx_packet, total_bytes);
                    906: 
                    907:             /* Send the packet somewhere */
                    908:             if (s->phy_loop) {
                    909:                 gem_receive(&s->nic->nc, tx_packet, total_bytes);
                    910:             } else {
                    911:                 qemu_send_packet(&s->nic->nc, tx_packet, total_bytes);
                    912:             }
                    913: 
                    914:             /* Prepare for next packet */
                    915:             p = tx_packet;
                    916:             total_bytes = 0;
                    917:         }
                    918: 
                    919:         /* read next descriptor */
                    920:         if (tx_desc_get_wrap(desc)) {
                    921:             packet_desc_addr = s->regs[GEM_TXQBASE];
                    922:         } else {
                    923:             packet_desc_addr += 8;
                    924:         }
                    925:         cpu_physical_memory_read(packet_desc_addr,
                    926:                                  (uint8_t *)&desc[0], sizeof(desc));
                    927:     }
                    928: 
                    929:     if (tx_desc_get_used(desc)) {
                    930:         s->regs[GEM_TXSTATUS] |= GEM_TXSTATUS_USED;
                    931:         gem_update_int_status(s);
                    932:     }
                    933: }
                    934: 
                    935: static void gem_phy_reset(GemState *s)
                    936: {
                    937:     memset(&s->phy_regs[0], 0, sizeof(s->phy_regs));
                    938:     s->phy_regs[PHY_REG_CONTROL] = 0x1140;
                    939:     s->phy_regs[PHY_REG_STATUS] = 0x7969;
                    940:     s->phy_regs[PHY_REG_PHYID1] = 0x0141;
                    941:     s->phy_regs[PHY_REG_PHYID2] = 0x0CC2;
                    942:     s->phy_regs[PHY_REG_ANEGADV] = 0x01E1;
                    943:     s->phy_regs[PHY_REG_LINKPABIL] = 0xCDE1;
                    944:     s->phy_regs[PHY_REG_ANEGEXP] = 0x000F;
                    945:     s->phy_regs[PHY_REG_NEXTP] = 0x2001;
                    946:     s->phy_regs[PHY_REG_LINKPNEXTP] = 0x40E6;
                    947:     s->phy_regs[PHY_REG_100BTCTRL] = 0x0300;
                    948:     s->phy_regs[PHY_REG_1000BTSTAT] = 0x7C00;
                    949:     s->phy_regs[PHY_REG_EXTSTAT] = 0x3000;
                    950:     s->phy_regs[PHY_REG_PHYSPCFC_CTL] = 0x0078;
                    951:     s->phy_regs[PHY_REG_PHYSPCFC_ST] = 0xBC00;
                    952:     s->phy_regs[PHY_REG_EXT_PHYSPCFC_CTL] = 0x0C60;
                    953:     s->phy_regs[PHY_REG_LED] = 0x4100;
                    954:     s->phy_regs[PHY_REG_EXT_PHYSPCFC_CTL2] = 0x000A;
                    955:     s->phy_regs[PHY_REG_EXT_PHYSPCFC_ST] = 0x848B;
                    956: 
                    957:     phy_update_link(s);
                    958: }
                    959: 
                    960: static void gem_reset(DeviceState *d)
                    961: {
                    962:     GemState *s = FROM_SYSBUS(GemState, sysbus_from_qdev(d));
                    963: 
                    964:     DB_PRINT("\n");
                    965: 
                    966:     /* Set post reset register values */
                    967:     memset(&s->regs[0], 0, sizeof(s->regs));
                    968:     s->regs[GEM_NWCFG] = 0x00080000;
                    969:     s->regs[GEM_NWSTATUS] = 0x00000006;
                    970:     s->regs[GEM_DMACFG] = 0x00020784;
                    971:     s->regs[GEM_IMR] = 0x07ffffff;
                    972:     s->regs[GEM_TXPAUSE] = 0x0000ffff;
                    973:     s->regs[GEM_TXPARTIALSF] = 0x000003ff;
                    974:     s->regs[GEM_RXPARTIALSF] = 0x000003ff;
                    975:     s->regs[GEM_MODID] = 0x00020118;
                    976:     s->regs[GEM_DESCONF] = 0x02500111;
                    977:     s->regs[GEM_DESCONF2] = 0x2ab13fff;
                    978:     s->regs[GEM_DESCONF5] = 0x002f2145;
                    979:     s->regs[GEM_DESCONF6] = 0x00000200;
                    980: 
                    981:     gem_phy_reset(s);
                    982: 
                    983:     gem_update_int_status(s);
                    984: }
                    985: 
                    986: static uint16_t gem_phy_read(GemState *s, unsigned reg_num)
                    987: {
                    988:     DB_PRINT("reg: %d value: 0x%04x\n", reg_num, s->phy_regs[reg_num]);
                    989:     return s->phy_regs[reg_num];
                    990: }
                    991: 
                    992: static void gem_phy_write(GemState *s, unsigned reg_num, uint16_t val)
                    993: {
                    994:     DB_PRINT("reg: %d value: 0x%04x\n", reg_num, val);
                    995: 
                    996:     switch (reg_num) {
                    997:     case PHY_REG_CONTROL:
                    998:         if (val & PHY_REG_CONTROL_RST) {
                    999:             /* Phy reset */
                   1000:             gem_phy_reset(s);
                   1001:             val &= ~(PHY_REG_CONTROL_RST | PHY_REG_CONTROL_LOOP);
                   1002:             s->phy_loop = 0;
                   1003:         }
                   1004:         if (val & PHY_REG_CONTROL_ANEG) {
                   1005:             /* Complete autonegotiation immediately */
                   1006:             val &= ~PHY_REG_CONTROL_ANEG;
                   1007:             s->phy_regs[PHY_REG_STATUS] |= PHY_REG_STATUS_ANEGCMPL;
                   1008:         }
                   1009:         if (val & PHY_REG_CONTROL_LOOP) {
                   1010:             DB_PRINT("PHY placed in loopback\n");
                   1011:             s->phy_loop = 1;
                   1012:         } else {
                   1013:             s->phy_loop = 0;
                   1014:         }
                   1015:         break;
                   1016:     }
                   1017:     s->phy_regs[reg_num] = val;
                   1018: }
                   1019: 
                   1020: /*
                   1021:  * gem_read32:
                   1022:  * Read a GEM register.
                   1023:  */
                   1024: static uint64_t gem_read(void *opaque, target_phys_addr_t offset, unsigned size)
                   1025: {
                   1026:     GemState *s;
                   1027:     uint32_t retval;
                   1028: 
                   1029:     s = (GemState *)opaque;
                   1030: 
                   1031:     offset >>= 2;
                   1032:     retval = s->regs[offset];
                   1033: 
                   1034:     DB_PRINT("offset: 0x%04x read: 0x%08x\n", offset*4, retval);
                   1035: 
                   1036:     switch (offset) {
                   1037:     case GEM_ISR:
                   1038:         qemu_set_irq(s->irq, 0);
                   1039:         break;
                   1040:     case GEM_PHYMNTNC:
                   1041:         if (retval & GEM_PHYMNTNC_OP_R) {
                   1042:             uint32_t phy_addr, reg_num;
                   1043: 
                   1044:             phy_addr = (retval & GEM_PHYMNTNC_ADDR) >> GEM_PHYMNTNC_ADDR_SHFT;
                   1045:             if (phy_addr == BOARD_PHY_ADDRESS) {
                   1046:                 reg_num = (retval & GEM_PHYMNTNC_REG) >> GEM_PHYMNTNC_REG_SHIFT;
                   1047:                 retval &= 0xFFFF0000;
                   1048:                 retval |= gem_phy_read(s, reg_num);
                   1049:             } else {
                   1050:                 retval |= 0xFFFF; /* No device at this address */
                   1051:             }
                   1052:         }
                   1053:         break;
                   1054:     }
                   1055: 
                   1056:     /* Squash read to clear bits */
                   1057:     s->regs[offset] &= ~(s->regs_rtc[offset]);
                   1058: 
                   1059:     /* Do not provide write only bits */
                   1060:     retval &= ~(s->regs_wo[offset]);
                   1061: 
                   1062:     DB_PRINT("0x%08x\n", retval);
                   1063:     return retval;
                   1064: }
                   1065: 
                   1066: /*
                   1067:  * gem_write32:
                   1068:  * Write a GEM register.
                   1069:  */
                   1070: static void gem_write(void *opaque, target_phys_addr_t offset, uint64_t val,
                   1071:         unsigned size)
                   1072: {
                   1073:     GemState *s = (GemState *)opaque;
                   1074:     uint32_t readonly;
                   1075: 
                   1076:     DB_PRINT("offset: 0x%04x write: 0x%08x ", offset, (unsigned)val);
                   1077:     offset >>= 2;
                   1078: 
                   1079:     /* Squash bits which are read only in write value */
                   1080:     val &= ~(s->regs_ro[offset]);
                   1081:     /* Preserve (only) bits which are read only in register */
                   1082:     readonly = s->regs[offset];
                   1083:     readonly &= s->regs_ro[offset];
                   1084: 
                   1085:     /* Squash bits which are write 1 to clear */
                   1086:     val &= ~(s->regs_w1c[offset] & val);
                   1087: 
                   1088:     /* Copy register write to backing store */
                   1089:     s->regs[offset] = val | readonly;
                   1090: 
                   1091:     /* Handle register write side effects */
                   1092:     switch (offset) {
                   1093:     case GEM_NWCTRL:
                   1094:         if (val & GEM_NWCTRL_TXSTART) {
                   1095:             gem_transmit(s);
                   1096:         }
                   1097:         if (!(val & GEM_NWCTRL_TXENA)) {
                   1098:             /* Reset to start of Q when transmit disabled. */
                   1099:             s->tx_desc_addr = s->regs[GEM_TXQBASE];
                   1100:         }
                   1101:         if (!(val & GEM_NWCTRL_RXENA)) {
                   1102:             /* Reset to start of Q when receive disabled. */
                   1103:             s->rx_desc_addr = s->regs[GEM_RXQBASE];
                   1104:         }
                   1105:         break;
                   1106: 
                   1107:     case GEM_TXSTATUS:
                   1108:         gem_update_int_status(s);
                   1109:         break;
                   1110:     case GEM_RXQBASE:
                   1111:         s->rx_desc_addr = val;
                   1112:         break;
                   1113:     case GEM_TXQBASE:
                   1114:         s->tx_desc_addr = val;
                   1115:         break;
                   1116:     case GEM_RXSTATUS:
                   1117:         gem_update_int_status(s);
                   1118:         break;
                   1119:     case GEM_IER:
                   1120:         s->regs[GEM_IMR] &= ~val;
                   1121:         gem_update_int_status(s);
                   1122:         break;
                   1123:     case GEM_IDR:
                   1124:         s->regs[GEM_IMR] |= val;
                   1125:         gem_update_int_status(s);
                   1126:         break;
                   1127:     case GEM_PHYMNTNC:
                   1128:         if (val & GEM_PHYMNTNC_OP_W) {
                   1129:             uint32_t phy_addr, reg_num;
                   1130: 
                   1131:             phy_addr = (val & GEM_PHYMNTNC_ADDR) >> GEM_PHYMNTNC_ADDR_SHFT;
                   1132:             if (phy_addr == BOARD_PHY_ADDRESS) {
                   1133:                 reg_num = (val & GEM_PHYMNTNC_REG) >> GEM_PHYMNTNC_REG_SHIFT;
                   1134:                 gem_phy_write(s, reg_num, val);
                   1135:             }
                   1136:         }
                   1137:         break;
                   1138:     }
                   1139: 
                   1140:     DB_PRINT("newval: 0x%08x\n", s->regs[offset]);
                   1141: }
                   1142: 
                   1143: static const MemoryRegionOps gem_ops = {
                   1144:     .read = gem_read,
                   1145:     .write = gem_write,
                   1146:     .endianness = DEVICE_LITTLE_ENDIAN,
                   1147: };
                   1148: 
                   1149: static void gem_cleanup(VLANClientState *nc)
                   1150: {
                   1151:     GemState *s = DO_UPCAST(NICState, nc, nc)->opaque;
                   1152: 
                   1153:     DB_PRINT("\n");
                   1154:     s->nic = NULL;
                   1155: }
                   1156: 
                   1157: static void gem_set_link(VLANClientState *nc)
                   1158: {
                   1159:     DB_PRINT("\n");
                   1160:     phy_update_link(DO_UPCAST(NICState, nc, nc)->opaque);
                   1161: }
                   1162: 
                   1163: static NetClientInfo net_gem_info = {
                   1164:     .type = NET_CLIENT_TYPE_NIC,
                   1165:     .size = sizeof(NICState),
                   1166:     .can_receive = gem_can_receive,
                   1167:     .receive = gem_receive,
                   1168:     .cleanup = gem_cleanup,
                   1169:     .link_status_changed = gem_set_link,
                   1170: };
                   1171: 
                   1172: static int gem_init(SysBusDevice *dev)
                   1173: {
                   1174:     GemState *s;
                   1175: 
                   1176:     DB_PRINT("\n");
                   1177: 
                   1178:     s = FROM_SYSBUS(GemState, dev);
                   1179:     gem_init_register_masks(s);
                   1180:     memory_region_init_io(&s->iomem, &gem_ops, s, "enet", sizeof(s->regs));
                   1181:     sysbus_init_mmio(dev, &s->iomem);
                   1182:     sysbus_init_irq(dev, &s->irq);
                   1183:     qemu_macaddr_default_if_unset(&s->conf.macaddr);
                   1184: 
                   1185:     s->nic = qemu_new_nic(&net_gem_info, &s->conf,
                   1186:             object_get_typename(OBJECT(dev)), dev->qdev.id, s);
                   1187: 
                   1188:     return 0;
                   1189: }
                   1190: 
                   1191: static const VMStateDescription vmstate_cadence_gem = {
                   1192:     .name = "cadence_gem",
                   1193:     .version_id = 1,
                   1194:     .minimum_version_id = 1,
                   1195:     .minimum_version_id_old = 1,
                   1196:     .fields      = (VMStateField[]) {
                   1197:         VMSTATE_UINT32_ARRAY(regs, GemState, GEM_MAXREG),
                   1198:         VMSTATE_UINT16_ARRAY(phy_regs, GemState, 32),
                   1199:         VMSTATE_UINT8(phy_loop, GemState),
                   1200:         VMSTATE_UINT32(rx_desc_addr, GemState),
                   1201:         VMSTATE_UINT32(tx_desc_addr, GemState),
                   1202:     }
                   1203: };
                   1204: 
                   1205: static Property gem_properties[] = {
                   1206:     DEFINE_NIC_PROPERTIES(GemState, conf),
                   1207:     DEFINE_PROP_END_OF_LIST(),
                   1208: };
                   1209: 
                   1210: static void gem_class_init(ObjectClass *klass, void *data)
                   1211: {
                   1212:     DeviceClass *dc = DEVICE_CLASS(klass);
                   1213:     SysBusDeviceClass *sdc = SYS_BUS_DEVICE_CLASS(klass);
                   1214: 
                   1215:     sdc->init = gem_init;
                   1216:     dc->props = gem_properties;
                   1217:     dc->vmsd = &vmstate_cadence_gem;
                   1218:     dc->reset = gem_reset;
                   1219: }
                   1220: 
                   1221: static TypeInfo gem_info = {
                   1222:     .class_init = gem_class_init,
                   1223:     .name  = "cadence_gem",
                   1224:     .parent = TYPE_SYS_BUS_DEVICE,
                   1225:     .instance_size  = sizeof(GemState),
                   1226: };
                   1227: 
                   1228: static void gem_register_types(void)
                   1229: {
                   1230:     type_register_static(&gem_info);
                   1231: }
                   1232: 
                   1233: type_init(gem_register_types)

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.