fm10k: move to drivers/net/
[dpdk.git] / lib / librte_pmd_i40e / i40e / i40e_common.c
index eb1ca9d..06ccde5 100644 (file)
@@ -36,6 +36,7 @@ POSSIBILITY OF SUCH DAMAGE.
 #include "i40e_prototype.h"
 #include "i40e_virtchnl.h"
 
+
 /**
  * i40e_set_mac_type - Sets MAC type
  * @hw: pointer to the HW structure
@@ -551,6 +552,30 @@ struct i40e_rx_ptype_decoded i40e_ptype_lookup[] = {
        I40E_PTT_UNUSED_ENTRY(255)
 };
 
+
+/**
+ * i40e_validate_mac_addr - Validate unicast MAC address
+ * @mac_addr: pointer to MAC address
+ *
+ * Tests a MAC address to ensure it is a valid Individual Address
+ **/
+enum i40e_status_code i40e_validate_mac_addr(u8 *mac_addr)
+{
+       enum i40e_status_code status = I40E_SUCCESS;
+
+       DEBUGFUNC("i40e_validate_mac_addr");
+
+       /* Broadcast addresses ARE multicast addresses
+        * Make sure it is not a multicast address
+        * Reject the zero address
+        */
+       if (I40E_IS_MULTICAST(mac_addr) ||
+           (mac_addr[0] == 0 && mac_addr[1] == 0 && mac_addr[2] == 0 &&
+             mac_addr[3] == 0 && mac_addr[4] == 0 && mac_addr[5] == 0))
+               status = I40E_ERR_INVALID_MAC_ADDR;
+
+       return status;
+}
 #ifdef PF_DRIVER
 
 /**
@@ -735,25 +760,60 @@ void i40e_pre_tx_queue_cfg(struct i40e_hw *hw, u32 queue, bool enable)
 }
 
 /**
- * i40e_validate_mac_addr - Validate unicast MAC address
- * @mac_addr: pointer to MAC address
+ *  i40e_read_pba_string - Reads part number string from EEPROM
+ *  @hw: pointer to hardware structure
+ *  @pba_num: stores the part number string from the EEPROM
+ *  @pba_num_size: part number string buffer length
  *
- * Tests a MAC address to ensure it is a valid Individual Address
+ *  Reads the part number string from the EEPROM.
  **/
-enum i40e_status_code i40e_validate_mac_addr(u8 *mac_addr)
+enum i40e_status_code i40e_read_pba_string(struct i40e_hw *hw, u8 *pba_num,
+                                           u32 pba_num_size)
 {
        enum i40e_status_code status = I40E_SUCCESS;
+       u16 pba_word = 0;
+       u16 pba_size = 0;
+       u16 pba_ptr = 0;
+       u16 i = 0;
 
-       DEBUGFUNC("i40e_validate_mac_addr");
+       status = i40e_read_nvm_word(hw, I40E_SR_PBA_FLAGS, &pba_word);
+       if ((status != I40E_SUCCESS) || (pba_word != 0xFAFA)) {
+               DEBUGOUT("Failed to read PBA flags or flag is invalid.\n");
+               return status;
+       }
 
-       /* Broadcast addresses ARE multicast addresses
-        * Make sure it is not a multicast address
-        * Reject the zero address
+       status = i40e_read_nvm_word(hw, I40E_SR_PBA_BLOCK_PTR, &pba_ptr);
+       if (status != I40E_SUCCESS) {
+               DEBUGOUT("Failed to read PBA Block pointer.\n");
+               return status;
+       }
+
+       status = i40e_read_nvm_word(hw, pba_ptr, &pba_size);
+       if (status != I40E_SUCCESS) {
+               DEBUGOUT("Failed to read PBA Block size.\n");
+               return status;
+       }
+
+       /* Subtract one to get PBA word count (PBA Size word is included in
+        * total size)
         */
-       if (I40E_IS_MULTICAST(mac_addr) ||
-           (mac_addr[0] == 0 && mac_addr[1] == 0 && mac_addr[2] == 0 &&
-             mac_addr[3] == 0 && mac_addr[4] == 0 && mac_addr[5] == 0))
-               status = I40E_ERR_INVALID_MAC_ADDR;
+       pba_size--;
+       if (pba_num_size < (((u32)pba_size * 2) + 1)) {
+               DEBUGOUT("Buffer to small for PBA data.\n");
+               return I40E_ERR_PARAM;
+       }
+
+       for (i = 0; i < pba_size; i++) {
+               status = i40e_read_nvm_word(hw, (pba_ptr + 1) + i, &pba_word);
+               if (status != I40E_SUCCESS) {
+                       DEBUGOUT1("Failed to read PBA Block word %d.\n", i);
+                       return status;
+               }
+
+               pba_num[(i * 2)] = (pba_word >> 8) & 0xFF;
+               pba_num[(i * 2) + 1] = pba_word & 0xFF;
+       }
+       pba_num[(pba_size * 2)] = '\0';
 
        return status;
 }
@@ -808,7 +868,7 @@ STATIC enum i40e_media_type i40e_get_media_type(struct i40e_hw *hw)
        return media;
 }
 
-#define I40E_PF_RESET_WAIT_COUNT       100
+#define I40E_PF_RESET_WAIT_COUNT       110
 /**
  * i40e_pf_reset - Reset the PF
  * @hw: pointer to the hardware structure
@@ -827,8 +887,9 @@ enum i40e_status_code i40e_pf_reset(struct i40e_hw *hw)
         * The grst delay value is in 100ms units, and we'll wait a
         * couple counts longer to be sure we don't just miss the end.
         */
-       grst_del = rd32(hw, I40E_GLGEN_RSTCTL) & I40E_GLGEN_RSTCTL_GRSTDEL_MASK
-                       >> I40E_GLGEN_RSTCTL_GRSTDEL_SHIFT;
+       grst_del = (rd32(hw, I40E_GLGEN_RSTCTL) &
+                       I40E_GLGEN_RSTCTL_GRSTDEL_MASK) >>
+                       I40E_GLGEN_RSTCTL_GRSTDEL_SHIFT;
        for (cnt = 0; cnt < grst_del + 2; cnt++) {
                reg = rd32(hw, I40E_GLGEN_RSTAT);
                if (!(reg & I40E_GLGEN_RSTAT_DEVSTATE_MASK))
@@ -1247,7 +1308,7 @@ enum i40e_status_code i40e_set_fc(struct i40e_hw *hw, u8 *aq_failures,
                return status;
        }
 
-       memset(&config, 0, sizeof(struct i40e_aq_set_phy_config));
+       memset(&config, 0, sizeof(config));
        /* clear the old pause settings */
        config.abilities = abilities.abilities & ~(I40E_AQ_PHY_FLAG_PAUSE_TX) &
                           ~(I40E_AQ_PHY_FLAG_PAUSE_RX);
@@ -1415,7 +1476,7 @@ enum i40e_status_code i40e_aq_get_link_info(struct i40e_hw *hw,
 
        /* save off old link status information */
        i40e_memcpy(&hw->phy.link_info_old, hw_link_info,
-                   sizeof(struct i40e_link_status), I40E_NONDMA_TO_NONDMA);
+                   sizeof(*hw_link_info), I40E_NONDMA_TO_NONDMA);
 
        /* update link status */
        hw_link_info->phy_type = (enum i40e_aq_phy_type)resp->phy_type;
@@ -1456,7 +1517,7 @@ enum i40e_status_code i40e_aq_get_link_info(struct i40e_hw *hw,
 
        /* save link status information */
        if (link)
-               i40e_memcpy(link, hw_link_info, sizeof(struct i40e_link_status),
+               i40e_memcpy(link, hw_link_info, sizeof(*hw_link_info),
                            I40E_NONDMA_TO_NONDMA);
 
        /* flag cleared so helper functions don't call AQ again */
@@ -1466,6 +1527,7 @@ aq_get_link_info_exit:
        return status;
 }
 
+
 /**
  * i40e_aq_set_phy_int_mask
  * @hw: pointer to the hw struct
@@ -2192,7 +2254,7 @@ enum i40e_status_code i40e_aq_add_macvlan(struct i40e_hw *hw, u16 seid,
        if (count == 0 || !mv_list || !hw)
                return I40E_ERR_PARAM;
 
-       buf_size = count * sizeof(struct i40e_aqc_add_macvlan_element_data);
+       buf_size = count * sizeof(*mv_list);
 
        /* prep the rest of the request */
        i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_add_macvlan);
@@ -2234,7 +2296,7 @@ enum i40e_status_code i40e_aq_remove_macvlan(struct i40e_hw *hw, u16 seid,
        if (count == 0 || !mv_list || !hw)
                return I40E_ERR_PARAM;
 
-       buf_size = count * sizeof(struct i40e_aqc_remove_macvlan_element_data);
+       buf_size = count * sizeof(*mv_list);
 
        /* prep the rest of the request */
        i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_remove_macvlan);
@@ -2274,7 +2336,7 @@ enum i40e_status_code i40e_aq_add_vlan(struct i40e_hw *hw, u16 seid,
        if (count == 0 || !v_list || !hw)
                return I40E_ERR_PARAM;
 
-       buf_size = count * sizeof(struct i40e_aqc_add_remove_vlan_element_data);
+       buf_size = count * sizeof(*v_list);
 
        /* prep the rest of the request */
        i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_add_vlan);
@@ -2314,7 +2376,7 @@ enum i40e_status_code i40e_aq_remove_vlan(struct i40e_hw *hw, u16 seid,
        if (count == 0 || !v_list || !hw)
                return I40E_ERR_PARAM;
 
-       buf_size = count * sizeof(struct i40e_aqc_add_remove_vlan_element_data);
+       buf_size = count * sizeof(*v_list);
 
        /* prep the rest of the request */
        i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_remove_vlan);
@@ -2619,6 +2681,77 @@ i40e_aq_read_nvm_exit:
        return status;
 }
 
+/**
+ * i40e_aq_read_nvm_config - read an nvm config block
+ * @hw: pointer to the hw struct
+ * @cmd_flags: NVM access admin command bits
+ * @field_id: field or feature id
+ * @data: buffer for result
+ * @buf_size: buffer size
+ * @element_count: pointer to count of elements read by FW
+ * @cmd_details: pointer to command details structure or NULL
+ **/
+enum i40e_status_code i40e_aq_read_nvm_config(struct i40e_hw *hw,
+                               u8 cmd_flags, u32 field_id, void *data,
+                               u16 buf_size, u16 *element_count,
+                               struct i40e_asq_cmd_details *cmd_details)
+{
+       struct i40e_aq_desc desc;
+       struct i40e_aqc_nvm_config_read *cmd =
+               (struct i40e_aqc_nvm_config_read *)&desc.params.raw;
+       enum i40e_status_code status;
+
+       i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_nvm_config_read);
+       desc.flags |= CPU_TO_LE16((u16)(I40E_AQ_FLAG_BUF));
+       if (buf_size > I40E_AQ_LARGE_BUF)
+               desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_LB);
+
+       cmd->cmd_flags = CPU_TO_LE16(cmd_flags);
+       cmd->element_id = CPU_TO_LE16((u16)(0xffff & field_id));
+       if (cmd_flags & I40E_AQ_ANVM_FEATURE_OR_IMMEDIATE_MASK)
+               cmd->element_id_msw = CPU_TO_LE16((u16)(field_id >> 16));
+       else
+               cmd->element_id_msw = 0;
+
+       status = i40e_asq_send_command(hw, &desc, data, buf_size, cmd_details);
+
+       if (!status && element_count)
+               *element_count = LE16_TO_CPU(cmd->element_count);
+
+       return status;
+}
+
+/**
+ * i40e_aq_write_nvm_config - write an nvm config block
+ * @hw: pointer to the hw struct
+ * @cmd_flags: NVM access admin command bits
+ * @data: buffer for result
+ * @buf_size: buffer size
+ * @element_count: count of elements to be written
+ * @cmd_details: pointer to command details structure or NULL
+ **/
+enum i40e_status_code i40e_aq_write_nvm_config(struct i40e_hw *hw,
+                               u8 cmd_flags, void *data, u16 buf_size,
+                               u16 element_count,
+                               struct i40e_asq_cmd_details *cmd_details)
+{
+       struct i40e_aq_desc desc;
+       struct i40e_aqc_nvm_config_write *cmd =
+               (struct i40e_aqc_nvm_config_write *)&desc.params.raw;
+       enum i40e_status_code status;
+
+       i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_nvm_config_write);
+       desc.flags |= CPU_TO_LE16((u16)(I40E_AQ_FLAG_BUF | I40E_AQ_FLAG_RD));
+       if (buf_size > I40E_AQ_LARGE_BUF)
+               desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_LB);
+
+       cmd->element_count = CPU_TO_LE16(element_count);
+       cmd->cmd_flags = CPU_TO_LE16(cmd_flags);
+       status = i40e_asq_send_command(hw, &desc, data, buf_size, cmd_details);
+
+       return status;
+}
+
 /**
  * i40e_aq_erase_nvm
  * @hw: pointer to the hw struct
@@ -2675,6 +2808,7 @@ i40e_aq_erase_nvm_exit:
 #define I40E_DEV_FUNC_CAP_VSI          0x17
 #define I40E_DEV_FUNC_CAP_DCB          0x18
 #define I40E_DEV_FUNC_CAP_FCOE         0x21
+#define I40E_DEV_FUNC_CAP_ISCSI                0x22
 #define I40E_DEV_FUNC_CAP_RSS          0x40
 #define I40E_DEV_FUNC_CAP_RX_QUEUES    0x41
 #define I40E_DEV_FUNC_CAP_TX_QUEUES    0x42
@@ -2774,6 +2908,10 @@ STATIC void i40e_parse_discover_capabilities(struct i40e_hw *hw, void *buff,
                        if (number == 1)
                                p->fcoe = true;
                        break;
+               case I40E_DEV_FUNC_CAP_ISCSI:
+                       if (number == 1)
+                               p->iscsi = true;
+                       break;
                case I40E_DEV_FUNC_CAP_RSS:
                        p->rss = true;
                        p->rss_table_size = number;
@@ -3027,6 +3165,45 @@ enum i40e_status_code i40e_aq_get_lldp_mib(struct i40e_hw *hw, u8 bridge_type,
        return status;
 }
 
+ /**
+ * i40e_aq_set_lldp_mib - Set the LLDP MIB
+ * @hw: pointer to the hw struct
+ * @mib_type: Local, Remote or both Local and Remote MIBs
+ * @buff: pointer to a user supplied buffer to store the MIB block
+ * @buff_size: size of the buffer (in bytes)
+ * @cmd_details: pointer to command details structure or NULL
+ *
+ * Set the LLDP MIB.
+ **/
+enum i40e_status_code i40e_aq_set_lldp_mib(struct i40e_hw *hw,
+                               u8 mib_type, void *buff, u16 buff_size,
+                               struct i40e_asq_cmd_details *cmd_details)
+{
+       struct i40e_aq_desc desc;
+       struct i40e_aqc_lldp_set_local_mib *cmd =
+               (struct i40e_aqc_lldp_set_local_mib *)&desc.params.raw;
+       enum i40e_status_code status;
+
+       if (buff_size == 0 || !buff)
+               return I40E_ERR_PARAM;
+
+       i40e_fill_default_direct_cmd_desc(&desc,
+                               i40e_aqc_opc_lldp_set_local_mib);
+       /* Indirect Command */
+       desc.flags |= CPU_TO_LE16((u16)(I40E_AQ_FLAG_BUF | I40E_AQ_FLAG_RD));
+       if (buff_size > I40E_AQ_LARGE_BUF)
+               desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_LB);
+       desc.datalen = CPU_TO_LE16(buff_size);
+
+       cmd->type = mib_type;
+       cmd->length = CPU_TO_LE16(buff_size);
+       cmd->address_high = CPU_TO_LE32(I40E_HI_WORD((u64)buff));
+       cmd->address_low =  CPU_TO_LE32(I40E_LO_DWORD((u64)buff));
+
+       status = i40e_asq_send_command(hw, &desc, buff, buff_size, cmd_details);
+       return status;
+}
+
 /**
  * i40e_aq_cfg_lldp_mib_change_event
  * @hw: pointer to the hw struct
@@ -3341,7 +3518,7 @@ enum i40e_status_code i40e_aq_add_udp_tunnel(struct i40e_hw *hw,
 
        status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
 
-       if (!status)
+       if (!status && filter_index)
                *filter_index = resp->index;
 
        return status;
@@ -3392,8 +3569,7 @@ enum i40e_status_code i40e_aq_get_switch_resource_alloc(struct i40e_hw *hw,
        struct i40e_aqc_get_switch_resource_alloc *cmd_resp =
                (struct i40e_aqc_get_switch_resource_alloc *)&desc.params.raw;
        enum i40e_status_code status;
-       u16 length = count
-                  * sizeof(struct i40e_aqc_switch_resource_alloc_element_resp);
+       u16 length = count * sizeof(*buf);
 
        i40e_fill_default_direct_cmd_desc(&desc,
                                        i40e_aqc_opc_get_switch_resource_alloc);
@@ -3404,7 +3580,7 @@ enum i40e_status_code i40e_aq_get_switch_resource_alloc(struct i40e_hw *hw,
 
        status = i40e_asq_send_command(hw, &desc, buf, length, cmd_details);
 
-       if (!status)
+       if (!status && num_entries)
                *num_entries = cmd_resp->num_entries;
 
        return status;
@@ -3819,7 +3995,7 @@ enum i40e_status_code i40e_aq_add_statistics(struct i40e_hw *hw, u16 seid,
 
        status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
 
-       if (!status)
+       if (!status && stat_index)
                *stat_index = LE16_TO_CPU(cmd_resp->stat_index);
 
        return status;
@@ -4406,8 +4582,7 @@ enum i40e_status_code i40e_aq_add_cloud_filters(struct i40e_hw *hw,
        i40e_fill_default_direct_cmd_desc(&desc,
                                          i40e_aqc_opc_add_cloud_filters);
 
-       buff_len = sizeof(struct i40e_aqc_add_remove_cloud_filters_element_data) *
-                         filter_count;
+       buff_len = filter_count * sizeof(*filters);
        desc.datalen = CPU_TO_LE16(buff_len);
        desc.flags |= CPU_TO_LE16((u16)(I40E_AQ_FLAG_BUF | I40E_AQ_FLAG_RD));
        cmd->num_filters = filter_count;
@@ -4444,8 +4619,7 @@ enum i40e_status_code i40e_aq_remove_cloud_filters(struct i40e_hw *hw,
        i40e_fill_default_direct_cmd_desc(&desc,
                                          i40e_aqc_opc_remove_cloud_filters);
 
-       buff_len = sizeof(struct i40e_aqc_add_remove_cloud_filters_element_data) *
-               filter_count;
+       buff_len = filter_count * sizeof(*filters);
        desc.datalen = CPU_TO_LE16(buff_len);
        desc.flags |= CPU_TO_LE16((u16)(I40E_AQ_FLAG_BUF | I40E_AQ_FLAG_RD));
        cmd->num_filters = filter_count;
@@ -4660,7 +4834,7 @@ enum i40e_status_code i40e_aq_alternate_write_done(struct i40e_hw *hw,
        cmd->cmd_flags = CPU_TO_LE16(bios_mode);
 
        status = i40e_asq_send_command(hw, &desc, NULL, 0, NULL);
-       if (!status)
+       if (!status && reset_needed)
                *reset_needed = ((LE16_TO_CPU(cmd->cmd_flags) &
                                 I40E_AQ_ALTERNATE_RESET_NEEDED) != 0);
 
@@ -4815,7 +4989,7 @@ enum i40e_status_code i40e_aq_configure_partition_bw(struct i40e_hw *hw,
 {
        enum i40e_status_code status;
        struct i40e_aq_desc desc;
-       u16 bwd_size = sizeof(struct i40e_aqc_configure_partition_bw_data);
+       u16 bwd_size = sizeof(*bw_data);
 
        i40e_fill_default_direct_cmd_desc(&desc,
                                i40e_aqc_opc_configure_partition_bw);