int e1000_attach(struct pci_func *pcif) { pci_func_enable(pcif); e1000_mem_init(); // Sanity check static_assert(sizeof(struct tx_desc) == 16 && sizeof(struct rcv_desc) == 16); boot_map_region(kern_pgdir, E1000_ADDR, pcif->reg_size[0], pcif->reg_base[0], PTE_PCD | PTE_PWT | PTE_W); e1000 = (uint32_t*)E1000_ADDR; e1000[E1000_TDBAL] = PADDR(tx_queue); e1000[E1000_TDBAH] = 0; e1000[E1000_TDLEN] = sizeof(struct tx_desc) * E1000_NTXDESC; e1000[E1000_TDH] = 0; e1000[E1000_TDT] = 0; // Ensure proper alignment of values assert(e1000[E1000_TDBAL] % 0x10 == 0 && e1000[E1000_TDLEN] % 0x80 == 0); // Setup TCTL register e1000[E1000_TCTL] |= E1000_TCTL_EN; e1000[E1000_TCTL] |= E1000_TCTL_PSP; e1000[E1000_TCTL] |= E1000_TCTL_CT; e1000[E1000_TCTL] |= E1000_TCTL_COLD; // Setup TIPG register e1000[E1000_TIPG] = 0; e1000[E1000_TIPG] |= E1000_TIPG_IPGT; e1000[E1000_TIPG] |= E1000_TIPG_IPGR1; e1000[E1000_TIPG] |= E1000_TIPG_IPGR2; e1000[E1000_FILTER_RAL] = 0x12005452; e1000[E1000_FILTER_RAH] = 0x00005634; e1000[E1000_FILTER_RAH] |= E1000_FILTER_RAH_VALID; //cprintf("Ethernet Address: 0x%08x%08x\n", e1000[E1000_FILTER_RAH], e1000[E1000_FILTER_RAL]); // Setup RCV Registers e1000[E1000_RDBAL] = PADDR(rcv_queue); e1000[E1000_RDBAH] = 0; e1000[E1000_RDLEN] = sizeof(struct rcv_desc) * E1000_NRCVDESC; e1000[E1000_RDH] = 1; e1000[E1000_RDT] = 0; // Gets reset later e1000[E1000_RCTL] = E1000_RCTL_EN; e1000[E1000_RCTL] &= ~E1000_RCTL_LPE; e1000[E1000_RCTL] &= ~E1000_RCTL_LBM; e1000[E1000_RCTL] &= ~E1000_RCTL_RDMTS; e1000[E1000_RCTL] &= ~E1000_RCTL_MO; e1000[E1000_RCTL] |= E1000_RCTL_BAM; e1000[E1000_RCTL] &= ~E1000_RCTL_BSIZE; e1000[E1000_RCTL] |= E1000_RCTL_SECRC; return 1; }
int e1000_attach(struct pci_func *f) { pci_func_enable(f); memmove(&e1000_pci_func, f, sizeof(struct pci_func)); e1000_mmio_beg = mmio_map_region(f->reg_base[0], f->reg_size[0]); init_tx(); init_rx(); return 0; }
int pci_e100_attach(struct pci_func *pcif) { pci_func_enable(pcif); cprintf("CSR Memory Mapped Base Address Register:%d bytes at 0x%x\n",pcif->reg_size[0],pcif->reg_base[0]); cprintf("CSR I/O Mapped Base Address Register:%d bytes at 0x%x\n",pcif->reg_size[1],pcif->reg_base[1]); cprintf("Flash Memory Base Address Register:%d bytes at 0x%x\n",pcif->reg_size[2],pcif->reg_base[2]); CSR_ADDR=pcif->reg_base[1];//利用I/O端口操作CSR outl(CSR_ADDR+CSR_PORT,software_reset);//向PORT中写入0,软件重启芯片 delay();//延时10us //panic("e100 initialization is not implemented\n"); return 0; }
// LAB 6: Your driver code here int e1000_attach(struct pci_func *pcif) { int i; pci_func_enable(pcif); e1000 = mmio_map_region(pcif->reg_base[0], pcif->reg_size[0]); // VM mapping for BAR 0 cprintf("Status is: 0x%x. Desired: 0x80080783\n", e1000[E1000_STATUS]); assert(sizeof(tx_descs) % 128 == 0); // should be 128-byte aligned assert(sizeof(rx_descs) % 128 == 0); // should be 128-byte aligned // perform transmit initialization e1000[E1000_TDBAL] = PADDR(tx_descs); e1000[E1000_TDLEN] = sizeof(tx_descs); e1000[E1000_TDH] = 0; e1000[E1000_TDT] = 0; e1000[E1000_TCTL] |= E1000_TCTL_EN; e1000[E1000_TCTL] |= E1000_TCTL_PSP; e1000[E1000_TCTL] |= E1000_TCTL_CT_INIT; e1000[E1000_TCTL] |= E1000_TCTL_COLD_INIT; e1000[E1000_TIPG] |= E1000_TIPG_INIT; // perform receive initialization e1000[E1000_RAL] = 0x12005452; // hardcoded 52:54:00:12:34:56 e1000[E1000_RAH] = 0x00005634 | E1000_RAH_AV; // hardcoded 52:54:00:12:34:56 e1000[E1000_RDBAL] = PADDR(rx_descs); e1000[E1000_RDLEN] = sizeof(rx_descs); e1000[E1000_RDH] = 0; e1000[E1000_RDT] = NRDESC - 1; e1000[E1000_RCTL] |= E1000_RCTL_EN; e1000[E1000_RCTL] &= (~E1000_RCTL_LPE); // turn off long packat for now e1000[E1000_RCTL] |= E1000_RCTL_LBM_NO; e1000[E1000_RCTL] |= E1000_RCTL_RDMTS_HALF; e1000[E1000_RCTL] |= E1000_RCTL_MO_0; e1000[E1000_RCTL] |= E1000_RCTL_BAM; e1000[E1000_RCTL] |= E1000_RCTL_SZ_2048; e1000[E1000_RCTL] |= E1000_RCTL_SECRC; // init transmit descriptors for (i = 0; i < NTDESC; i++) { tx_descs[i].addr = PADDR(&tx_packets[i * MAXPKTLEN]); tx_descs[i].cmd |= E1000_TXD_CMD_RS; tx_descs[i].status |= E1000_TXD_STA_DD; } // init receive descriptors for (i = 0; i < NRDESC; i++){ rx_descs[i].addr = PADDR(&rx_packets[i * MAXPKTLEN]); } return 0; }
int e100_pci_attach(struct pci_func *pcif) { // The device has been found but needs to be enabled. pci_func_enable(pcif); // Record the IRQ line and base I/O port assigned to the device // so we'll be able to communicate with the E100. e100.io_base = pcif->reg_base[E100_IO]; e100.irq_line = pcif->irq_line; e100_init(); return 0; }
// function to attach the E100 device int e100_attach(struct pci_func* f) { int i; int base; // enable the E100 device pci_func_enable(f); for (i = 0; i < 6; i++) { store.reg_base[i] = f->reg_base[i]; store.reg_size[i] = f->reg_size[i]; } store.irq_line = f->irq_line; // do a software reset base = store.reg_base[1]; // for I/O Port Base outl(base + 0x8, 0x0); // initialize the TBC Ring for CU alloc_tcb_ring(); // load the CU Base register with the base address of the ring_tcb outl(base + 0x4, PADDR(&ring_tcb[0])); outw(base + 0x2, SCB_CU_LOAD_CU_BASE); //op code in SCB command word // initialize the RFD Ring for RU alloc_rfd_ring(); // load the RU Base register with the base address of the ring_rfd // outl(base + 0x4, PADDR(&ring_rfd[0])); // outw(base + 0x2, SCB_RU_LOAD_RU_BASE); // Start the RU outl(base + 0x4, PADDR((uint32_t)&ring_rfd[ru_ind])); outw(base + 0x2, SCB_RU_START); return 0; }
int e100_attach(pci_pdata_t pd) { pci_func_enable(pd); e100.busno = pd->busno; e100.slot = pd->slot; e100.func = pd->func; e100.device = pd->device; e100.vendor = pd->vendor; e100.class_code= pd->class_code; int i; for (i = 0; i < 6; i++) { e100.addr_base[i] = pd->addr_base[i]; e100.addr_size[i] = pd->addr_size[i]; } e100.irq_line = pd->irq_line; // initialize network interface controller nic.io_base = pd->addr_base[E100_IO]; nic.io_size = pd->addr_size[E100_IO]; // initize e100 driver e100_init(); return 0; }
int E1000_attach_function(struct pci_func *pcif) { pci_func_enable(pcif); e1000_bar_base = mmio_map_region(pcif->reg_base[0], pcif->reg_size[0] ); /* Debugging*/ // cprintf("value of device status register%x\n", *(e1000_bar_address+ 0x00008/4)); int i; for (i = 0; i < E1000_TX_DESCS; ++i) { tx_descriptors[i].status = E1000_TXD_STAT_DD; } /* Transmitter registers*/ e1000_bar_base[E1000_TDH / 4] = 0; e1000_bar_base[E1000_TDT / 4] = 0; e1000_bar_base[E1000_TDBAL / 4] = PADDR(tx_descriptors); e1000_bar_base[E1000_TDBAH / 4] = 0; e1000_bar_base[E1000_TDLEN / 4] = sizeof(struct tx_desc) * E1000_TX_DESCS; e1000_bar_base[E1000_TCTL / 4] |= E1000_TCTL_EN; e1000_bar_base[E1000_TCTL / 4] |= E1000_TCTL_PSP; e1000_bar_base[E1000_TCTL / 4] &= ~E1000_TCTL_CT; e1000_bar_base[E1000_TCTL / 4] |= (E1000_TCTL_CT_VAL << 4); e1000_bar_base[E1000_TCTL / 4] &= ~E1000_TCTL_COLD; e1000_bar_base[E1000_TCTL / 4] |= (E1000_TCTL_COLD_VAL << 12); e1000_bar_base[E1000_TIPG / 4] = (E1000_TIPG_IPGT_VAL ) | (E1000_TIPG_IPGR1_VAL << 10) | (E1000_TIPG_IPGR2_VAL << 20) | (E1000_TIPG_RESERVED_VAL << 30); /* Receiver registers */ e1000_bar_base[E1000_RDBAL / 4] = PADDR(rx_descriptors); e1000_bar_base[E1000_RDBAH / 4] = 0; e1000_bar_base[E1000_RDLEN / 4] = sizeof(struct rx_desc) * E1000_RX_DESCS; for (i = 0; i < E1000_TX_DESCS; ++i) { rx_descriptors[i].addr = PADDR(rx_bufs[i]); } e1000_bar_base[E1000_IMS / 4] = 0; for (i = 0; i < E1000_N_MTA_ELEMS; ++i) { e1000_bar_base[E1000_MTA / 4] = 0; } e1000_bar_base[E1000_RDH / 4] = 0; e1000_bar_base[E1000_RDT / 4] = E1000_RX_DESCS - 1; e1000_bar_base[E1000_RCTL / 4] |= E1000_RCTL_EN; e1000_bar_base[E1000_RCTL / 4] &= ~E1000_RCTL_LPE; e1000_bar_base[E1000_RCTL / 4] |= E1000_RCTL_BAM; e1000_bar_base[E1000_RCTL / 4] |= E1000_RCTL_SECRC; e1000_bar_base[E1000_RAL(0) / 4] = 0x12005452; e1000_bar_base[E1000_RAH(0) / 4] = 0x5634; e1000_bar_base[E1000_RAH(0) / 4] |= E1000_RAH_AV; /* Test tx_packet transmit*/ /* Debugging char d='a'; E1000_tx_packet(&d, 1); */ return 0; }
int attachE1000(struct pci_func *pcif) { int i; pci_func_enable(pcif); loc_mmio=(uint32_t *)mmio_map_region((physaddr_t)pcif->reg_base[0] ,(size_t)pcif->reg_size[0]); memset(tx_que, 0x0, sizeof(struct trans_desc) * MAXTX_DESC); memset(pkt_que, 0x0, sizeof(struct trans_pkt) * MAXTX_DESC); for( i=0; i<MAXTX_DESC; i++) { tx_que[i].addr = PADDR(pkt_que[i].arr); tx_que[i].status |= E1000_TXD_STAT_DD; } memset(rx_que, 0x0, sizeof(struct rcv_desc) * MAXTX_DESC); memset(rpkt_que, 0x0, sizeof(struct rcv_pkt) * MAXTX_DESC); for( i=0; i<MAXTX_DESC; i++) { rx_que[i].addr = PADDR(rpkt_que[i].arr); //tx_que[i].status |= E1000_TXD_STAT_DD; } loc_mmio[E1000_RAL] = 0x52; loc_mmio[E1000_RAL] |= (0x54) << 8; loc_mmio[E1000_RAL] |= (0x00) << 16; loc_mmio[E1000_RAL] |= (0x12) << 24; loc_mmio[E1000_RAH] |= (0x34); loc_mmio[E1000_RAH] |= (0x56) << 8; loc_mmio[E1000_RAH] |= 0x80000000; //initialization of various registers loc_mmio[E1000_TDBAH] = 0x0; loc_mmio[E1000_TDBAL] = PADDR(tx_que); loc_mmio[E1000_TDLEN] = sizeof(struct trans_desc) * MAXTX_DESC; loc_mmio[E1000_TDH] = 0x0; loc_mmio[E1000_TDT] = 0x0; loc_mmio[E1000_RDBAH] = 0x0; loc_mmio[E1000_RDBAL] = PADDR(rx_que); loc_mmio[E1000_RDLEN] = sizeof(struct rcv_desc) * MAXTX_DESC; loc_mmio[E1000_RDH] = 0x0; loc_mmio[E1000_RDT] = 0x0; loc_mmio[E1000_TCTL] |= E1000_TCTL_EN|E1000_TCTL_PSP|(E1000_TCTL_CT & (0x10 << 4))|(E1000_TCTL_COLD & (0x40 << 12)); loc_mmio[E1000_RCTL] |= E1000_RCTL_EN; loc_mmio[E1000_RCTL] &= ~E1000_RCTL_LPE; loc_mmio[E1000_RCTL] &= ~(E1000_RCTL_LBM_MAC | E1000_RCTL_LBM_SLP |E1000_RCTL_LBM_TCVR); loc_mmio[E1000_RCTL] &= ~(E1000_RCTL_RDMTS_QUAT | E1000_RCTL_RDMTS_EIGTH); loc_mmio[E1000_RCTL] &= ~(E1000_RCTL_MO_3); loc_mmio[E1000_RCTL] &= ~E1000_RCTL_BAM; loc_mmio[E1000_RCTL] &= ~(E1000_RCTL_BSEX); loc_mmio[E1000_RCTL] &= ~(E1000_RCTL_SZ_256); loc_mmio[E1000_RCTL] |= E1000_RCTL_SECRC; // loc_mmio[E1000_TIPG] = 0x0; // loc_mmio[E1000_TIPG] |= 0xA; // loc_mmio[E1000_TIPG] |= (0x6) << 20; // loc_mmio[E1000_TIPG] |= (0x4) << 10; return 0; }
// LAB 6: Your driver code here int e1000_attach(struct pci_func *pcif) { uint32_t i; // Enable PCI device pci_func_enable(pcif); // Memory map I/O for PCI device boot_map_region(kern_pgdir, E1000_MMIOADDR, pcif->reg_size[0], pcif->reg_base[0], PTE_PCD | PTE_PWT | PTE_W); e1000 = (uint32_t *) E1000_MMIOADDR; assert(e1000[E1000_STATUS] == 0x80080783); // Initialize tx buffer array memset(tx_desc_array, 0x0, sizeof(struct tx_desc) * E1000_TXDESC); memset(tx_pkt_bufs, 0x0, sizeof(struct tx_pkt) * E1000_TXDESC); for (i = 0; i < E1000_TXDESC; i++) { tx_desc_array[i].addr = PADDR(tx_pkt_bufs[i].buf); tx_desc_array[i].status |= E1000_TXD_STAT_DD; } // Initialize rcv desc buffer array memset(rcv_desc_array, 0x0, sizeof(struct rcv_desc) * E1000_RCVDESC); memset(rcv_pkt_bufs, 0x0, sizeof(struct rcv_pkt) * E1000_RCVDESC); for (i = 0; i < E1000_RCVDESC; i++) { rcv_desc_array[i].addr = PADDR(rcv_pkt_bufs[i].buf); } /* Transmit initialization */ // Program the Transmit Descriptor Base Address Registers e1000[E1000_TDBAL] = PADDR(tx_desc_array); e1000[E1000_TDBAH] = 0x0; // Set the Transmit Descriptor Length Register e1000[E1000_TDLEN] = sizeof(struct tx_desc) * E1000_TXDESC; // Set the Transmit Descriptor Head and Tail Registers e1000[E1000_TDH] = 0x0; e1000[E1000_TDT] = 0x0; // Initialize the Transmit Control Register e1000[E1000_TCTL] |= E1000_TCTL_EN; e1000[E1000_TCTL] |= E1000_TCTL_PSP; e1000[E1000_TCTL] &= ~E1000_TCTL_CT; e1000[E1000_TCTL] |= (0x10) << 4; e1000[E1000_TCTL] &= ~E1000_TCTL_COLD; e1000[E1000_TCTL] |= (0x40) << 12; // Program the Transmit IPG Register e1000[E1000_TIPG] = 0x0; e1000[E1000_TIPG] |= (0x6) << 20; // IPGR2 e1000[E1000_TIPG] |= (0x4) << 10; // IPGR1 e1000[E1000_TIPG] |= 0xA; // IPGR /* Receive Initialization */ // Program the Receive Address Registers e1000[E1000_EERD] = 0x0; e1000[E1000_EERD] |= E1000_EERD_START; while (!(e1000[E1000_EERD] & E1000_EERD_DONE)); e1000[E1000_RAL] = e1000[E1000_EERD] >> 16; e1000[E1000_EERD] = 0x1 << 8; e1000[E1000_EERD] |= E1000_EERD_START; while (!(e1000[E1000_EERD] & E1000_EERD_DONE)); e1000[E1000_RAL] |= e1000[E1000_EERD] & 0xffff0000; e1000[E1000_EERD] = 0x2 << 8; e1000[E1000_EERD] |= E1000_EERD_START; while (!(e1000[E1000_EERD] & E1000_EERD_DONE)); e1000[E1000_RAH] = e1000[E1000_EERD] >> 16; e1000[E1000_RAH] |= 0x1 << 31; // Program the Receive Descriptor Base Address Registers e1000[E1000_RDBAL] = PADDR(rcv_desc_array); e1000[E1000_RDBAH] = 0x0; // Set the Receive Descriptor Length Register e1000[E1000_RDLEN] = sizeof(struct rcv_desc) * E1000_RCVDESC; // Set the Receive Descriptor Head and Tail Registers e1000[E1000_RDH] = 0x0; e1000[E1000_RDT] = 0x0; // Initialize the Receive Control Register e1000[E1000_RCTL] |= E1000_RCTL_EN; e1000[E1000_RCTL] &= ~E1000_RCTL_LPE; e1000[E1000_RCTL] &= ~E1000_RCTL_LBM; e1000[E1000_RCTL] &= ~E1000_RCTL_RDMTS; e1000[E1000_RCTL] &= ~E1000_RCTL_MO; e1000[E1000_RCTL] |= E1000_RCTL_BAM; e1000[E1000_RCTL] &= ~E1000_RCTL_SZ; // 2048 byte size e1000[E1000_RCTL] |= E1000_RCTL_SECRC; return 0; }
int net_pci_attach(struct pci_func *pcif){ int i = 0; // Register the PCI device and enable pci_func_enable(pcif); // Provide the memory for the PCI device net_pci_addr = mmio_map_region(pcif->reg_base[0], pcif->reg_size[0]); // Check to see if the correct value gets printed cprintf("NET PCI status: %x\n", net_pci_addr[E1000_STATUS]); // Initialize transmit descriptor array and packet buffer (not necessarily needed) memset(tx_desc_arr, 0, sizeof(struct tx_desc) * PCI_TXDESC); memset(tx_pkt_buf, 0, sizeof(struct tx_pkt) * PCI_TXDESC); /* Transmit initialization */ // Transmit descriptor base address registers init net_pci_addr[E1000_TDBAL] = PADDR(tx_desc_arr); net_pci_addr[E1000_TDBAH] = 0x0; // Transmit descriptor length register init net_pci_addr[E1000_TDLEN] = sizeof(struct tx_desc) * PCI_TXDESC; // Transmit descriptor head and tail registers init net_pci_addr[E1000_TDH] = 0x0; net_pci_addr[E1000_TDT] = 0x0; // Transmit control register init // 1st bit net_pci_addr[E1000_TCTL] = E1000_TCTL_EN; // 2nd bit net_pci_addr[E1000_TCTL] |= E1000_TCTL_PSP; // TCTL-CT starts from 4th bit and extends to 11th bit // clear all those bits and set it to 10h (11:4) (as per manual) net_pci_addr[E1000_TCTL] &= ~E1000_TCTL_CT; net_pci_addr[E1000_TCTL] |= (0x10) << 4; // TCTL-COLD starts from 12the bit and extends to 21st bit // clear all those bits and set i to 40h (21:12) (as per manual) net_pci_addr[E1000_TCTL] &= ~E1000_TCTL_COLD; net_pci_addr[E1000_TCTL] |= (0x40) << 12; /* Transmit IPG register init */ // Set to zero first net_pci_addr[E1000_TIPG] = 0x0; // IPGT value 10 for IEEE 802.3 standard (as per maunal) net_pci_addr[E1000_TIPG] |= 0xA; // IPGR1 2/3 the value of IPGR2 as per IEEE 802.3 standard (as per manual) // Starts from the 10th bit net_pci_addr[E1000_TIPG] |= (0x4) << 10; // IPGR2 starts from the 20th bit, value = 6(as per manual) net_pci_addr[E1000_TIPG] |= (0x6) << 20; /* Receive Initialization */ // Program the Receive Address Registers net_pci_addr[E1000_RAL] = 0x12005452; net_pci_addr[E1000_RAH] = 0x5634 | E1000_RAH_AV; // HArd coded mac address. (needed to specify end of RAH) net_pci_addr[E1000_MTA] = 0x0; // Program the Receive Descriptor Base Address Registers net_pci_addr[E1000_RDBAL] = PADDR(rx_desc_arr); net_pci_addr[E1000_RDBAH] = 0x0; // Set the Receive Descriptor Length Register net_pci_addr[E1000_RDLEN] = sizeof(struct rx_desc) * PCI_RXDESC; // Set the Receive Descriptor Head and Tail Registers net_pci_addr[E1000_RDH] = 0x0; net_pci_addr[E1000_RDT] = 0x0; // Initialize the Receive Control Register net_pci_addr[E1000_RCTL] |= E1000_RCTL_EN; // Bradcast set 1b net_pci_addr[E1000_RCTL] |= E1000_RCTL_BAM; // CRC strip net_pci_addr[E1000_RCTL] |= E1000_RCTL_SECRC; // Associate the descriptors with the packets. (one to one mapping) for (i = 0; i < PCI_TXDESC; i++) { tx_desc_arr[i].addr = PADDR(tx_pkt_buf[i].buf); tx_desc_arr[i].status |= E1000_TXD_STAT_DD; rx_desc_arr[i].addr = PADDR(rx_pkt_buf[i].buf); } return 0; }