Commit dc49c772 authored by Anirudh Venkataramanan's avatar Anirudh Venkataramanan Committed by Jeff Kirsher

ice: Get MAC/PHY/link info and scheduler topology

This patch adds code to continue the initialization flow as follows:

1) Get PHY/link information and store it
2) Get default scheduler tree topology and store it
3) Get the MAC address associated with the port and store it
Signed-off-by: default avatarAnirudh Venkataramanan <anirudh.venkataramanan@intel.com>
Tested-by: default avatarTony Brelinski <tonyx.brelinski@intel.com>
Signed-off-by: default avatarJeff Kirsher <jeffrey.t.kirsher@intel.com>
parent 9c20346b
......@@ -10,6 +10,7 @@
#include <linux/module.h>
#include <linux/netdevice.h>
#include <linux/compiler.h>
#include <linux/etherdevice.h>
#include <linux/pci.h>
#include <linux/aer.h>
#include <linux/delay.h>
......
......@@ -36,13 +36,238 @@ enum ice_status ice_clear_pf_cfg(struct ice_hw *hw)
return ice_aq_send_cmd(hw, &desc, NULL, 0, NULL);
}
/**
* ice_aq_manage_mac_read - manage MAC address read command
* @hw: pointer to the hw struct
* @buf: a virtual buffer to hold the manage MAC read response
* @buf_size: Size of the virtual buffer
* @cd: pointer to command details structure or NULL
*
* This function is used to return per PF station MAC address (0x0107).
* NOTE: Upon successful completion of this command, MAC address information
* is returned in user specified buffer. Please interpret user specified
* buffer as "manage_mac_read" response.
* Response such as various MAC addresses are stored in HW struct (port.mac)
* ice_aq_discover_caps is expected to be called before this function is called.
*/
static enum ice_status
ice_aq_manage_mac_read(struct ice_hw *hw, void *buf, u16 buf_size,
struct ice_sq_cd *cd)
{
struct ice_aqc_manage_mac_read_resp *resp;
struct ice_aqc_manage_mac_read *cmd;
struct ice_aq_desc desc;
enum ice_status status;
u16 flags;
cmd = &desc.params.mac_read;
if (buf_size < sizeof(*resp))
return ICE_ERR_BUF_TOO_SHORT;
ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_manage_mac_read);
status = ice_aq_send_cmd(hw, &desc, buf, buf_size, cd);
if (status)
return status;
resp = (struct ice_aqc_manage_mac_read_resp *)buf;
flags = le16_to_cpu(cmd->flags) & ICE_AQC_MAN_MAC_READ_M;
if (!(flags & ICE_AQC_MAN_MAC_LAN_ADDR_VALID)) {
ice_debug(hw, ICE_DBG_LAN, "got invalid MAC address\n");
return ICE_ERR_CFG;
}
ether_addr_copy(hw->port_info->mac.lan_addr, resp->mac_addr);
ether_addr_copy(hw->port_info->mac.perm_addr, resp->mac_addr);
return 0;
}
/**
* ice_aq_get_phy_caps - returns PHY capabilities
* @pi: port information structure
* @qual_mods: report qualified modules
* @report_mode: report mode capabilities
* @pcaps: structure for PHY capabilities to be filled
* @cd: pointer to command details structure or NULL
*
* Returns the various PHY capabilities supported on the Port (0x0600)
*/
static enum ice_status
ice_aq_get_phy_caps(struct ice_port_info *pi, bool qual_mods, u8 report_mode,
struct ice_aqc_get_phy_caps_data *pcaps,
struct ice_sq_cd *cd)
{
struct ice_aqc_get_phy_caps *cmd;
u16 pcaps_size = sizeof(*pcaps);
struct ice_aq_desc desc;
enum ice_status status;
cmd = &desc.params.get_phy;
if (!pcaps || (report_mode & ~ICE_AQC_REPORT_MODE_M) || !pi)
return ICE_ERR_PARAM;
ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_get_phy_caps);
if (qual_mods)
cmd->param0 |= cpu_to_le16(ICE_AQC_GET_PHY_RQM);
cmd->param0 |= cpu_to_le16(report_mode);
status = ice_aq_send_cmd(pi->hw, &desc, pcaps, pcaps_size, cd);
if (!status && report_mode == ICE_AQC_REPORT_TOPO_CAP)
pi->phy.phy_type_low = le64_to_cpu(pcaps->phy_type_low);
return status;
}
/**
* ice_get_media_type - Gets media type
* @pi: port information structure
*/
static enum ice_media_type ice_get_media_type(struct ice_port_info *pi)
{
struct ice_link_status *hw_link_info;
if (!pi)
return ICE_MEDIA_UNKNOWN;
hw_link_info = &pi->phy.link_info;
if (hw_link_info->phy_type_low) {
switch (hw_link_info->phy_type_low) {
case ICE_PHY_TYPE_LOW_1000BASE_SX:
case ICE_PHY_TYPE_LOW_1000BASE_LX:
case ICE_PHY_TYPE_LOW_10GBASE_SR:
case ICE_PHY_TYPE_LOW_10GBASE_LR:
case ICE_PHY_TYPE_LOW_10G_SFI_C2C:
case ICE_PHY_TYPE_LOW_25GBASE_SR:
case ICE_PHY_TYPE_LOW_25GBASE_LR:
case ICE_PHY_TYPE_LOW_25G_AUI_C2C:
case ICE_PHY_TYPE_LOW_40GBASE_SR4:
case ICE_PHY_TYPE_LOW_40GBASE_LR4:
return ICE_MEDIA_FIBER;
case ICE_PHY_TYPE_LOW_100BASE_TX:
case ICE_PHY_TYPE_LOW_1000BASE_T:
case ICE_PHY_TYPE_LOW_2500BASE_T:
case ICE_PHY_TYPE_LOW_5GBASE_T:
case ICE_PHY_TYPE_LOW_10GBASE_T:
case ICE_PHY_TYPE_LOW_25GBASE_T:
return ICE_MEDIA_BASET;
case ICE_PHY_TYPE_LOW_10G_SFI_DA:
case ICE_PHY_TYPE_LOW_25GBASE_CR:
case ICE_PHY_TYPE_LOW_25GBASE_CR_S:
case ICE_PHY_TYPE_LOW_25GBASE_CR1:
case ICE_PHY_TYPE_LOW_40GBASE_CR4:
return ICE_MEDIA_DA;
case ICE_PHY_TYPE_LOW_1000BASE_KX:
case ICE_PHY_TYPE_LOW_2500BASE_KX:
case ICE_PHY_TYPE_LOW_2500BASE_X:
case ICE_PHY_TYPE_LOW_5GBASE_KR:
case ICE_PHY_TYPE_LOW_10GBASE_KR_CR1:
case ICE_PHY_TYPE_LOW_25GBASE_KR:
case ICE_PHY_TYPE_LOW_25GBASE_KR1:
case ICE_PHY_TYPE_LOW_25GBASE_KR_S:
case ICE_PHY_TYPE_LOW_40GBASE_KR4:
return ICE_MEDIA_BACKPLANE;
}
}
return ICE_MEDIA_UNKNOWN;
}
/**
* ice_aq_get_link_info
* @pi: port information structure
* @ena_lse: enable/disable LinkStatusEvent reporting
* @link: pointer to link status structure - optional
* @cd: pointer to command details structure or NULL
*
* Get Link Status (0x607). Returns the link status of the adapter.
*/
enum ice_status
ice_aq_get_link_info(struct ice_port_info *pi, bool ena_lse,
struct ice_link_status *link, struct ice_sq_cd *cd)
{
struct ice_link_status *hw_link_info_old, *hw_link_info;
struct ice_aqc_get_link_status_data link_data = { 0 };
struct ice_aqc_get_link_status *resp;
enum ice_media_type *hw_media_type;
struct ice_fc_info *hw_fc_info;
bool tx_pause, rx_pause;
struct ice_aq_desc desc;
enum ice_status status;
u16 cmd_flags;
if (!pi)
return ICE_ERR_PARAM;
hw_link_info_old = &pi->phy.link_info_old;
hw_media_type = &pi->phy.media_type;
hw_link_info = &pi->phy.link_info;
hw_fc_info = &pi->fc;
ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_get_link_status);
cmd_flags = (ena_lse) ? ICE_AQ_LSE_ENA : ICE_AQ_LSE_DIS;
resp = &desc.params.get_link_status;
resp->cmd_flags = cpu_to_le16(cmd_flags);
resp->lport_num = pi->lport;
status = ice_aq_send_cmd(pi->hw, &desc, &link_data, sizeof(link_data),
cd);
if (status)
return status;
/* save off old link status information */
*hw_link_info_old = *hw_link_info;
/* update current link status information */
hw_link_info->link_speed = le16_to_cpu(link_data.link_speed);
hw_link_info->phy_type_low = le64_to_cpu(link_data.phy_type_low);
*hw_media_type = ice_get_media_type(pi);
hw_link_info->link_info = link_data.link_info;
hw_link_info->an_info = link_data.an_info;
hw_link_info->ext_info = link_data.ext_info;
hw_link_info->max_frame_size = le16_to_cpu(link_data.max_frame_size);
hw_link_info->pacing = link_data.cfg & ICE_AQ_CFG_PACING_M;
/* update fc info */
tx_pause = !!(link_data.an_info & ICE_AQ_LINK_PAUSE_TX);
rx_pause = !!(link_data.an_info & ICE_AQ_LINK_PAUSE_RX);
if (tx_pause && rx_pause)
hw_fc_info->current_mode = ICE_FC_FULL;
else if (tx_pause)
hw_fc_info->current_mode = ICE_FC_TX_PAUSE;
else if (rx_pause)
hw_fc_info->current_mode = ICE_FC_RX_PAUSE;
else
hw_fc_info->current_mode = ICE_FC_NONE;
hw_link_info->lse_ena =
!!(resp->cmd_flags & cpu_to_le16(ICE_AQ_LSE_IS_ENABLED));
/* save link status information */
if (link)
*link = *hw_link_info;
/* flag cleared so calling functions don't call AQ again */
pi->phy.get_link_info = false;
return status;
}
/**
* ice_init_hw - main hardware initialization routine
* @hw: pointer to the hardware structure
*/
enum ice_status ice_init_hw(struct ice_hw *hw)
{
struct ice_aqc_get_phy_caps_data *pcaps;
enum ice_status status;
u16 mac_buf_len;
void *mac_buf;
/* Set MAC type based on DeviceID */
status = ice_set_mac_type(hw);
......@@ -98,8 +323,46 @@ enum ice_status ice_init_hw(struct ice_hw *hw)
goto err_unroll_alloc;
}
/* Initialize port_info struct with scheduler data */
status = ice_sched_init_port(hw->port_info);
if (status)
goto err_unroll_sched;
pcaps = devm_kzalloc(ice_hw_to_dev(hw), sizeof(*pcaps), GFP_KERNEL);
if (!pcaps) {
status = ICE_ERR_NO_MEMORY;
goto err_unroll_sched;
}
/* Initialize port_info struct with PHY capabilities */
status = ice_aq_get_phy_caps(hw->port_info, false,
ICE_AQC_REPORT_TOPO_CAP, pcaps, NULL);
devm_kfree(ice_hw_to_dev(hw), pcaps);
if (status)
goto err_unroll_sched;
/* Initialize port_info struct with link information */
status = ice_aq_get_link_info(hw->port_info, false, NULL, NULL);
if (status)
goto err_unroll_sched;
/* Get port MAC information */
mac_buf_len = sizeof(struct ice_aqc_manage_mac_read_resp);
mac_buf = devm_kzalloc(ice_hw_to_dev(hw), mac_buf_len, GFP_KERNEL);
if (!mac_buf)
goto err_unroll_sched;
status = ice_aq_manage_mac_read(hw, mac_buf, mac_buf_len, NULL);
devm_kfree(ice_hw_to_dev(hw), mac_buf);
if (status)
goto err_unroll_sched;
return 0;
err_unroll_sched:
ice_sched_cleanup_all(hw);
err_unroll_alloc:
devm_kfree(ice_hw_to_dev(hw), hw->port_info);
err_unroll_cqinit:
......@@ -115,6 +378,7 @@ void ice_deinit_hw(struct ice_hw *hw)
{
ice_sched_cleanup_all(hw);
ice_shutdown_all_ctrlq(hw);
if (hw->port_info) {
devm_kfree(ice_hw_to_dev(hw), hw->port_info);
hw->port_info = NULL;
......
......@@ -35,4 +35,7 @@ ice_aq_send_cmd(struct ice_hw *hw, struct ice_aq_desc *desc,
void *buf, u16 buf_size, struct ice_sq_cd *cd);
enum ice_status ice_aq_get_fw_ver(struct ice_hw *hw, struct ice_sq_cd *cd);
enum ice_status ice_clear_pf_cfg(struct ice_hw *hw);
enum ice_status
ice_aq_get_link_info(struct ice_port_info *pi, bool ena_lse,
struct ice_link_status *link, struct ice_sq_cd *cd);
#endif /* _ICE_COMMON_H_ */
......@@ -3,6 +3,141 @@
#include "ice_sched.h"
/**
* ice_sched_add_root_node - Insert the Tx scheduler root node in SW DB
* @pi: port information structure
* @info: Scheduler element information from firmware
*
* This function inserts the root node of the scheduling tree topology
* to the SW DB.
*/
static enum ice_status
ice_sched_add_root_node(struct ice_port_info *pi,
struct ice_aqc_txsched_elem_data *info)
{
struct ice_sched_node *root;
struct ice_hw *hw;
u16 max_children;
if (!pi)
return ICE_ERR_PARAM;
hw = pi->hw;
root = devm_kzalloc(ice_hw_to_dev(hw), sizeof(*root), GFP_KERNEL);
if (!root)
return ICE_ERR_NO_MEMORY;
max_children = le16_to_cpu(hw->layer_info[0].max_children);
root->children = devm_kcalloc(ice_hw_to_dev(hw), max_children,
sizeof(*root), GFP_KERNEL);
if (!root->children) {
devm_kfree(ice_hw_to_dev(hw), root);
return ICE_ERR_NO_MEMORY;
}
memcpy(&root->info, info, sizeof(*info));
pi->root = root;
return 0;
}
/**
* ice_sched_find_node_by_teid - Find the Tx scheduler node in SW DB
* @start_node: pointer to the starting ice_sched_node struct in a sub-tree
* @teid: node teid to search
*
* This function searches for a node matching the teid in the scheduling tree
* from the SW DB. The search is recursive and is restricted by the number of
* layers it has searched through; stopping at the max supported layer.
*
* This function needs to be called when holding the port_info->sched_lock
*/
struct ice_sched_node *
ice_sched_find_node_by_teid(struct ice_sched_node *start_node, u32 teid)
{
u16 i;
/* The TEID is same as that of the start_node */
if (ICE_TXSCHED_GET_NODE_TEID(start_node) == teid)
return start_node;
/* The node has no children or is at the max layer */
if (!start_node->num_children ||
start_node->tx_sched_layer >= ICE_AQC_TOPO_MAX_LEVEL_NUM ||
start_node->info.data.elem_type == ICE_AQC_ELEM_TYPE_LEAF)
return NULL;
/* Check if teid matches to any of the children nodes */
for (i = 0; i < start_node->num_children; i++)
if (ICE_TXSCHED_GET_NODE_TEID(start_node->children[i]) == teid)
return start_node->children[i];
/* Search within each child's sub-tree */
for (i = 0; i < start_node->num_children; i++) {
struct ice_sched_node *tmp;
tmp = ice_sched_find_node_by_teid(start_node->children[i],
teid);
if (tmp)
return tmp;
}
return NULL;
}
/**
* ice_sched_add_node - Insert the Tx scheduler node in SW DB
* @pi: port information structure
* @layer: Scheduler layer of the node
* @info: Scheduler element information from firmware
*
* This function inserts a scheduler node to the SW DB.
*/
enum ice_status
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_sched_node *node;
struct ice_hw *hw;
u16 max_children;
if (!pi)
return ICE_ERR_PARAM;
hw = pi->hw;
/* A valid parent node should be there */
parent = ice_sched_find_node_by_teid(pi->root,
le32_to_cpu(info->parent_teid));
if (!parent) {
ice_debug(hw, ICE_DBG_SCHED,
"Parent Node not found for parent_teid=0x%x\n",
le32_to_cpu(info->parent_teid));
return ICE_ERR_PARAM;
}
node = devm_kzalloc(ice_hw_to_dev(hw), sizeof(*node), GFP_KERNEL);
if (!node)
return ICE_ERR_NO_MEMORY;
max_children = le16_to_cpu(hw->layer_info[layer].max_children);
if (max_children) {
node->children = devm_kcalloc(ice_hw_to_dev(hw), max_children,
sizeof(*node), GFP_KERNEL);
if (!node->children) {
devm_kfree(ice_hw_to_dev(hw), node);
return ICE_ERR_NO_MEMORY;
}
}
node->in_use = true;
node->parent = parent;
node->tx_sched_layer = layer;
parent->children[parent->num_children++] = node;
memcpy(&node->info, info, sizeof(*info));
return 0;
}
/**
* ice_aq_delete_sched_elems - delete scheduler elements
* @hw: pointer to the hw struct
......@@ -194,6 +329,36 @@ void ice_free_sched_node(struct ice_port_info *pi, struct ice_sched_node *node)
devm_kfree(ice_hw_to_dev(hw), node);
}
/**
* ice_aq_get_dflt_topo - gets default scheduler topology
* @hw: pointer to the hw struct
* @lport: logical port number
* @buf: pointer to buffer
* @buf_size: buffer size in bytes
* @num_branches: returns total number of queue to port branches
* @cd: pointer to command details structure or NULL
*
* Get default scheduler topology (0x400)
*/
static enum ice_status
ice_aq_get_dflt_topo(struct ice_hw *hw, u8 lport,
struct ice_aqc_get_topo_elem *buf, u16 buf_size,
u8 *num_branches, struct ice_sq_cd *cd)
{
struct ice_aqc_get_topo *cmd;
struct ice_aq_desc desc;
enum ice_status status;
cmd = &desc.params.get_topo;
ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_get_dflt_topo);
cmd->port_num = lport;
status = ice_aq_send_cmd(hw, &desc, buf, buf_size, cd);
if (!status && num_branches)
*num_branches = cmd->num_branches;
return status;
}
/**
* ice_aq_query_sched_res - query scheduler resource
* @hw: pointer to the hw struct
......@@ -297,6 +462,169 @@ void ice_sched_cleanup_all(struct ice_hw *hw)
hw->max_cgds = 0;
}
/**
* ice_rm_dflt_leaf_node - remove the default leaf node in the tree
* @pi: port information structure
*
* This function removes the leaf node that was created by the FW
* during initialization
*/
static void
ice_rm_dflt_leaf_node(struct ice_port_info *pi)
{
struct ice_sched_node *node;
node = pi->root;
while (node) {
if (!node->num_children)
break;
node = node->children[0];
}
if (node && node->info.data.elem_type == ICE_AQC_ELEM_TYPE_LEAF) {
u32 teid = le32_to_cpu(node->info.node_teid);
enum ice_status status;
/* remove the default leaf node */
status = ice_sched_remove_elems(pi->hw, node->parent, 1, &teid);
if (!status)
ice_free_sched_node(pi, node);
}
}
/**
* ice_sched_rm_dflt_nodes - free the default nodes in the tree
* @pi: port information structure
*
* This function frees all the nodes except root and TC that were created by
* the FW during initialization
*/
static void
ice_sched_rm_dflt_nodes(struct ice_port_info *pi)
{
struct ice_sched_node *node;
ice_rm_dflt_leaf_node(pi);
/* remove the default nodes except TC and root nodes */
node = pi->root;
while (node) {
if (node->tx_sched_layer >= pi->hw->sw_entry_point_layer &&
node->info.data.elem_type != ICE_AQC_ELEM_TYPE_TC &&
node->info.data.elem_type != ICE_AQC_ELEM_TYPE_ROOT_PORT) {
ice_free_sched_node(pi, node);
break;
}
if (!node->num_children)
break;
node = node->children[0];
}
}
/**
* ice_sched_init_port - Initialize scheduler by querying information from FW
* @pi: port info structure for the tree to cleanup
*
* This function is the initial call to find the total number of Tx scheduler
* resources, default topology created by firmware and storing the information
* in SW DB.
*/
enum ice_status ice_sched_init_port(struct ice_port_info *pi)
{
struct ice_aqc_get_topo_elem *buf;
enum ice_status status;
struct ice_hw *hw;
u8 num_branches;
u16 num_elems;
u8 i, j;
if (!pi)
return ICE_ERR_PARAM;
hw = pi->hw;
/* Query the Default Topology from FW */
buf = devm_kcalloc(ice_hw_to_dev(hw), ICE_TXSCHED_MAX_BRANCHES,
sizeof(*buf), GFP_KERNEL);
if (!buf)
return ICE_ERR_NO_MEMORY;
/* Query default scheduling tree topology */
status = ice_aq_get_dflt_topo(hw, pi->lport, buf,
sizeof(*buf) * ICE_TXSCHED_MAX_BRANCHES,
&num_branches, NULL);
if (status)
goto err_init_port;
/* num_branches should be between 1-8 */
if (num_branches < 1 || num_branches > ICE_TXSCHED_MAX_BRANCHES) {
ice_debug(hw, ICE_DBG_SCHED, "num_branches unexpected %d\n",
num_branches);
status = ICE_ERR_PARAM;
goto err_init_port;
}
/* get the number of elements on the default/first branch */
num_elems = le16_to_cpu(buf[0].hdr.num_elems);
/* num_elems should always be between 1-9 */
if (num_elems < 1 || num_elems > ICE_AQC_TOPO_MAX_LEVEL_NUM) {
ice_debug(hw, ICE_DBG_SCHED, "num_elems unexpected %d\n",
num_elems);
status = ICE_ERR_PARAM;
goto err_init_port;
}
/* If the last node is a leaf node then the index of the Q group
* layer is two less than the number of elements.
*/
if (num_elems > 2 && buf[0].generic[num_elems - 1].data.elem_type ==
ICE_AQC_ELEM_TYPE_LEAF)
pi->last_node_teid =
le32_to_cpu(buf[0].generic[num_elems - 2].node_teid);
else
pi->last_node_teid =
le32_to_cpu(buf[0].generic[num_elems - 1].node_teid);
/* Insert the Tx Sched root node */
status = ice_sched_add_root_node(pi, &buf[0].generic[0]);
if (status)
goto err_init_port;
/* Parse the default tree and cache the information */
for (i = 0; i < num_branches; i++) {
num_elems = le16_to_cpu(buf[i].hdr.num_elems);
/* Skip root element as already inserted */
for (j = 1; j < num_elems; j++) {
/* update the sw entry point */
if (buf[0].generic[j].data.elem_type ==
ICE_AQC_ELEM_TYPE_ENTRY_POINT)
hw->sw_entry_point_layer = j;
status = ice_sched_add_node(pi, j, &buf[i].generic[j]);
if (status)
goto err_init_port;
}
}
/* Remove the default nodes. */
if (pi->root)
ice_sched_rm_dflt_nodes(pi);
/* initialize the port for handling the scheduler tree */
pi->port_state = ICE_SCHED_PORT_STATE_READY;
mutex_init(&pi->sched_lock);
INIT_LIST_HEAD(&pi->agg_list);
INIT_LIST_HEAD(&pi->vsi_info_list);
err_init_port:
if (status && pi->root) {
ice_free_sched_node(pi, pi->root);
pi->root = NULL;
}
devm_kfree(ice_hw_to_dev(hw), buf);
return status;
}
/**
* ice_sched_query_res_alloc - query the FW for num of logical sched layers
* @hw: pointer to the HW struct
......
......@@ -21,8 +21,14 @@ struct ice_sched_agg_info {
};
/* FW AQ command calls */
enum ice_status ice_sched_init_port(struct ice_port_info *pi);
enum ice_status ice_sched_query_res_alloc(struct ice_hw *hw);
void ice_sched_cleanup_all(struct ice_hw *hw);
struct ice_sched_node *
ice_sched_find_node_by_teid(struct ice_sched_node *start_node, u32 teid);
enum ice_status
ice_sched_add_node(struct ice_port_info *pi, u8 layer,
struct ice_aqc_txsched_elem_data *info);
void ice_free_sched_node(struct ice_port_info *pi, struct ice_sched_node *node);
struct ice_sched_node *ice_sched_get_tc_node(struct ice_port_info *pi, u8 tc);
#endif /* _ICE_SCHED_H_ */
......@@ -15,6 +15,7 @@ enum ice_status {
ICE_ERR_NO_MEMORY = -11,
ICE_ERR_CFG = -12,
ICE_ERR_OUT_OF_RANGE = -13,
ICE_ERR_BUF_TOO_SHORT = -52,
ICE_ERR_NVM_BLANK_MODE = -53,
ICE_ERR_AQ_ERROR = -100,
ICE_ERR_AQ_TIMEOUT = -101,
......
......@@ -12,6 +12,7 @@
/* debug masks - set these bits in hw->debug_mask to control output */
#define ICE_DBG_INIT BIT_ULL(1)
#define ICE_DBG_NVM BIT_ULL(7)
#define ICE_DBG_LAN BIT_ULL(8)
#define ICE_DBG_SW BIT_ULL(13)
#define ICE_DBG_SCHED BIT_ULL(14)
#define ICE_DBG_RES BIT_ULL(17)
......@@ -30,12 +31,56 @@ enum ice_aq_res_access_type {
ICE_RES_WRITE
};
enum ice_fc_mode {
ICE_FC_NONE = 0,
ICE_FC_RX_PAUSE,
ICE_FC_TX_PAUSE,
ICE_FC_FULL,
ICE_FC_PFC,
ICE_FC_DFLT
};
/* Various MAC types */
enum ice_mac_type {
ICE_MAC_UNKNOWN = 0,
ICE_MAC_GENERIC,
};
/* Media Types */
enum ice_media_type {
ICE_MEDIA_UNKNOWN = 0,
ICE_MEDIA_FIBER,
ICE_MEDIA_BASET,
ICE_MEDIA_BACKPLANE,
ICE_MEDIA_DA,
};
struct ice_link_status {
/* Refer to ice_aq_phy_type for bits definition */
u64 phy_type_low;
u16 max_frame_size;
u16 link_speed;
bool lse_ena; /* Link Status Event notification */
u8 link_info;
u8 an_info;
u8 ext_info;
u8 pacing;
u8 req_speeds;
/* Refer to #define from module_type[ICE_MODULE_TYPE_TOTAL_BYTE] of
* ice_aqc_get_phy_caps structure
*/
u8 module_type[ICE_MODULE_TYPE_TOTAL_BYTE];
};
/* PHY info such as phy_type, etc... */
struct ice_phy_info {
struct ice_link_status link_info;
struct ice_link_status link_info_old;
u64 phy_type_low;
enum ice_media_type media_type;
bool get_link_info;
};
/* Common HW capabilities for SW use */
struct ice_hw_common_caps {
/* TX/RX queues */
......@@ -68,6 +113,12 @@ struct ice_hw_dev_caps {
u32 num_vsi_allocd_to_host; /* Excluding EMP VSI */
};
/* MAC info */
struct ice_mac_info {
u8 lan_addr[ETH_ALEN];
u8 perm_addr[ETH_ALEN];
};
/* Various RESET request, These are not tied with HW reset types */
enum ice_reset_req {
ICE_RESET_PFR = 0,
......@@ -81,6 +132,12 @@ struct ice_bus_info {
u8 func;
};
/* Flow control (FC) parameters */
struct ice_fc_info {
enum ice_fc_mode current_mode; /* FC mode in effect */
enum ice_fc_mode req_mode; /* FC mode requested by caller */
};
/* NVM Information */
struct ice_nvm_info {
u32 eetrack; /* NVM data version */
......@@ -92,6 +149,7 @@ struct ice_nvm_info {
/* Max number of port to queue branches w.r.t topology */
#define ICE_MAX_TRAFFIC_CLASS 8
#define ICE_TXSCHED_MAX_BRANCHES ICE_MAX_TRAFFIC_CLASS
struct ice_sched_node {
struct ice_sched_node *parent;
......@@ -108,6 +166,9 @@ struct ice_sched_node {
#define ICE_SCHED_NODE_OWNER_LAN 0
};
/* Access Macros for Tx Sched Elements data */
#define ICE_TXSCHED_GET_NODE_TEID(x) le32_to_cpu((x)->info.node_teid)
/* The aggregator type determines if identifier is for a VSI group,
* aggregator group, aggregator of queues, or queue group.
*/
......@@ -138,6 +199,7 @@ struct ice_sched_tx_policy {
struct ice_port_info {
struct ice_sched_node *root; /* Root Node per Port */
struct ice_hw *hw; /* back pointer to hw instance */
u32 last_node_teid; /* scheduler last node info */
u16 sw_id; /* Initial switch ID belongs to port */
u16 pf_vf_num;
u8 port_state;
......@@ -145,6 +207,9 @@ struct ice_port_info {
#define ICE_SCHED_PORT_STATE_READY 0x1
u16 dflt_tx_vsi_num;
u16 dflt_rx_vsi_num;
struct ice_fc_info fc;
struct ice_mac_info mac;
struct ice_phy_info phy;
struct mutex sched_lock; /* protect access to TXSched tree */
struct ice_sched_tx_policy sched_policy;
struct list_head vsi_info_list;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment