static int nd_3c59x_probe(void) { struct netdev *nd = &net_dev_3com_3c59x; unsigned long pci_config_base; int i; pci_config_base = pci_lookup_vendor_device(0x10b7, 0x5900); if (!pci_config_base) pci_config_base = pci_lookup_vendor_device(0x10b7, 0x5950); if (!pci_config_base) pci_config_base = pci_lookup_vendor_device(0x10b7, 0x5951); if (!pci_config_base) pci_config_base = pci_lookup_vendor_device(0x10b7, 0x5952); if (pci_config_base) { nd->io_base = pci_read_config_long(pci_config_base, PCI_BASE0) & ~3; for (i = 0; i < 3; i++) { int addr; addr = eeprom_read(nd, i + 10); nd->hw_addr[i * 2] = addr >> 8; nd->hw_addr[i * 2 + 1] = addr; } eth_setup(nd); } return net_dev_3com_3c59x.io_base ? 0 : -1; }
static int eth_initialize(struct device *port) { struct eth_runtime *context = port->driver_data; const struct eth_config *config = port->config->config_info; uint32_t base_addr; union { struct { uint8_t bytes[6]; uint8_t pad[2]; } __attribute__((packed)); uint32_t words[2]; } mac_addr; if (!eth_setup(port)) return -EPERM; base_addr = context->base_addr; /* Read the MAC address from the device. */ mac_addr.words[1] = eth_read(base_addr, REG_ADDR_MACADDR_HI); mac_addr.words[0] = eth_read(base_addr, REG_ADDR_MACADDR_LO); net_set_mac(mac_addr.bytes, sizeof(mac_addr.bytes)); /* Initialize the frame filter enabling unicast messages */ eth_write(base_addr, REG_ADDR_MAC_FRAME_FILTER, MAC_FILTER_4_PM); /* Initialize transmit descriptor. */ context->tx_desc.tdes0 = 0; context->tx_desc.tdes1 = 0; context->tx_desc.buf1_ptr = (uint8_t *)context->tx_buf; context->tx_desc.tx_end_of_ring = 1; context->tx_desc.first_seg_in_frm = 1; context->tx_desc.last_seg_in_frm = 1; context->tx_desc.tx_end_of_ring = 1; /* Initialize receive descriptor. */ context->rx_desc.rdes0 = 0; context->rx_desc.rdes1 = 0; context->rx_desc.buf1_ptr = (uint8_t *)context->rx_buf; context->rx_desc.own = 1; context->rx_desc.first_desc = 1; context->rx_desc.last_desc = 1; context->rx_desc.rx_buf1_sz = UIP_BUFSIZE; context->rx_desc.rx_end_of_ring = 1; /* Install transmit and receive descriptors. */ eth_write(base_addr, REG_ADDR_RX_DESC_LIST, (uint32_t)&context->rx_desc); eth_write(base_addr, REG_ADDR_TX_DESC_LIST, (uint32_t)&context->tx_desc); eth_write(base_addr, REG_ADDR_MAC_CONF, /* Set the RMII speed to 100Mbps */ MAC_CONF_14_RMII_100M | /* Enable full-duplex mode */ MAC_CONF_11_DUPLEX | /* Enable transmitter */ MAC_CONF_3_TX_EN | /* Enable receiver */ MAC_CONF_2_RX_EN); eth_write(base_addr, REG_ADDR_INT_ENABLE, INT_ENABLE_NORMAL | /* Enable receive interrupts */ INT_ENABLE_RX); /* Mask all the MMC interrupts */ eth_write(base_addr, REG_MMC_RX_INTR_MASK, MMC_DEFAULT_MASK); eth_write(base_addr, REG_MMC_TX_INTR_MASK, MMC_DEFAULT_MASK); eth_write(base_addr, REG_MMC_RX_IPC_INTR_MASK, MMC_DEFAULT_MASK); eth_write(base_addr, REG_ADDR_DMA_OPERATION, /* Enable receive store-and-forward mode for simplicity. */ OP_MODE_25_RX_STORE_N_FORWARD | /* Enable transmit store-and-forward mode for simplicity. */ OP_MODE_21_TX_STORE_N_FORWARD | /* Place the transmitter state machine in the Running state. */ OP_MODE_13_START_TX | /* Place the receiver state machine in the Running state. */ OP_MODE_1_START_RX); SYS_LOG_INF("Enabled 100M full-duplex mode."); net_driver_ethernet_register_tx(eth_net_tx); config->config_func(port); return 0; }