src/dev/net/ns_gige.cc
void
NSGigE::eepromKick()
{
    switch (eepromState) {

      case eepromStart:

        // Wait for start bit
        if (regs.mear & MEAR_EEDI) {
            // Set up to get 2 opcode bits
            eepromState = eepromGetOpcode;
            eepromBitsToRx = 2;
            eepromOpcode = 0;
        }
        break;

      case eepromGetOpcode:
        eepromOpcode <<= 1;
        eepromOpcode += (regs.mear & MEAR_EEDI) ? 1 : 0;
        --eepromBitsToRx;

        // Done getting opcode
        if (eepromBitsToRx == 0) {
            if (eepromOpcode != EEPROM_READ)
                panic("only EEPROM reads are implemented!");

            // Set up to get address
            eepromState = eepromGetAddress;
            eepromBitsToRx = 6;
            eepromAddress = 0;
        }
        break;

      case eepromGetAddress:
        eepromAddress <<= 1;
        eepromAddress += (regs.mear & MEAR_EEDI) ? 1 : 0;
        --eepromBitsToRx;

        // Done getting address
        if (eepromBitsToRx == 0) {

            if (eepromAddress >= EEPROM_SIZE)
                panic("EEPROM read access out of range!");

            switch (eepromAddress) {

              case EEPROM_PMATCH2_ADDR:
                eepromData = rom.perfectMatch[5];
                eepromData <<= 8;
                eepromData += rom.perfectMatch[4];
                break;

              case EEPROM_PMATCH1_ADDR:
                eepromData = rom.perfectMatch[3];
                eepromData <<= 8;
                eepromData += rom.perfectMatch[2];
                break;

              case EEPROM_PMATCH0_ADDR:
                eepromData = rom.perfectMatch[1];
                eepromData <<= 8;
                eepromData += rom.perfectMatch[0];
                break;

              default:
                panic("FreeBSD driver only uses EEPROM to read PMATCH!");
            }
            // Set up to read data
            eepromState = eepromRead;
            eepromBitsToRx = 16;

            // Clear data in bit
            regs.mear &= ~MEAR_EEDI;
        }
        break;

      case eepromRead:
        // Clear Data Out bit
        regs.mear &= ~MEAR_EEDO;
        // Set bit to value of current EEPROM bit
        regs.mear |= (eepromData & 0x8000) ? MEAR_EEDO : 0x0;

        eepromData <<= 1;
        --eepromBitsToRx;

        // All done
        if (eepromBitsToRx == 0) {
            eepromState = eepromStart;
        }
        break;

      default:
        panic("invalid EEPROM state");
    }

}
/**
 * Advance the EEPROM state machine
 * Called on rising edge of EEPROM clock bit in MEAR
 */
Advance the EEPROM state machine
Called on rising edge of EEPROM clock bit in MEAR
Advance the EEPROM state machine Called on rising edge of EEPROM clock bit in MEAR
void
NSGigE::eepromKick()
{
    switch (eepromState) {
      case eepromStart:
        if (regs.mear & MEAR_EEDI) {
            eepromState = eepromGetOpcode;
            eepromBitsToRx = 2;
            eepromOpcode = 0;
        }
        break;
      case eepromGetOpcode:
        eepromOpcode <<= 1;
        eepromOpcode += (regs.mear & MEAR_EEDI) ? 1 : 0;
        --eepromBitsToRx;
        if (eepromBitsToRx == 0) {
            if (eepromOpcode != EEPROM_READ)
                panic("only EEPROM reads are implemented!");
            eepromState = eepromGetAddress;
            eepromBitsToRx = 6;
            eepromAddress = 0;
        }
        break;
      case eepromGetAddress:
        eepromAddress <<= 1;
        eepromAddress += (regs.mear & MEAR_EEDI) ? 1 : 0;
        --eepromBitsToRx;
        if (eepromBitsToRx == 0) {
            if (eepromAddress >= EEPROM_SIZE)
                panic("EEPROM read access out of range!");
            switch (eepromAddress) {
              case EEPROM_PMATCH2_ADDR:
                eepromData = rom.perfectMatch[5];
                eepromData <<= 8;
                eepromData += rom.perfectMatch[4];
                break;
              case EEPROM_PMATCH1_ADDR:
                eepromData = rom.perfectMatch[3];
                eepromData <<= 8;
                eepromData += rom.perfectMatch[2];
                break;
              case EEPROM_PMATCH0_ADDR:
                eepromData = rom.perfectMatch[1];
                eepromData <<= 8;
                eepromData += rom.perfectMatch[0];
                break;
              default:
                panic("FreeBSD driver only uses EEPROM to read PMATCH!");
            }
            eepromState = eepromRead;
            eepromBitsToRx = 16;
            regs.mear &= ~MEAR_EEDI;
        }
        break;
      case eepromRead:
        regs.mear &= ~MEAR_EEDO;
        regs.mear |= (eepromData & 0x8000) ? MEAR_EEDO : 0x0;
        eepromData <<= 1;
        --eepromBitsToRx;
        if (eepromBitsToRx == 0) {
            eepromState = eepromStart;
        }
        break;
      default:
        panic("invalid EEPROM state");
    }
}
void NSGigE :: eepromKick ( ) { switch ( eepromState ) { case eepromStart : if ( regs . mear & MEAR_EEDI ) { eepromState = eepromGetOpcode ; eepromBitsToRx = 2 ; eepromOpcode = 0 ; } break ; case eepromGetOpcode : eepromOpcode <<= 1 ; eepromOpcode += ( regs . mear & MEAR_EEDI ) ? 1 : 0 ; -- eepromBitsToRx ; if ( eepromBitsToRx == 0 ) { if ( eepromOpcode != EEPROM_READ ) panic ( " " ) ; eepromState = eepromGetAddress ; eepromBitsToRx = 6 ; eepromAddress = 0 ; } break ; case eepromGetAddress : eepromAddress <<= 1 ; eepromAddress += ( regs . mear & MEAR_EEDI ) ? 1 : 0 ; -- eepromBitsToRx ; if ( eepromBitsToRx == 0 ) { if ( eepromAddress >= EEPROM_SIZE ) panic ( " " ) ; switch ( eepromAddress ) { case EEPROM_PMATCH2_ADDR : eepromData = rom . perfectMatch [ 5 ] ; eepromData <<= 8 ; eepromData += rom . perfectMatch [ 4 ] ; break ; case EEPROM_PMATCH1_ADDR : eepromData = rom . perfectMatch [ 3 ] ; eepromData <<= 8 ; eepromData += rom . perfectMatch [ 2 ] ; break ; case EEPROM_PMATCH0_ADDR : eepromData = rom . perfectMatch [ 1 ] ; eepromData <<= 8 ; eepromData += rom . perfectMatch [ 0 ] ; break ; default : panic ( " " ) ; } eepromState = eepromRead ; eepromBitsToRx = 16 ; regs . mear &= ~ MEAR_EEDI ; } break ; case eepromRead : regs . mear &= ~ MEAR_EEDO ; regs . mear |= ( eepromData & 0x8000 ) ? MEAR_EEDO : 0x0 ; eepromData <<= 1 ; -- eepromBitsToRx ; if ( eepromBitsToRx == 0 ) { eepromState = eepromStart ; } break ; default : panic ( " " ) ; } }
Advance the EEPROM state machine
 Called on rising edge of EEPROM clock bit in MEAR
Advance the EEPROM state machine Called on rising edge of EEPROM clock bit in MEAR
// Wait for start bit // Set up to get 2 opcode bits // Done getting opcode // Set up to get address // Done getting address // Set up to read data // Clear data in bit // Clear Data Out bit // Set bit to value of current EEPROM bit // All done