/****************************************************************************** * Returns EEPROM to a "standby" state * * hw - Struct containing variables accessed by shared code *****************************************************************************/ static void ixgb_standby_eeprom(struct ixgb_hw *hw) { u32 eecd_reg; eecd_reg = IXGB_READ_REG(hw, EECD); /* Deselect EEPROM */ eecd_reg &= ~(IXGB_EECD_CS | IXGB_EECD_SK); IXGB_WRITE_REG(hw, EECD, eecd_reg); IXGB_WRITE_FLUSH(hw); udelay(50); /* Clock high */ eecd_reg |= IXGB_EECD_SK; IXGB_WRITE_REG(hw, EECD, eecd_reg); IXGB_WRITE_FLUSH(hw); udelay(50); /* Select EEPROM */ eecd_reg |= IXGB_EECD_CS; IXGB_WRITE_REG(hw, EECD, eecd_reg); IXGB_WRITE_FLUSH(hw); udelay(50); /* Clock low */ eecd_reg &= ~IXGB_EECD_SK; IXGB_WRITE_REG(hw, EECD, eecd_reg); IXGB_WRITE_FLUSH(hw); udelay(50); }
/****************************************************************************** * Raises then lowers the EEPROM's clock pin * * hw - Struct containing variables accessed by shared code *****************************************************************************/ static void ixgb_clock_eeprom(struct ixgb_hw *hw) { u32 eecd_reg; eecd_reg = IXGB_READ_REG(hw, EECD); /* Rising edge of clock */ eecd_reg |= IXGB_EECD_SK; IXGB_WRITE_REG(hw, EECD, eecd_reg); IXGB_WRITE_FLUSH(hw); udelay(50); /* Falling edge of clock */ eecd_reg &= ~IXGB_EECD_SK; IXGB_WRITE_REG(hw, EECD, eecd_reg); IXGB_WRITE_FLUSH(hw); udelay(50); }
/****************************************************************************** * Lowers the EEPROM's clock input. * * hw - Struct containing variables accessed by shared code * eecd_reg - EECD's current value *****************************************************************************/ static void ixgb_lower_clock(struct ixgb_hw *hw, u32 *eecd_reg) { /* Lower the clock input to the EEPROM (by clearing the SK bit), and then * wait 50 microseconds. */ *eecd_reg = *eecd_reg & ~IXGB_EECD_SK; IXGB_WRITE_REG(hw, EECD, *eecd_reg); IXGB_WRITE_FLUSH(hw); udelay(50); }
/****************************************************************************** * Raises the EEPROM's clock input. * * hw - Struct containing variables accessed by shared code * eecd_reg - EECD's current value *****************************************************************************/ static void ixgb_raise_clock(struct ixgb_hw *hw, u32 *eecd_reg) { /* Raise the clock input to the EEPROM (by setting the SK bit), and then * wait 50 microseconds. */ *eecd_reg = *eecd_reg | IXGB_EECD_SK; IXGB_WRITE_REG(hw, EECD, *eecd_reg); IXGB_WRITE_FLUSH(hw); udelay(50); }
/****************************************************************************** * Reset the transmit and receive units; mask and clear all interrupts. * * hw - Struct containing variables accessed by shared code *****************************************************************************/ bool ixgb_adapter_stop(struct ixgb_hw *hw) { u32 ctrl_reg; u32 icr_reg; ENTER(); /* If we are stopped or resetting exit gracefully and wait to be * started again before accessing the hardware. */ if (hw->adapter_stopped) { pr_debug("Exiting because the adapter is already stopped!!!\n"); return false; } /* Set the Adapter Stopped flag so other driver functions stop * touching the Hardware. */ hw->adapter_stopped = true; /* Clear interrupt mask to stop board from generating interrupts */ pr_debug("Masking off all interrupts\n"); IXGB_WRITE_REG(hw, IMC, 0xFFFFFFFF); /* Disable the Transmit and Receive units. Then delay to allow * any pending transactions to complete before we hit the MAC with * the global reset. */ IXGB_WRITE_REG(hw, RCTL, IXGB_READ_REG(hw, RCTL) & ~IXGB_RCTL_RXEN); IXGB_WRITE_REG(hw, TCTL, IXGB_READ_REG(hw, TCTL) & ~IXGB_TCTL_TXEN); IXGB_WRITE_FLUSH(hw); msleep(IXGB_DELAY_BEFORE_RESET); /* Issue a global reset to the MAC. This will reset the chip's * transmit, receive, DMA, and link units. It will not effect * the current PCI configuration. The global reset bit is self- * clearing, and should clear within a microsecond. */ pr_debug("Issuing a global reset to MAC\n"); ctrl_reg = ixgb_mac_reset(hw); /* Clear interrupt mask to stop board from generating interrupts */ pr_debug("Masking off all interrupts\n"); IXGB_WRITE_REG(hw, IMC, 0xffffffff); /* Clear any pending interrupt events. */ icr_reg = IXGB_READ_REG(hw, ICR); return ctrl_reg & IXGB_CTRL0_RST; }
/****************************************************************************** * Shift data bits out to the EEPROM. * * hw - Struct containing variables accessed by shared code * data - data to send to the EEPROM * count - number of bits to shift out *****************************************************************************/ static void ixgb_shift_out_bits(struct ixgb_hw *hw, u16 data, u16 count) { u32 eecd_reg; u32 mask; /* We need to shift "count" bits out to the EEPROM. So, value in the * "data" parameter will be shifted out to the EEPROM one bit at a time. * In order to do this, "data" must be broken down into bits. */ mask = 0x01 << (count - 1); eecd_reg = IXGB_READ_REG(hw, EECD); eecd_reg &= ~(IXGB_EECD_DO | IXGB_EECD_DI); do { /* A "1" is shifted out to the EEPROM by setting bit "DI" to a "1", * and then raising and then lowering the clock (the SK bit controls * the clock input to the EEPROM). A "0" is shifted out to the EEPROM * by setting "DI" to "0" and then raising and then lowering the clock. */ eecd_reg &= ~IXGB_EECD_DI; if (data & mask) eecd_reg |= IXGB_EECD_DI; IXGB_WRITE_REG(hw, EECD, eecd_reg); IXGB_WRITE_FLUSH(hw); udelay(50); ixgb_raise_clock(hw, &eecd_reg); ixgb_lower_clock(hw, &eecd_reg); mask = mask >> 1; } while (mask); /* We leave the "DI" bit set to "0" when we leave this routine. */ eecd_reg &= ~IXGB_EECD_DI; IXGB_WRITE_REG(hw, EECD, eecd_reg); }