ethdev: better typing of RSS constants
[dpdk.git] / lib / librte_pmd_e1000 / e1000 / e1000_nvm.c
index fc586fe..8be437a 100644 (file)
@@ -1,6 +1,6 @@
 /*******************************************************************************
 
-Copyright (c) 2001-2012, Intel Corporation
+Copyright (c) 2001-2014, Intel Corporation
 All rights reserved.
 
 Redistribution and use in source and binary forms, with or without
@@ -62,9 +62,12 @@ void e1000_init_nvm_ops_generic(struct e1000_hw *hw)
  *  e1000_null_nvm_read - No-op function, return 0
  *  @hw: pointer to the HW structure
  **/
-s32 e1000_null_read_nvm(struct e1000_hw *hw, u16 a, u16 b, u16 *c)
+s32 e1000_null_read_nvm(struct e1000_hw E1000_UNUSEDARG *hw,
+                       u16 E1000_UNUSEDARG a, u16 E1000_UNUSEDARG b,
+                       u16 E1000_UNUSEDARG *c)
 {
        DEBUGFUNC("e1000_null_read_nvm");
+       UNREFERENCED_4PARAMETER(hw, a, b, c);
        return E1000_SUCCESS;
 }
 
@@ -72,9 +75,10 @@ s32 e1000_null_read_nvm(struct e1000_hw *hw, u16 a, u16 b, u16 *c)
  *  e1000_null_nvm_generic - No-op function, return void
  *  @hw: pointer to the HW structure
  **/
-void e1000_null_nvm_generic(struct e1000_hw *hw)
+void e1000_null_nvm_generic(struct e1000_hw E1000_UNUSEDARG *hw)
 {
        DEBUGFUNC("e1000_null_nvm_generic");
+       UNREFERENCED_1PARAMETER(hw);
        return;
 }
 
@@ -82,9 +86,11 @@ void e1000_null_nvm_generic(struct e1000_hw *hw)
  *  e1000_null_led_default - No-op function, return 0
  *  @hw: pointer to the HW structure
  **/
-s32 e1000_null_led_default(struct e1000_hw *hw, u16 *data)
+s32 e1000_null_led_default(struct e1000_hw E1000_UNUSEDARG *hw,
+                          u16 E1000_UNUSEDARG *data)
 {
        DEBUGFUNC("e1000_null_led_default");
+       UNREFERENCED_2PARAMETER(hw, data);
        return E1000_SUCCESS;
 }
 
@@ -92,9 +98,12 @@ s32 e1000_null_led_default(struct e1000_hw *hw, u16 *data)
  *  e1000_null_write_nvm - No-op function, return 0
  *  @hw: pointer to the HW structure
  **/
-s32 e1000_null_write_nvm(struct e1000_hw *hw, u16 a, u16 b, u16 *c)
+s32 e1000_null_write_nvm(struct e1000_hw E1000_UNUSEDARG *hw,
+                        u16 E1000_UNUSEDARG a, u16 E1000_UNUSEDARG b,
+                        u16 E1000_UNUSEDARG *c)
 {
        DEBUGFUNC("e1000_null_write_nvm");
+       UNREFERENCED_4PARAMETER(hw, a, b, c);
        return E1000_SUCCESS;
 }
 
@@ -105,7 +114,7 @@ s32 e1000_null_write_nvm(struct e1000_hw *hw, u16 a, u16 b, u16 *c)
  *
  *  Enable/Raise the EEPROM clock bit.
  **/
-static void e1000_raise_eec_clk(struct e1000_hw *hw, u32 *eecd)
+STATIC void e1000_raise_eec_clk(struct e1000_hw *hw, u32 *eecd)
 {
        *eecd = *eecd | E1000_EECD_SK;
        E1000_WRITE_REG(hw, E1000_EECD, *eecd);
@@ -120,7 +129,7 @@ static void e1000_raise_eec_clk(struct e1000_hw *hw, u32 *eecd)
  *
  *  Clear/Lower the EEPROM clock bit.
  **/
-static void e1000_lower_eec_clk(struct e1000_hw *hw, u32 *eecd)
+STATIC void e1000_lower_eec_clk(struct e1000_hw *hw, u32 *eecd)
 {
        *eecd = *eecd & ~E1000_EECD_SK;
        E1000_WRITE_REG(hw, E1000_EECD, *eecd);
@@ -138,7 +147,7 @@ static void e1000_lower_eec_clk(struct e1000_hw *hw, u32 *eecd)
  *  "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.
  **/
-static void e1000_shift_out_eec_bits(struct e1000_hw *hw, u16 data, u16 count)
+STATIC void e1000_shift_out_eec_bits(struct e1000_hw *hw, u16 data, u16 count)
 {
        struct e1000_nvm_info *nvm = &hw->nvm;
        u32 eecd = E1000_READ_REG(hw, E1000_EECD);
@@ -185,7 +194,7 @@ static void e1000_shift_out_eec_bits(struct e1000_hw *hw, u16 data, u16 count)
  *  "DO" bit.  During this "shifting in" process the data in "DI" bit should
  *  always be clear.
  **/
-static u16 e1000_shift_in_eec_bits(struct e1000_hw *hw, u16 count)
+STATIC u16 e1000_shift_in_eec_bits(struct e1000_hw *hw, u16 count)
 {
        u32 eecd;
        u32 i;
@@ -286,7 +295,7 @@ s32 e1000_acquire_nvm_generic(struct e1000_hw *hw)
  *
  *  Return the EEPROM to a standby state.
  **/
-static void e1000_standby_nvm(struct e1000_hw *hw)
+STATIC void e1000_standby_nvm(struct e1000_hw *hw)
 {
        struct e1000_nvm_info *nvm = &hw->nvm;
        u32 eecd = E1000_READ_REG(hw, E1000_EECD);
@@ -372,7 +381,7 @@ void e1000_release_nvm_generic(struct e1000_hw *hw)
  *
  *  Setups the EEPROM for reading and writing.
  **/
-static s32 e1000_ready_nvm_eeprom(struct e1000_hw *hw)
+STATIC s32 e1000_ready_nvm_eeprom(struct e1000_hw *hw)
 {
        struct e1000_nvm_info *nvm = &hw->nvm;
        u32 eecd = E1000_READ_REG(hw, E1000_EECD);
@@ -396,15 +405,14 @@ static s32 e1000_ready_nvm_eeprom(struct e1000_hw *hw)
                E1000_WRITE_FLUSH(hw);
                usec_delay(1);
 
-               /*
-                * Read "Status Register" repeatedly until the LSB is cleared.
+               /* Read "Status Register" repeatedly until the LSB is cleared.
                 * The EEPROM will signal that the command has been completed
                 * by clearing bit 0 of the internal status register.  If it's
                 * not cleared within 'timeout', then error out.
                 */
                while (timeout) {
                        e1000_shift_out_eec_bits(hw, NVM_RDSR_OPCODE_SPI,
-                                                hw->nvm.opcode_bits);
+                                                hw->nvm.opcode_bits);
                        spi_stat_reg = (u8)e1000_shift_in_eec_bits(hw, 8);
                        if (!(spi_stat_reg & NVM_STATUS_RDY_SPI))
                                break;
@@ -442,8 +450,7 @@ s32 e1000_read_nvm_spi(struct e1000_hw *hw, u16 offset, u16 words, u16 *data)
 
        DEBUGFUNC("e1000_read_nvm_spi");
 
-       /*
-        * A check for invalid values:  offset too large, too many words,
+       /* A check for invalid values:  offset too large, too many words,
         * and not enough words.
         */
        if ((offset >= nvm->word_size) || (words > (nvm->word_size - offset)) ||
@@ -469,8 +476,7 @@ s32 e1000_read_nvm_spi(struct e1000_hw *hw, u16 offset, u16 words, u16 *data)
        e1000_shift_out_eec_bits(hw, read_opcode, nvm->opcode_bits);
        e1000_shift_out_eec_bits(hw, (u16)(offset*2), nvm->address_bits);
 
-       /*
-        * Read the data.  SPI NVMs increment the address with each byte
+       /* Read the data.  SPI NVMs increment the address with each byte
         * read and will roll over if reading beyond the end.  This allows
         * us to read the whole NVM from any offset
         */
@@ -495,7 +501,7 @@ release:
  *  Reads a 16 bit word from the EEPROM.
  **/
 s32 e1000_read_nvm_microwire(struct e1000_hw *hw, u16 offset, u16 words,
-                             u16 *data)
+                            u16 *data)
 {
        struct e1000_nvm_info *nvm = &hw->nvm;
        u32 i = 0;
@@ -504,8 +510,7 @@ s32 e1000_read_nvm_microwire(struct e1000_hw *hw, u16 offset, u16 words,
 
        DEBUGFUNC("e1000_read_nvm_microwire");
 
-       /*
-        * A check for invalid values:  offset too large, too many words,
+       /* A check for invalid values:  offset too large, too many words,
         * and not enough words.
         */
        if ((offset >= nvm->word_size) || (words > (nvm->word_size - offset)) ||
@@ -528,8 +533,7 @@ s32 e1000_read_nvm_microwire(struct e1000_hw *hw, u16 offset, u16 words,
                e1000_shift_out_eec_bits(hw, (u16)(offset + i),
                                        nvm->address_bits);
 
-               /*
-                * Read the data.  For microwire, each word requires the
+               /* Read the data.  For microwire, each word requires the
                 * overhead of setup and tear-down.
                 */
                data[i] = e1000_shift_in_eec_bits(hw, 16);
@@ -559,8 +563,7 @@ s32 e1000_read_nvm_eerd(struct e1000_hw *hw, u16 offset, u16 words, u16 *data)
 
        DEBUGFUNC("e1000_read_nvm_eerd");
 
-       /*
-        * A check for invalid values:  offset too large, too many words,
+       /* A check for invalid values:  offset too large, too many words,
         * too many words for the offset, and not enough words.
         */
        if ((offset >= nvm->word_size) || (words > (nvm->word_size - offset)) ||
@@ -579,7 +582,7 @@ s32 e1000_read_nvm_eerd(struct e1000_hw *hw, u16 offset, u16 words, u16 *data)
                        break;
 
                data[i] = (E1000_READ_REG(hw, E1000_EERD) >>
-                          E1000_NVM_RW_REG_DATA);
+                          E1000_NVM_RW_REG_DATA);
        }
 
        return ret_val;
@@ -605,8 +608,7 @@ s32 e1000_write_nvm_spi(struct e1000_hw *hw, u16 offset, u16 words, u16 *data)
 
        DEBUGFUNC("e1000_write_nvm_spi");
 
-       /*
-        * A check for invalid values:  offset too large, too many words,
+       /* A check for invalid values:  offset too large, too many words,
         * and not enough words.
         */
        if ((offset >= nvm->word_size) || (words > (nvm->word_size - offset)) ||
@@ -632,12 +634,11 @@ s32 e1000_write_nvm_spi(struct e1000_hw *hw, u16 offset, u16 words, u16 *data)
 
                /* Send the WRITE ENABLE command (8 bit opcode) */
                e1000_shift_out_eec_bits(hw, NVM_WREN_OPCODE_SPI,
-                                        nvm->opcode_bits);
+                                        nvm->opcode_bits);
 
                e1000_standby_nvm(hw);
 
-               /*
-                * Some SPI eeproms use the 8th address bit embedded in the
+               /* Some SPI eeproms use the 8th address bit embedded in the
                 * opcode
                 */
                if ((nvm->address_bits == 8) && (offset >= 128))
@@ -646,7 +647,7 @@ s32 e1000_write_nvm_spi(struct e1000_hw *hw, u16 offset, u16 words, u16 *data)
                /* Send the Write command (8-bit opcode + addr) */
                e1000_shift_out_eec_bits(hw, write_opcode, nvm->opcode_bits);
                e1000_shift_out_eec_bits(hw, (u16)((offset + widx) * 2),
-                                        nvm->address_bits);
+                                        nvm->address_bits);
 
                /* Loop to allow for up to whole page write of eeprom */
                while (widx < words) {
@@ -660,8 +661,8 @@ s32 e1000_write_nvm_spi(struct e1000_hw *hw, u16 offset, u16 words, u16 *data)
                                break;
                        }
                }
-       msec_delay(10);
-       nvm->ops.release(hw);
+               msec_delay(10);
+               nvm->ops.release(hw);
        }
 
        return ret_val;
@@ -680,7 +681,7 @@ s32 e1000_write_nvm_spi(struct e1000_hw *hw, u16 offset, u16 words, u16 *data)
  *  EEPROM will most likely contain an invalid checksum.
  **/
 s32 e1000_write_nvm_microwire(struct e1000_hw *hw, u16 offset, u16 words,
-                              u16 *data)
+                             u16 *data)
 {
        struct e1000_nvm_info *nvm = &hw->nvm;
        s32  ret_val;
@@ -690,8 +691,7 @@ s32 e1000_write_nvm_microwire(struct e1000_hw *hw, u16 offset, u16 words,
 
        DEBUGFUNC("e1000_write_nvm_microwire");
 
-       /*
-        * A check for invalid values:  offset too large, too many words,
+       /* A check for invalid values:  offset too large, too many words,
         * and not enough words.
         */
        if ((offset >= nvm->word_size) || (words > (nvm->word_size - offset)) ||
@@ -709,7 +709,7 @@ s32 e1000_write_nvm_microwire(struct e1000_hw *hw, u16 offset, u16 words,
                goto release;
 
        e1000_shift_out_eec_bits(hw, NVM_EWEN_OPCODE_MICROWIRE,
-                                (u16)(nvm->opcode_bits + 2));
+                                (u16)(nvm->opcode_bits + 2));
 
        e1000_shift_out_eec_bits(hw, 0, (u16)(nvm->address_bits - 2));
 
@@ -717,10 +717,10 @@ s32 e1000_write_nvm_microwire(struct e1000_hw *hw, u16 offset, u16 words,
 
        while (words_written < words) {
                e1000_shift_out_eec_bits(hw, NVM_WRITE_OPCODE_MICROWIRE,
-                                        nvm->opcode_bits);
+                                        nvm->opcode_bits);
 
                e1000_shift_out_eec_bits(hw, (u16)(offset + words_written),
-                                        nvm->address_bits);
+                                        nvm->address_bits);
 
                e1000_shift_out_eec_bits(hw, data[words_written], 16);
 
@@ -745,7 +745,7 @@ s32 e1000_write_nvm_microwire(struct e1000_hw *hw, u16 offset, u16 words,
        }
 
        e1000_shift_out_eec_bits(hw, NVM_EWDS_OPCODE_MICROWIRE,
-                                (u16)(nvm->opcode_bits + 2));
+                                (u16)(nvm->opcode_bits + 2));
 
        e1000_shift_out_eec_bits(hw, 0, (u16)(nvm->address_bits - 2));
 
@@ -765,7 +765,7 @@ release:
  *  the value in pba_num.
  **/
 s32 e1000_read_pba_string_generic(struct e1000_hw *hw, u8 *pba_num,
-                                  u32 pba_num_size)
+                                 u32 pba_num_size)
 {
        s32 ret_val;
        u16 nvm_data;
@@ -775,6 +775,12 @@ s32 e1000_read_pba_string_generic(struct e1000_hw *hw, u8 *pba_num,
 
        DEBUGFUNC("e1000_read_pba_string_generic");
 
+       if ((hw->mac.type >= e1000_i210) &&
+           !e1000_get_flash_presence_i210(hw)) {
+               DEBUGOUT("Flashless no PBA string\n");
+               return -E1000_ERR_NVM_PBA_SECTION;
+       }
+
        if (pba_num == NULL) {
                DEBUGOUT("PBA string buffer was null\n");
                return -E1000_ERR_INVALID_ARGUMENT;
@@ -792,8 +798,7 @@ s32 e1000_read_pba_string_generic(struct e1000_hw *hw, u8 *pba_num,
                return ret_val;
        }
 
-       /*
-        * if nvm_data is not ptr guard the PBA must be in legacy format which
+       /* if nvm_data is not ptr guard the PBA must be in legacy format which
         * means pba_ptr is actually our second data word for the PBA number
         * and we can decode it into an ascii string
         */
@@ -917,8 +922,7 @@ s32 e1000_read_pba_length_generic(struct e1000_hw *hw, u32 *pba_num_size)
                return -E1000_ERR_NVM_PBA_SECTION;
        }
 
-       /*
-        * Convert from length in u16 values to u8 chars, add 1 for NULL,
+       /* Convert from length in u16 values to u8 chars, add 1 for NULL,
         * and subtract 2 because length field is included in length.
         */
        *pba_num_size = ((u32)length * 2) - 1;
@@ -926,6 +930,41 @@ s32 e1000_read_pba_length_generic(struct e1000_hw *hw, u32 *pba_num_size)
        return E1000_SUCCESS;
 }
 
+/**
+ *  e1000_read_pba_num_generic - Read device part number
+ *  @hw: pointer to the HW structure
+ *  @pba_num: pointer to device part number
+ *
+ *  Reads the product board assembly (PBA) number from the EEPROM and stores
+ *  the value in pba_num.
+ **/
+s32 e1000_read_pba_num_generic(struct e1000_hw *hw, u32 *pba_num)
+{
+       s32 ret_val;
+       u16 nvm_data;
+
+       DEBUGFUNC("e1000_read_pba_num_generic");
+
+       ret_val = hw->nvm.ops.read(hw, NVM_PBA_OFFSET_0, 1, &nvm_data);
+       if (ret_val) {
+               DEBUGOUT("NVM Read Error\n");
+               return ret_val;
+       } else if (nvm_data == NVM_PBA_PTR_GUARD) {
+               DEBUGOUT("NVM Not Supported\n");
+               return -E1000_NOT_IMPLEMENTED;
+       }
+       *pba_num = (u32)(nvm_data << 16);
+
+       ret_val = hw->nvm.ops.read(hw, NVM_PBA_OFFSET_1, 1, &nvm_data);
+       if (ret_val) {
+               DEBUGOUT("NVM Read Error\n");
+               return ret_val;
+       }
+       *pba_num |= nvm_data;
+
+       return E1000_SUCCESS;
+}
+
 
 /**
  *  e1000_read_pba_raw
@@ -984,7 +1023,7 @@ s32 e1000_read_pba_raw(struct e1000_hw *hw, u16 *eeprom_buf,
                                return ret_val;
                } else {
                        if (eeprom_buf_size > (u32)(pba->word[1] +
-                                             pba->pba_block[0])) {
+                                             pba_block_size)) {
                                memcpy(pba->pba_block,
                                       &eeprom_buf[pba->word[1]],
                                       pba_block_size * sizeof(u16));
@@ -1094,7 +1133,7 @@ s32 e1000_get_pba_block_size(struct e1000_hw *hw, u16 *eeprom_buf,
                        ret_val = e1000_read_nvm(hw, pba_word[1] + 0, 1,
                                                 &length);
                        if (ret_val)
-       return ret_val;
+                               return ret_val;
                } else {
                        if (eeprom_buf_size > pba_word[1])
                                length = eeprom_buf[pba_word[1] + 0];
@@ -1237,12 +1276,15 @@ STATIC void e1000_reload_nvm_generic(struct e1000_hw *hw)
  **/
 void e1000_get_fw_version(struct e1000_hw *hw, struct e1000_fw_version *fw_vers)
 {
-       u16 eeprom_verh, eeprom_verl, fw_version;
+       u16 eeprom_verh, eeprom_verl, etrack_test, fw_version;
+       u8 q, hval, rem, result;
        u16 comb_verh, comb_verl, comb_offset;
 
        memset(fw_vers, 0, sizeof(struct e1000_fw_version));
 
-       /* this code only applies to certain mac types */
+       /* basic eeprom version numbers, bits used vary by part and by tool
+        * used to create the nvm images */
+       /* Check which data format we have */
        switch (hw->mac.type) {
        case e1000_i211:
                e1000_read_invm_version(hw, fw_vers);
@@ -1250,26 +1292,28 @@ void e1000_get_fw_version(struct e1000_hw *hw, struct e1000_fw_version *fw_vers)
        case e1000_82575:
        case e1000_82576:
        case e1000_82580:
-       case e1000_i350:
-       case e1000_i210:
+               hw->nvm.ops.read(hw, NVM_ETRACK_HIWORD, 1, &etrack_test);
+               /* Use this format, unless EETRACK ID exists,
+                * then use alternate format
+                */
+               if ((etrack_test &  NVM_MAJOR_MASK) != NVM_ETRACK_VALID) {
+                       hw->nvm.ops.read(hw, NVM_VERSION, 1, &fw_version);
+                       fw_vers->eep_major = (fw_version & NVM_MAJOR_MASK)
+                                             >> NVM_MAJOR_SHIFT;
+                       fw_vers->eep_minor = (fw_version & NVM_MINOR_MASK)
+                                             >> NVM_MINOR_SHIFT;
+                       fw_vers->eep_build = (fw_version & NVM_IMAGE_ID_MASK);
+                       goto etrack_id;
+               }
                break;
-       default:
-               return;
-       }
-
-       /* basic eeprom version numbers */
-       hw->nvm.ops.read(hw, NVM_VERSION, 1, &fw_version);
-       fw_vers->eep_major = (fw_version & NVM_MAJOR_MASK) >> NVM_MAJOR_SHIFT;
-       fw_vers->eep_minor = (fw_version & NVM_MINOR_MASK);
-
-       /* etrack id */
-       hw->nvm.ops.read(hw, NVM_ETRACK_WORD, 1, &eeprom_verl);
-       hw->nvm.ops.read(hw, (NVM_ETRACK_WORD + 1), 1, &eeprom_verh);
-       fw_vers->etrack_id = (eeprom_verh << NVM_ETRACK_SHIFT) | eeprom_verl;
-
-       switch (hw->mac.type) {
        case e1000_i210:
+               if (!(e1000_get_flash_presence_i210(hw))) {
+                       e1000_read_invm_version(hw, fw_vers);
+                       return;
+               }
+               /* fall through */
        case e1000_i350:
+               hw->nvm.ops.read(hw, NVM_ETRACK_HIWORD, 1, &etrack_test);
                /* find combo image version */
                hw->nvm.ops.read(hw, NVM_COMB_VER_PTR, 1, &comb_offset);
                if ((comb_offset != 0x0) &&
@@ -1296,9 +1340,36 @@ void e1000_get_fw_version(struct e1000_hw *hw, struct e1000_fw_version *fw_vers)
                        }
                }
                break;
-
        default:
-               break;
+               hw->nvm.ops.read(hw, NVM_ETRACK_HIWORD, 1, &etrack_test);
+               return;
+       }
+       hw->nvm.ops.read(hw, NVM_VERSION, 1, &fw_version);
+       fw_vers->eep_major = (fw_version & NVM_MAJOR_MASK)
+                             >> NVM_MAJOR_SHIFT;
+
+       /* check for old style version format in newer images*/
+       if ((fw_version & NVM_NEW_DEC_MASK) == 0x0) {
+               eeprom_verl = (fw_version & NVM_COMB_VER_MASK);
+       } else {
+               eeprom_verl = (fw_version & NVM_MINOR_MASK)
+                               >> NVM_MINOR_SHIFT;
+       }
+       /* Convert minor value to hex before assigning to output struct
+        * Val to be converted will not be higher than 99, per tool output
+        */
+       q = eeprom_verl / NVM_HEX_CONV;
+       hval = q * NVM_HEX_TENS;
+       rem = eeprom_verl % NVM_HEX_CONV;
+       result = hval + rem;
+       fw_vers->eep_minor = result;
+
+etrack_id:
+       if ((etrack_test &  NVM_MAJOR_MASK) == NVM_ETRACK_VALID) {
+               hw->nvm.ops.read(hw, NVM_ETRACK_WORD, 1, &eeprom_verl);
+               hw->nvm.ops.read(hw, (NVM_ETRACK_WORD + 1), 1, &eeprom_verh);
+               fw_vers->etrack_id = (eeprom_verh << NVM_ETRACK_SHIFT)
+                       | eeprom_verl;
        }
        return;
 }