|
|
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)
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.