static void sis900_init(struct nic *nic) { sis900_reset(nic); sis900_init_rxfilter(nic); sis900_init_txd(nic); sis900_init_rxd(nic); sis900_set_rx_mode(nic); sis900_check_mode(nic); outl(RxENA, ioaddr + cr); }
static int sis900_open(struct device *net_dev) { struct sis900_private *sis_priv = (struct sis900_private *)net_dev->priv; long ioaddr = net_dev->base_addr; /* Soft reset the chip. */ sis900_reset(net_dev); if (request_irq(net_dev->irq, &sis900_interrupt, SA_SHIRQ, net_dev->name, net_dev)) { return -EAGAIN; } MOD_INC_USE_COUNT; sis900_init_rxfilter(net_dev); sis900_init_tx_ring(net_dev); sis900_init_rx_ring(net_dev); set_rx_mode(net_dev); net_dev->tbusy = 0; net_dev->interrupt = 0; net_dev->start = 1; /* Enable all known interrupts by setting the interrupt mask. */ outl((RxSOVR|RxORN|RxERR|RxOK|TxURN|TxERR|TxIDLE), ioaddr + imr); outl(RxENA, ioaddr + cr); outl(IE, ioaddr + ier); sis900_check_mode(net_dev, sis_priv->mii); /* Set the timer to switch to check for link beat and perhaps switch to an alternate media type. */ init_timer(&sis_priv->timer); sis_priv->timer.expires = jiffies + HZ; sis_priv->timer.data = (unsigned long)net_dev; sis_priv->timer.function = &sis900_timer; add_timer(&sis_priv->timer); return 0; }
status_t device_open(const char *name, uint32 flags, void **cookie) { struct sis_info *info; area_id area; int id; // verify device access (we only allow one user at a time) { char *thisName; int32 mask; // search for device name for (id = 0; (thisName = gDeviceNames[id]) != NULL; id++) { if (!strcmp(name, thisName)) break; } if (!thisName) return EINVAL; // check if device is already open mask = 1L << id; if (atomic_or(&gDeviceOpenMask, mask) & mask) return B_BUSY; } // allocate internal device structure if ((area = create_area(DEVICE_NAME " private data", cookie, B_ANY_KERNEL_ADDRESS, ROUND_TO_PAGE_SIZE(sizeof(struct sis_info)), B_FULL_LOCK, B_READ_AREA | B_WRITE_AREA)) < B_OK) { gDeviceOpenMask &= ~(1L << id); return B_NO_MEMORY; } info = (struct sis_info *)*cookie; memset(info, 0, sizeof(struct sis_info)); info->cookieMagic = SiS_COOKIE_MAGIC; info->thisArea = area; info->id = id; info->pciInfo = pciInfo[id]; info->registers = (addr_t)pciInfo[id]->u.h0.base_registers[0]; if (sis900_getMACAddress(info)) dprintf(DEVICE_NAME ": MAC address %02x:%02x:%02x:%02x:%02x:%02x\n", info->address.ebyte[0], info->address.ebyte[1], info->address.ebyte[2], info->address.ebyte[3], info->address.ebyte[4], info->address.ebyte[5]); else dprintf(DEVICE_NAME ": could not get MAC address\n"); readSettings(info); if (createSemaphores(info) == B_OK) { status_t status = sis900_initPHYs(info); if (status == B_OK) { TRACE((DEVICE_NAME ": MII status = %d\n", mdio_read(info, MII_STATUS))); //sis900_configFIFOs(info); sis900_reset(info); // install & enable interrupts install_io_interrupt_handler(info->pciInfo->u.h0.interrupt_line, sis900_interrupt, info, 0); sis900_enableInterrupts(info); sis900_setRxFilter(info); sis900_createRings(info); // enable receiver's state machine write32(info->registers + SiS900_MAC_COMMAND, SiS900_MAC_CMD_Rx_ENABLE); // check link mode & add timer (once every second) sis900_checkMode(info); add_timer(&info->timer, sis900_timer, 1000000LL, B_PERIODIC_TIMER); return B_OK; } dprintf(DEVICE_NAME ": could not initialize MII PHY: %s\n", strerror(status)); deleteSemaphores(info); } else dprintf(DEVICE_NAME ": could not create semaphores.\n"); gDeviceOpenMask &= ~(1L << id); delete_area(area); return B_ERROR; }