⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 e100.c

📁 xen虚拟机源代码安装包
💻 C
📖 第 1 页 / 共 5 页
字号:
        struct        {            uint16_t data;       // Data            uint8_t regaddr:5;   // PHY register address            uint8_t phyaddr:5;   // PHY address            uint8_t opcode:2;    // Opcode            uint8_t r:1;         // Ready            uint8_t ie:1;        // Interrup enable            uint8_t rs1:2;       // Reserved        }u;    } mdi_ctrl;    /* Receive byte counter register */    uint32_t rx_byte_counter;    /* Early receive interrupt register */    uint8_t early_interrupt;    /* Flow control register */    union    {        uint16_t val;    }flow_ctrl;    /* Power management driver register */    union    {        uint8_t val;        struct        {            uint8_t pme_s:1;     // PME status            uint8_t tco_r:1;     // TCO request            uint8_t f_tco_i:1;   // Force TCO indication            uint8_t tco_re:1;    // TCO ready            uint8_t rs1:1;       // Reserved            uint8_t isp:1;       // Intersting packet            uint8_t mg:1;        // Magic packet            uint8_t lsci:1;      // Link status change indication        }u;    }pm_reg;    /* General control register */    uint8_t gen_ctrl;    /* General status register */    uint8_t gen_status;    /* These are reserved or we don't support register */    uint8_t others[30];} __attribute__ ((packed)) csr_t;typedef struct{    uint8_t byte_count;    uint8_t rx_fifo_limit:4;    uint8_t tx_fifo_limit:4;    uint8_t adpt_inf_spacing;    uint8_t rs1;    uint8_t rx_dma_max_bytes;    uint8_t tx_dma_max_bytes:7;    uint8_t dmbc_en:1;    uint8_t late_scb:1,            rs2:1,            tno_intr:1,            ci_intr:1,            rs3:1,            rs4:1,            dis_overrun_rx:1,            save_bad_frame:1;    uint8_t dis_short_rx:1,            underrun_retry:2,            rs5:5;    uint8_t mii:1,            rs6:7;    uint8_t rs7;    uint8_t rs8:3,            nsai:1,            preamble_len:2,            loopback:2;    uint8_t linear_prio:3,            rs9:5;    uint8_t pri_mode:1,            rs10:3,            interframe_spacing:4;    uint16_t rs11;    uint8_t promiscuous:1,            broadcast_dis:1,            rs12:5,            crs_cdt:1;    uint16_t rs13;    uint8_t strip:1,            padding:1,            rx_crc:1,            rs14:5;    uint8_t rs15:6,            force_fdx:1,            fdx_en:1;    uint8_t rs16:6,            mul_ia:2;    uint8_t rs17:3,            mul_all:1,            rs18:4;} __attribute__ ((packed)) i82557_cfg_t;typedef struct {    VLANClientState *vc;    PCIDevice *pci_dev;    int mmio_index;    uint8_t scb_stat;           /* SCB stat/ack byte */    uint32_t region_base_addr[REGION_NUM];         /* PCI region addresses */    uint8_t macaddr[6];    uint16_t mdimem[32];    eeprom_t eeprom;    uint32_t device;            /* device variant */    uint8_t mult_list[8];       /* Multicast address list */    int is_multcast_enable;    /* (cu_base + cu_offset) address the next command block in the command block list. */    uint32_t cu_base;           /* CU base address */    uint32_t cu_offset;         /* CU address offset */    uint32_t cu_next;           /* Point to next command when CU go to suspend */    /* (ru_base + ru_offset) address the RFD in the Receive Frame Area. */    uint32_t ru_base;           /* RU base address */    uint32_t ru_offset;         /* RU address offset */    uint32_t statsaddr;         /* pointer to e100_stats_t */    e100_stats_t statistics;        /* statistical counters */    /* Configuration bytes. */    i82557_cfg_t config;    /* FIFO buffer of card. The packet that need to be sent buffered in it */    uint8_t pkt_buf[MAX_ETH_FRAME_SIZE+4];    /* Data length in FIFO buffer */    int pkt_buf_len;    /* Data in mem is always in the byte order of the controller (le). */    union    {        csr_t csr;        uint8_t mem[PCI_MEM_SIZE];    }pci_mem;} E100State;/* CB structure, filled by device driver * This is a common structure of CB. In some * special case such as TRANSMIT command, the * reserved field will be used. */struct  control_block{    uint16_t rs1:13;            /* reserved */    uint8_t ok:1;               /* 1:command executed without error, otherwise 0 */    uint8_t rs2:1;    uint8_t c:1;                /* execution status. set by device, clean by software */    uint8_t cmd:3;              /* command */    uint16_t rs3:10;            /* most time equal to 0 */    uint8_t i:1;                /* whether trigger interrupt after execution. 1:yes; 0:no */    uint8_t s:1;                /* suspend */    uint8_t el:1;               /* end flag */    uint32_t link_addr;} __attribute__ ((packed));typedef struct{    uint32_t tx_desc_addr;      /* transmit buffer decsriptor array address. */    uint16_t tcb_bytes:14;         /* transmit command block byte count (in lower 14 bits)*/    uint8_t rs1:1;    uint8_t eof:1;    uint8_t tx_threshold;       /* transmit threshold */    uint8_t tbd_num;          /* TBD number */} __attribute__ ((packed)) tbd_t;/* Receive frame descriptore structure */typedef struct{    uint16_t status:13;     // Result of receive opration    uint8_t ok:1;           // 1:receive without error, otherwise 0    uint8_t rs1:1;    uint8_t c:1;            // 1:receive complete    uint8_t rs2:3;    uint8_t sf:1;           // 0:simplified mode    uint8_t h:1;            // 1:header RFD    uint16_t rs3:9;    uint8_t s:1;            // 1:go to suspend    uint8_t el:1;           // 1:last RFD    uint32_t link_addr;     // Add on RU base point to next RFD    uint32_t rs4;    uint16_t count:14;      // Number of bytes written into data area    uint8_t f:1;            // Set by device when count field update    uint8_t eof:1;          // Set by device when placing data into data area complete    uint16_t size:14;       // Buffer size (even number)    uint8_t rs5:2;} __attribute__ ((packed)) rfd_t;enum{    RX_COLLISION = BIT(0),  // 1:Receive collision detected    RX_IA_MATCH = BIT(1),      // 0:Receive frame match individual address    RX_NO_MATCH = BIT(2), // 1:Receive frame match no address    RX_ERR = BIT(4),        // 1:Receive frame error    RX_TYPE = BIT(5),       // 1:Receive frame is a type frame    RX_SHORT = BIT(7),      // 1:Receive frame is too short    RX_DMA_ERR = BIT(8),    RX_LARGE = BIT(9),      // 1:Receive frame is too large    RX_CRC_ERR = BIT(10),} RFD_STATUS;typedef struct PCIE100State {    PCIDevice dev;    E100State e100;} PCIE100State;/* Default values for MDI (PHY) registers */static const uint16_t e100_mdi_default[] = {    /* MDI Registers 0 - 6, 7 */    0x3000, 0x780d, 0x02a8, 0x0154, 0x05e1, 0x0000, 0x0000, 0x0000,    /* MDI Registers 8 - 15 */    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,    /* MDI Registers 16 - 31 */    0x0003, 0x0000, 0x0001, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,};static const uint8_t broadcast_macaddr[6] =    { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };/* Debugging codes */#ifdef  DEBUG_E100static void e100_dump(char *comment, uint8_t *info, int len){    int i;    if ( !comment || !info )        return;    fprintf(stderr, "EE100\t%-24s%s", __func__, comment);    for ( i=0; i<len; i++ )        fprintf(stderr, "%x ", info[i]);    fprintf(stderr, "\n");}static const char *regname[] ={    [0] = "SCB Status", [1] = "SCB Ack",    [2] = "SCB Cmd", [3] = "SCB Interrupt Mask",    [4] = "SCB Pointer", [8] = "SCB Port",    [0xc] = "SCB Flash", [0xe] = "SCB Eeprom",    [0x10] = "SCB Ctrl MDI", [0x14] = "SCB Early RX",};#define SCBNAME(x)    \    ( (x) < (sizeof(regname) / sizeof(regname[0])) ? regname[(x)] : "Unknown SCB Register" )static const char *cb_cmd_name[] ={    [CBL_NOP] = "NOP", [CBL_IASETUP] = "Individual address setup",    [CBL_CONFIGURE] = "Configure", [CBL_MULTCAST_ADDR_SETUP] = "Set Multcast address list",    [CBL_TRANSMIT] = "Transmit", [CBL_LOAD_MICROCODE] = "Load microcode",    [CBL_DUMP] = "Dump", [CBL_DIAGNOSE] = "Diagnose",};#define CB_CMD_NAME(x)  \    ( (x) < (sizeof(cb_cmd_name) / sizeof(cb_cmd_name[0])) ? cb_cmd_name[(x)] : "Unknown CB command" )static const char *eeprom_opcode_name[] ={    [0] = "Unknow", [EEPROM_WRITE] = "Write",    [EEPROM_READ] = "Read", [EEPROM_ERASE] = "Erase",};#define EEPROM_OPCODE_NAME(x)   \    ( (x) < (sizeof(eeprom_opcode_name) / sizeof(eeprom_opcode_name[0])) ?  \      eeprom_opcode_name[(x)] : "Unknown" )static struct eeprom_trace_data{    uint8_t eedo[256];    uint8_t di[256];    int op;    int i;    uint32_t data;}etd = {.op = NOP};static void eeprom_trace(int eedo, int di, int dir, int next_op, int clr){    int i;    if ( clr )    {        char *opname = NULL;        switch ( etd.op )        {            case NOP:                break;            case OPCODE:                opname = "opcode";                break;            case ADDR:                opname = "address";                break;            case DATA:                opname = "data transfer";                break;            default:                opname = "Unknown";        }        if ( opname )        {            logout("EEPROM trace:\n");            fprintf(stderr, "\toperation: %s\n", opname);            fprintf(stderr, "\tDI track:");            for ( i=0; i<etd.i; i++ )                fprintf(stderr, "%x ", etd.di[i]);            fprintf(stderr, "\n\tDO track:");            for ( i=0; i<etd.i; i++ )                fprintf(stderr, "%x ", etd.eedo[i]);            fprintf(stderr, "\n\tData:%#x\n", etd.data);        }        memset(&etd, 0x0, sizeof(etd));        etd.op = next_op;        return;    }    etd.eedo[etd.i] = eedo;    etd.di[etd.i] = di;    etd.i ++;    if ( dir == EEPROM_READ && etd.op == DATA )        etd.data = (etd.data << 1) | eedo;    else        etd.data = (etd.data << 1) | di;}#define INT_NAME(x) \    ({  \     char *name = NULL; \     switch (x) \     {  \     case INT_FCP:  \            name = "FCP";   \            break;  \     case INT_SWI:  \            name = "SWI";   \            break;  \     case INT_MDI:  \            name = "MDI";   \            break;  \     case INT_RNR:  \            name = "RNR";   \            break;  \     case INT_CNA:  \            name = "CNA";   \            break;  \     case INT_FR:   \            name = "FR";    \            break;  \     case INT_CX_TNO:   \            name ="CX/TNO"; \            break;  \     default:   \            name ="Unknown"; \     }  \     name;  \     })#elsestatic void e100_dump(char *comment, uint8_t *info, int len) {}static void eeprom_trace(int eedo, int di, int dir, int next_op, int clr) {}#endifstatic void pci_reset(E100State * s){    uint8_t *pci_conf = s->pci_dev->config;    memcpy(pci_conf, &e100_pci_configure[0], sizeof(e100_pci_configure));    logout("%p\n", s);    /* I82557 */    PCI_CONFIG_8(E100_PCI_REVISION_ID, 0x01);    PCI_CONFIG_8(0x3c, 0x0);}static void e100_selective_reset(E100State * s){    memset(s->pci_mem.mem, 0x0, sizeof(s->pci_mem.mem));    // Set RU/CU to idle, maintain the register mentioned in spec,    SET_CU_STATE(CU_IDLE);    SET_RU_STATE(RU_IDLE);    logout("CU and RU go to idle\n");    s->ru_offset = 0;    s->cu_offset = 0;    s->cu_next = 0;    // For 82557, special interrupt bits are all 1

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -