]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
ice: Query the Tx scheduler node before adding it
authorAnirudh Venkataramanan <anirudh.venkataramanan@intel.com>
Thu, 20 Sep 2018 00:23:09 +0000 (17:23 -0700)
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>
Thu, 27 Sep 2018 15:20:15 +0000 (08:20 -0700)
Query the Tx scheduler tree node information from FW before adding it to
the driver's software database. This will keep the node information current
in driver.

Signed-off-by: Anirudh Venkataramanan <anirudh.venkataramanan@intel.com>
Tested-by: Andrew Bowers <andrewx.bowers@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
drivers/net/ethernet/intel/ice/ice_adminq_cmd.h
drivers/net/ethernet/intel/ice/ice_sched.c

index f8dfd675486c5b6bf5c21598a7a7f25eb59907f4..c100b4bda1958f21b96d26e92f91d9599bef7841 100644 (file)
@@ -736,6 +736,10 @@ struct ice_aqc_add_elem {
        struct ice_aqc_txsched_elem_data generic[1];
 };
 
+struct ice_aqc_get_elem {
+       struct ice_aqc_txsched_elem_data generic[1];
+};
+
 struct ice_aqc_get_topo_elem {
        struct ice_aqc_txsched_topo_grp_info_hdr hdr;
        struct ice_aqc_txsched_elem_data
@@ -1409,6 +1413,7 @@ enum ice_adminq_opc {
        /* transmit scheduler commands */
        ice_aqc_opc_get_dflt_topo                       = 0x0400,
        ice_aqc_opc_add_sched_elems                     = 0x0401,
+       ice_aqc_opc_get_sched_elems                     = 0x0404,
        ice_aqc_opc_suspend_sched_elems                 = 0x0409,
        ice_aqc_opc_resume_sched_elems                  = 0x040A,
        ice_aqc_opc_delete_sched_elems                  = 0x040F,
index 9b7b505549522c02310f6e1d8a4f0cf11df5c950..9c4f408f222d556437a96ee1f538d2e43ba2f780 100644 (file)
@@ -84,6 +84,62 @@ ice_sched_find_node_by_teid(struct ice_sched_node *start_node, u32 teid)
        return NULL;
 }
 
+/**
+ * ice_aq_query_sched_elems - query scheduler elements
+ * @hw: pointer to the hw struct
+ * @elems_req: number of elements to query
+ * @buf: pointer to buffer
+ * @buf_size: buffer size in bytes
+ * @elems_ret: returns total number of elements returned
+ * @cd: pointer to command details structure or NULL
+ *
+ * Query scheduling elements (0x0404)
+ */
+static enum ice_status
+ice_aq_query_sched_elems(struct ice_hw *hw, u16 elems_req,
+                        struct ice_aqc_get_elem *buf, u16 buf_size,
+                        u16 *elems_ret, struct ice_sq_cd *cd)
+{
+       struct ice_aqc_get_cfg_elem *cmd;
+       struct ice_aq_desc desc;
+       enum ice_status status;
+
+       cmd = &desc.params.get_update_elem;
+       ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_get_sched_elems);
+       cmd->num_elem_req = cpu_to_le16(elems_req);
+       desc.flags |= cpu_to_le16(ICE_AQ_FLAG_RD);
+       status = ice_aq_send_cmd(hw, &desc, buf, buf_size, cd);
+       if (!status && elems_ret)
+               *elems_ret = le16_to_cpu(cmd->num_elem_resp);
+
+       return status;
+}
+
+/**
+ * ice_sched_query_elem - query element information from hw
+ * @hw: pointer to the hw struct
+ * @node_teid: node teid to be queried
+ * @buf: buffer to element information
+ *
+ * This function queries HW element information
+ */
+static enum ice_status
+ice_sched_query_elem(struct ice_hw *hw, u32 node_teid,
+                    struct ice_aqc_get_elem *buf)
+{
+       u16 buf_size, num_elem_ret = 0;
+       enum ice_status status;
+
+       buf_size = sizeof(*buf);
+       memset(buf, 0, buf_size);
+       buf->generic[0].node_teid = cpu_to_le32(node_teid);
+       status = ice_aq_query_sched_elems(hw, 1, buf, buf_size, &num_elem_ret,
+                                         NULL);
+       if (status || num_elem_ret != 1)
+               ice_debug(hw, ICE_DBG_SCHED, "query element failed\n");
+       return status;
+}
+
 /**
  * ice_sched_add_node - Insert the Tx scheduler node in SW DB
  * @pi: port information structure
@@ -97,7 +153,9 @@ ice_sched_add_node(struct ice_port_info *pi, u8 layer,
                   struct ice_aqc_txsched_elem_data *info)
 {
        struct ice_sched_node *parent;
+       struct ice_aqc_get_elem elem;
        struct ice_sched_node *node;
+       enum ice_status status;
        struct ice_hw *hw;
 
        if (!pi)
@@ -115,6 +173,13 @@ ice_sched_add_node(struct ice_port_info *pi, u8 layer,
                return ICE_ERR_PARAM;
        }
 
+       /* query the current node information from FW  before additing it
+        * to the SW DB
+        */
+       status = ice_sched_query_elem(hw, le32_to_cpu(info->node_teid), &elem);
+       if (status)
+               return status;
+
        node = devm_kzalloc(ice_hw_to_dev(hw), sizeof(*node), GFP_KERNEL);
        if (!node)
                return ICE_ERR_NO_MEMORY;
@@ -133,7 +198,7 @@ ice_sched_add_node(struct ice_port_info *pi, u8 layer,
        node->parent = parent;
        node->tx_sched_layer = layer;
        parent->children[parent->num_children++] = node;
-       memcpy(&node->info, info, sizeof(*info));
+       memcpy(&node->info, &elem.generic[0], sizeof(node->info));
        return 0;
 }