net/ice/base: add ethertype IPv6 check for dummy packet
[dpdk.git] / drivers / net / ice / base / ice_common.c
index ac412a1..e8d66aa 100644 (file)
@@ -64,6 +64,28 @@ static enum ice_status ice_set_mac_type(struct ice_hw *hw)
        return ICE_SUCCESS;
 }
 
+/**
+ * ice_is_generic_mac
+ * @hw: pointer to the hardware structure
+ *
+ * returns true if mac_type is ICE_MAC_GENERIC, false if not
+ */
+bool ice_is_generic_mac(struct ice_hw *hw)
+{
+       return hw->mac_type == ICE_MAC_GENERIC;
+}
+
+/**
+ * ice_is_e810
+ * @hw: pointer to the hardware structure
+ *
+ * returns true if the device is E810 based, false if not.
+ */
+bool ice_is_e810(struct ice_hw *hw)
+{
+       return hw->mac_type == ICE_MAC_E810;
+}
+
 /**
  * ice_clear_pf_cfg - Clear PF configuration
  * @hw: pointer to the hardware structure
@@ -830,10 +852,6 @@ enum ice_status ice_init_hw(struct ice_hw *hw)
        status = ice_aq_manage_mac_read(hw, mac_buf, mac_buf_len, NULL);
        ice_free(hw, mac_buf);
 
-       if (status)
-               goto err_unroll_fltr_mgmt_struct;
-       /* enable jumbo frame support at MAC level */
-       status = ice_aq_set_mac_cfg(hw, ICE_AQ_SET_MAC_FRAME_SIZE_MAX, NULL);
        if (status)
                goto err_unroll_fltr_mgmt_struct;
        /* Obtain counter base index which would be used by flow director */
@@ -1354,6 +1372,127 @@ ice_clear_tx_drbell_q_ctx(struct ice_hw *hw, u32 tx_drbell_q_index)
        return ICE_SUCCESS;
 }
 
+/* Sideband Queue command wrappers */
+
+/**
+ * ice_get_sbq - returns the right control queue to use for sideband
+ * @hw: pointer to the hardware structure
+ */
+static struct ice_ctl_q_info *ice_get_sbq(struct ice_hw *hw)
+{
+       if (!ice_is_generic_mac(hw))
+               return &hw->adminq;
+       return &hw->sbq;
+}
+
+/**
+ * ice_sbq_send_cmd - send Sideband Queue command to Sideband Queue
+ * @hw: pointer to the HW struct
+ * @desc: descriptor describing the command
+ * @buf: buffer to use for indirect commands (NULL for direct commands)
+ * @buf_size: size of buffer for indirect commands (0 for direct commands)
+ * @cd: pointer to command details structure
+ */
+static enum ice_status
+ice_sbq_send_cmd(struct ice_hw *hw, struct ice_sbq_cmd_desc *desc,
+                void *buf, u16 buf_size, struct ice_sq_cd *cd)
+{
+       return ice_sq_send_cmd(hw, ice_get_sbq(hw), (struct ice_aq_desc *)desc,
+                              buf, buf_size, cd);
+}
+
+/**
+ * ice_sbq_send_cmd_nolock - send Sideband Queue command to Sideband Queue
+ *                           but do not lock sq_lock
+ * @hw: pointer to the HW struct
+ * @desc: descriptor describing the command
+ * @buf: buffer to use for indirect commands (NULL for direct commands)
+ * @buf_size: size of buffer for indirect commands (0 for direct commands)
+ * @cd: pointer to command details structure
+ */
+static enum ice_status
+ice_sbq_send_cmd_nolock(struct ice_hw *hw, struct ice_sbq_cmd_desc *desc,
+                       void *buf, u16 buf_size, struct ice_sq_cd *cd)
+{
+       return ice_sq_send_cmd_nolock(hw, ice_get_sbq(hw),
+                                     (struct ice_aq_desc *)desc, buf,
+                                     buf_size, cd);
+}
+
+/**
+ * ice_sbq_rw_reg_lp - Fill Sideband Queue command, with lock parameter
+ * @hw: pointer to the HW struct
+ * @in: message info to be filled in descriptor
+ * @lock: true to lock the sq_lock (the usual case); false if the sq_lock has
+ *        already been locked at a higher level
+ */
+enum ice_status ice_sbq_rw_reg_lp(struct ice_hw *hw,
+                                 struct ice_sbq_msg_input *in, bool lock)
+{
+       struct ice_sbq_cmd_desc desc = {0};
+       struct ice_sbq_msg_req msg = {0};
+       enum ice_status status;
+       u16 msg_len;
+
+       msg_len = sizeof(msg);
+
+       msg.dest_dev = in->dest_dev;
+       msg.opcode = in->opcode;
+       msg.flags = ICE_SBQ_MSG_FLAGS;
+       msg.sbe_fbe = ICE_SBQ_MSG_SBE_FBE;
+       msg.msg_addr_low = CPU_TO_LE16(in->msg_addr_low);
+       msg.msg_addr_high = CPU_TO_LE32(in->msg_addr_high);
+
+       if (in->opcode)
+               msg.data = CPU_TO_LE32(in->data);
+       else
+               /* data read comes back in completion, so shorten the struct by
+                * sizeof(msg.data)
+                */
+               msg_len -= sizeof(msg.data);
+
+       desc.flags = CPU_TO_LE16(ICE_AQ_FLAG_RD);
+       desc.opcode = CPU_TO_LE16(ice_sbq_opc_neigh_dev_req);
+       desc.param0.cmd_len = CPU_TO_LE16(msg_len);
+       if (lock)
+               status = ice_sbq_send_cmd(hw, &desc, &msg, msg_len, NULL);
+       else
+               status = ice_sbq_send_cmd_nolock(hw, &desc, &msg, msg_len,
+                                                NULL);
+       if (!status && !in->opcode)
+               in->data = LE32_TO_CPU
+                       (((struct ice_sbq_msg_cmpl *)&msg)->data);
+       return status;
+}
+
+/**
+ * ice_sbq_rw_reg - Fill Sideband Queue command
+ * @hw: pointer to the HW struct
+ * @in: message info to be filled in descriptor
+ */
+enum ice_status ice_sbq_rw_reg(struct ice_hw *hw, struct ice_sbq_msg_input *in)
+{
+       return ice_sbq_rw_reg_lp(hw, in, true);
+}
+
+/**
+ * ice_sbq_lock - Lock the sideband queue's sq_lock
+ * @hw: pointer to the HW struct
+ */
+void ice_sbq_lock(struct ice_hw *hw)
+{
+       ice_acquire_lock(&ice_get_sbq(hw)->sq_lock);
+}
+
+/**
+ * ice_sbq_unlock - Unlock the sideband queue's sq_lock
+ * @hw: pointer to the HW struct
+ */
+void ice_sbq_unlock(struct ice_hw *hw)
+{
+       ice_release_lock(&ice_get_sbq(hw)->sq_lock);
+}
+
 /* FW Admin Queue command wrappers */
 
 /**
@@ -2009,9 +2148,6 @@ ice_parse_common_caps(struct ice_hw *hw, struct ice_hw_common_caps *caps,
        {
                u8 index = cap - ICE_AQC_CAPS_EXT_TOPO_DEV_IMG0;
 
-               if (index >= ICE_EXT_TOPO_DEV_IMG_COUNT)
-                       break;
-
                caps->ext_topo_dev_img_ver_high[index] = number;
                caps->ext_topo_dev_img_ver_low[index] = logical_id;
                caps->ext_topo_dev_img_part_num[index] =
@@ -2093,6 +2229,60 @@ ice_parse_vsi_func_caps(struct ice_hw *hw, struct ice_hw_func_caps *func_p,
                  func_p->guar_num_vsi);
 }
 
+/**
+ * ice_parse_1588_func_caps - Parse ICE_AQC_CAPS_1588 function caps
+ * @hw: pointer to the HW struct
+ * @func_p: pointer to function capabilities structure
+ * @cap: pointer to the capability element to parse
+ *
+ * Extract function capabilities for ICE_AQC_CAPS_1588.
+ */
+static void
+ice_parse_1588_func_caps(struct ice_hw *hw, struct ice_hw_func_caps *func_p,
+                        struct ice_aqc_list_caps_elem *cap)
+{
+       struct ice_ts_func_info *info = &func_p->ts_func_info;
+       u32 number = LE32_TO_CPU(cap->number);
+
+       info->ena = ((number & ICE_TS_FUNC_ENA_M) != 0);
+       func_p->common_cap.ieee_1588 = info->ena;
+
+       info->src_tmr_owned = ((number & ICE_TS_SRC_TMR_OWND_M) != 0);
+       info->tmr_ena = ((number & ICE_TS_TMR_ENA_M) != 0);
+       info->tmr_index_owned = ((number & ICE_TS_TMR_IDX_OWND_M) != 0);
+       info->tmr_index_assoc = ((number & ICE_TS_TMR_IDX_ASSOC_M) != 0);
+
+       info->clk_freq = (number & ICE_TS_CLK_FREQ_M) >> ICE_TS_CLK_FREQ_S;
+       info->clk_src = ((number & ICE_TS_CLK_SRC_M) != 0);
+
+       if (info->clk_freq < NUM_ICE_TIME_REF_FREQ) {
+               info->time_ref = (enum ice_time_ref_freq)info->clk_freq;
+       } else {
+               /* Unknown clock frequency, so assume a (probably incorrect)
+                * default to avoid out-of-bounds look ups of frequency
+                * related information.
+                */
+               ice_debug(hw, ICE_DBG_INIT, "1588 func caps: unknown clock frequency %u\n",
+                         info->clk_freq);
+               info->time_ref = ICE_TIME_REF_FREQ_25_000;
+       }
+
+       ice_debug(hw, ICE_DBG_INIT, "func caps: ieee_1588 = %u\n",
+                 func_p->common_cap.ieee_1588);
+       ice_debug(hw, ICE_DBG_INIT, "func caps: src_tmr_owned = %u\n",
+                 info->src_tmr_owned);
+       ice_debug(hw, ICE_DBG_INIT, "func caps: tmr_ena = %u\n",
+                 info->tmr_ena);
+       ice_debug(hw, ICE_DBG_INIT, "func caps: tmr_index_owned = %u\n",
+                 info->tmr_index_owned);
+       ice_debug(hw, ICE_DBG_INIT, "func caps: tmr_index_assoc = %u\n",
+                 info->tmr_index_assoc);
+       ice_debug(hw, ICE_DBG_INIT, "func caps: clk_freq = %u\n",
+                 info->clk_freq);
+       ice_debug(hw, ICE_DBG_INIT, "func caps: clk_src = %u\n",
+                 info->clk_src);
+}
+
 /**
  * ice_parse_fdir_func_caps - Parse ICE_AQC_CAPS_FD function caps
  * @hw: pointer to the HW struct
@@ -2158,6 +2348,9 @@ ice_parse_func_caps(struct ice_hw *hw, struct ice_hw_func_caps *func_p,
                case ICE_AQC_CAPS_VSI:
                        ice_parse_vsi_func_caps(hw, func_p, &cap_resp[i]);
                        break;
+               case ICE_AQC_CAPS_1588:
+                       ice_parse_1588_func_caps(hw, func_p, &cap_resp[i]);
+                       break;
                case ICE_AQC_CAPS_FD:
                        ice_parse_fdir_func_caps(hw, func_p);
                        break;
@@ -2211,6 +2404,57 @@ ice_parse_vsi_dev_caps(struct ice_hw *hw, struct ice_hw_dev_caps *dev_p,
                  dev_p->num_vsi_allocd_to_host);
 }
 
+/**
+ * ice_parse_1588_dev_caps - Parse ICE_AQC_CAPS_1588 device caps
+ * @hw: pointer to the HW struct
+ * @dev_p: pointer to device capabilities structure
+ * @cap: capability element to parse
+ *
+ * Parse ICE_AQC_CAPS_1588 for device capabilities.
+ */
+static void
+ice_parse_1588_dev_caps(struct ice_hw *hw, struct ice_hw_dev_caps *dev_p,
+                       struct ice_aqc_list_caps_elem *cap)
+{
+       struct ice_ts_dev_info *info = &dev_p->ts_dev_info;
+       u32 logical_id = LE32_TO_CPU(cap->logical_id);
+       u32 phys_id = LE32_TO_CPU(cap->phys_id);
+       u32 number = LE32_TO_CPU(cap->number);
+
+       info->ena = ((number & ICE_TS_DEV_ENA_M) != 0);
+       dev_p->common_cap.ieee_1588 = info->ena;
+
+       info->tmr0_owner = number & ICE_TS_TMR0_OWNR_M;
+       info->tmr0_owned = ((number & ICE_TS_TMR0_OWND_M) != 0);
+       info->tmr0_ena = ((number & ICE_TS_TMR0_ENA_M) != 0);
+
+       info->tmr1_owner = (number & ICE_TS_TMR1_OWNR_M) >> ICE_TS_TMR1_OWNR_S;
+       info->tmr1_owned = ((number & ICE_TS_TMR1_OWND_M) != 0);
+       info->tmr1_ena = ((number & ICE_TS_TMR1_ENA_M) != 0);
+
+       info->ena_ports = logical_id;
+       info->tmr_own_map = phys_id;
+
+       ice_debug(hw, ICE_DBG_INIT, "dev caps: ieee_1588 = %u\n",
+                 dev_p->common_cap.ieee_1588);
+       ice_debug(hw, ICE_DBG_INIT, "dev caps: tmr0_owner = %u\n",
+                 info->tmr0_owner);
+       ice_debug(hw, ICE_DBG_INIT, "dev caps: tmr0_owned = %u\n",
+                 info->tmr0_owned);
+       ice_debug(hw, ICE_DBG_INIT, "dev caps: tmr0_ena = %u\n",
+                 info->tmr0_ena);
+       ice_debug(hw, ICE_DBG_INIT, "dev caps: tmr1_owner = %u\n",
+                 info->tmr1_owner);
+       ice_debug(hw, ICE_DBG_INIT, "dev caps: tmr1_owned = %u\n",
+                 info->tmr1_owned);
+       ice_debug(hw, ICE_DBG_INIT, "dev caps: tmr1_ena = %u\n",
+                 info->tmr1_ena);
+       ice_debug(hw, ICE_DBG_INIT, "dev caps: ieee_1588 ena_ports = %u\n",
+                 info->ena_ports);
+       ice_debug(hw, ICE_DBG_INIT, "dev caps: tmr_own_map = %u\n",
+                 info->tmr_own_map);
+}
+
 /**
  * ice_parse_fdir_dev_caps - Parse ICE_AQC_CAPS_FD device caps
  * @hw: pointer to the HW struct
@@ -2269,6 +2513,9 @@ ice_parse_dev_caps(struct ice_hw *hw, struct ice_hw_dev_caps *dev_p,
                case ICE_AQC_CAPS_VSI:
                        ice_parse_vsi_dev_caps(hw, dev_p, &cap_resp[i]);
                        break;
+               case ICE_AQC_CAPS_1588:
+                       ice_parse_1588_dev_caps(hw, dev_p, &cap_resp[i]);
+                       break;
                case  ICE_AQC_CAPS_FD:
                        ice_parse_fdir_dev_caps(hw, dev_p, &cap_resp[i]);
                        break;