1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174
|
/*
* QEMU Freescale eTSEC Emulator
*
* Copyright (c) 2011-2013 AdaCore
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#ifndef _ETSEC_H_
#define _ETSEC_H_
#include "hw/qdev.h"
#include "hw/sysbus.h"
#include "net/net.h"
#include "hw/ptimer.h"
/* Buffer Descriptors */
typedef struct eTSEC_rxtx_bd {
uint16_t flags;
uint16_t length;
uint32_t bufptr;
} eTSEC_rxtx_bd;
#define BD_WRAP (1 << 13)
#define BD_INTERRUPT (1 << 12)
#define BD_LAST (1 << 11)
#define BD_TX_READY (1 << 15)
#define BD_TX_PADCRC (1 << 14)
#define BD_TX_TC (1 << 10)
#define BD_TX_PREDEF (1 << 9)
#define BD_TX_HFELC (1 << 7)
#define BD_TX_CFRL (1 << 6)
#define BD_TX_RC_MASK 0xF
#define BD_TX_RC_OFFSET 0x2
#define BD_TX_TOEUN (1 << 1)
#define BD_TX_TR (1 << 0)
#define BD_RX_EMPTY (1 << 15)
#define BD_RX_RO1 (1 << 14)
#define BD_RX_FIRST (1 << 10)
#define BD_RX_MISS (1 << 8)
#define BD_RX_BROADCAST (1 << 7)
#define BD_RX_MULTICAST (1 << 6)
#define BD_RX_LG (1 << 5)
#define BD_RX_NO (1 << 4)
#define BD_RX_SH (1 << 3)
#define BD_RX_CR (1 << 2)
#define BD_RX_OV (1 << 1)
#define BD_RX_TR (1 << 0)
/* Tx FCB flags */
#define FCB_TX_VLN (1 << 7)
#define FCB_TX_IP (1 << 6)
#define FCB_TX_IP6 (1 << 5)
#define FCB_TX_TUP (1 << 4)
#define FCB_TX_UDP (1 << 3)
#define FCB_TX_CIP (1 << 2)
#define FCB_TX_CTU (1 << 1)
#define FCB_TX_NPH (1 << 0)
/* PHY Status Register */
#define MII_SR_EXTENDED_CAPS 0x0001 /* Extended register capabilities */
#define MII_SR_JABBER_DETECT 0x0002 /* Jabber Detected */
#define MII_SR_LINK_STATUS 0x0004 /* Link Status 1 = link */
#define MII_SR_AUTONEG_CAPS 0x0008 /* Auto Neg Capable */
#define MII_SR_REMOTE_FAULT 0x0010 /* Remote Fault Detect */
#define MII_SR_AUTONEG_COMPLETE 0x0020 /* Auto Neg Complete */
#define MII_SR_PREAMBLE_SUPPRESS 0x0040 /* Preamble may be suppressed */
#define MII_SR_EXTENDED_STATUS 0x0100 /* Ext. status info in Reg 0x0F */
#define MII_SR_100T2_HD_CAPS 0x0200 /* 100T2 Half Duplex Capable */
#define MII_SR_100T2_FD_CAPS 0x0400 /* 100T2 Full Duplex Capable */
#define MII_SR_10T_HD_CAPS 0x0800 /* 10T Half Duplex Capable */
#define MII_SR_10T_FD_CAPS 0x1000 /* 10T Full Duplex Capable */
#define MII_SR_100X_HD_CAPS 0x2000 /* 100X Half Duplex Capable */
#define MII_SR_100X_FD_CAPS 0x4000 /* 100X Full Duplex Capable */
#define MII_SR_100T4_CAPS 0x8000 /* 100T4 Capable */
/* eTSEC */
/* Number of register in the device */
#define ETSEC_REG_NUMBER 1024
typedef struct eTSEC_Register {
const char *name;
const char *desc;
uint32_t access;
uint32_t value;
} eTSEC_Register;
typedef struct eTSEC {
SysBusDevice busdev;
MemoryRegion io_area;
eTSEC_Register regs[ETSEC_REG_NUMBER];
NICState *nic;
NICConf conf;
/* Tx */
uint8_t *tx_buffer;
uint32_t tx_buffer_len;
eTSEC_rxtx_bd first_bd;
/* Rx */
uint8_t *rx_buffer;
uint32_t rx_buffer_len;
uint32_t rx_remaining_data;
uint8_t rx_first_in_frame;
uint8_t rx_fcb_size;
eTSEC_rxtx_bd rx_first_bd;
uint8_t rx_fcb[10];
uint32_t rx_padding;
/* IRQs */
qemu_irq tx_irq;
qemu_irq rx_irq;
qemu_irq err_irq;
uint16_t phy_status;
uint16_t phy_control;
/* Polling */
QEMUBH *bh;
struct ptimer_state *ptimer;
} eTSEC;
#define TYPE_ETSEC_COMMON "eTSEC"
#define ETSEC_COMMON(obj) \
OBJECT_CHECK(eTSEC, (obj), TYPE_ETSEC_COMMON)
#define eTSEC_TRANSMIT 1
#define eTSEC_RECEIVE 2
DeviceState *etsec_create(hwaddr base,
MemoryRegion *mr,
NICInfo *nd,
qemu_irq tx_irq,
qemu_irq rx_irq,
qemu_irq err_irq);
void etsec_walk_tx_ring(eTSEC *etsec, int ring_nbr);
void etsec_walk_rx_ring(eTSEC *etsec, int ring_nbr);
void etsec_rx_ring_write(eTSEC *etsec, const uint8_t *buf, size_t size);
void etsec_write_miim(eTSEC *etsec,
eTSEC_Register *reg,
uint32_t reg_index,
uint32_t value);
void etsec_miim_link_status(eTSEC *etsec, NetClientState *nc);
#endif /* ! _ETSEC_H_ */
|