src/dev/net/ns_gige.cc
/**
 * 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