Commit eb67e07a authored by David S. Miller's avatar David S. Miller

Merge branch 'qed-DCBx-and-Attentions-series'

Yuval Mintz says:

====================
qed: DCBx and Attentions series

The series contains 2 major components [& some odd bits]:
 - The first 3 patches are DCBx-related, containg missing bits in the
   implementation, correcting existing API and removing code no longer
   necessary.
 - Most of the remaining patches are interrupt/hw-attention related,
   adding some differeneces relating to QL41xxx and QL45xxx differences.
   While at it, they also remove a large chunk of unnecessary structure
   definitions.

The series also contain a patch [#10] that was accidently missing
from a previous series.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents b11dabfd fc6575bc
...@@ -191,17 +191,19 @@ static void ...@@ -191,17 +191,19 @@ static void
qed_dcbx_set_params(struct qed_dcbx_results *p_data, qed_dcbx_set_params(struct qed_dcbx_results *p_data,
struct qed_hw_info *p_info, struct qed_hw_info *p_info,
bool enable, bool enable,
bool update,
u8 prio, u8 prio,
u8 tc, u8 tc,
enum dcbx_protocol_type type, enum dcbx_protocol_type type,
enum qed_pci_personality personality) enum qed_pci_personality personality)
{ {
/* PF update ramrod data */ /* PF update ramrod data */
p_data->arr[type].update = update;
p_data->arr[type].enable = enable; p_data->arr[type].enable = enable;
p_data->arr[type].priority = prio; p_data->arr[type].priority = prio;
p_data->arr[type].tc = tc; p_data->arr[type].tc = tc;
if (enable)
p_data->arr[type].update = UPDATE_DCB;
else
p_data->arr[type].update = DONT_UPDATE_DCB_DSCP;
/* QM reconf data */ /* QM reconf data */
if (p_info->personality == personality) if (p_info->personality == personality)
...@@ -213,7 +215,6 @@ static void ...@@ -213,7 +215,6 @@ static void
qed_dcbx_update_app_info(struct qed_dcbx_results *p_data, qed_dcbx_update_app_info(struct qed_dcbx_results *p_data,
struct qed_hwfn *p_hwfn, struct qed_hwfn *p_hwfn,
bool enable, bool enable,
bool update,
u8 prio, u8 tc, enum dcbx_protocol_type type) u8 prio, u8 tc, enum dcbx_protocol_type type)
{ {
struct qed_hw_info *p_info = &p_hwfn->hw_info; struct qed_hw_info *p_info = &p_hwfn->hw_info;
...@@ -231,7 +232,7 @@ qed_dcbx_update_app_info(struct qed_dcbx_results *p_data, ...@@ -231,7 +232,7 @@ qed_dcbx_update_app_info(struct qed_dcbx_results *p_data,
personality = qed_dcbx_app_update[i].personality; personality = qed_dcbx_app_update[i].personality;
name = qed_dcbx_app_update[i].name; name = qed_dcbx_app_update[i].name;
qed_dcbx_set_params(p_data, p_info, enable, update, qed_dcbx_set_params(p_data, p_info, enable,
prio, tc, type, personality); prio, tc, type, personality);
} }
} }
...@@ -304,22 +305,11 @@ qed_dcbx_process_tlv(struct qed_hwfn *p_hwfn, ...@@ -304,22 +305,11 @@ qed_dcbx_process_tlv(struct qed_hwfn *p_hwfn,
*/ */
enable = !(type == DCBX_PROTOCOL_ETH); enable = !(type == DCBX_PROTOCOL_ETH);
qed_dcbx_update_app_info(p_data, p_hwfn, enable, true, qed_dcbx_update_app_info(p_data, p_hwfn, enable,
priority, tc, type); priority, tc, type);
} }
} }
/* If RoCE-V2 TLV is not detected, driver need to use RoCE app
* data for RoCE-v2 not the default app data.
*/
if (!p_data->arr[DCBX_PROTOCOL_ROCE_V2].update &&
p_data->arr[DCBX_PROTOCOL_ROCE].update) {
tc = p_data->arr[DCBX_PROTOCOL_ROCE].tc;
priority = p_data->arr[DCBX_PROTOCOL_ROCE].priority;
qed_dcbx_update_app_info(p_data, p_hwfn, true, true,
priority, tc, DCBX_PROTOCOL_ROCE_V2);
}
/* Update ramrod protocol data and hw_info fields /* Update ramrod protocol data and hw_info fields
* with default info when corresponding APP TLV's are not detected. * with default info when corresponding APP TLV's are not detected.
* The enabled field has a different logic for ethernet as only for * The enabled field has a different logic for ethernet as only for
...@@ -332,8 +322,8 @@ qed_dcbx_process_tlv(struct qed_hwfn *p_hwfn, ...@@ -332,8 +322,8 @@ qed_dcbx_process_tlv(struct qed_hwfn *p_hwfn,
if (p_data->arr[type].update) if (p_data->arr[type].update)
continue; continue;
enable = !(type == DCBX_PROTOCOL_ETH); enable = (type == DCBX_PROTOCOL_ETH) ? false : !!dcbx_version;
qed_dcbx_update_app_info(p_data, p_hwfn, enable, true, qed_dcbx_update_app_info(p_data, p_hwfn, enable,
priority, tc, type); priority, tc, type);
} }
...@@ -1460,7 +1450,7 @@ static u8 qed_dcbnl_getcap(struct qed_dev *cdev, int capid, u8 *cap) ...@@ -1460,7 +1450,7 @@ static u8 qed_dcbnl_getcap(struct qed_dev *cdev, int capid, u8 *cap)
break; break;
case DCB_CAP_ATTR_DCBX: case DCB_CAP_ATTR_DCBX:
*cap = (DCB_CAP_DCBX_LLD_MANAGED | DCB_CAP_DCBX_VER_CEE | *cap = (DCB_CAP_DCBX_LLD_MANAGED | DCB_CAP_DCBX_VER_CEE |
DCB_CAP_DCBX_VER_IEEE); DCB_CAP_DCBX_VER_IEEE | DCB_CAP_DCBX_STATIC);
break; break;
default: default:
*cap = false; *cap = false;
...@@ -1534,6 +1524,8 @@ static u8 qed_dcbnl_getdcbx(struct qed_dev *cdev) ...@@ -1534,6 +1524,8 @@ static u8 qed_dcbnl_getdcbx(struct qed_dev *cdev)
mode |= DCB_CAP_DCBX_VER_IEEE; mode |= DCB_CAP_DCBX_VER_IEEE;
if (dcbx_info->operational.cee) if (dcbx_info->operational.cee)
mode |= DCB_CAP_DCBX_VER_CEE; mode |= DCB_CAP_DCBX_VER_CEE;
if (dcbx_info->operational.local)
mode |= DCB_CAP_DCBX_STATIC;
DP_VERBOSE(hwfn, QED_MSG_DCB, "dcb mode = %d\n", mode); DP_VERBOSE(hwfn, QED_MSG_DCB, "dcb mode = %d\n", mode);
kfree(dcbx_info); kfree(dcbx_info);
......
...@@ -52,7 +52,7 @@ enum qed_mib_read_type { ...@@ -52,7 +52,7 @@ enum qed_mib_read_type {
struct qed_dcbx_app_data { struct qed_dcbx_app_data {
bool enable; /* DCB enabled */ bool enable; /* DCB enabled */
bool update; /* Update indication */ u8 update; /* Update indication */
u8 priority; /* Priority */ u8 priority; /* Priority */
u8 tc; /* Traffic Class */ u8 tc; /* Traffic Class */
}; };
......
...@@ -5352,8 +5352,85 @@ enum dbg_status qed_dbg_fw_asserts_dump(struct qed_hwfn *p_hwfn, ...@@ -5352,8 +5352,85 @@ enum dbg_status qed_dbg_fw_asserts_dump(struct qed_hwfn *p_hwfn,
return DBG_STATUS_OK; return DBG_STATUS_OK;
} }
enum dbg_status qed_dbg_read_attn(struct qed_hwfn *p_hwfn,
struct qed_ptt *p_ptt,
enum block_id block_id,
enum dbg_attn_type attn_type,
bool clear_status,
struct dbg_attn_block_result *results)
{
enum dbg_status status = qed_dbg_dev_init(p_hwfn, p_ptt);
u8 reg_idx, num_attn_regs, num_result_regs = 0;
const struct dbg_attn_reg *attn_reg_arr;
if (status != DBG_STATUS_OK)
return status;
if (!s_dbg_arrays[BIN_BUF_DBG_MODE_TREE].ptr ||
!s_dbg_arrays[BIN_BUF_DBG_ATTN_BLOCKS].ptr ||
!s_dbg_arrays[BIN_BUF_DBG_ATTN_REGS].ptr)
return DBG_STATUS_DBG_ARRAY_NOT_SET;
attn_reg_arr = qed_get_block_attn_regs(block_id,
attn_type, &num_attn_regs);
for (reg_idx = 0; reg_idx < num_attn_regs; reg_idx++) {
const struct dbg_attn_reg *reg_data = &attn_reg_arr[reg_idx];
struct dbg_attn_reg_result *reg_result;
u32 sts_addr, sts_val;
u16 modes_buf_offset;
bool eval_mode;
/* Check mode */
eval_mode = GET_FIELD(reg_data->mode.data,
DBG_MODE_HDR_EVAL_MODE) > 0;
modes_buf_offset = GET_FIELD(reg_data->mode.data,
DBG_MODE_HDR_MODES_BUF_OFFSET);
if (eval_mode && !qed_is_mode_match(p_hwfn, &modes_buf_offset))
continue;
/* Mode match - read attention status register */
sts_addr = DWORDS_TO_BYTES(clear_status ?
reg_data->sts_clr_address :
GET_FIELD(reg_data->data,
DBG_ATTN_REG_STS_ADDRESS));
sts_val = qed_rd(p_hwfn, p_ptt, sts_addr);
if (!sts_val)
continue;
/* Non-zero attention status - add to results */
reg_result = &results->reg_results[num_result_regs];
SET_FIELD(reg_result->data,
DBG_ATTN_REG_RESULT_STS_ADDRESS, sts_addr);
SET_FIELD(reg_result->data,
DBG_ATTN_REG_RESULT_NUM_REG_ATTN,
GET_FIELD(reg_data->data, DBG_ATTN_REG_NUM_REG_ATTN));
reg_result->block_attn_offset = reg_data->block_attn_offset;
reg_result->sts_val = sts_val;
reg_result->mask_val = qed_rd(p_hwfn,
p_ptt,
DWORDS_TO_BYTES
(reg_data->mask_address));
num_result_regs++;
}
results->block_id = (u8)block_id;
results->names_offset =
qed_get_block_attn_data(block_id, attn_type)->names_offset;
SET_FIELD(results->data, DBG_ATTN_BLOCK_RESULT_ATTN_TYPE, attn_type);
SET_FIELD(results->data,
DBG_ATTN_BLOCK_RESULT_NUM_REGS, num_result_regs);
return DBG_STATUS_OK;
}
/******************************* Data Types **********************************/ /******************************* Data Types **********************************/
struct block_info {
const char *name;
enum block_id id;
};
struct mcp_trace_format { struct mcp_trace_format {
u32 data; u32 data;
#define MCP_TRACE_FORMAT_MODULE_MASK 0x0000ffff #define MCP_TRACE_FORMAT_MODULE_MASK 0x0000ffff
...@@ -5534,6 +5611,97 @@ struct user_dbg_array { ...@@ -5534,6 +5611,97 @@ struct user_dbg_array {
static struct user_dbg_array static struct user_dbg_array
s_user_dbg_arrays[MAX_BIN_DBG_BUFFER_TYPE] = { {NULL} }; s_user_dbg_arrays[MAX_BIN_DBG_BUFFER_TYPE] = { {NULL} };
/* Block names array */
static struct block_info s_block_info_arr[] = {
{"grc", BLOCK_GRC},
{"miscs", BLOCK_MISCS},
{"misc", BLOCK_MISC},
{"dbu", BLOCK_DBU},
{"pglue_b", BLOCK_PGLUE_B},
{"cnig", BLOCK_CNIG},
{"cpmu", BLOCK_CPMU},
{"ncsi", BLOCK_NCSI},
{"opte", BLOCK_OPTE},
{"bmb", BLOCK_BMB},
{"pcie", BLOCK_PCIE},
{"mcp", BLOCK_MCP},
{"mcp2", BLOCK_MCP2},
{"pswhst", BLOCK_PSWHST},
{"pswhst2", BLOCK_PSWHST2},
{"pswrd", BLOCK_PSWRD},
{"pswrd2", BLOCK_PSWRD2},
{"pswwr", BLOCK_PSWWR},
{"pswwr2", BLOCK_PSWWR2},
{"pswrq", BLOCK_PSWRQ},
{"pswrq2", BLOCK_PSWRQ2},
{"pglcs", BLOCK_PGLCS},
{"ptu", BLOCK_PTU},
{"dmae", BLOCK_DMAE},
{"tcm", BLOCK_TCM},
{"mcm", BLOCK_MCM},
{"ucm", BLOCK_UCM},
{"xcm", BLOCK_XCM},
{"ycm", BLOCK_YCM},
{"pcm", BLOCK_PCM},
{"qm", BLOCK_QM},
{"tm", BLOCK_TM},
{"dorq", BLOCK_DORQ},
{"brb", BLOCK_BRB},
{"src", BLOCK_SRC},
{"prs", BLOCK_PRS},
{"tsdm", BLOCK_TSDM},
{"msdm", BLOCK_MSDM},
{"usdm", BLOCK_USDM},
{"xsdm", BLOCK_XSDM},
{"ysdm", BLOCK_YSDM},
{"psdm", BLOCK_PSDM},
{"tsem", BLOCK_TSEM},
{"msem", BLOCK_MSEM},
{"usem", BLOCK_USEM},
{"xsem", BLOCK_XSEM},
{"ysem", BLOCK_YSEM},
{"psem", BLOCK_PSEM},
{"rss", BLOCK_RSS},
{"tmld", BLOCK_TMLD},
{"muld", BLOCK_MULD},
{"yuld", BLOCK_YULD},
{"xyld", BLOCK_XYLD},
{"ptld", BLOCK_PTLD},
{"ypld", BLOCK_YPLD},
{"prm", BLOCK_PRM},
{"pbf_pb1", BLOCK_PBF_PB1},
{"pbf_pb2", BLOCK_PBF_PB2},
{"rpb", BLOCK_RPB},
{"btb", BLOCK_BTB},
{"pbf", BLOCK_PBF},
{"rdif", BLOCK_RDIF},
{"tdif", BLOCK_TDIF},
{"cdu", BLOCK_CDU},
{"ccfc", BLOCK_CCFC},
{"tcfc", BLOCK_TCFC},
{"igu", BLOCK_IGU},
{"cau", BLOCK_CAU},
{"rgfs", BLOCK_RGFS},
{"rgsrc", BLOCK_RGSRC},
{"tgfs", BLOCK_TGFS},
{"tgsrc", BLOCK_TGSRC},
{"umac", BLOCK_UMAC},
{"xmac", BLOCK_XMAC},
{"dbg", BLOCK_DBG},
{"nig", BLOCK_NIG},
{"wol", BLOCK_WOL},
{"bmbn", BLOCK_BMBN},
{"ipc", BLOCK_IPC},
{"nwm", BLOCK_NWM},
{"nws", BLOCK_NWS},
{"ms", BLOCK_MS},
{"phy_pcie", BLOCK_PHY_PCIE},
{"led", BLOCK_LED},
{"avs_wrap", BLOCK_AVS_WRAP},
{"misc_aeu", BLOCK_MISC_AEU},
{"bar0_map", BLOCK_BAR0_MAP}
};
/* Status string array */ /* Status string array */
static const char * const s_status_str[] = { static const char * const s_status_str[] = {
/* DBG_STATUS_OK */ /* DBG_STATUS_OK */
...@@ -7193,6 +7361,88 @@ enum dbg_status qed_print_fw_asserts_results(struct qed_hwfn *p_hwfn, ...@@ -7193,6 +7361,88 @@ enum dbg_status qed_print_fw_asserts_results(struct qed_hwfn *p_hwfn,
results_buf, &parsed_buf_size); results_buf, &parsed_buf_size);
} }
enum dbg_status qed_dbg_parse_attn(struct qed_hwfn *p_hwfn,
struct dbg_attn_block_result *results)
{
struct user_dbg_array *block_attn, *pstrings;
const u32 *block_attn_name_offsets;
enum dbg_attn_type attn_type;
const char *block_name;
u8 num_regs, i, j;
num_regs = GET_FIELD(results->data, DBG_ATTN_BLOCK_RESULT_NUM_REGS);
attn_type = (enum dbg_attn_type)
GET_FIELD(results->data,
DBG_ATTN_BLOCK_RESULT_ATTN_TYPE);
block_name = s_block_info_arr[results->block_id].name;
if (!s_user_dbg_arrays[BIN_BUF_DBG_ATTN_INDEXES].ptr ||
!s_user_dbg_arrays[BIN_BUF_DBG_ATTN_NAME_OFFSETS].ptr ||
!s_user_dbg_arrays[BIN_BUF_DBG_PARSING_STRINGS].ptr)
return DBG_STATUS_DBG_ARRAY_NOT_SET;
block_attn = &s_user_dbg_arrays[BIN_BUF_DBG_ATTN_NAME_OFFSETS];
block_attn_name_offsets = &block_attn->ptr[results->names_offset];
/* Go over registers with a non-zero attention status */
for (i = 0; i < num_regs; i++) {
struct dbg_attn_reg_result *reg_result;
struct dbg_attn_bit_mapping *mapping;
u8 num_reg_attn, bit_idx = 0;
reg_result = &results->reg_results[i];
num_reg_attn = GET_FIELD(reg_result->data,
DBG_ATTN_REG_RESULT_NUM_REG_ATTN);
block_attn = &s_user_dbg_arrays[BIN_BUF_DBG_ATTN_INDEXES];
mapping = &((struct dbg_attn_bit_mapping *)
block_attn->ptr)[reg_result->block_attn_offset];
pstrings = &s_user_dbg_arrays[BIN_BUF_DBG_PARSING_STRINGS];
/* Go over attention status bits */
for (j = 0; j < num_reg_attn; j++) {
u16 attn_idx_val = GET_FIELD(mapping[j].data,
DBG_ATTN_BIT_MAPPING_VAL);
const char *attn_name, *attn_type_str, *masked_str;
u32 name_offset, sts_addr;
/* Check if bit mask should be advanced (due to unused
* bits).
*/
if (GET_FIELD(mapping[j].data,
DBG_ATTN_BIT_MAPPING_IS_UNUSED_BIT_CNT)) {
bit_idx += (u8)attn_idx_val;
continue;
}
/* Check current bit index */
if (!(reg_result->sts_val & BIT(bit_idx))) {
bit_idx++;
continue;
}
/* Find attention name */
name_offset = block_attn_name_offsets[attn_idx_val];
attn_name = &((const char *)
pstrings->ptr)[name_offset];
attn_type_str = attn_type == ATTN_TYPE_INTERRUPT ?
"Interrupt" : "Parity";
masked_str = reg_result->mask_val & BIT(bit_idx) ?
" [masked]" : "";
sts_addr = GET_FIELD(reg_result->data,
DBG_ATTN_REG_RESULT_STS_ADDRESS);
DP_NOTICE(p_hwfn,
"%s (%s) : %s [address 0x%08x, bit %d]%s\n",
block_name, attn_type_str, attn_name,
sts_addr, bit_idx, masked_str);
bit_idx++;
}
}
return DBG_STATUS_OK;
}
/* Wrapper for unifying the idle_chk and mcp_trace api */ /* Wrapper for unifying the idle_chk and mcp_trace api */
static enum dbg_status static enum dbg_status
qed_print_idle_chk_results_wrapper(struct qed_hwfn *p_hwfn, qed_print_idle_chk_results_wrapper(struct qed_hwfn *p_hwfn,
......
...@@ -1227,6 +1227,10 @@ static void qed_init_cache_line_size(struct qed_hwfn *p_hwfn, ...@@ -1227,6 +1227,10 @@ static void qed_init_cache_line_size(struct qed_hwfn *p_hwfn,
L1_CACHE_BYTES, wr_mbs); L1_CACHE_BYTES, wr_mbs);
STORE_RT_REG(p_hwfn, PGLUE_REG_B_CACHE_LINE_SIZE_RT_OFFSET, val); STORE_RT_REG(p_hwfn, PGLUE_REG_B_CACHE_LINE_SIZE_RT_OFFSET, val);
if (val > 0) {
STORE_RT_REG(p_hwfn, PSWRQ2_REG_DRAM_ALIGN_WR_RT_OFFSET, val);
STORE_RT_REG(p_hwfn, PSWRQ2_REG_DRAM_ALIGN_RD_RT_OFFSET, val);
}
} }
static int qed_hw_init_common(struct qed_hwfn *p_hwfn, static int qed_hw_init_common(struct qed_hwfn *p_hwfn,
...@@ -1433,8 +1437,15 @@ qed_hw_init_pf_doorbell_bar(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt) ...@@ -1433,8 +1437,15 @@ qed_hw_init_pf_doorbell_bar(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt)
static int qed_hw_init_port(struct qed_hwfn *p_hwfn, static int qed_hw_init_port(struct qed_hwfn *p_hwfn,
struct qed_ptt *p_ptt, int hw_mode) struct qed_ptt *p_ptt, int hw_mode)
{ {
return qed_init_run(p_hwfn, p_ptt, PHASE_PORT, int rc = 0;
p_hwfn->port_id, hw_mode);
rc = qed_init_run(p_hwfn, p_ptt, PHASE_PORT, p_hwfn->port_id, hw_mode);
if (rc)
return rc;
qed_wr(p_hwfn, p_ptt, PGLUE_B_REG_MASTER_WRITE_PAD_ENABLE, 0);
return 0;
} }
static int qed_hw_init_pf(struct qed_hwfn *p_hwfn, static int qed_hw_init_pf(struct qed_hwfn *p_hwfn,
......
...@@ -3076,6 +3076,29 @@ enum dbg_status qed_dbg_fw_asserts_dump(struct qed_hwfn *p_hwfn, ...@@ -3076,6 +3076,29 @@ enum dbg_status qed_dbg_fw_asserts_dump(struct qed_hwfn *p_hwfn,
u32 *dump_buf, u32 *dump_buf,
u32 buf_size_in_dwords, u32 buf_size_in_dwords,
u32 *num_dumped_dwords); u32 *num_dumped_dwords);
/**
* @brief qed_dbg_read_attn - Reads the attention registers of the specified
* block and type, and writes the results into the specified buffer.
*
* @param p_hwfn - HW device data
* @param p_ptt - Ptt window used for writing the registers.
* @param block - Block ID.
* @param attn_type - Attention type.
* @param clear_status - Indicates if the attention status should be cleared.
* @param results - OUT: Pointer to write the read results into
*
* @return error if one of the following holds:
* - the version wasn't set
* Otherwise, returns ok.
*/
enum dbg_status qed_dbg_read_attn(struct qed_hwfn *p_hwfn,
struct qed_ptt *p_ptt,
enum block_id block,
enum dbg_attn_type attn_type,
bool clear_status,
struct dbg_attn_block_result *results);
/** /**
* @brief qed_dbg_print_attn - Prints attention registers values in the * @brief qed_dbg_print_attn - Prints attention registers values in the
* specified results struct. * specified results struct.
...@@ -3309,6 +3332,20 @@ enum dbg_status qed_print_fw_asserts_results(struct qed_hwfn *p_hwfn, ...@@ -3309,6 +3332,20 @@ enum dbg_status qed_print_fw_asserts_results(struct qed_hwfn *p_hwfn,
u32 num_dumped_dwords, u32 num_dumped_dwords,
char *results_buf); char *results_buf);
/**
* @brief qed_dbg_parse_attn - Parses and prints attention registers values in
* the specified results struct.
*
* @param p_hwfn - HW device data
* @param results - Pointer to the attention read results
*
* @return error if one of the following holds:
* - the version wasn't set
* Otherwise, returns ok.
*/
enum dbg_status qed_dbg_parse_attn(struct qed_hwfn *p_hwfn,
struct dbg_attn_block_result *results);
/* Debug Bus blocks */ /* Debug Bus blocks */
static const u32 dbg_bus_blocks[] = { static const u32 dbg_bus_blocks[] = {
0x0000000f, /* grc, bb, 15 lines */ 0x0000000f, /* grc, bb, 15 lines */
...@@ -11474,9 +11511,11 @@ struct public_drv_mb { ...@@ -11474,9 +11511,11 @@ struct public_drv_mb {
#define DRV_MSG_CODE_BW_UPDATE_ACK 0x32000000 #define DRV_MSG_CODE_BW_UPDATE_ACK 0x32000000
#define DRV_MSG_CODE_NIG_DRAIN 0x30000000 #define DRV_MSG_CODE_NIG_DRAIN 0x30000000
#define DRV_MSG_CODE_S_TAG_UPDATE_ACK 0x3b000000
#define DRV_MSG_CODE_INITIATE_PF_FLR 0x02010000 #define DRV_MSG_CODE_INITIATE_PF_FLR 0x02010000
#define DRV_MSG_CODE_VF_DISABLED_DONE 0xc0000000 #define DRV_MSG_CODE_VF_DISABLED_DONE 0xc0000000
#define DRV_MSG_CODE_CFG_VF_MSIX 0xc0010000 #define DRV_MSG_CODE_CFG_VF_MSIX 0xc0010000
#define DRV_MSG_CODE_CFG_PF_VFS_MSIX 0xc0020000
#define DRV_MSG_CODE_NVM_GET_FILE_ATT 0x00030000 #define DRV_MSG_CODE_NVM_GET_FILE_ATT 0x00030000
#define DRV_MSG_CODE_NVM_READ_NVRAM 0x00050000 #define DRV_MSG_CODE_NVM_READ_NVRAM 0x00050000
#define DRV_MSG_CODE_MCP_RESET 0x00090000 #define DRV_MSG_CODE_MCP_RESET 0x00090000
...@@ -11633,6 +11672,7 @@ struct public_drv_mb { ...@@ -11633,6 +11672,7 @@ struct public_drv_mb {
#define FW_MSG_CODE_RESOURCE_ALLOC_OK 0x34000000 #define FW_MSG_CODE_RESOURCE_ALLOC_OK 0x34000000
#define FW_MSG_CODE_RESOURCE_ALLOC_UNKNOWN 0x35000000 #define FW_MSG_CODE_RESOURCE_ALLOC_UNKNOWN 0x35000000
#define FW_MSG_CODE_RESOURCE_ALLOC_DEPRECATED 0x36000000 #define FW_MSG_CODE_RESOURCE_ALLOC_DEPRECATED 0x36000000
#define FW_MSG_CODE_S_TAG_UPDATE_ACK_DONE 0x3b000000
#define FW_MSG_CODE_DRV_CFG_VF_MSIX_DONE 0xb0010000 #define FW_MSG_CODE_DRV_CFG_VF_MSIX_DONE 0xb0010000
#define FW_MSG_CODE_NVM_OK 0x00010000 #define FW_MSG_CODE_NVM_OK 0x00010000
...@@ -11640,7 +11680,7 @@ struct public_drv_mb { ...@@ -11640,7 +11680,7 @@ struct public_drv_mb {
#define FW_MSG_CODE_OS_WOL_SUPPORTED 0x00800000 #define FW_MSG_CODE_OS_WOL_SUPPORTED 0x00800000
#define FW_MSG_CODE_OS_WOL_NOT_SUPPORTED 0x00810000 #define FW_MSG_CODE_OS_WOL_NOT_SUPPORTED 0x00810000
#define FW_MSG_CODE_DRV_CFG_PF_VFS_MSIX_DONE 0x00870000
#define FW_MSG_SEQ_NUMBER_MASK 0x0000ffff #define FW_MSG_SEQ_NUMBER_MASK 0x0000ffff
u32 fw_mb_param; u32 fw_mb_param;
...@@ -11680,7 +11720,7 @@ enum MFW_DRV_MSG_TYPE { ...@@ -11680,7 +11720,7 @@ enum MFW_DRV_MSG_TYPE {
MFW_DRV_MSG_DCBX_OPERATIONAL_MIB_UPDATED, MFW_DRV_MSG_DCBX_OPERATIONAL_MIB_UPDATED,
MFW_DRV_MSG_RESERVED4, MFW_DRV_MSG_RESERVED4,
MFW_DRV_MSG_BW_UPDATE, MFW_DRV_MSG_BW_UPDATE,
MFW_DRV_MSG_BW_UPDATE5, MFW_DRV_MSG_S_TAG_UPDATE,
MFW_DRV_MSG_GET_LAN_STATS, MFW_DRV_MSG_GET_LAN_STATS,
MFW_DRV_MSG_GET_FCOE_STATS, MFW_DRV_MSG_GET_FCOE_STATS,
MFW_DRV_MSG_GET_ISCSI_STATS, MFW_DRV_MSG_GET_ISCSI_STATS,
......
This diff is collapsed.
...@@ -1398,6 +1398,28 @@ static void qed_mcp_update_bw(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt) ...@@ -1398,6 +1398,28 @@ static void qed_mcp_update_bw(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt)
&param); &param);
} }
static void qed_mcp_update_stag(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt)
{
struct public_func shmem_info;
u32 resp = 0, param = 0;
qed_mcp_get_shmem_func(p_hwfn, p_ptt, &shmem_info, MCP_PF_ID(p_hwfn));
p_hwfn->mcp_info->func_info.ovlan = (u16)shmem_info.ovlan_stag &
FUNC_MF_CFG_OV_STAG_MASK;
p_hwfn->hw_info.ovlan = p_hwfn->mcp_info->func_info.ovlan;
if ((p_hwfn->hw_info.hw_mode & BIT(MODE_MF_SD)) &&
(p_hwfn->hw_info.ovlan != QED_MCP_VLAN_UNSET)) {
qed_wr(p_hwfn, p_ptt,
NIG_REG_LLH_FUNC_TAG_VALUE, p_hwfn->hw_info.ovlan);
qed_sp_pf_update_stag(p_hwfn);
}
/* Acknowledge the MFW */
qed_mcp_cmd(p_hwfn, p_ptt, DRV_MSG_CODE_S_TAG_UPDATE_ACK, 0,
&resp, &param);
}
int qed_mcp_handle_events(struct qed_hwfn *p_hwfn, int qed_mcp_handle_events(struct qed_hwfn *p_hwfn,
struct qed_ptt *p_ptt) struct qed_ptt *p_ptt)
{ {
...@@ -1453,6 +1475,10 @@ int qed_mcp_handle_events(struct qed_hwfn *p_hwfn, ...@@ -1453,6 +1475,10 @@ int qed_mcp_handle_events(struct qed_hwfn *p_hwfn,
case MFW_DRV_MSG_BW_UPDATE: case MFW_DRV_MSG_BW_UPDATE:
qed_mcp_update_bw(p_hwfn, p_ptt); qed_mcp_update_bw(p_hwfn, p_ptt);
break; break;
case MFW_DRV_MSG_S_TAG_UPDATE:
qed_mcp_update_stag(p_hwfn, p_ptt);
break;
break;
default: default:
DP_INFO(p_hwfn, "Unimplemented MFW message %d\n", i); DP_INFO(p_hwfn, "Unimplemented MFW message %d\n", i);
rc = -EINVAL; rc = -EINVAL;
...@@ -1801,8 +1827,9 @@ int qed_mcp_get_flash_size(struct qed_hwfn *p_hwfn, ...@@ -1801,8 +1827,9 @@ int qed_mcp_get_flash_size(struct qed_hwfn *p_hwfn,
return 0; return 0;
} }
int qed_mcp_config_vf_msix(struct qed_hwfn *p_hwfn, static int
struct qed_ptt *p_ptt, u8 vf_id, u8 num) qed_mcp_config_vf_msix_bb(struct qed_hwfn *p_hwfn,
struct qed_ptt *p_ptt, u8 vf_id, u8 num)
{ {
u32 resp = 0, param = 0, rc_param = 0; u32 resp = 0, param = 0, rc_param = 0;
int rc; int rc;
...@@ -1832,6 +1859,36 @@ int qed_mcp_config_vf_msix(struct qed_hwfn *p_hwfn, ...@@ -1832,6 +1859,36 @@ int qed_mcp_config_vf_msix(struct qed_hwfn *p_hwfn,
return rc; return rc;
} }
static int
qed_mcp_config_vf_msix_ah(struct qed_hwfn *p_hwfn,
struct qed_ptt *p_ptt, u8 num)
{
u32 resp = 0, param = num, rc_param = 0;
int rc;
rc = qed_mcp_cmd(p_hwfn, p_ptt, DRV_MSG_CODE_CFG_PF_VFS_MSIX,
param, &resp, &rc_param);
if (resp != FW_MSG_CODE_DRV_CFG_PF_VFS_MSIX_DONE) {
DP_NOTICE(p_hwfn, "MFW failed to set MSI-X for VFs\n");
rc = -EINVAL;
} else {
DP_VERBOSE(p_hwfn, QED_MSG_IOV,
"Requested 0x%02x MSI-x interrupts for VFs\n", num);
}
return rc;
}
int qed_mcp_config_vf_msix(struct qed_hwfn *p_hwfn,
struct qed_ptt *p_ptt, u8 vf_id, u8 num)
{
if (QED_IS_BB(p_hwfn->cdev))
return qed_mcp_config_vf_msix_bb(p_hwfn, p_ptt, vf_id, num);
else
return qed_mcp_config_vf_msix_ah(p_hwfn, p_ptt, num);
}
int int
qed_mcp_send_drv_version(struct qed_hwfn *p_hwfn, qed_mcp_send_drv_version(struct qed_hwfn *p_hwfn,
struct qed_ptt *p_ptt, struct qed_ptt *p_ptt,
......
...@@ -242,6 +242,8 @@ ...@@ -242,6 +242,8 @@
0x50196cUL 0x50196cUL
#define NIG_REG_LLH_CLS_TYPE_DUALMODE \ #define NIG_REG_LLH_CLS_TYPE_DUALMODE \
0x501964UL 0x501964UL
#define NIG_REG_LLH_FUNC_TAG_EN 0x5019b0UL
#define NIG_REG_LLH_FUNC_TAG_VALUE 0x5019d0UL
#define NIG_REG_LLH_FUNC_FILTER_VALUE \ #define NIG_REG_LLH_FUNC_FILTER_VALUE \
0x501a00UL 0x501a00UL
#define NIG_REG_LLH_FUNC_FILTER_VALUE_SIZE \ #define NIG_REG_LLH_FUNC_FILTER_VALUE_SIZE \
...@@ -1557,6 +1559,7 @@ ...@@ -1557,6 +1559,7 @@
#define PGLUE_B_REG_PGL_ADDR_EC_F0_K2 0x2aaf9cUL #define PGLUE_B_REG_PGL_ADDR_EC_F0_K2 0x2aaf9cUL
#define PGLUE_B_REG_PGL_ADDR_F0_F0_K2 0x2aafa0UL #define PGLUE_B_REG_PGL_ADDR_F0_F0_K2 0x2aafa0UL
#define PGLUE_B_REG_PGL_ADDR_F4_F0_K2 0x2aafa4UL #define PGLUE_B_REG_PGL_ADDR_F4_F0_K2 0x2aafa4UL
#define PGLUE_B_REG_MASTER_WRITE_PAD_ENABLE 0x2aae30UL
#define NIG_REG_TSGEN_FREECNT_UPDATE_K2 0x509008UL #define NIG_REG_TSGEN_FREECNT_UPDATE_K2 0x509008UL
#define CNIG_REG_NIG_PORT0_CONF_K2 0x218200UL #define CNIG_REG_NIG_PORT0_CONF_K2 0x218200UL
......
...@@ -417,6 +417,15 @@ int qed_sp_pf_start(struct qed_hwfn *p_hwfn, ...@@ -417,6 +417,15 @@ int qed_sp_pf_start(struct qed_hwfn *p_hwfn,
int qed_sp_pf_update(struct qed_hwfn *p_hwfn); int qed_sp_pf_update(struct qed_hwfn *p_hwfn);
/**
* @brief qed_sp_pf_update_stag - Update firmware of new outer tag
*
* @param p_hwfn
*
* @return int
*/
int qed_sp_pf_update_stag(struct qed_hwfn *p_hwfn);
/** /**
* @brief qed_sp_pf_stop - PF Function Stop Ramrod * @brief qed_sp_pf_stop - PF Function Stop Ramrod
* *
......
...@@ -514,3 +514,27 @@ int qed_sp_heartbeat_ramrod(struct qed_hwfn *p_hwfn) ...@@ -514,3 +514,27 @@ int qed_sp_heartbeat_ramrod(struct qed_hwfn *p_hwfn)
return qed_spq_post(p_hwfn, p_ent, NULL); return qed_spq_post(p_hwfn, p_ent, NULL);
} }
int qed_sp_pf_update_stag(struct qed_hwfn *p_hwfn)
{
struct qed_spq_entry *p_ent = NULL;
struct qed_sp_init_data init_data;
int rc = -EINVAL;
/* Get SPQ entry */
memset(&init_data, 0, sizeof(init_data));
init_data.cid = qed_spq_get_cid(p_hwfn);
init_data.opaque_fid = p_hwfn->hw_info.opaque_fid;
init_data.comp_mode = QED_SPQ_MODE_CB;
rc = qed_sp_init_request(p_hwfn, &p_ent,
COMMON_RAMROD_PF_UPDATE, PROTOCOLID_COMMON,
&init_data);
if (rc)
return rc;
p_ent->ramrod.pf_update.update_mf_vlan_flag = true;
p_ent->ramrod.pf_update.mf_vlan = cpu_to_le16(p_hwfn->hw_info.ovlan);
return qed_spq_post(p_hwfn, p_ent, NULL);
}
...@@ -747,6 +747,35 @@ static void qed_iov_vf_igu_set_int(struct qed_hwfn *p_hwfn, ...@@ -747,6 +747,35 @@ static void qed_iov_vf_igu_set_int(struct qed_hwfn *p_hwfn,
qed_fid_pretend(p_hwfn, p_ptt, (u16) p_hwfn->hw_info.concrete_fid); qed_fid_pretend(p_hwfn, p_ptt, (u16) p_hwfn->hw_info.concrete_fid);
} }
static int
qed_iov_enable_vf_access_msix(struct qed_hwfn *p_hwfn,
struct qed_ptt *p_ptt, u8 abs_vf_id, u8 num_sbs)
{
u8 current_max = 0;
int i;
/* For AH onward, configuration is per-PF. Find maximum of all
* the currently enabled child VFs, and set the number to be that.
*/
if (!QED_IS_BB(p_hwfn->cdev)) {
qed_for_each_vf(p_hwfn, i) {
struct qed_vf_info *p_vf;
p_vf = qed_iov_get_vf_info(p_hwfn, (u16)i, true);
if (!p_vf)
continue;
current_max = max_t(u8, current_max, p_vf->num_sbs);
}
}
if (num_sbs > current_max)
return qed_mcp_config_vf_msix(p_hwfn, p_ptt,
abs_vf_id, num_sbs);
return 0;
}
static int qed_iov_enable_vf_access(struct qed_hwfn *p_hwfn, static int qed_iov_enable_vf_access(struct qed_hwfn *p_hwfn,
struct qed_ptt *p_ptt, struct qed_ptt *p_ptt,
struct qed_vf_info *vf) struct qed_vf_info *vf)
...@@ -771,7 +800,8 @@ static int qed_iov_enable_vf_access(struct qed_hwfn *p_hwfn, ...@@ -771,7 +800,8 @@ static int qed_iov_enable_vf_access(struct qed_hwfn *p_hwfn,
qed_iov_vf_igu_reset(p_hwfn, p_ptt, vf); qed_iov_vf_igu_reset(p_hwfn, p_ptt, vf);
rc = qed_mcp_config_vf_msix(p_hwfn, p_ptt, vf->abs_vf_id, vf->num_sbs); rc = qed_iov_enable_vf_access_msix(p_hwfn, p_ptt,
vf->abs_vf_id, vf->num_sbs);
if (rc) if (rc)
return rc; return rc;
......
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