/* . Function: smc_enable . Purpose: let the chip talk to the outside work . Method: . 1. Enable the transmitter . 2. Enable the receiver . 3. Enable interrupts */ static void smc_enable(struct eth_device *dev) { PRINTK2("%s: smc_enable\n", SMC_DEV_NAME); SMC_SELECT_BANK( dev, 0 ); /* see the header file for options in TCR/RCR DEFAULT*/ SMC_outw( dev, TCR_DEFAULT, TCR_REG ); SMC_outw( dev, RCR_DEFAULT, RCR_REG ); /* clear MII_DIS */ /* smc_write_phy_register(PHY_CNTL_REG, 0x0000); */ }
/* . Function: smc_reset( void ) . Purpose: . This sets the SMC91111 chip to its normal state, hopefully from whatever . mess that any other DOS driver has put it in. . . Maybe I should reset more registers to defaults in here? SOFTRST should . do that for me. . . Method: . 1. send a SOFT RESET . 2. wait for it to finish . 3. enable autorelease mode . 4. reset the memory management unit . 5. clear all interrupts . */ static void smc_reset (struct eth_device *dev) { PRINTK2 ("%s: smc_reset\n", SMC_DEV_NAME); /* This resets the registers mostly to defaults, but doesn't affect EEPROM. That seems unnecessary */ SMC_SELECT_BANK (dev, 0); SMC_outw (dev, RCR_SOFTRST, RCR_REG); /* Setup the Configuration Register */ /* This is necessary because the CONFIG_REG is not affected */ /* by a soft reset */ SMC_SELECT_BANK (dev, 1); #if defined(CONFIG_SMC91111_EXT_PHY) SMC_outw (dev, CONFIG_DEFAULT | CONFIG_EXT_PHY, CONFIG_REG); #else SMC_outw (dev, CONFIG_DEFAULT, CONFIG_REG); #endif /* Release from possible power-down state */ /* Configuration register is not affected by Soft Reset */ SMC_outw (dev, SMC_inw (dev, CONFIG_REG) | CONFIG_EPH_POWER_EN, CONFIG_REG); SMC_SELECT_BANK (dev, 0); /* this should pause enough for the chip to be happy */ udelay (10); /* Disable transmit and receive functionality */ SMC_outw (dev, RCR_CLEAR, RCR_REG); SMC_outw (dev, TCR_CLEAR, TCR_REG); /* set the control register */ SMC_SELECT_BANK (dev, 1); SMC_outw (dev, CTL_DEFAULT, CTL_REG); /* Reset the MMU */ SMC_SELECT_BANK (dev, 2); smc_wait_mmu_release_complete (dev); SMC_outw (dev, MC_RESET, MMU_CMD_REG); while (SMC_inw (dev, MMU_CMD_REG) & MC_BUSY) udelay (1); /* Wait until not busy */ /* Note: It doesn't seem that waiting for the MMU busy is needed here, but this is a place where future chipsets _COULD_ break. Be wary of issuing another MMU command right after this */ /* Disable all interrupts */ SMC_outb (dev, 0, IM_REG); }
/* . Function: smc_halt . Purpose: closes down the SMC91xxx chip. . Method: . 1. zero the interrupt mask . 2. clear the enable receive flag . 3. clear the enable xmit flags . . TODO: . (1) maybe utilize power down mode. . Why not yet? Because while the chip will go into power down mode, . the manual says that it will wake up in response to any I/O requests . in the register space. Empirical results do not show this working. */ static void smc_halt(struct eth_device *dev) { PRINTK2("%s: smc_halt\n", SMC_DEV_NAME); /* no more interrupts for me */ SMC_SELECT_BANK( dev, 2 ); SMC_outb( dev, 0, IM_REG ); /* and tell the card to stay away from that nasty outside world */ SMC_SELECT_BANK( dev, 0 ); SMC_outb( dev, RCR_CLEAR, RCR_REG ); SMC_outb( dev, TCR_CLEAR, TCR_REG ); swap_to(FLASH); }
/* . Function: smc_shutdown . Purpose: closes down the SMC91xxx chip. . Method: . 1. zero the interrupt mask . 2. clear the enable receive flag . 3. clear the enable xmit flags . . TODO: . (1) maybe utilize power down mode. . Why not yet? Because while the chip will go into power down mode, . the manual says that it will wake up in response to any I/O requests . in the register space. Empirical results do not show this working. */ static void smc_shutdown() { PRINTK2(CARDNAME ": smc_shutdown\n"); /* no more interrupts for me */ SMC_SELECT_BANK( 2 ); SMC_outb( 0, IM_REG ); /* and tell the card to stay away from that nasty outside world */ SMC_SELECT_BANK( 0 ); SMC_outb( RCR_CLEAR, RCR_REG ); SMC_outb( TCR_CLEAR, TCR_REG ); #ifdef SHARED_RESOURCES swap_to(FLASH); #endif }
static int poll4int (struct eth_device *dev, byte mask, int timeout) { int tmo = get_timer (0) + timeout * CONFIG_SYS_HZ; int is_timeout = 0; word old_bank = SMC_inw (dev, BSR_REG); PRINTK2 ("Polling...\n"); SMC_SELECT_BANK (dev, 2); while ((SMC_inw (dev, SMC91111_INT_REG) & mask) == 0) { if (get_timer (0) >= tmo) { is_timeout = 1; break; } } /* restore old bank selection */ SMC_SELECT_BANK (dev, old_bank); if (is_timeout) return 1; else return 0; }
static int poll4int (byte mask, int timeout) { int tmo = get_timer (0) + timeout * CFG_HZ; int is_timeout = 0; word old_bank = SMC_inw (BSR_REG); PRINTK2 ("Polling...\n"); SMC_SELECT_BANK (2); while ((SMC_inw (SMC91111_INT_REG) & mask) == 0) { if (get_timer (0) >= tmo) { is_timeout = 1; break; } } /* restore old bank selection */ SMC_SELECT_BANK (old_bank); if (is_timeout) return 1; else return 0; }