e1000: support Rx interrupt setup
[dpdk.git] / drivers / net / i40e / base / i40e_common.c
index 1dac22f..d7c940d 100644 (file)
@@ -70,6 +70,22 @@ STATIC enum i40e_status_code i40e_set_mac_type(struct i40e_hw *hw)
                case I40E_DEV_ID_20G_KR2_A:
                        hw->mac.type = I40E_MAC_XL710;
                        break;
+#ifdef X722_SUPPORT
+#ifdef X722_A0_SUPPORT
+               case I40E_DEV_ID_X722_A0:
+#endif
+               case I40E_DEV_ID_SFP_X722:
+               case I40E_DEV_ID_1G_BASE_T_X722:
+               case I40E_DEV_ID_10G_BASE_T_X722:
+                       hw->mac.type = I40E_MAC_X722;
+                       break;
+#endif
+#ifdef X722_SUPPORT
+               case I40E_DEV_ID_X722_VF:
+               case I40E_DEV_ID_X722_VF_HV:
+                       hw->mac.type = I40E_MAC_X722_VF;
+                       break;
+#endif
                case I40E_DEV_ID_VF:
                case I40E_DEV_ID_VF_HV:
                        hw->mac.type = I40E_MAC_VF;
@@ -419,6 +435,166 @@ enum i40e_status_code i40e_aq_queue_shutdown(struct i40e_hw *hw,
 
        return status;
 }
+#ifdef X722_SUPPORT
+
+/**
+ * i40e_aq_get_set_rss_lut
+ * @hw: pointer to the hardware structure
+ * @vsi_id: vsi fw index
+ * @pf_lut: for PF table set true, for VSI table set false
+ * @lut: pointer to the lut buffer provided by the caller
+ * @lut_size: size of the lut buffer
+ * @set: set true to set the table, false to get the table
+ *
+ * Internal function to get or set RSS look up table
+ **/
+STATIC enum i40e_status_code i40e_aq_get_set_rss_lut(struct i40e_hw *hw,
+                                                    u16 vsi_id, bool pf_lut,
+                                                    u8 *lut, u16 lut_size,
+                                                    bool set)
+{
+       enum i40e_status_code status;
+       struct i40e_aq_desc desc;
+       struct i40e_aqc_get_set_rss_lut *cmd_resp =
+                  (struct i40e_aqc_get_set_rss_lut *)&desc.params.raw;
+
+       if (set)
+               i40e_fill_default_direct_cmd_desc(&desc,
+                                                 i40e_aqc_opc_set_rss_lut);
+       else
+               i40e_fill_default_direct_cmd_desc(&desc,
+                                                 i40e_aqc_opc_get_rss_lut);
+
+       /* Indirect command */
+       desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_BUF);
+       desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_RD);
+
+       cmd_resp->vsi_id =
+                       CPU_TO_LE16((u16)((vsi_id <<
+                                         I40E_AQC_SET_RSS_LUT_VSI_ID_SHIFT) &
+                                         I40E_AQC_SET_RSS_LUT_VSI_ID_MASK));
+       cmd_resp->vsi_id |= CPU_TO_LE16((u16)I40E_AQC_SET_RSS_LUT_VSI_VALID);
+
+       if (pf_lut)
+               cmd_resp->flags |= CPU_TO_LE16((u16)
+                                       ((I40E_AQC_SET_RSS_LUT_TABLE_TYPE_PF <<
+                                       I40E_AQC_SET_RSS_LUT_TABLE_TYPE_SHIFT) &
+                                       I40E_AQC_SET_RSS_LUT_TABLE_TYPE_MASK));
+       else
+               cmd_resp->flags |= CPU_TO_LE16((u16)
+                                       ((I40E_AQC_SET_RSS_LUT_TABLE_TYPE_VSI <<
+                                       I40E_AQC_SET_RSS_LUT_TABLE_TYPE_SHIFT) &
+                                       I40E_AQC_SET_RSS_LUT_TABLE_TYPE_MASK));
+
+       status = i40e_asq_send_command(hw, &desc, lut, lut_size, NULL);
+
+       return status;
+}
+
+/**
+ * i40e_aq_get_rss_lut
+ * @hw: pointer to the hardware structure
+ * @vsi_id: vsi fw index
+ * @pf_lut: for PF table set true, for VSI table set false
+ * @lut: pointer to the lut buffer provided by the caller
+ * @lut_size: size of the lut buffer
+ *
+ * get the RSS lookup table, PF or VSI type
+ **/
+enum i40e_status_code i40e_aq_get_rss_lut(struct i40e_hw *hw, u16 vsi_id,
+                                         bool pf_lut, u8 *lut, u16 lut_size)
+{
+       return i40e_aq_get_set_rss_lut(hw, vsi_id, pf_lut, lut, lut_size,
+                                      false);
+}
+
+/**
+ * i40e_aq_set_rss_lut
+ * @hw: pointer to the hardware structure
+ * @vsi_id: vsi fw index
+ * @pf_lut: for PF table set true, for VSI table set false
+ * @lut: pointer to the lut buffer provided by the caller
+ * @lut_size: size of the lut buffer
+ *
+ * set the RSS lookup table, PF or VSI type
+ **/
+enum i40e_status_code i40e_aq_set_rss_lut(struct i40e_hw *hw, u16 vsi_id,
+                                         bool pf_lut, u8 *lut, u16 lut_size)
+{
+       return i40e_aq_get_set_rss_lut(hw, vsi_id, pf_lut, lut, lut_size, true);
+}
+
+/**
+ * i40e_aq_get_set_rss_key
+ * @hw: pointer to the hw struct
+ * @vsi_id: vsi fw index
+ * @key: pointer to key info struct
+ * @set: set true to set the key, false to get the key
+ *
+ * get the RSS key per VSI
+ **/
+STATIC enum i40e_status_code i40e_aq_get_set_rss_key(struct i40e_hw *hw,
+                                     u16 vsi_id,
+                                     struct i40e_aqc_get_set_rss_key_data *key,
+                                     bool set)
+{
+       enum i40e_status_code status;
+       struct i40e_aq_desc desc;
+       struct i40e_aqc_get_set_rss_key *cmd_resp =
+                       (struct i40e_aqc_get_set_rss_key *)&desc.params.raw;
+       u16 key_size = sizeof(struct i40e_aqc_get_set_rss_key_data);
+
+       if (set)
+               i40e_fill_default_direct_cmd_desc(&desc,
+                                                 i40e_aqc_opc_set_rss_key);
+       else
+               i40e_fill_default_direct_cmd_desc(&desc,
+                                                 i40e_aqc_opc_get_rss_key);
+
+       /* Indirect command */
+       desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_BUF);
+       desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_RD);
+
+       cmd_resp->vsi_id =
+                       CPU_TO_LE16((u16)((vsi_id <<
+                                         I40E_AQC_SET_RSS_KEY_VSI_ID_SHIFT) &
+                                         I40E_AQC_SET_RSS_KEY_VSI_ID_MASK));
+       cmd_resp->vsi_id |= CPU_TO_LE16((u16)I40E_AQC_SET_RSS_KEY_VSI_VALID);
+
+       status = i40e_asq_send_command(hw, &desc, key, key_size, NULL);
+
+       return status;
+}
+
+/**
+ * i40e_aq_get_rss_key
+ * @hw: pointer to the hw struct
+ * @vsi_id: vsi fw index
+ * @key: pointer to key info struct
+ *
+ **/
+enum i40e_status_code i40e_aq_get_rss_key(struct i40e_hw *hw,
+                                     u16 vsi_id,
+                                     struct i40e_aqc_get_set_rss_key_data *key)
+{
+       return i40e_aq_get_set_rss_key(hw, vsi_id, key, false);
+}
+
+/**
+ * i40e_aq_set_rss_key
+ * @hw: pointer to the hw struct
+ * @vsi_id: vsi fw index
+ * @key: pointer to key info struct
+ *
+ * set the RSS key per VSI
+ **/
+enum i40e_status_code i40e_aq_set_rss_key(struct i40e_hw *hw,
+                                     u16 vsi_id,
+                                     struct i40e_aqc_get_set_rss_key_data *key)
+{
+       return i40e_aq_get_set_rss_key(hw, vsi_id, key, true);
+}
+#endif /* X722_SUPPORT */
 
 /* The i40e_ptype_lookup table is used to convert from the 8-bit ptype in the
  * hardware to a bit-field that can be used by SW to more easily determine the
@@ -834,6 +1010,9 @@ enum i40e_status_code i40e_init_shared_code(struct i40e_hw *hw)
 
        switch (hw->mac.type) {
        case I40E_MAC_XL710:
+#ifdef X722_SUPPORT
+       case I40E_MAC_X722:
+#endif
                break;
        default:
                return I40E_ERR_DEVICE_NOT_SUPPORTED;
@@ -1124,7 +1303,11 @@ enum i40e_status_code i40e_pf_reset(struct i40e_hw *hw)
        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++) {
+#ifdef I40E_ESS_SUPPORT
+       /* It can take upto 15 secs for GRST steady state */
+       grst_del = grst_del * 20; /* bump it to 16 secs max to be safe */
+#endif
+       for (cnt = 0; cnt < grst_del + 10; cnt++) {
                reg = rd32(hw, I40E_GLGEN_RSTAT);
                if (!(reg & I40E_GLGEN_RSTAT_DEVSTATE_MASK))
                        break;
@@ -3151,6 +3334,9 @@ i40e_aq_erase_nvm_exit:
 #define I40E_DEV_FUNC_CAP_NPAR         0x03
 #define I40E_DEV_FUNC_CAP_OS2BMC       0x04
 #define I40E_DEV_FUNC_CAP_VALID_FUNC   0x05
+#ifdef X722_SUPPORT
+#define I40E_DEV_FUNC_CAP_WOL_PROXY    0x08
+#endif
 #define I40E_DEV_FUNC_CAP_SRIOV_1_1    0x12
 #define I40E_DEV_FUNC_CAP_VF           0x13
 #define I40E_DEV_FUNC_CAP_VMDQ         0x14
@@ -3173,6 +3359,7 @@ i40e_aq_erase_nvm_exit:
 #define I40E_DEV_FUNC_CAP_LED          0x61
 #define I40E_DEV_FUNC_CAP_SDP          0x62
 #define I40E_DEV_FUNC_CAP_MDIO         0x63
+#define I40E_DEV_FUNC_CAP_WR_CSR_PROT  0x64
 
 /**
  * i40e_parse_discover_capabilities
@@ -3331,11 +3518,31 @@ STATIC void i40e_parse_discover_capabilities(struct i40e_hw *hw, void *buff,
                        p->fd_filters_guaranteed = number;
                        p->fd_filters_best_effort = logical_id;
                        break;
+               case I40E_DEV_FUNC_CAP_WR_CSR_PROT:
+                       p->wr_csr_prot = (u64)number;
+                       p->wr_csr_prot |= (u64)logical_id << 32;
+                       break;
+#ifdef X722_SUPPORT
+               case I40E_DEV_FUNC_CAP_WOL_PROXY:
+                       hw->num_wol_proxy_filters = (u16)number;
+                       hw->wol_proxy_vsi_seid = (u16)logical_id;
+                       p->apm_wol_support = phys_id & I40E_WOL_SUPPORT_MASK;
+                       if (phys_id & I40E_ACPI_PROGRAMMING_METHOD_MASK)
+                               p->acpi_prog_method = I40E_ACPI_PROGRAMMING_METHOD_AQC_FPK;
+                       else
+                               p->acpi_prog_method = I40E_ACPI_PROGRAMMING_METHOD_HW_FVL;
+                       p->proxy_support = (phys_id & I40E_PROXY_SUPPORT_MASK) ? 1 : 0;
+                       p->proxy_support = p->proxy_support;
+                       break;
+#endif
                default:
                        break;
                }
        }
 
+       if (p->fcoe)
+               i40e_debug(hw, I40E_DEBUG_ALL, "device is FCoE capable\n");
+
 #ifdef I40E_FCOE_ENA
        /* Software override ensuring FCoE is disabled if npar or mfp
         * mode because it is not supported in these modes.
@@ -5116,8 +5323,6 @@ enum i40e_status_code i40e_aq_alternate_write_indirect(struct i40e_hw *hw,
 
        cmd_resp->address = CPU_TO_LE32(addr);
        cmd_resp->length = CPU_TO_LE32(dw_count);
-       cmd_resp->addr_high = CPU_TO_LE32(I40E_HI_WORD((u64)buffer));
-       cmd_resp->addr_low = CPU_TO_LE32(I40E_LO_DWORD((u64)buffer));
 
        status = i40e_asq_send_command(hw, &desc, buffer,
                                       I40E_LO_DWORD(4*dw_count), NULL);
@@ -5199,8 +5404,6 @@ enum i40e_status_code i40e_aq_alternate_read_indirect(struct i40e_hw *hw,
 
        cmd_resp->address = CPU_TO_LE32(addr);
        cmd_resp->length = CPU_TO_LE32(dw_count);
-       cmd_resp->addr_high = CPU_TO_LE32(I40E_HI_DWORD((u64)buffer));
-       cmd_resp->addr_low = CPU_TO_LE32(I40E_LO_DWORD((u64)buffer));
 
        status = i40e_asq_send_command(hw, &desc, buffer,
                                       I40E_LO_DWORD(4*dw_count), NULL);
@@ -5430,11 +5633,11 @@ enum i40e_status_code i40e_read_bw_from_alt_ram(struct i40e_hw *hw,
 
        /* Calculate the address of the min/max bw registers */
        max_bw_addr = I40E_ALT_STRUCT_FIRST_PF_OFFSET +
-               I40E_ALT_STRUCT_MAX_BW_OFFSET +
-               (I40E_ALT_STRUCT_DWORDS_PER_PF*hw->pf_id);
+                     I40E_ALT_STRUCT_MAX_BW_OFFSET +
+                     (I40E_ALT_STRUCT_DWORDS_PER_PF * hw->pf_id);
        min_bw_addr = I40E_ALT_STRUCT_FIRST_PF_OFFSET +
-               I40E_ALT_STRUCT_MIN_BW_OFFSET +
-               (I40E_ALT_STRUCT_DWORDS_PER_PF*hw->pf_id);
+                     I40E_ALT_STRUCT_MIN_BW_OFFSET +
+                     (I40E_ALT_STRUCT_DWORDS_PER_PF * hw->pf_id);
 
        /* Read the bandwidths from alt ram */
        status = i40e_aq_alternate_read(hw, max_bw_addr, max_bw,
@@ -5586,3 +5789,162 @@ enum i40e_status_code i40e_vf_reset(struct i40e_hw *hw)
                                      I40E_SUCCESS, NULL, 0, NULL);
 }
 #endif /* VF_DRIVER */
+#ifdef X722_SUPPORT
+
+/**
+ * i40e_aq_set_arp_proxy_config
+ * @hw: pointer to the HW structure
+ * @proxy_config - pointer to proxy config command table struct
+ * @cmd_details: pointer to command details
+ *
+ * Set ARP offload parameters from pre-populated
+ * i40e_aqc_arp_proxy_data struct
+ **/
+enum i40e_status_code i40e_aq_set_arp_proxy_config(struct i40e_hw *hw,
+                               struct i40e_aqc_arp_proxy_data *proxy_config,
+                               struct i40e_asq_cmd_details *cmd_details)
+{
+       struct i40e_aq_desc desc;
+       struct i40e_aqc_set_proxy_config *cmd =
+               (struct i40e_aqc_set_proxy_config *) &desc.params.raw;
+       enum i40e_status_code status;
+
+       if (!proxy_config)
+               return I40E_ERR_PARAM;
+
+       i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_set_proxy_config);
+
+       cmd->address_high = CPU_TO_LE32(I40E_HI_DWORD((u64)proxy_config));
+       cmd->address_low = CPU_TO_LE32(I40E_LO_DWORD((u64)proxy_config));
+
+       status = i40e_asq_send_command(hw, &desc, proxy_config,
+                                      sizeof(struct i40e_aqc_arp_proxy_data),
+                                      cmd_details);
+
+       return status;
+}
+
+/**
+ * i40e_aq_opc_set_ns_proxy_table_entry
+ * @hw: pointer to the HW structure
+ * @ns_proxy_table_entry: pointer to NS table entry command struct
+ * @cmd_details: pointer to command details
+ *
+ * Set IPv6 Neighbor Solicitation (NS) protocol offload parameters
+ * from pre-populated i40e_aqc_ns_proxy_data struct
+ **/
+enum i40e_status_code i40e_aq_set_ns_proxy_table_entry(struct i40e_hw *hw,
+                       struct i40e_aqc_ns_proxy_data *ns_proxy_table_entry,
+                       struct i40e_asq_cmd_details *cmd_details)
+{
+       struct i40e_aq_desc desc;
+       struct i40e_aqc_set_ns_proxy_table_entry *cmd =
+               (struct i40e_aqc_set_ns_proxy_table_entry *) &desc.params.raw;
+       enum i40e_status_code status;
+
+       if (!ns_proxy_table_entry)
+               return I40E_ERR_PARAM;
+
+       i40e_fill_default_direct_cmd_desc(&desc,
+                               i40e_aqc_opc_set_ns_proxy_table_entry);
+
+       cmd->address_high =
+               CPU_TO_LE32(I40E_HI_DWORD((u64)ns_proxy_table_entry));
+       cmd->address_low =
+               CPU_TO_LE32(I40E_LO_DWORD((u64)ns_proxy_table_entry));
+
+       status = i40e_asq_send_command(hw, &desc, ns_proxy_table_entry,
+                                      sizeof(struct i40e_aqc_ns_proxy_data),
+                                      cmd_details);
+
+       return status;
+}
+
+/**
+ * i40e_aq_set_clear_wol_filter
+ * @hw: pointer to the hw struct
+ * @filter_index: index of filter to modify (0-7)
+ * @filter: buffer containing filter to be set
+ * @set_filter: true to set filter, false to clear filter
+ * @no_wol_tco: if true, pass through packets cannot cause wake-up
+ *             if false, pass through packets may cause wake-up
+ * @filter_valid: true if filter action is valid
+ * @no_wol_tco_valid: true if no WoL in TCO traffic action valid
+ * @cmd_details: pointer to command details structure or NULL
+ *
+ * Set or clear WoL filter for port attached to the PF
+ **/
+enum i40e_status_code i40e_aq_set_clear_wol_filter(struct i40e_hw *hw,
+                               u8 filter_index,
+                               struct i40e_aqc_set_wol_filter_data *filter,
+                               bool set_filter, bool no_wol_tco,
+                               bool filter_valid, bool no_wol_tco_valid,
+                               struct i40e_asq_cmd_details *cmd_details)
+{
+       struct i40e_aq_desc desc;
+       struct i40e_aqc_set_wol_filter *cmd =
+               (struct i40e_aqc_set_wol_filter *)&desc.params.raw;
+       enum i40e_status_code status;
+       u16 cmd_flags = 0;
+       u16 valid_flags = 0;
+       u16 buff_len = 0;
+
+       i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_set_wol_filter);
+
+       if (filter_index >= I40E_AQC_MAX_NUM_WOL_FILTERS)
+               return  I40E_ERR_PARAM;
+       cmd->filter_index = CPU_TO_LE16(filter_index);
+
+       if (set_filter) {
+               if (!filter)
+                       return  I40E_ERR_PARAM;
+               cmd_flags |= I40E_AQC_SET_WOL_FILTER;
+               buff_len = sizeof(*filter);
+       }
+       if (no_wol_tco)
+               cmd_flags |= I40E_AQC_SET_WOL_FILTER_NO_TCO_WOL;
+       cmd->cmd_flags = CPU_TO_LE16(cmd_flags);
+
+       if (filter_valid)
+               valid_flags |= I40E_AQC_SET_WOL_FILTER_ACTION_VALID;
+       if (no_wol_tco_valid)
+               valid_flags |= I40E_AQC_SET_WOL_FILTER_NO_TCO_ACTION_VALID;
+       cmd->valid_flags = CPU_TO_LE16(valid_flags);
+
+       cmd->address_high = CPU_TO_LE32(I40E_HI_DWORD((u64)filter));
+       cmd->address_low = CPU_TO_LE32(I40E_LO_DWORD((u64)filter));
+
+       status = i40e_asq_send_command(hw, &desc, filter,
+                                      buff_len, cmd_details);
+
+       return status;
+}
+
+/**
+ * i40e_aq_get_wake_event_reason
+ * @hw: pointer to the hw struct
+ * @wake_reason: return value, index of matching filter
+ * @cmd_details: pointer to command details structure or NULL
+ *
+ * Get information for the reason of a Wake Up event
+ **/
+enum i40e_status_code i40e_aq_get_wake_event_reason(struct i40e_hw *hw,
+                               u16 *wake_reason,
+                               struct i40e_asq_cmd_details *cmd_details)
+{
+       struct i40e_aq_desc desc;
+       struct i40e_aqc_get_wake_reason_completion *resp =
+               (struct i40e_aqc_get_wake_reason_completion *)&desc.params.raw;
+       enum i40e_status_code status;
+
+       i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_get_wake_reason);
+
+       status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
+
+       if (status == I40E_SUCCESS)
+               *wake_reason = LE16_TO_CPU(resp->wake_reason);
+
+       return status;
+}
+
+#endif /* X722_SUPPORT */