[PATCH v2 net-next 06/10] qed: Get rid of the attention-arrays

2017-05-28 Thread Yuval Mintz
We have almost all the necessary information regarding attentions
in the logic employed for taking register dumps.
Add some more and get rid of the seperate implementation we have today
for identifying & printing various attention sources.

Signed-off-by: Yuval Mintz 
---
 drivers/net/ethernet/qlogic/qed/qed_debug.c |  250 +
 drivers/net/ethernet/qlogic/qed/qed_hsi.h   |   37 +
 drivers/net/ethernet/qlogic/qed/qed_int.c   | 1312 +--
 3 files changed, 312 insertions(+), 1287 deletions(-)

diff --git a/drivers/net/ethernet/qlogic/qed/qed_debug.c 
b/drivers/net/ethernet/qlogic/qed/qed_debug.c
index 87a1389..9cea710 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_debug.c
+++ b/drivers/net/ethernet/qlogic/qed/qed_debug.c
@@ -5352,8 +5352,85 @@ enum dbg_status qed_dbg_fw_asserts_dump(struct qed_hwfn 
*p_hwfn,
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 **/
 
+struct block_info {
+   const char *name;
+   enum block_id id;
+};
+
 struct mcp_trace_format {
u32 data;
 #define MCP_TRACE_FORMAT_MODULE_MASK   0x
@@ -5534,6 +5611,97 @@ struct user_dbg_array {
 static struct user_dbg_array
 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},
+   

[PATCH v2 net-next 09/10] qed: Mask parities after occurance

2017-05-28 Thread Yuval Mintz
Parities might exhibit a flood behavior since we re-enable the
attention line without preventing the parity from re-triggering the
assertion.
Mask the source in AEU until the parity would be handled.

Signed-off-by: Yuval Mintz 
---
 drivers/net/ethernet/qlogic/qed/qed_int.c | 36 ---
 1 file changed, 23 insertions(+), 13 deletions(-)

diff --git a/drivers/net/ethernet/qlogic/qed/qed_int.c 
b/drivers/net/ethernet/qlogic/qed/qed_int.c
index e19a002..6ac6d80 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_int.c
+++ b/drivers/net/ethernet/qlogic/qed/qed_int.c
@@ -793,16 +793,18 @@ static void qed_int_attn_print(struct qed_hwfn *p_hwfn,
  *
  * @param p_hwfn
  * @param p_aeu - descriptor of an AEU bit which caused the parity
+ * @param aeu_en_reg - address of the AEU enable register
  * @param bit_index
  */
 static void qed_int_deassertion_parity(struct qed_hwfn *p_hwfn,
   struct aeu_invert_reg_bit *p_aeu,
-  u8 bit_index)
+  u32 aeu_en_reg, u8 bit_index)
 {
-   u32 block_id = p_aeu->block_index;
+   u32 block_id = p_aeu->block_index, mask, val;
 
-   DP_INFO(p_hwfn->cdev, "%s[%d] parity attention is set\n",
-   p_aeu->bit_name, bit_index);
+   DP_NOTICE(p_hwfn->cdev,
+ "%s parity attention is set [address 0x%08x, bit %d]\n",
+ p_aeu->bit_name, aeu_en_reg, bit_index);
 
if (block_id != MAX_BLOCK_ID) {
qed_int_attn_print(p_hwfn, block_id, ATTN_TYPE_PARITY, false);
@@ -815,6 +817,13 @@ static void qed_int_deassertion_parity(struct qed_hwfn 
*p_hwfn,
   ATTN_TYPE_PARITY, false);
}
}
+
+   /* Prevent this parity error from being re-asserted */
+   mask = ~BIT(bit_index);
+   val = qed_rd(p_hwfn, p_hwfn->p_dpc_ptt, aeu_en_reg);
+   qed_wr(p_hwfn, p_hwfn->p_dpc_ptt, aeu_en_reg, val & mask);
+   DP_INFO(p_hwfn, "`%s' - Disabled future parity errors\n",
+   p_aeu->bit_name);
 }
 
 /**
@@ -829,7 +838,7 @@ static int qed_int_deassertion(struct qed_hwfn  *p_hwfn,
   u16 deasserted_bits)
 {
struct qed_sb_attn_info *sb_attn_sw = p_hwfn->p_sb_attn;
-   u32 aeu_inv_arr[NUM_ATTN_REGS], aeu_mask;
+   u32 aeu_inv_arr[NUM_ATTN_REGS], aeu_mask, aeu_en, en;
u8 i, j, k, bit_idx;
int rc = 0;
 
@@ -846,11 +855,11 @@ static int qed_int_deassertion(struct qed_hwfn  *p_hwfn,
/* Find parity attentions first */
for (i = 0; i < NUM_ATTN_REGS; i++) {
struct aeu_invert_reg *p_aeu = &sb_attn_sw->p_aeu_desc[i];
-   u32 en = qed_rd(p_hwfn, p_hwfn->p_dpc_ptt,
-   MISC_REG_AEU_ENABLE1_IGU_OUT_0 +
-   i * sizeof(u32));
u32 parities;
 
+   aeu_en = MISC_REG_AEU_ENABLE1_IGU_OUT_0 + i * sizeof(u32);
+   en = qed_rd(p_hwfn, p_hwfn->p_dpc_ptt, aeu_en);
+
/* Skip register in which no parity bit is currently set */
parities = sb_attn_sw->parity_mask[i] & aeu_inv_arr[i] & en;
if (!parities)
@@ -862,7 +871,7 @@ static int qed_int_deassertion(struct qed_hwfn  *p_hwfn,
if (qed_int_is_parity_flag(p_hwfn, p_bit) &&
!!(parities & BIT(bit_idx)))
qed_int_deassertion_parity(p_hwfn, p_bit,
-  bit_idx);
+  aeu_en, bit_idx);
 
bit_idx += ATTENTION_LENGTH(p_bit->flags);
}
@@ -877,10 +886,11 @@ static int qed_int_deassertion(struct qed_hwfn  *p_hwfn,
continue;
 
for (i = 0; i < NUM_ATTN_REGS; i++) {
-   u32 aeu_en = MISC_REG_AEU_ENABLE1_IGU_OUT_0 +
-i * sizeof(u32) +
-k * sizeof(u32) * NUM_ATTN_REGS;
-   u32 en, bits;
+   u32 bits;
+
+   aeu_en = MISC_REG_AEU_ENABLE1_IGU_OUT_0 +
+i * sizeof(u32) +
+k * sizeof(u32) * NUM_ATTN_REGS;
 
en = qed_rd(p_hwfn, p_hwfn->p_dpc_ptt, aeu_en);
bits = aeu_inv_arr[i] & en;
-- 
1.9.3



[PATCH v2 net-next 08/10] qed: Print multi-bit attentions properly

2017-05-28 Thread Yuval Mintz
In strucuture reflecting the AEU hw block some entries
represent multiple HW bits, and the associated name is in fact
a pattern.
Today, whenever such an attention would be asserted the resulted
prints would show the pattern string instead of indicating which
of the possible bits was set.

Signed-off-by: Yuval Mintz 
---
 drivers/net/ethernet/qlogic/qed/qed_int.c | 38 +++
 1 file changed, 33 insertions(+), 5 deletions(-)

diff --git a/drivers/net/ethernet/qlogic/qed/qed_int.c 
b/drivers/net/ethernet/qlogic/qed/qed_int.c
index de6f60c..e19a002 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_int.c
+++ b/drivers/net/ethernet/qlogic/qed/qed_int.c
@@ -749,19 +749,19 @@ static void qed_int_attn_print(struct qed_hwfn *p_hwfn,
 qed_int_deassertion_aeu_bit(struct qed_hwfn *p_hwfn,
struct aeu_invert_reg_bit *p_aeu,
u32 aeu_en_reg,
-   u32 bitmask)
+   const char *p_bit_name, u32 bitmask)
 {
bool b_fatal = false;
int rc = -EINVAL;
u32 val;
 
DP_INFO(p_hwfn, "Deasserted attention `%s'[%08x]\n",
-   p_aeu->bit_name, bitmask);
+   p_bit_name, bitmask);
 
/* Call callback before clearing the interrupt status */
if (p_aeu->cb) {
DP_INFO(p_hwfn, "`%s (attention)': Calling Callback function\n",
-   p_aeu->bit_name);
+   p_bit_name);
rc = p_aeu->cb(p_hwfn);
}
 
@@ -782,7 +782,7 @@ static void qed_int_attn_print(struct qed_hwfn *p_hwfn,
val = qed_rd(p_hwfn, p_hwfn->p_dpc_ptt, aeu_en_reg);
qed_wr(p_hwfn, p_hwfn->p_dpc_ptt, aeu_en_reg, (val & ~bitmask));
DP_INFO(p_hwfn, "`%s' - Disabled future attentions\n",
-   p_aeu->bit_name);
+   p_bit_name);
 
 out:
return rc;
@@ -894,8 +894,8 @@ static int qed_int_deassertion(struct qed_hwfn  *p_hwfn,
 * previous assertion.
 */
for (j = 0, bit_idx = 0; bit_idx < 32; j++) {
+   long unsigned int bitmask;
u8 bit, bit_len;
-   u32 bitmask;
 
p_aeu = &sb_attn_sw->p_aeu_desc[i].bits[j];
p_aeu = qed_int_aeu_translate(p_hwfn, p_aeu);
@@ -909,11 +909,39 @@ static int qed_int_deassertion(struct qed_hwfn  *p_hwfn,
}
 
bitmask = bits & (((1 << bit_len) - 1) << bit);
+   bitmask >>= bit;
+
if (bitmask) {
+   u32 flags = p_aeu->flags;
+   char bit_name[30];
+   u8 num;
+
+   num = (u8)find_first_bit(&bitmask,
+bit_len);
+
+   /* Some bits represent more than a
+* a single interrupt. Correctly print
+* their name.
+*/
+   if (ATTENTION_LENGTH(flags) > 2 ||
+   ((flags & ATTENTION_PAR_INT) &&
+ATTENTION_LENGTH(flags) > 1))
+   snprintf(bit_name, 30,
+p_aeu->bit_name, num);
+   else
+   strncpy(bit_name,
+   p_aeu->bit_name, 30);
+
+   /* We now need to pass bitmask in its
+* correct position.
+*/
+   bitmask <<= bit;
+
/* Handle source of the attention */
qed_int_deassertion_aeu_bit(p_hwfn,
p_aeu,
aeu_en,
+   bit_name,
bitmask);
}
 
-- 
1.9.3



[PATCH v2 net-next 10/10] qed: Cache alignemnt padding to match host

2017-05-28 Thread Yuval Mintz
Improve PCI performance by adjusting padding sizes to match those of the
host machine's cacheline.

Signed-off-by: Yuval Mintz 
---
 drivers/net/ethernet/qlogic/qed/qed_dev.c  | 15 +--
 drivers/net/ethernet/qlogic/qed/qed_reg_addr.h |  1 +
 2 files changed, 14 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/qlogic/qed/qed_dev.c 
b/drivers/net/ethernet/qlogic/qed/qed_dev.c
index 072d950..d73e3c2 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_dev.c
+++ b/drivers/net/ethernet/qlogic/qed/qed_dev.c
@@ -1227,6 +1227,10 @@ static void qed_init_cache_line_size(struct qed_hwfn 
*p_hwfn,
L1_CACHE_BYTES, wr_mbs);
 
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,
@@ -1433,8 +1437,15 @@ enum QED_ROCE_EDPM_MODE {
 static int qed_hw_init_port(struct qed_hwfn *p_hwfn,
struct qed_ptt *p_ptt, int hw_mode)
 {
-   return qed_init_run(p_hwfn, p_ptt, PHASE_PORT,
-   p_hwfn->port_id, hw_mode);
+   int rc = 0;
+
+   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,
diff --git a/drivers/net/ethernet/qlogic/qed/qed_reg_addr.h 
b/drivers/net/ethernet/qlogic/qed/qed_reg_addr.h
index 6abf918..67172d7 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_reg_addr.h
+++ b/drivers/net/ethernet/qlogic/qed/qed_reg_addr.h
@@ -1559,6 +1559,7 @@
 #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_F4_F0_K2 0x2aafa4UL
+#define PGLUE_B_REG_MASTER_WRITE_PAD_ENABLE 0x2aae30UL
 #define NIG_REG_TSGEN_FREECNT_UPDATE_K2 0x509008UL
 #define CNIG_REG_NIG_PORT0_CONF_K2 0x218200UL
 
-- 
1.9.3



[PATCH v2 net-next 05/10] qed: Support dynamic s-tag change

2017-05-28 Thread Yuval Mintz
In case management firmware indicates a change in the used S-tag,
propagate the configuration to HW and FW.

Signed-off-by: Yuval Mintz 
---
 drivers/net/ethernet/qlogic/qed/qed_hsi.h |  4 +++-
 drivers/net/ethernet/qlogic/qed/qed_mcp.c | 26 +++
 drivers/net/ethernet/qlogic/qed/qed_reg_addr.h|  2 ++
 drivers/net/ethernet/qlogic/qed/qed_sp.h  |  9 
 drivers/net/ethernet/qlogic/qed/qed_sp_commands.c | 24 +
 5 files changed, 64 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/qlogic/qed/qed_hsi.h 
b/drivers/net/ethernet/qlogic/qed/qed_hsi.h
index f610e52..24b1458 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_hsi.h
+++ b/drivers/net/ethernet/qlogic/qed/qed_hsi.h
@@ -11474,6 +11474,7 @@ struct public_drv_mb {
 
 #define DRV_MSG_CODE_BW_UPDATE_ACK 0x3200
 #define DRV_MSG_CODE_NIG_DRAIN 0x3000
+#define DRV_MSG_CODE_S_TAG_UPDATE_ACK  0x3b00
 #define DRV_MSG_CODE_INITIATE_PF_FLR0x0201
 #define DRV_MSG_CODE_VF_DISABLED_DONE  0xc000
 #define DRV_MSG_CODE_CFG_VF_MSIX   0xc001
@@ -11634,6 +11635,7 @@ struct public_drv_mb {
 #define FW_MSG_CODE_RESOURCE_ALLOC_OK   0x3400
 #define FW_MSG_CODE_RESOURCE_ALLOC_UNKNOWN  0x3500
 #define FW_MSG_CODE_RESOURCE_ALLOC_DEPRECATED   0x3600
+#define FW_MSG_CODE_S_TAG_UPDATE_ACK_DONE  0x3b00
 #define FW_MSG_CODE_DRV_CFG_VF_MSIX_DONE   0xb001
 
 #define FW_MSG_CODE_NVM_OK 0x0001
@@ -11681,7 +11683,7 @@ enum MFW_DRV_MSG_TYPE {
MFW_DRV_MSG_DCBX_OPERATIONAL_MIB_UPDATED,
MFW_DRV_MSG_RESERVED4,
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_FCOE_STATS,
MFW_DRV_MSG_GET_ISCSI_STATS,
diff --git a/drivers/net/ethernet/qlogic/qed/qed_mcp.c 
b/drivers/net/ethernet/qlogic/qed/qed_mcp.c
index 24c9b71..31c88e1 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_mcp.c
+++ b/drivers/net/ethernet/qlogic/qed/qed_mcp.c
@@ -1398,6 +1398,28 @@ static void qed_mcp_update_bw(struct qed_hwfn *p_hwfn, 
struct qed_ptt *p_ptt)
¶m);
 }
 
+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, ¶m);
+}
+
 int qed_mcp_handle_events(struct qed_hwfn *p_hwfn,
  struct qed_ptt *p_ptt)
 {
@@ -1453,6 +1475,10 @@ int qed_mcp_handle_events(struct qed_hwfn *p_hwfn,
case MFW_DRV_MSG_BW_UPDATE:
qed_mcp_update_bw(p_hwfn, p_ptt);
break;
+   case MFW_DRV_MSG_S_TAG_UPDATE:
+   qed_mcp_update_stag(p_hwfn, p_ptt);
+   break;
+   break;
default:
DP_INFO(p_hwfn, "Unimplemented MFW message %d\n", i);
rc = -EINVAL;
diff --git a/drivers/net/ethernet/qlogic/qed/qed_reg_addr.h 
b/drivers/net/ethernet/qlogic/qed/qed_reg_addr.h
index f14772b..6abf918 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_reg_addr.h
+++ b/drivers/net/ethernet/qlogic/qed/qed_reg_addr.h
@@ -242,6 +242,8 @@
0x50196cUL
 #define NIG_REG_LLH_CLS_TYPE_DUALMODE \
0x501964UL
+#define NIG_REG_LLH_FUNC_TAG_EN 0x5019b0UL
+#define NIG_REG_LLH_FUNC_TAG_VALUE 0x5019d0UL
 #define NIG_REG_LLH_FUNC_FILTER_VALUE \
0x501a00UL
 #define NIG_REG_LLH_FUNC_FILTER_VALUE_SIZE \
diff --git a/drivers/net/ethernet/qlogic/qed/qed_sp.h 
b/drivers/net/ethernet/qlogic/qed/qed_sp.h
index ef77de4..b9464f3 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_sp.h
+++ b/drivers/net/ethernet/qlogic/qed/qed_sp.h
@@ -418,6 +418,15 @@ int qed_sp_pf_start(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
  *
  * This ramrod is sent to close a Physical Function (PF). It is the last ramrod
diff --git a/drivers/net/etherne

[PATCH v2 net-next 07/10] qed: Diffrentiate adapter-specific attentions

2017-05-28 Thread Yuval Mintz
There are 4 attention bits in AEU that have different meaning
for QL45xxx and QL41xxx adapters.

Instead of doing a massive infrastructure change in favor of these
bits, we implement a point fix where only those four would change
meaning dependent on the adapter involved.

Signed-off-by: Yuval Mintz 
---
 drivers/net/ethernet/qlogic/qed/qed_int.c | 80 ++-
 1 file changed, 69 insertions(+), 11 deletions(-)

diff --git a/drivers/net/ethernet/qlogic/qed/qed_int.c 
b/drivers/net/ethernet/qlogic/qed/qed_int.c
index 7f4f8e7..de6f60c 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_int.c
+++ b/drivers/net/ethernet/qlogic/qed/qed_int.c
@@ -90,6 +90,12 @@ struct aeu_invert_reg_bit {
 /* Multiple bits start with this offset */
 #define ATTENTION_OFFSET_MASK   (0x000ff000)
 #define ATTENTION_OFFSET_SHIFT  (12)
+
+#define ATTENTION_BB_MASK   (0x0070)
+#define ATTENTION_BB_SHIFT  (20)
+#define ATTENTION_BB(value) (value << ATTENTION_BB_SHIFT)
+#define ATTENTION_BB_DIFFERENT  BIT(23)
+
unsigned int flags;
 
/* Callback to call if attention will be triggered */
@@ -381,6 +387,25 @@ static int qed_dorq_attn_cb(struct qed_hwfn *p_hwfn)
return -EINVAL;
 }
 
+/* Instead of major changes to the data-structure, we have a some 'special'
+ * identifiers for sources that changed meaning between adapters.
+ */
+enum aeu_invert_reg_special_type {
+   AEU_INVERT_REG_SPECIAL_CNIG_0,
+   AEU_INVERT_REG_SPECIAL_CNIG_1,
+   AEU_INVERT_REG_SPECIAL_CNIG_2,
+   AEU_INVERT_REG_SPECIAL_CNIG_3,
+   AEU_INVERT_REG_SPECIAL_MAX,
+};
+
+static struct aeu_invert_reg_bit
+aeu_descs_special[AEU_INVERT_REG_SPECIAL_MAX] = {
+   {"CNIG port 0", ATTENTION_SINGLE, NULL, BLOCK_CNIG},
+   {"CNIG port 1", ATTENTION_SINGLE, NULL, BLOCK_CNIG},
+   {"CNIG port 2", ATTENTION_SINGLE, NULL, BLOCK_CNIG},
+   {"CNIG port 3", ATTENTION_SINGLE, NULL, BLOCK_CNIG},
+};
+
 /* Notice aeu_invert_reg must be defined in the same order of bits as HW;  */
 static struct aeu_invert_reg aeu_descs[NUM_ATTN_REGS] = {
{
@@ -427,8 +452,22 @@ static int qed_dorq_attn_cb(struct qed_hwfn *p_hwfn)
 (33 << ATTENTION_OFFSET_SHIFT), NULL, MAX_BLOCK_ID},
{"General Attention 35", ATTENTION_SINGLE,
 NULL, MAX_BLOCK_ID},
-   {"CNIG port %d", (4 << ATTENTION_LENGTH_SHIFT),
-NULL, BLOCK_CNIG},
+   {"NWS Parity",
+ATTENTION_PAR | ATTENTION_BB_DIFFERENT |
+ATTENTION_BB(AEU_INVERT_REG_SPECIAL_CNIG_0),
+NULL, BLOCK_NWS},
+   {"NWS Interrupt",
+ATTENTION_SINGLE | ATTENTION_BB_DIFFERENT |
+ATTENTION_BB(AEU_INVERT_REG_SPECIAL_CNIG_1),
+NULL, BLOCK_NWS},
+   {"NWM Parity",
+ATTENTION_PAR | ATTENTION_BB_DIFFERENT |
+ATTENTION_BB(AEU_INVERT_REG_SPECIAL_CNIG_2),
+NULL, BLOCK_NWM},
+   {"NWM Interrupt",
+ATTENTION_SINGLE | ATTENTION_BB_DIFFERENT |
+ATTENTION_BB(AEU_INVERT_REG_SPECIAL_CNIG_3),
+NULL, BLOCK_NWM},
{"MCP CPU", ATTENTION_SINGLE,
 qed_mcp_attn_cb, MAX_BLOCK_ID},
{"MCP Watchdog timer", ATTENTION_SINGLE,
@@ -566,6 +605,27 @@ static int qed_dorq_attn_cb(struct qed_hwfn *p_hwfn)
},
 };
 
+static struct aeu_invert_reg_bit *
+qed_int_aeu_translate(struct qed_hwfn *p_hwfn,
+ struct aeu_invert_reg_bit *p_bit)
+{
+   if (!QED_IS_BB(p_hwfn->cdev))
+   return p_bit;
+
+   if (!(p_bit->flags & ATTENTION_BB_DIFFERENT))
+   return p_bit;
+
+   return &aeu_descs_special[(p_bit->flags & ATTENTION_BB_MASK) >>
+ ATTENTION_BB_SHIFT];
+}
+
+static bool qed_int_is_parity_flag(struct qed_hwfn *p_hwfn,
+  struct aeu_invert_reg_bit *p_bit)
+{
+   return !!(qed_int_aeu_translate(p_hwfn, p_bit)->flags &
+  ATTENTION_PARITY);
+}
+
 #define ATTN_STATE_BITS (0xfff)
 #define ATTN_BITS_MASKABLE  (0x3ff)
 struct qed_sb_attn_info {
@@ -799,7 +859,7 @@ static int qed_int_deassertion(struct qed_hwfn  *p_hwfn,
for (j = 0, bit_idx = 0; bit_idx < 32; j++) {
struct aeu_invert_reg_bit *p_bit = &p_aeu->bits[j];
 
-   if ((p_bit->flags & ATTENTION_PARITY) &&
+   if (qed_int_is_parity_flag(p_hwfn, p_bit) &&
!!(parities & BIT(bit_idx)))
qed_int_deassertion_parity(p_hwfn, p_bit,
   bit_id

[PATCH v2 net-next 03/10] qed: Don't inherit RoCE DCBx for V2

2017-05-28 Thread Yuval Mintz
From: Sudarsana Reddy Kalluru 

Older firmware used by device didn't distinguish between RoCE and RoCE
V2 from DCBx configuration perspective, and as a result we've used to
take a the RoCE-related configuration and apply to it for both.

Since we now support configuring each its own values, there's no reason
to reflect [& configure] that both are using the same.

Signed-off-by: Sudarsana Reddy Kalluru 
Signed-off-by: Yuval Mintz 
---
 drivers/net/ethernet/qlogic/qed/qed_dcbx.c | 11 ---
 1 file changed, 11 deletions(-)

diff --git a/drivers/net/ethernet/qlogic/qed/qed_dcbx.c 
b/drivers/net/ethernet/qlogic/qed/qed_dcbx.c
index 64c2e7c..e2a62c0 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_dcbx.c
+++ b/drivers/net/ethernet/qlogic/qed/qed_dcbx.c
@@ -310,17 +310,6 @@ static bool qed_dcbx_roce_v2_tlv(u32 app_info_bitmap, u16 
proto_id, bool ieee)
}
}
 
-   /* 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,
-priority, tc, DCBX_PROTOCOL_ROCE_V2);
-   }
-
/* Update ramrod protocol data and hw_info fields
 * with default info when corresponding APP TLV's are not detected.
 * The enabled field has a different logic for ethernet as only for
-- 
1.9.3



[PATCH v2 net-next 04/10] qed: QL41xxx VF MSI-x table

2017-05-28 Thread Yuval Mintz
The QL41xxx adapters' PCI allows a single configuration for the
MSI-x table size of all child VFs of a given PF.
The existing code wouldn't cause the management firmware to set
that value, meaning the VFs would retain the default MSI-x table
size.

Introduce a new scheme so that whenever a VF is enabled, driver
would set the number of MSI-x to be the maximum over the various
VFs' needs.

Signed-off-by: Yuval Mintz 
---
 drivers/net/ethernet/qlogic/qed/qed_hsi.h   |  3 ++-
 drivers/net/ethernet/qlogic/qed/qed_mcp.c   | 35 +++--
 drivers/net/ethernet/qlogic/qed/qed_sriov.c | 32 +-
 3 files changed, 66 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ethernet/qlogic/qed/qed_hsi.h 
b/drivers/net/ethernet/qlogic/qed/qed_hsi.h
index 802c162..f610e52 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_hsi.h
+++ b/drivers/net/ethernet/qlogic/qed/qed_hsi.h
@@ -11477,6 +11477,7 @@ struct public_drv_mb {
 #define DRV_MSG_CODE_INITIATE_PF_FLR0x0201
 #define DRV_MSG_CODE_VF_DISABLED_DONE  0xc000
 #define DRV_MSG_CODE_CFG_VF_MSIX   0xc001
+#define DRV_MSG_CODE_CFG_PF_VFS_MSIX   0xc002
 #define DRV_MSG_CODE_NVM_GET_FILE_ATT  0x0003
 #define DRV_MSG_CODE_NVM_READ_NVRAM0x0005
 #define DRV_MSG_CODE_MCP_RESET 0x0009
@@ -11640,7 +11641,7 @@ struct public_drv_mb {
 
 #define FW_MSG_CODE_OS_WOL_SUPPORTED0x0080
 #define FW_MSG_CODE_OS_WOL_NOT_SUPPORTED0x0081
-
+#define FW_MSG_CODE_DRV_CFG_PF_VFS_MSIX_DONE   0x0087
 #define FW_MSG_SEQ_NUMBER_MASK 0x
 
u32 fw_mb_param;
diff --git a/drivers/net/ethernet/qlogic/qed/qed_mcp.c 
b/drivers/net/ethernet/qlogic/qed/qed_mcp.c
index fc49c75e..24c9b71 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_mcp.c
+++ b/drivers/net/ethernet/qlogic/qed/qed_mcp.c
@@ -1801,8 +1801,9 @@ int qed_mcp_get_flash_size(struct qed_hwfn *p_hwfn,
return 0;
 }
 
-int qed_mcp_config_vf_msix(struct qed_hwfn *p_hwfn,
-  struct qed_ptt *p_ptt, u8 vf_id, u8 num)
+static int
+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;
int rc;
@@ -1832,6 +1833,36 @@ int qed_mcp_config_vf_msix(struct qed_hwfn *p_hwfn,
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
 qed_mcp_send_drv_version(struct qed_hwfn *p_hwfn,
 struct qed_ptt *p_ptt,
diff --git a/drivers/net/ethernet/qlogic/qed/qed_sriov.c 
b/drivers/net/ethernet/qlogic/qed/qed_sriov.c
index 71e392f..b6bda45d 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_sriov.c
+++ b/drivers/net/ethernet/qlogic/qed/qed_sriov.c
@@ -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);
 }
 
+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,
struct qed_ptt *p_ptt,
  

[PATCH v2 net-next 01/10] qed: Add missing static/local dcbx info

2017-05-28 Thread Yuval Mintz
From: Sudarsana Reddy Kalluru 

Some getters are not getting filled with the correct information
regarding local DCBx.

Fixes: 49632b5822ea ("qed: Add support for static dcbx.")
Signed-off-by: Sudarsana Reddy Kalluru 
Signed-off-by: Yuval Mintz 
---
 drivers/net/ethernet/qlogic/qed/qed_dcbx.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/qlogic/qed/qed_dcbx.c 
b/drivers/net/ethernet/qlogic/qed/qed_dcbx.c
index b83fe1d..efe309e 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_dcbx.c
+++ b/drivers/net/ethernet/qlogic/qed/qed_dcbx.c
@@ -1460,7 +1460,7 @@ static u8 qed_dcbnl_getcap(struct qed_dev *cdev, int 
capid, u8 *cap)
break;
case DCB_CAP_ATTR_DCBX:
*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;
default:
*cap = false;
@@ -1534,6 +1534,8 @@ static u8 qed_dcbnl_getdcbx(struct qed_dev *cdev)
mode |= DCB_CAP_DCBX_VER_IEEE;
if (dcbx_info->operational.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);
kfree(dcbx_info);
-- 
1.9.3



[PATCH v2 net-next 02/10] qed: Correct DCBx update scheme

2017-05-28 Thread Yuval Mintz
From: Sudarsana Reddy Kalluru 

Instead of using a boolean value that propagates to FW configuration,
use the proper firmware HSI values.

Signed-off-by: Sudarsana Reddy Kalluru 
Signed-off-by: Yuval Mintz 
---
 drivers/net/ethernet/qlogic/qed/qed_dcbx.c | 17 +
 drivers/net/ethernet/qlogic/qed/qed_dcbx.h |  2 +-
 2 files changed, 10 insertions(+), 9 deletions(-)

diff --git a/drivers/net/ethernet/qlogic/qed/qed_dcbx.c 
b/drivers/net/ethernet/qlogic/qed/qed_dcbx.c
index efe309e..64c2e7c 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_dcbx.c
+++ b/drivers/net/ethernet/qlogic/qed/qed_dcbx.c
@@ -191,17 +191,19 @@ static bool qed_dcbx_roce_v2_tlv(u32 app_info_bitmap, u16 
proto_id, bool ieee)
 qed_dcbx_set_params(struct qed_dcbx_results *p_data,
struct qed_hw_info *p_info,
bool enable,
-   bool update,
u8 prio,
u8 tc,
enum dcbx_protocol_type type,
enum qed_pci_personality personality)
 {
/* PF update ramrod data */
-   p_data->arr[type].update = update;
p_data->arr[type].enable = enable;
p_data->arr[type].priority = prio;
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 */
if (p_info->personality == personality)
@@ -213,7 +215,6 @@ static bool qed_dcbx_roce_v2_tlv(u32 app_info_bitmap, u16 
proto_id, bool ieee)
 qed_dcbx_update_app_info(struct qed_dcbx_results *p_data,
 struct qed_hwfn *p_hwfn,
 bool enable,
-bool update,
 u8 prio, u8 tc, enum dcbx_protocol_type type)
 {
struct qed_hw_info *p_info = &p_hwfn->hw_info;
@@ -231,7 +232,7 @@ static bool qed_dcbx_roce_v2_tlv(u32 app_info_bitmap, u16 
proto_id, bool ieee)
personality = qed_dcbx_app_update[i].personality;
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);
}
 }
@@ -304,7 +305,7 @@ static bool qed_dcbx_roce_v2_tlv(u32 app_info_bitmap, u16 
proto_id, bool ieee)
 */
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);
}
}
@@ -316,7 +317,7 @@ static bool qed_dcbx_roce_v2_tlv(u32 app_info_bitmap, u16 
proto_id, bool ieee)
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,
+   qed_dcbx_update_app_info(p_data, p_hwfn, true,
 priority, tc, DCBX_PROTOCOL_ROCE_V2);
}
 
@@ -332,8 +333,8 @@ static bool qed_dcbx_roce_v2_tlv(u32 app_info_bitmap, u16 
proto_id, bool ieee)
if (p_data->arr[type].update)
continue;
 
-   enable = !(type == DCBX_PROTOCOL_ETH);
-   qed_dcbx_update_app_info(p_data, p_hwfn, enable, true,
+   enable = (type == DCBX_PROTOCOL_ETH) ? false : !!dcbx_version;
+   qed_dcbx_update_app_info(p_data, p_hwfn, enable,
 priority, tc, type);
}
 
diff --git a/drivers/net/ethernet/qlogic/qed/qed_dcbx.h 
b/drivers/net/ethernet/qlogic/qed/qed_dcbx.h
index 414e262..5feb90e 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_dcbx.h
+++ b/drivers/net/ethernet/qlogic/qed/qed_dcbx.h
@@ -52,7 +52,7 @@ enum qed_mib_read_type {
 
 struct qed_dcbx_app_data {
bool enable;/* DCB enabled */
-   bool update;/* Update indication */
+   u8 update;  /* Update indication */
u8 priority;/* Priority */
u8 tc;  /* Traffic Class */
 };
-- 
1.9.3



[PATCH v2 net-next 00/10] qed: DCBx and Attentions series

2017-05-28 Thread Yuval Mintz
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.

Dave,

Please consider applying this series to `net-next'.

Thanks,
Yuval

Changes from previous versions
--
 - V1 - Correct compilation in #2 to prevent bisection from breaking
  - Some style changes in #6

Sudarsana Reddy Kalluru (3):
  qed: Add missing static/local dcbx info
  qed: Correct DCBx update scheme
  qed: Don't inherit RoCE DCBx for V2

Yuval Mintz (7):
  qed: QL41xxx VF MSI-x table
  qed: Support dynamic s-tag change
  qed: Get rid of the attention-arrays
  qed: Diffrentiate adapter-specific attentions
  qed: Print multi-bit attentions properly
  qed: Mask parities after occurance
  qed: Cache alignemnt padding to match host

 drivers/net/ethernet/qlogic/qed/qed_dcbx.c|   30 +-
 drivers/net/ethernet/qlogic/qed/qed_dcbx.h|2 +-
 drivers/net/ethernet/qlogic/qed/qed_debug.c   |  250 
 drivers/net/ethernet/qlogic/qed/qed_dev.c |   15 +-
 drivers/net/ethernet/qlogic/qed/qed_hsi.h |   44 +-
 drivers/net/ethernet/qlogic/qed/qed_int.c | 1466 +++--
 drivers/net/ethernet/qlogic/qed/qed_mcp.c |   61 +-
 drivers/net/ethernet/qlogic/qed/qed_reg_addr.h|3 +
 drivers/net/ethernet/qlogic/qed/qed_sp.h  |9 +
 drivers/net/ethernet/qlogic/qed/qed_sp_commands.c |   24 +
 drivers/net/ethernet/qlogic/qed/qed_sriov.c   |   32 +-
 11 files changed, 593 insertions(+), 1343 deletions(-)

-- 
1.9.3



Re: vxlan: use after free error

2017-05-28 Thread Mark Bloch
Hi Roopa,

On 29/05/2017 05:50, Roopa Prabhu wrote:
> On Sun, May 28, 2017 at 3:49 AM, Mark Bloch  wrote:
>> Hi,
>>
>> I'm getting a KASAN (use after free) error when doing:
>>
>> ip link add vxlan1 type vxlan external
>> ip link set vxlan1 up
>> ip link set vxlan1 down
>> ip link del vxlan1
>>
>> [  600.495331] 
>> ==
>> [  600.509678] BUG: KASAN: use-after-free in vxlan_dellink+0x33d/0x390 
>> [vxlan]
>> [  600.523083] Write of size 8 at addr 88056ce54018 by task ip/16216
>>
>> [  600.542239] CPU: 12 PID: 16216 Comm: ip Not tainted 4.12.0-rc2 #24
>> [  600.554442] Hardware name: HP ProLiant DL380p Gen8, BIOS P70 08/02/2014
>> [  600.567013] Call Trace:
>> [  600.574742]  dump_stack+0x63/0x89
>> [  600.583458]  print_address_description+0x78/0x290
>> [  600.593612]  kasan_report+0x257/0x370
>> [  600.602857]  ? vxlan_dellink+0x33d/0x390 [vxlan]
>> [  600.612765]  __asan_report_store8_noabort+0x1c/0x20
>> [  600.622937]  vxlan_dellink+0x33d/0x390 [vxlan]
>> [  600.632636]  rtnl_delete_link+0xb9/0x110
>> [  600.641542]  ? rtnl_af_register+0xc0/0xc0
>> [  600.650898]  ? nla_parse+0x36/0x260
>> [  600.659558]  rtnl_dellink+0x1fb/0x780
>> [  600.668350]  ? unwind_dump+0x360/0x360
>> [  600.676802]  ? rtnl_bridge_getlink+0x620/0x620
>> [  600.686036]  ? __module_text_address+0x18/0x150
>> [  600.695300]  ? ns_capable_common+0xd4/0x110
>> [  600.704157]  ? sock_sendmsg+0xba/0xf0
>> [  600.712264]  ? ns_capable+0x13/0x20
>> [  600.720201]  ? __netlink_ns_capable+0xcc/0x100
>> [  600.729131]  rtnetlink_rcv_msg+0x255/0x6c0
>> [  600.737464]  ? rtnl_newlink+0x1640/0x1640
>> [  600.745604]  ? __read_once_size_nocheck.constprop.7+0x20/0x20
>> [  600.755882]  ? __read_once_size_nocheck.constprop.7+0x20/0x20
>> [  600.765963]  ? memset+0x31/0x40
>> [  600.772985]  netlink_rcv_skb+0x2de/0x460
>> [  600.780829]  ? rtnl_newlink+0x1640/0x1640
>> [  600.788755]  ? netlink_ack+0xaf0/0xaf0
>> [  600.796181]  ? __kmalloc_node_track_caller+0x205/0x2d0
>> [  600.805370]  ? __alloc_skb+0xdd/0x580
>> [  600.812646]  rtnetlink_rcv+0x28/0x30
>> [  600.819882]  netlink_unicast+0x430/0x620
>> [  600.827433]  ? netlink_attachskb+0x660/0x660
>> [  600.835211]  ? rw_copy_check_uvector+0x90/0x290
>> [  600.843097]  ? __module_text_address+0x18/0x150
>> [  600.850985]  netlink_sendmsg+0x7df/0xb90
>> [  600.858105]  ? netlink_unicast+0x620/0x620
>> [  600.865493]  ? kasan_alloc_pages+0x38/0x40
>> [  600.873060]  ? netlink_unicast+0x620/0x620
>> [  600.880458]  sock_sendmsg+0xba/0xf0
>> [  600.886784]  ___sys_sendmsg+0x6c9/0x8e0
>> [  600.893300]  ? copy_msghdr_from_user+0x520/0x520
>> [  600.901017]  ? memcg_write_event_control+0xd50/0xd50
>> [  600.908938]  ? __alloc_pages_slowpath+0x1ef0/0x1ef0
>> [  600.916082]  ? mem_cgroup_commit_charge+0xc4/0x1420
>> [  600.923049]  ? lru_cache_add_active_or_unevictable+0x7d/0x1a0
>> [  600.931943]  ? __handle_mm_fault+0x1bfe/0x2ba0
>> [  600.939255]  ? __pmd_alloc+0x240/0x240
>> [  600.944767]  __sys_sendmsg+0xce/0x160
>> [  600.950154]  ? __sys_sendmsg+0xce/0x160
>> [  600.956030]  ? SyS_shutdown+0x190/0x190
>> [  600.962546]  ? mntput+0x57/0x70
>> [  600.968576]  ? __fput+0x429/0x730
>> [  600.973526]  ? handle_mm_fault+0x28a/0x650
>> [  600.979844]  ? find_vma+0x1f/0x160
>> [  600.985801]  SyS_sendmsg+0x12/0x20
>> [  600.991857]  entry_SYSCALL_64_fastpath+0x1a/0xa5
>> [  600.999044] RIP: 0033:0x7fe11cd80037
>> [  601.005021] RSP: 002b:7ffe0e7fc738 EFLAGS: 0246 ORIG_RAX: 
>> 002e
>> [  601.014890] RAX: ffda RBX:  RCX: 
>> 7fe11cd80037
>> [  601.024808] RDX:  RSI: 7ffe0e7fc780 RDI: 
>> 0003
>> [  601.035392] RBP: 7ffe0e7fc780 R08: 0001 R09: 
>> fefefeff77686d74
>> [  601.045517] R10: 05eb R11: 0246 R12: 
>> 7ffe0e7fc7c0
>> [  601.055590] R13: 00669400 R14: 7ffe0e804830 R15: 
>> 
>>
>> [  601.069998] The buggy address belongs to the page:
>> [  601.078182] page:ea0015b39500 count:0 mapcount:-127 mapping:  
>> (null) index:0x0
>> [  601.089760] flags: 0x2f8000()
>> [  601.096304] raw: 002f8000   
>> ff80
>> [  601.107417] raw: ea00156b2020 ea001836cb20 0002 
>> 
>> [  601.118699] page dumped because: kasan: bad access detected
>>
>> [  601.131352] Memory state around the buggy address:
>> [  601.139488]  88056ce53f00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
>> 00 00
>> [  601.149179]  88056ce53f80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
>> 00 00
>> [  601.159941] >88056ce54000: ff ff ff ff ff ff ff ff ff ff ff ff ff ff 
>> ff ff
>> [  601.170313] ^
>> [  601.176429]  88056ce54080: ff ff ff ff ff ff ff ff ff ff ff ff ff ff 
>> ff ff
>> [  601.187098]  88056ce54100: ff ff ff ff ff ff ff ff ff ff ff ff ff ff 
>> ff ff
>> [  6

[PATCH] Documentation: networking: add DPAA Ethernet document

2017-05-28 Thread Madalin Bucur
Signed-off-by: Madalin Bucur 
Signed-off-by: Camelia Groza 
---
 Documentation/networking/dpaa.txt | 194 ++
 1 file changed, 194 insertions(+)
 create mode 100644 Documentation/networking/dpaa.txt

diff --git a/Documentation/networking/dpaa.txt 
b/Documentation/networking/dpaa.txt
new file mode 100644
index 000..76e016d
--- /dev/null
+++ b/Documentation/networking/dpaa.txt
@@ -0,0 +1,194 @@
+The QorIQ DPAA Ethernet Driver
+==
+
+Authors:
+Madalin Bucur 
+Camelia Groza 
+
+Contents
+
+
+   - DPAA Ethernet Overview
+   - DPAA Ethernet Supported SoCs
+   - Configuring DPAA Ethernet in your kernel
+   - DPAA Ethernet Frame Processing
+   - DPAA Ethernet Features
+   - Debugging
+
+DPAA Ethernet Overview
+==
+
+DPAA stands for Data Path Acceleration Architecture and it is a
+set of networking acceleration IPs that are available on several
+generations of SoCs, both on PowerPC and ARM64.
+
+The Freescale DPAA architecture consists of a series of hardware blocks
+that support Ethernet connectivity. The Ethernet driver depends upon the
+following drivers in the Linux kernel:
+
+ - Peripheral Access Memory Unit (PAMU) (* needed only for PPC platforms)
+drivers/iommu/fsl_*
+ - Frame Manager (FMan)
+drivers/net/ethernet/freescale/fman
+ - Queue Manager (QMan), Buffer Manager (BMan)
+drivers/soc/fsl/qbman
+
+A simplified view of the dpaa_eth interfaces mapped to FMan MACs:
+
+  dpaa_eth   /eth0\ ...   /ethN\
+  driver|  | |  |
+  -      ---      -
+   -Ports  / Tx  Rx \.../ Tx  Rx \
+  FMan|  | |  |
+   -MACs  |   MAC0   | |   MACN   |
+ /   dtsec0   \  ...  /   dtsecN   \ (or tgec)
+/  \ /  \(or memac)
+  -  --  ---  --  -
+  FMan, FMan Port, FMan SP, FMan MURAM drivers
+  -
+  FMan HW blocks: MURAM, MACs, Ports, SP
+  -
+
+The dpaa_eth relation to the QMan, BMan and FMan:
+  
+  dpaa_eth   /eth0\
+  driver/  \
+  -   -^-   -^-   -^-   ----
+  QMan driver / \   / \   / \  \   /  | BMan|
+ |Rx | |Rx | |Tx | |Tx |  | driver  |
+  -  |Dfl| |Err| |Cnf| |FQs|  | |
+  QMan HW|FQ | |FQ | |FQs| |   |  | |
+ /   \ /   \ /   \  \ /   | |
+  -   ---   ---   ---   -v--
+|FMan QMI | |
+| FMan HW   FMan BMI  | BMan HW |
+  ---   
+
+where the acronyms used above (and in the code) are:
+DPAA = Data Path Acceleration Architecture
+FMan = DPAA Frame Manager
+QMan = DPAA Queue Manager
+BMan = DPAA Buffers Manager
+QMI = QMan interface in FMan
+BMI = BMan interface in FMan
+FMan SP = FMan Storage Profiles
+MURAM = Multi-user RAM in FMan
+FQ = QMan Frame Queue
+Rx Dfl FQ = default reception FQ
+Rx Err FQ = Rx error frames FQ
+Tx Cnf FQ = Tx confirmation FQs
+Tx FQs = transmission frame queues
+dtsec = datapath three speed Ethernet controller (10/100/1000 Mbps)
+tgec = ten gigabit Ethernet controller (10 Gbps)
+memac = multirate Ethernet MAC (10/100/1000/1)
+
+DPAA Ethernet Supported SoCs
+
+
+The DPAA drivers enable the Ethernet controllers present on the following SoCs:
+
+# PPC
+P1023
+P2041
+P3041
+P4080
+P5020
+P5040
+T1023
+T1024
+T1040
+T1042
+T2080
+T4240
+B4860
+
+# ARM
+LS1043A
+LS1046A
+
+Configuring DPAA Ethernet in your kernel
+
+
+To enable the DPAA Ethernet driver, the following Kconfig options are required:
+
+# common for arch/arm64 and arch/powerpc platforms
+CONFIG_FSL_DPAA=y
+CONFIG_FSL_FMAN=y
+CONFIG_FSL_DPAA_ETH=y
+CONFIG_FSL_XGMAC_MDIO=y
+
+# for arch/powerpc only
+CONFIG_FSL_PAMU=y
+
+# common options needed for the PHYs used on the RDBs
+CONFIG_VITESSE_PHY=y
+CONFIG_REALTEK_PHY=y
+CONFIG_AQUANTIA_PHY=y
+
+DPAA Ethernet Frame Processing
+==
+
+On Rx, buffers for the incoming frames are retrieved from one of the three
+existing buffers pools. The driver initializes and seeds these, each with
+buffers of different sizes: 1KB, 2KB and 4KB.
+
+On Tx, all transmitted frames are returned to the driver through Tx
+confirmation frame queues. The driver is then responsible for freeing the
+buffers. In order to do this properly, a backpointer is added to the buffer
+before transmission that points to the skb. When the buffer returns to the
+driver on a confirmation FQ, the skb can be correctly consumed.
+
+DPAA Ethernet Features
+==
+
+C

Re: [for-next 5/6] net/mlx5: Bump driver version

2017-05-28 Thread Leon Romanovsky
On Fri, May 26, 2017 at 02:53:18PM -0700, Jakub Kicinski wrote:
> On Fri, 26 May 2017 12:55:22 -0400, Dennis Dalessandro wrote:
> > >> I realize Dave has already pulled this and I'm not asking for it to be
> > >> reverted but maybe some discussion will help guide future patch 
> > >> submissions
> > >> which do this stuff.
> > >>
> > >
> > > Sure, although i don't think we are going to use those version fields
> > > in the future,
> > > please allow me to ask, how do you do your driver versioning ? how do
> > > you track things ?
> > > and what is your future vision regarding ethool->drv_version ?
> >
> > That's just the thing, we don't do anything with it either really. I'm
> > trying to justify its existence to myself and if you folks had some whiz
> > bang idea for a driver version I was interested in hearing what it was.
>
> FWIW I put VERMAGIC_STRING in drv_version:
>
> # ethtool -i p4p1
> driver: nfp
> version: 4.12.0-rc2-perf-00282-gc42dfc79
> ...
>
> I think I got that idea from Felix Fietkau.  The backport-ified version
> of the driver [1] uses git hash and "o-o-t" sting:
>
> # ethtool -i p4p1
> driver: nfp
> version: 49e5c6abf5b2 (o-o-t)
> ...
>
> So it's pretty easy to tell which driver the customer is using.  I
> could probably throw in the output of $(git rev-list --count HEAD) to
> have an automatic monotonically increasing "version" when built
> out-of-tree, hm...

Thanks for the pointer. I'll try to evaluate it.

>
> [1] https://github.com/Netronome/nfp-drv-kmods


signature.asc
Description: PGP signature


Re: running an eBPF program

2017-05-28 Thread Y Song
On Sun, May 28, 2017 at 12:38 AM, Adel Fuchs  wrote:
> Hi,
> Is there any way to run this eBPF program without that patch?
> Alternatively, is there any other eBPF sample that does run properly? I need
> to run a program that filters packets according to IP address or port.

The following is temporary workaround you can use:
int poff, nh_off = BPF_LL_OFF + ETH_HLEN;
-   __be16 proto = skb->protocol;
+   __be16 proto = (__be16)*(volatile __u32 *)&skb->protocol;
__u8 ip_proto;


Re: vxlan: use after free error

2017-05-28 Thread Roopa Prabhu
On Sun, May 28, 2017 at 3:49 AM, Mark Bloch  wrote:
> Hi,
>
> I'm getting a KASAN (use after free) error when doing:
>
> ip link add vxlan1 type vxlan external
> ip link set vxlan1 up
> ip link set vxlan1 down
> ip link del vxlan1
>
> [  600.495331] 
> ==
> [  600.509678] BUG: KASAN: use-after-free in vxlan_dellink+0x33d/0x390 [vxlan]
> [  600.523083] Write of size 8 at addr 88056ce54018 by task ip/16216
>
> [  600.542239] CPU: 12 PID: 16216 Comm: ip Not tainted 4.12.0-rc2 #24
> [  600.554442] Hardware name: HP ProLiant DL380p Gen8, BIOS P70 08/02/2014
> [  600.567013] Call Trace:
> [  600.574742]  dump_stack+0x63/0x89
> [  600.583458]  print_address_description+0x78/0x290
> [  600.593612]  kasan_report+0x257/0x370
> [  600.602857]  ? vxlan_dellink+0x33d/0x390 [vxlan]
> [  600.612765]  __asan_report_store8_noabort+0x1c/0x20
> [  600.622937]  vxlan_dellink+0x33d/0x390 [vxlan]
> [  600.632636]  rtnl_delete_link+0xb9/0x110
> [  600.641542]  ? rtnl_af_register+0xc0/0xc0
> [  600.650898]  ? nla_parse+0x36/0x260
> [  600.659558]  rtnl_dellink+0x1fb/0x780
> [  600.668350]  ? unwind_dump+0x360/0x360
> [  600.676802]  ? rtnl_bridge_getlink+0x620/0x620
> [  600.686036]  ? __module_text_address+0x18/0x150
> [  600.695300]  ? ns_capable_common+0xd4/0x110
> [  600.704157]  ? sock_sendmsg+0xba/0xf0
> [  600.712264]  ? ns_capable+0x13/0x20
> [  600.720201]  ? __netlink_ns_capable+0xcc/0x100
> [  600.729131]  rtnetlink_rcv_msg+0x255/0x6c0
> [  600.737464]  ? rtnl_newlink+0x1640/0x1640
> [  600.745604]  ? __read_once_size_nocheck.constprop.7+0x20/0x20
> [  600.755882]  ? __read_once_size_nocheck.constprop.7+0x20/0x20
> [  600.765963]  ? memset+0x31/0x40
> [  600.772985]  netlink_rcv_skb+0x2de/0x460
> [  600.780829]  ? rtnl_newlink+0x1640/0x1640
> [  600.788755]  ? netlink_ack+0xaf0/0xaf0
> [  600.796181]  ? __kmalloc_node_track_caller+0x205/0x2d0
> [  600.805370]  ? __alloc_skb+0xdd/0x580
> [  600.812646]  rtnetlink_rcv+0x28/0x30
> [  600.819882]  netlink_unicast+0x430/0x620
> [  600.827433]  ? netlink_attachskb+0x660/0x660
> [  600.835211]  ? rw_copy_check_uvector+0x90/0x290
> [  600.843097]  ? __module_text_address+0x18/0x150
> [  600.850985]  netlink_sendmsg+0x7df/0xb90
> [  600.858105]  ? netlink_unicast+0x620/0x620
> [  600.865493]  ? kasan_alloc_pages+0x38/0x40
> [  600.873060]  ? netlink_unicast+0x620/0x620
> [  600.880458]  sock_sendmsg+0xba/0xf0
> [  600.886784]  ___sys_sendmsg+0x6c9/0x8e0
> [  600.893300]  ? copy_msghdr_from_user+0x520/0x520
> [  600.901017]  ? memcg_write_event_control+0xd50/0xd50
> [  600.908938]  ? __alloc_pages_slowpath+0x1ef0/0x1ef0
> [  600.916082]  ? mem_cgroup_commit_charge+0xc4/0x1420
> [  600.923049]  ? lru_cache_add_active_or_unevictable+0x7d/0x1a0
> [  600.931943]  ? __handle_mm_fault+0x1bfe/0x2ba0
> [  600.939255]  ? __pmd_alloc+0x240/0x240
> [  600.944767]  __sys_sendmsg+0xce/0x160
> [  600.950154]  ? __sys_sendmsg+0xce/0x160
> [  600.956030]  ? SyS_shutdown+0x190/0x190
> [  600.962546]  ? mntput+0x57/0x70
> [  600.968576]  ? __fput+0x429/0x730
> [  600.973526]  ? handle_mm_fault+0x28a/0x650
> [  600.979844]  ? find_vma+0x1f/0x160
> [  600.985801]  SyS_sendmsg+0x12/0x20
> [  600.991857]  entry_SYSCALL_64_fastpath+0x1a/0xa5
> [  600.999044] RIP: 0033:0x7fe11cd80037
> [  601.005021] RSP: 002b:7ffe0e7fc738 EFLAGS: 0246 ORIG_RAX: 
> 002e
> [  601.014890] RAX: ffda RBX:  RCX: 
> 7fe11cd80037
> [  601.024808] RDX:  RSI: 7ffe0e7fc780 RDI: 
> 0003
> [  601.035392] RBP: 7ffe0e7fc780 R08: 0001 R09: 
> fefefeff77686d74
> [  601.045517] R10: 05eb R11: 0246 R12: 
> 7ffe0e7fc7c0
> [  601.055590] R13: 00669400 R14: 7ffe0e804830 R15: 
> 
>
> [  601.069998] The buggy address belongs to the page:
> [  601.078182] page:ea0015b39500 count:0 mapcount:-127 mapping:  
> (null) index:0x0
> [  601.089760] flags: 0x2f8000()
> [  601.096304] raw: 002f8000   
> ff80
> [  601.107417] raw: ea00156b2020 ea001836cb20 0002 
> 
> [  601.118699] page dumped because: kasan: bad access detected
>
> [  601.131352] Memory state around the buggy address:
> [  601.139488]  88056ce53f00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
> 00 00
> [  601.149179]  88056ce53f80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
> 00 00
> [  601.159941] >88056ce54000: ff ff ff ff ff ff ff ff ff ff ff ff ff ff 
> ff ff
> [  601.170313] ^
> [  601.176429]  88056ce54080: ff ff ff ff ff ff ff ff ff ff ff ff ff ff 
> ff ff
> [  601.187098]  88056ce54100: ff ff ff ff ff ff ff ff ff ff ff ff ff ff 
> ff ff
> [  601.196978] 
> ==
>
> The flow is something like this:
> When we are upping the interface, we are calli

[PATCH net] cxgb4: avoid crash on PCI error recovery path

2017-05-28 Thread Guilherme G. Piccoli
During PCI error recovery process, specifically on eeh_err_detected()
we might have a NULL netdev struct, hence a direct dereference will
lead to a kernel oops. This was observed with latest upstream kernel
(v4.12-rc2) on Chelsio adapter T422-CR in PowerPC machines.

This patch checks for NULL pointer and avoids the crash, both in
eeh_err_detected() and eeh_resume(). Also, we avoid to trigger
a fatal error or to try disabling interrupts on FW during PCI
error recovery, because: (a) driver might not be able to accurately
access PCI regions in this case, and (b) trigger a fatal error
_during_ the recovery steps is a mistake that could prevent the
recovery path to complete successfully.

Reported-by: Harsha Thyagaraja 
Signed-off-by: Guilherme G. Piccoli 
---
 drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c | 21 +
 drivers/net/ethernet/chelsio/cxgb4/t4_hw.c  |  9 +++--
 2 files changed, 20 insertions(+), 10 deletions(-)

diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c 
b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
index 38a5c6764bb5..b512149684fd 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
@@ -2771,6 +2771,9 @@ void t4_fatal_err(struct adapter *adap)
 {
int port;
 
+   if (pci_channel_offline(adap->pdev))
+   return;
+
/* Disable the SGE since ULDs are going to free resources that
 * could be exposed to the adapter.  RDMA MWs for example...
 */
@@ -3882,9 +3885,10 @@ static pci_ers_result_t eeh_err_detected(struct pci_dev 
*pdev,
spin_lock(&adap->stats_lock);
for_each_port(adap, i) {
struct net_device *dev = adap->port[i];
-
-   netif_device_detach(dev);
-   netif_carrier_off(dev);
+   if (dev) {
+   netif_device_detach(dev);
+   netif_carrier_off(dev);
+   }
}
spin_unlock(&adap->stats_lock);
disable_interrupts(adap);
@@ -3963,12 +3967,13 @@ static void eeh_resume(struct pci_dev *pdev)
rtnl_lock();
for_each_port(adap, i) {
struct net_device *dev = adap->port[i];
-
-   if (netif_running(dev)) {
-   link_start(dev);
-   cxgb_set_rxmode(dev);
+   if (dev) {
+   if (netif_running(dev)) {
+   link_start(dev);
+   cxgb_set_rxmode(dev);
+   }
+   netif_device_attach(dev);
}
-   netif_device_attach(dev);
}
rtnl_unlock();
 }
diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c 
b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c
index aded42b96f6d..3a34aa629f7d 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c
@@ -4557,8 +4557,13 @@ void t4_intr_enable(struct adapter *adapter)
  */
 void t4_intr_disable(struct adapter *adapter)
 {
-   u32 whoami = t4_read_reg(adapter, PL_WHOAMI_A);
-   u32 pf = CHELSIO_CHIP_VERSION(adapter->params.chip) <= CHELSIO_T5 ?
+   u32 whoami, pf;
+
+   if (pci_channel_offline(adapter->pdev))
+   return;
+
+   whoami = t4_read_reg(adapter, PL_WHOAMI_A);
+   pf = CHELSIO_CHIP_VERSION(adapter->params.chip) <= CHELSIO_T5 ?
SOURCEPF_G(whoami) : T6_SOURCEPF_G(whoami);
 
t4_write_reg(adapter, MYPF_REG(PL_PF_INT_ENABLE_A), 0);
-- 
2.12.0.rc0



[PATCH net-next v2 08/13] nfp: support variable NSP response lengths

2017-05-28 Thread Jakub Kicinski
We want to support extendable commands, where newer versions
of the management FW may provide more information.  Zero out
the communication buffer before passing control to NSP.  This
way if management FW is old and only fills in first N bytes,
the remaining ones will be zeros which extended ABI fields
should reserve as not supported/not available.

Signed-off-by: Jakub Kicinski 
---
 drivers/net/ethernet/netronome/nfp/nfpcore/nfp_nsp.c | 8 
 1 file changed, 8 insertions(+)

diff --git a/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_nsp.c 
b/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_nsp.c
index 2fa9247bb23d..58cc3d532769 100644
--- a/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_nsp.c
+++ b/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_nsp.c
@@ -419,6 +419,14 @@ static int nfp_nsp_command_buf(struct nfp_nsp *nsp, u16 
code, u32 option,
if (err < 0)
return err;
}
+   /* Zero out remaining part of the buffer */
+   if (out_buf && out_size && out_size > in_size) {
+   memset(out_buf, 0, out_size - in_size);
+   err = nfp_cpp_write(cpp, cpp_id, cpp_buf + in_size,
+   out_buf, out_size - in_size);
+   if (err < 0)
+   return err;
+   }
 
ret = nfp_nsp_command(nsp, code, option, cpp_id, cpp_buf);
if (ret < 0)
-- 
2.11.0



[PATCH net-next v2 07/13] nfp: shorten CPP core probe logs

2017-05-28 Thread Jakub Kicinski
We currently print reserved BAR mappings info as we create them.
This makes the probe logs longer than necessary.  Print into a
buffer instead and log all the info as a single line.

Signed-off-by: Jakub Kicinski 
---
 .../net/ethernet/netronome/nfp/nfpcore/nfp6000_pcie.c | 19 +++
 1 file changed, 11 insertions(+), 8 deletions(-)

diff --git a/drivers/net/ethernet/netronome/nfp/nfpcore/nfp6000_pcie.c 
b/drivers/net/ethernet/netronome/nfp/nfpcore/nfp6000_pcie.c
index 597ac8febb63..cd678323bacb 100644
--- a/drivers/net/ethernet/netronome/nfp/nfpcore/nfp6000_pcie.c
+++ b/drivers/net/ethernet/netronome/nfp/nfpcore/nfp6000_pcie.c
@@ -588,9 +588,15 @@ static int enable_bars(struct nfp6000_pcie *nfp, u16 
interface)
NFP_PCIE_BAR_PCIE2CPP_MapType(
NFP_PCIE_BAR_PCIE2CPP_MapType_EXPLICIT3),
};
+   char status_msg[196] = {};
struct nfp_bar *bar;
int i, bars_free;
int expl_groups;
+   char *msg, *end;
+
+   msg = status_msg +
+   snprintf(status_msg, sizeof(status_msg) - 1, "RESERVED BARs: ");
+   end = status_msg + sizeof(status_msg) - 1;
 
bar = &nfp->bar[0];
for (i = 0; i < ARRAY_SIZE(nfp->bar); i++, bar++) {
@@ -637,8 +643,7 @@ static int enable_bars(struct nfp6000_pcie *nfp, u16 
interface)
bar->iomem = ioremap_nocache(nfp_bar_resource_start(bar),
 nfp_bar_resource_len(bar));
if (bar->iomem) {
-   dev_info(nfp->dev,
-"BAR0.0 RESERVED: General Mapping/MSI-X SRAM\n");
+   msg += snprintf(msg, end - msg, "0.0: General/MSI-X SRAM, ");
atomic_inc(&bar->refcnt);
bars_free--;
 
@@ -665,7 +670,7 @@ static int enable_bars(struct nfp6000_pcie *nfp, u16 
interface)
 
/* Configure, and lock, BAR0.1 for PCIe XPB (MSI-X PBA) */
bar = &nfp->bar[1];
-   dev_info(nfp->dev, "BAR0.1 RESERVED: PCIe XPB/MSI-X PBA\n");
+   msg += snprintf(msg, end - msg, "0.1: PCIe XPB/MSI-X PBA, ");
atomic_inc(&bar->refcnt);
bars_free--;
 
@@ -684,9 +689,8 @@ static int enable_bars(struct nfp6000_pcie *nfp, u16 
interface)
bar->iomem = ioremap_nocache(nfp_bar_resource_start(bar),
 nfp_bar_resource_len(bar));
if (bar->iomem) {
-   dev_info(nfp->dev,
-"BAR0.%d RESERVED: Explicit%d Mapping\n",
-4 + i, i);
+   msg += snprintf(msg, end - msg,
+   "0.%d: Explicit%d, ", 4 + i, i);
atomic_inc(&bar->refcnt);
bars_free--;
 
@@ -704,8 +708,7 @@ static int enable_bars(struct nfp6000_pcie *nfp, u16 
interface)
sort(&nfp->bar[0], nfp->bars, sizeof(nfp->bar[0]),
 bar_cmp, NULL);
 
-   dev_info(nfp->dev, "%d NFP PCI2CPP BARs, %d free\n",
-nfp->bars, bars_free);
+   dev_info(nfp->dev, "%sfree: %d/%d\n", status_msg, bars_free, nfp->bars);
 
return 0;
 }
-- 
2.11.0



[PATCH net-next v2 09/13] nfp: add hwmon support

2017-05-28 Thread Jakub Kicinski
From: David Brunecz 

Add support for retrieving temperature and power sensor and limits via NSP.

Signed-off-by: David Brunecz 
Signed-off-by: Jakub Kicinski 
---
 drivers/net/ethernet/netronome/nfp/Makefile|   1 +
 drivers/net/ethernet/netronome/nfp/nfp_hwmon.c | 192 +
 drivers/net/ethernet/netronome/nfp/nfp_main.c  |  21 ++-
 drivers/net/ethernet/netronome/nfp/nfp_main.h  |  10 ++
 drivers/net/ethernet/netronome/nfp/nfpcore/nfp.h   |   2 +
 .../net/ethernet/netronome/nfp/nfpcore/nfp_nsp.c   |   8 +
 .../net/ethernet/netronome/nfp/nfpcore/nfp_nsp.h   |  12 ++
 .../ethernet/netronome/nfp/nfpcore/nfp_nsp_cmds.c  |  47 -
 8 files changed, 286 insertions(+), 7 deletions(-)
 create mode 100644 drivers/net/ethernet/netronome/nfp/nfp_hwmon.c

diff --git a/drivers/net/ethernet/netronome/nfp/Makefile 
b/drivers/net/ethernet/netronome/nfp/Makefile
index 95f6b97b5d71..83039c65e061 100644
--- a/drivers/net/ethernet/netronome/nfp/Makefile
+++ b/drivers/net/ethernet/netronome/nfp/Makefile
@@ -16,6 +16,7 @@ nfp-objs := \
nfpcore/nfp_target.o \
nfp_app.o \
nfp_devlink.o \
+   nfp_hwmon.o \
nfp_main.o \
nfp_net_common.o \
nfp_net_ethtool.o \
diff --git a/drivers/net/ethernet/netronome/nfp/nfp_hwmon.c 
b/drivers/net/ethernet/netronome/nfp/nfp_hwmon.c
new file mode 100644
index ..f0dcf45aeec1
--- /dev/null
+++ b/drivers/net/ethernet/netronome/nfp/nfp_hwmon.c
@@ -0,0 +1,192 @@
+/*
+ * Copyright (C) 2017 Netronome Systems, Inc.
+ *
+ * This software is dual licensed under the GNU General License Version 2,
+ * June 1991 as shown in the file COPYING in the top-level directory of this
+ * source tree or the BSD 2-Clause License provided below.  You have the
+ * option to license this software under the complete terms of either license.
+ *
+ * The BSD 2-Clause License:
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ *  1. Redistributions of source code must retain the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer.
+ *
+ *  2. Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include 
+#include 
+#include 
+
+#include "nfpcore/nfp_cpp.h"
+#include "nfpcore/nfp_nsp.h"
+#include "nfp_main.h"
+
+#define NFP_TEMP_MAX   (95 * 1000)
+#define NFP_TEMP_CRIT  (105 * 1000)
+
+#define NFP_POWER_MAX  (25 * 1000 * 1000)
+
+static int nfp_hwmon_sensor_id(enum hwmon_sensor_types type, int channel)
+{
+   if (type == hwmon_temp)
+   return NFP_SENSOR_CHIP_TEMPERATURE;
+   if (type == hwmon_power)
+   return NFP_SENSOR_ASSEMBLY_POWER + channel;
+   return -EINVAL;
+}
+
+static int
+nfp_hwmon_read(struct device *dev, enum hwmon_sensor_types type, u32 attr,
+  int channel, long *val)
+{
+   static const struct {
+   enum hwmon_sensor_types type;
+   u32 attr;
+   long val;
+   } const_vals[] = {
+   { hwmon_temp,   hwmon_temp_max, NFP_TEMP_MAX },
+   { hwmon_temp,   hwmon_temp_crit,NFP_TEMP_CRIT },
+   { hwmon_power,  hwmon_power_max,NFP_POWER_MAX },
+   };
+   struct nfp_pf *pf = dev_get_drvdata(dev);
+   enum nfp_nsp_sensor_id id;
+   int err, i;
+
+   for (i = 0; i < ARRAY_SIZE(const_vals); i++)
+   if (const_vals[i].type == type && const_vals[i].attr == attr) {
+   *val = const_vals[i].val;
+   return 0;
+   }
+
+   err = nfp_hwmon_sensor_id(type, channel);
+   if (err < 0)
+   return err;
+   id = err;
+
+   if (!(pf->nspi->sensor_mask & BIT(id)))
+   return -EOPNOTSUPP;
+
+   if (type == hwmon_temp && attr == hwmon_temp_input)
+   return nfp_hwmon_read_sensor(pf->cpp, id, val);
+   if (type == hwmon_power && attr == hwmon_power_input)
+   return nfp_hwmon_read_sensor(pf->cpp, id, val);
+
+   return -EINVAL;
+}
+
+static umode_t
+nfp_hwmon_is_visible(const void *data, enum hwmon_sensor_types type, u32 attr,
+

[PATCH net-next v2 01/13] nfp: add MAY_USE_DEVLINK dependency

2017-05-28 Thread Jakub Kicinski
Fix build with DEVLINK=m and NFP=y.

Fixes: 1851f93fd2ee ("nfp: add devlink support")
Reported-by: kbuild test robot 
Signed-off-by: Jakub Kicinski 
---
 drivers/net/ethernet/netronome/Kconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/net/ethernet/netronome/Kconfig 
b/drivers/net/ethernet/netronome/Kconfig
index 967d7ca8c28c..0d5a7b9203a4 100644
--- a/drivers/net/ethernet/netronome/Kconfig
+++ b/drivers/net/ethernet/netronome/Kconfig
@@ -19,6 +19,7 @@ config NFP
tristate "Netronome(R) NFP4000/NFP6000 NIC driver"
depends on PCI && PCI_MSI
depends on VXLAN || VXLAN=n
+   depends on MAY_USE_DEVLINK
---help---
  This driver supports the Netronome(R) NFP4000/NFP6000 based
  cards working as a advanced Ethernet NIC.  It works with both
-- 
2.11.0



[PATCH net-next v2 04/13] nfp: don't set aux pointers if ioremap failed

2017-05-28 Thread Jakub Kicinski
If ioremap of PCIe ctrl memory failed we can still get to it through
PCI config space, therefore we allow ioremap() to fail.  When if fails,
however, we must leave all the IOMEM pointers as NULL.  Currently we
would calculate csr and em pointers, adding offsets to the potential
NULL value and therefore making the NULL-checks throughout the code
ineffective.

Signed-off-by: Jakub Kicinski 
---
 .../ethernet/netronome/nfp/nfpcore/nfp6000_pcie.c| 20 
 1 file changed, 12 insertions(+), 8 deletions(-)

diff --git a/drivers/net/ethernet/netronome/nfp/nfpcore/nfp6000_pcie.c 
b/drivers/net/ethernet/netronome/nfp/nfpcore/nfp6000_pcie.c
index 43dc68e01274..1fde213d5b83 100644
--- a/drivers/net/ethernet/netronome/nfp/nfpcore/nfp6000_pcie.c
+++ b/drivers/net/ethernet/netronome/nfp/nfpcore/nfp6000_pcie.c
@@ -639,19 +639,23 @@ static int enable_bars(struct nfp6000_pcie *nfp, u16 
interface)
nfp6000_bar_write(nfp, bar, barcfg_msix_general);
 
nfp->expl.data = bar->iomem + NFP_PCIE_SRAM + 0x1000;
+
+   if (nfp->pdev->device == PCI_DEVICE_ID_NETRONOME_NFP4000 ||
+   nfp->pdev->device == PCI_DEVICE_ID_NETRONOME_NFP6000) {
+   nfp->iomem.csr = bar->iomem + NFP_PCIE_BAR(0);
+   } else {
+   int pf = nfp->pdev->devfn & 7;
+
+   nfp->iomem.csr = bar->iomem + NFP_PCIE_BAR(pf);
+   }
+   nfp->iomem.em = bar->iomem + NFP_PCIE_EM;
}
 
if (nfp->pdev->device == PCI_DEVICE_ID_NETRONOME_NFP4000 ||
-   nfp->pdev->device == PCI_DEVICE_ID_NETRONOME_NFP6000) {
-   nfp->iomem.csr = bar->iomem + NFP_PCIE_BAR(0);
+   nfp->pdev->device == PCI_DEVICE_ID_NETRONOME_NFP6000)
expl_groups = 4;
-   } else {
-   int pf = nfp->pdev->devfn & 7;
-
-   nfp->iomem.csr = bar->iomem + NFP_PCIE_BAR(pf);
+   else
expl_groups = 1;
-   }
-   nfp->iomem.em = bar->iomem + NFP_PCIE_EM;
 
/* Configure, and lock, BAR0.1 for PCIe XPB (MSI-X PBA) */
bar = &nfp->bar[1];
-- 
2.11.0



[PATCH net-next v2 13/13] nfp: don't keep count for free buffers delayed kick

2017-05-28 Thread Jakub Kicinski
We only kick RX free buffer queue controller every NFP_NET_FL_BATCH
(currently 16) entries.  This means that we will always kick the QC
when write ring index is divisable by NFP_NET_FL_BATCH.  There is
no need to keep counts.

Signed-off-by: Jakub Kicinski 
---
 drivers/net/ethernet/netronome/nfp/nfp_net.h| 3 ---
 drivers/net/ethernet/netronome/nfp/nfp_net_common.c | 7 ++-
 2 files changed, 2 insertions(+), 8 deletions(-)

diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net.h 
b/drivers/net/ethernet/netronome/nfp/nfp_net.h
index 7882d2604835..cb7114309656 100644
--- a/drivers/net/ethernet/netronome/nfp/nfp_net.h
+++ b/drivers/net/ethernet/netronome/nfp/nfp_net.h
@@ -328,8 +328,6 @@ struct nfp_net_rx_buf {
  * @idx:Ring index from Linux's perspective
  * @fl_qcidx:   Queue Controller Peripheral (QCP) queue index for the freelist
  * @qcp_fl: Pointer to base of the QCP freelist queue
- * @wr_ptr_add: Accumulated number of buffers to add to QCP write pointer
- *  (used for free list batching)
  * @rxbufs: Array of transmitted FL/RX buffers
  * @rxds:   Virtual address of FL/RX ring in host memory
  * @dma:DMA address of the FL/RX ring
@@ -343,7 +341,6 @@ struct nfp_net_rx_ring {
u32 rd_p;
 
u32 idx;
-   u32 wr_ptr_add;
 
int fl_qcidx;
u8 __iomem *qcp_fl;
diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net_common.c 
b/drivers/net/ethernet/netronome/nfp/nfp_net_common.c
index 68013d048e9d..c9a140376621 100644
--- a/drivers/net/ethernet/netronome/nfp/nfp_net_common.c
+++ b/drivers/net/ethernet/netronome/nfp/nfp_net_common.c
@@ -1212,14 +1212,12 @@ static void nfp_net_rx_give_one(const struct nfp_net_dp 
*dp,
  dma_addr + dp->rx_dma_off);
 
rx_ring->wr_p++;
-   rx_ring->wr_ptr_add++;
-   if (rx_ring->wr_ptr_add >= NFP_NET_FL_BATCH) {
+   if (!(rx_ring->wr_p % NFP_NET_FL_BATCH)) {
/* Update write pointer of the freelist queue. Make
 * sure all writes are flushed before telling the hardware.
 */
wmb();
-   nfp_qcp_wr_ptr_add(rx_ring->qcp_fl, rx_ring->wr_ptr_add);
-   rx_ring->wr_ptr_add = 0;
+   nfp_qcp_wr_ptr_add(rx_ring->qcp_fl, NFP_NET_FL_BATCH);
}
 }
 
@@ -1245,7 +1243,6 @@ static void nfp_net_rx_ring_reset(struct nfp_net_rx_ring 
*rx_ring)
memset(rx_ring->rxds, 0, sizeof(*rx_ring->rxds) * rx_ring->cnt);
rx_ring->wr_p = 0;
rx_ring->rd_p = 0;
-   rx_ring->wr_ptr_add = 0;
 }
 
 /**
-- 
2.11.0



[PATCH net-next v2 00/13] nfp: pci core, hwmon, live mac addr change

2017-05-28 Thread Jakub Kicinski
This series brings updates to core PCI code, SR-IOV, exposes 
firmware's capability to change MAC address at runtime and HWMON
interfaces.  

The PCI code updates include resiliency improvement in conditions 
which are quite unusual, but still shouldn't make the driver oops.
We also handle very large device memory operation more gracefully.
A timeout is added to acquiring mutexes in device memory.

Pablo provides a patch to expose to the stack the ability to change
MAC addresses under traffic while David adds HWMON interface for
reading device temperature and power consumption.

Last three patches are minor improvements to the netdev code.

v2:
 - add patch 1 - fix for devlink build;
 - fix build issue with the hwmon patch.

David Brunecz (1):
  nfp: add hwmon support

Jakub Kicinski (11):
  nfp: add MAY_USE_DEVLINK dependency
  nfp: set driver VF limit
  nfp: don't set aux pointers if ioremap failed
  nfp: only try to get to PCIe ctrl memory if BARs are wide enough
  nfp: support long reads and writes with the cpp helpers
  nfp: shorten CPP core probe logs
  nfp: support variable NSP response lengths
  nfp: don't wait for resources indefinitely
  nfp: fix print format for ring pointers in ring dumps
  nfp: don't add ring size to index calculations
  nfp: don't keep count for free buffers delayed kick

Pablo Cascón (1):
  nfp: add set_mac_address support while the interface is up

 drivers/net/ethernet/netronome/Kconfig |   1 +
 drivers/net/ethernet/netronome/nfp/Makefile|   1 +
 drivers/net/ethernet/netronome/nfp/nfp_hwmon.c | 192 +
 drivers/net/ethernet/netronome/nfp/nfp_main.c  |  44 +++--
 drivers/net/ethernet/netronome/nfp/nfp_main.h  |  10 ++
 drivers/net/ethernet/netronome/nfp/nfp_net.h   |   3 -
 .../net/ethernet/netronome/nfp/nfp_net_common.c|  55 --
 drivers/net/ethernet/netronome/nfp/nfp_net_ctrl.h  |   2 +
 .../net/ethernet/netronome/nfp/nfp_net_debugfs.c   |   4 +-
 drivers/net/ethernet/netronome/nfp/nfpcore/nfp.h   |   2 +
 .../ethernet/netronome/nfp/nfpcore/nfp6000_pcie.c  |  49 --
 .../net/ethernet/netronome/nfp/nfpcore/nfp_cpp.h   |   8 +
 .../ethernet/netronome/nfp/nfpcore/nfp_cppcore.c   |  87 --
 .../net/ethernet/netronome/nfp/nfpcore/nfp_mutex.c |   9 +-
 .../net/ethernet/netronome/nfp/nfpcore/nfp_nsp.c   |  16 ++
 .../net/ethernet/netronome/nfp/nfpcore/nfp_nsp.h   |  12 ++
 .../ethernet/netronome/nfp/nfpcore/nfp_nsp_cmds.c  |  47 -
 .../ethernet/netronome/nfp/nfpcore/nfp_resource.c  |  10 +-
 18 files changed, 475 insertions(+), 77 deletions(-)
 create mode 100644 drivers/net/ethernet/netronome/nfp/nfp_hwmon.c

-- 
2.11.0



[PATCH net-next v2 12/13] nfp: don't add ring size to index calculations

2017-05-28 Thread Jakub Kicinski
Adding ring size to index calculation is pointless, since index
will be masked with ring size - 1.

Suggested-by: David Laight 
Signed-off-by: Jakub Kicinski 
---
 drivers/net/ethernet/netronome/nfp/nfp_net_common.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net_common.c 
b/drivers/net/ethernet/netronome/nfp/nfp_net_common.c
index 9312a737fbc9..68013d048e9d 100644
--- a/drivers/net/ethernet/netronome/nfp/nfp_net_common.c
+++ b/drivers/net/ethernet/netronome/nfp/nfp_net_common.c
@@ -928,7 +928,7 @@ static void nfp_net_tx_complete(struct nfp_net_tx_ring 
*tx_ring)
if (qcp_rd_p == tx_ring->qcp_rd_p)
return;
 
-   todo = D_IDX(tx_ring, qcp_rd_p + tx_ring->cnt - tx_ring->qcp_rd_p);
+   todo = D_IDX(tx_ring, qcp_rd_p - tx_ring->qcp_rd_p);
 
while (todo--) {
idx = D_IDX(tx_ring, tx_ring->rd_p++);
@@ -999,7 +999,7 @@ static bool nfp_net_xdp_complete(struct nfp_net_tx_ring 
*tx_ring)
if (qcp_rd_p == tx_ring->qcp_rd_p)
return true;
 
-   todo = D_IDX(tx_ring, qcp_rd_p + tx_ring->cnt - tx_ring->qcp_rd_p);
+   todo = D_IDX(tx_ring, qcp_rd_p - tx_ring->qcp_rd_p);
 
done_all = todo <= NFP_NET_XDP_MAX_COMPLETE;
todo = min(todo, NFP_NET_XDP_MAX_COMPLETE);
-- 
2.11.0



[PATCH net-next v2 06/13] nfp: support long reads and writes with the cpp helpers

2017-05-28 Thread Jakub Kicinski
nfp_cpp_{read,write}() helpers perform device memory mapping (setting
the PCIe -> NOC translation BARs) and accessing it.  They, however,
currently implicitly expect that the length of entire operation will
fit in one BAR translation window.  There is a number of 16MB windows
available, and we don't really need to access such large areas today.

If the user, however, manages to trick the driver into making a big
mapping (e.g. by providing a huge fake FW file), the driver will
print a warning saying "No suitable BAR found for request" and a
stack trace - which most users find concerning.

To be future-proof and not scare users with warnings, make the
nfp_cpp_{read,write}() helpers do accesses chunk by chunk if the area
size is large.  Set the notion of "large" to 2MB, which is the size
of the smallest BAR window.

Signed-off-by: Jakub Kicinski 
---
 .../net/ethernet/netronome/nfp/nfpcore/nfp_cpp.h   |  3 +
 .../ethernet/netronome/nfp/nfpcore/nfp_cppcore.c   | 87 +-
 2 files changed, 72 insertions(+), 18 deletions(-)

diff --git a/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_cpp.h 
b/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_cpp.h
index 154b0b594184..8d46b9acb69f 100644
--- a/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_cpp.h
+++ b/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_cpp.h
@@ -42,6 +42,7 @@
 
 #include 
 #include 
+#include 
 
 #ifndef NFP_SUBSYS
 #define NFP_SUBSYS "nfp"
@@ -59,6 +60,8 @@
 #define PCI_64BIT_BAR_COUNT 3
 
 #define NFP_CPP_NUM_TARGETS 16
+/* Max size of area it should be safe to request */
+#define NFP_CPP_SAFE_AREA_SIZE SZ_2M
 
 struct device;
 
diff --git a/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_cppcore.c 
b/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_cppcore.c
index e2abba4c3a3f..5672d309d07d 100644
--- a/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_cppcore.c
+++ b/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_cppcore.c
@@ -924,18 +924,9 @@ area_cache_put(struct nfp_cpp *cpp, struct 
nfp_cpp_area_cache *cache)
mutex_unlock(&cpp->area_cache_mutex);
 }
 
-/**
- * nfp_cpp_read() - read from CPP target
- * @cpp:   CPP handle
- * @destination:   CPP id
- * @address:   offset into CPP target
- * @kernel_vaddr:  kernel buffer for result
- * @length:number of bytes to read
- *
- * Return: length of io, or -ERRNO
- */
-int nfp_cpp_read(struct nfp_cpp *cpp, u32 destination,
-unsigned long long address, void *kernel_vaddr, size_t length)
+static int __nfp_cpp_read(struct nfp_cpp *cpp, u32 destination,
+ unsigned long long address, void *kernel_vaddr,
+ size_t length)
 {
struct nfp_cpp_area_cache *cache;
struct nfp_cpp_area *area;
@@ -968,18 +959,43 @@ int nfp_cpp_read(struct nfp_cpp *cpp, u32 destination,
 }
 
 /**
- * nfp_cpp_write() - write to CPP target
+ * nfp_cpp_read() - read from CPP target
  * @cpp:   CPP handle
  * @destination:   CPP id
  * @address:   offset into CPP target
- * @kernel_vaddr:  kernel buffer to read from
- * @length:number of bytes to write
+ * @kernel_vaddr:  kernel buffer for result
+ * @length:number of bytes to read
  *
  * Return: length of io, or -ERRNO
  */
-int nfp_cpp_write(struct nfp_cpp *cpp, u32 destination,
- unsigned long long address,
- const void *kernel_vaddr, size_t length)
+int nfp_cpp_read(struct nfp_cpp *cpp, u32 destination,
+unsigned long long address, void *kernel_vaddr,
+size_t length)
+{
+   size_t n, offset;
+   int ret;
+
+   for (offset = 0; offset < length; offset += n) {
+   unsigned long long r_addr = address + offset;
+
+   /* make first read smaller to align to safe window */
+   n = min_t(size_t, length - offset,
+ ALIGN(r_addr + 1, NFP_CPP_SAFE_AREA_SIZE) - r_addr);
+
+   ret = __nfp_cpp_read(cpp, destination, address + offset,
+kernel_vaddr + offset, n);
+   if (ret < 0)
+   return ret;
+   if (ret != n)
+   return offset + n;
+   }
+
+   return length;
+}
+
+static int __nfp_cpp_write(struct nfp_cpp *cpp, u32 destination,
+  unsigned long long address,
+  const void *kernel_vaddr, size_t length)
 {
struct nfp_cpp_area_cache *cache;
struct nfp_cpp_area *area;
@@ -1011,6 +1027,41 @@ int nfp_cpp_write(struct nfp_cpp *cpp, u32 destination,
return err;
 }
 
+/**
+ * nfp_cpp_write() - write to CPP target
+ * @cpp:   CPP handle
+ * @destination:   CPP id
+ * @address:   offset into CPP target
+ * @kernel_vaddr:  kernel buffer to read from
+ * @length:number of bytes to write
+ *
+ * Return: length of io, or -ERRNO
+ *

[PATCH net-next v2 10/13] nfp: don't wait for resources indefinitely

2017-05-28 Thread Jakub Kicinski
There is currently no timeout to the resource and lock acquiring
loops.  We printed warnings and depended on user sending a signal
to the waiting process to stop the waiting.  This doesn't work
very well when wait happens out of a work queue.  The simplest
example of that is PCI probe.  When user loads the module and card
is in a broken state modprobe will wait forever and signals sent
to it will not actually reach the probing thread.

Make sure all wait loops have a time out.  Set the upper wait time
to 60 seconds to stay on the safe side.

Signed-off-by: Jakub Kicinski 
---
 drivers/net/ethernet/netronome/nfp/nfpcore/nfp_cpp.h  |  5 +
 drivers/net/ethernet/netronome/nfp/nfpcore/nfp_mutex.c|  9 +++--
 drivers/net/ethernet/netronome/nfp/nfpcore/nfp_resource.c | 10 --
 3 files changed, 20 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_cpp.h 
b/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_cpp.h
index 8d46b9acb69f..0a46c0984e68 100644
--- a/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_cpp.h
+++ b/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_cpp.h
@@ -63,6 +63,11 @@
 /* Max size of area it should be safe to request */
 #define NFP_CPP_SAFE_AREA_SIZE SZ_2M
 
+/* NFP_MUTEX_WAIT_* are timeouts in seconds when waiting for a mutex */
+#define NFP_MUTEX_WAIT_FIRST_WARN  15
+#define NFP_MUTEX_WAIT_NEXT_WARN   5
+#define NFP_MUTEX_WAIT_ERROR   60
+
 struct device;
 
 struct nfp_cpp_area;
diff --git a/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_mutex.c 
b/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_mutex.c
index 8a99c189efa8..f7b958181126 100644
--- a/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_mutex.c
+++ b/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_mutex.c
@@ -195,7 +195,8 @@ void nfp_cpp_mutex_free(struct nfp_cpp_mutex *mutex)
  */
 int nfp_cpp_mutex_lock(struct nfp_cpp_mutex *mutex)
 {
-   unsigned long warn_at = jiffies + 15 * HZ;
+   unsigned long warn_at = jiffies + NFP_MUTEX_WAIT_FIRST_WARN * HZ;
+   unsigned long err_at = jiffies + NFP_MUTEX_WAIT_ERROR * HZ;
unsigned int timeout_ms = 1;
int err;
 
@@ -214,12 +215,16 @@ int nfp_cpp_mutex_lock(struct nfp_cpp_mutex *mutex)
return -ERESTARTSYS;
 
if (time_is_before_eq_jiffies(warn_at)) {
-   warn_at = jiffies + 60 * HZ;
+   warn_at = jiffies + NFP_MUTEX_WAIT_NEXT_WARN * HZ;
nfp_warn(mutex->cpp,
 "Warning: waiting for NFP mutex [depth:%hd 
target:%d addr:%llx key:%08x]\n",
 mutex->depth,
 mutex->target, mutex->address, mutex->key);
}
+   if (time_is_before_eq_jiffies(err_at)) {
+   nfp_err(mutex->cpp, "Error: mutex wait timed out\n");
+   return -EBUSY;
+   }
}
 
return err;
diff --git a/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_resource.c 
b/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_resource.c
index 2d15a7c9d0de..072612263dab 100644
--- a/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_resource.c
+++ b/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_resource.c
@@ -181,7 +181,8 @@ nfp_resource_try_acquire(struct nfp_cpp *cpp, struct 
nfp_resource *res,
 struct nfp_resource *
 nfp_resource_acquire(struct nfp_cpp *cpp, const char *name)
 {
-   unsigned long warn_at = jiffies + 15 * HZ;
+   unsigned long warn_at = jiffies + NFP_MUTEX_WAIT_FIRST_WARN * HZ;
+   unsigned long err_at = jiffies + NFP_MUTEX_WAIT_ERROR * HZ;
struct nfp_cpp_mutex *dev_mutex;
struct nfp_resource *res;
int err;
@@ -214,10 +215,15 @@ nfp_resource_acquire(struct nfp_cpp *cpp, const char 
*name)
}
 
if (time_is_before_eq_jiffies(warn_at)) {
-   warn_at = jiffies + 60 * HZ;
+   warn_at = jiffies + NFP_MUTEX_WAIT_NEXT_WARN * HZ;
nfp_warn(cpp, "Warning: waiting for NFP resource %s\n",
 name);
}
+   if (time_is_before_eq_jiffies(err_at)) {
+   nfp_err(cpp, "Error: resource %s timed out\n", name);
+   err = -EBUSY;
+   goto err_free;
+   }
}
 
nfp_cpp_mutex_free(dev_mutex);
-- 
2.11.0



[PATCH net-next v2 05/13] nfp: only try to get to PCIe ctrl memory if BARs are wide enough

2017-05-28 Thread Jakub Kicinski
For accessing PCIe ctrl memory we depend on the BAR aperture being
large enough to reach all registers.  Since the BAR aperture can
be set in the flash make sure the driver won't oops the kernel
when the PCIe configuration is unusual.

Signed-off-by: Jakub Kicinski 
---
 drivers/net/ethernet/netronome/nfp/nfpcore/nfp6000_pcie.c | 10 --
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/netronome/nfp/nfpcore/nfp6000_pcie.c 
b/drivers/net/ethernet/netronome/nfp/nfpcore/nfp6000_pcie.c
index 1fde213d5b83..597ac8febb63 100644
--- a/drivers/net/ethernet/netronome/nfp/nfpcore/nfp6000_pcie.c
+++ b/drivers/net/ethernet/netronome/nfp/nfpcore/nfp6000_pcie.c
@@ -119,6 +119,11 @@
 #define NFP_PCIE_EM 0x02
 #define NFP_PCIE_SRAM   0x00
 
+/* Minimal size of the PCIe cfg memory we depend on being mapped,
+ * queue controller and DMA controller don't have to be covered.
+ */
+#define NFP_PCI_MIN_MAP_SIZE   0x08
+
 #define NFP_PCIE_P2C_FIXED_SIZE(bar)   (1 << (bar)->bitsize)
 #define NFP_PCIE_P2C_BULK_SIZE(bar)(1 << (bar)->bitsize)
 #define NFP_PCIE_P2C_GENERAL_TARGET_OFFSET(bar, x) ((x) << ((bar)->bitsize - 
2))
@@ -628,8 +633,9 @@ static int enable_bars(struct nfp6000_pcie *nfp, u16 
interface)
 
/* Configure, and lock, BAR0.0 for General Target use (MSI-X SRAM) */
bar = &nfp->bar[0];
-   bar->iomem = ioremap_nocache(nfp_bar_resource_start(bar),
-nfp_bar_resource_len(bar));
+   if (nfp_bar_resource_len(bar) >= NFP_PCI_MIN_MAP_SIZE)
+   bar->iomem = ioremap_nocache(nfp_bar_resource_start(bar),
+nfp_bar_resource_len(bar));
if (bar->iomem) {
dev_info(nfp->dev,
 "BAR0.0 RESERVED: General Mapping/MSI-X SRAM\n");
-- 
2.11.0



[PATCH net-next v2 03/13] nfp: set driver VF limit

2017-05-28 Thread Jakub Kicinski
PCI subsystem has support for drivers limiting the number of VFs
available below what the IOV capability claims.  Make use of it.

While at it remove the #ifdef/#endif on CONFIG_PCI_IOV, it was
there to avoid unnecessary warnings in case device read failed
but kernel doesn't have SR-IOV support anyway.  Device reads
should not fail.

Note that we still need the driver-internal check for the case
where max VFs is 0 since PCI subsystem treats 0 as limit not set.

Signed-off-by: Jakub Kicinski 
---
 drivers/net/ethernet/netronome/nfp/nfp_main.c | 23 +++
 1 file changed, 15 insertions(+), 8 deletions(-)

diff --git a/drivers/net/ethernet/netronome/nfp/nfp_main.c 
b/drivers/net/ethernet/netronome/nfp/nfp_main.c
index f22f56c9218f..ba174e163834 100644
--- a/drivers/net/ethernet/netronome/nfp/nfp_main.c
+++ b/drivers/net/ethernet/netronome/nfp/nfp_main.c
@@ -73,20 +73,22 @@ static const struct pci_device_id nfp_pci_device_ids[] = {
 };
 MODULE_DEVICE_TABLE(pci, nfp_pci_device_ids);
 
-static void nfp_pcie_sriov_read_nfd_limit(struct nfp_pf *pf)
+static int nfp_pcie_sriov_read_nfd_limit(struct nfp_pf *pf)
 {
-#ifdef CONFIG_PCI_IOV
int err;
 
pf->limit_vfs = nfp_rtsym_read_le(pf->cpp, "nfd_vf_cfg_max_vfs", &err);
if (!err)
-   return;
+   return pci_sriov_set_totalvfs(pf->pdev, pf->limit_vfs);
 
pf->limit_vfs = ~0;
+   pci_sriov_set_totalvfs(pf->pdev, 0); /* 0 is unset */
/* Allow any setting for backwards compatibility if symbol not found */
-   if (err != -ENOENT)
-   nfp_warn(pf->cpp, "Warning: VF limit read failed: %d\n", err);
-#endif
+   if (err == -ENOENT)
+   return 0;
+
+   nfp_warn(pf->cpp, "Warning: VF limit read failed: %d\n", err);
+   return err;
 }
 
 static int nfp_pcie_sriov_enable(struct pci_dev *pdev, int num_vfs)
@@ -373,14 +375,18 @@ static int nfp_pci_probe(struct pci_dev *pdev,
if (err)
goto err_devlink_unreg;
 
-   nfp_pcie_sriov_read_nfd_limit(pf);
+   err = nfp_pcie_sriov_read_nfd_limit(pf);
+   if (err)
+   goto err_fw_unload;
 
err = nfp_net_pci_probe(pf);
if (err)
-   goto err_fw_unload;
+   goto err_sriov_unlimit;
 
return 0;
 
+err_sriov_unlimit:
+   pci_sriov_set_totalvfs(pf->pdev, 0);
 err_fw_unload:
if (pf->fw_loaded)
nfp_fw_unload(pf);
@@ -411,6 +417,7 @@ static void nfp_pci_remove(struct pci_dev *pdev)
nfp_net_pci_remove(pf);
 
nfp_pcie_sriov_disable(pdev);
+   pci_sriov_set_totalvfs(pf->pdev, 0);
 
devlink_unregister(devlink);
 
-- 
2.11.0



[PATCH net-next v2 02/13] nfp: add set_mac_address support while the interface is up

2017-05-28 Thread Jakub Kicinski
From: Pablo Cascón 

Expose FW app ability to change MAC address at runtime.  Make sure
we only depend on it if FW app advertised the right capability.

Signed-off-by: Pablo Cascón 
Reviewed-by: Jakub Kicinski 
---
 .../net/ethernet/netronome/nfp/nfp_net_common.c| 44 +-
 drivers/net/ethernet/netronome/nfp/nfp_net_ctrl.h  |  2 +
 2 files changed, 36 insertions(+), 10 deletions(-)

diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net_common.c 
b/drivers/net/ethernet/netronome/nfp/nfp_net_common.c
index b3f5c8af6789..9312a737fbc9 100644
--- a/drivers/net/ethernet/netronome/nfp/nfp_net_common.c
+++ b/drivers/net/ethernet/netronome/nfp/nfp_net_common.c
@@ -2123,17 +2123,16 @@ void nfp_net_coalesce_write_cfg(struct nfp_net *nn)
 /**
  * nfp_net_write_mac_addr() - Write mac address to the device control BAR
  * @nn:  NFP Net device to reconfigure
+ * @addr:MAC address to write
  *
  * Writes the MAC address from the netdev to the device control BAR.  Does not
  * perform the required reconfig.  We do a bit of byte swapping dance because
  * firmware is LE.
  */
-static void nfp_net_write_mac_addr(struct nfp_net *nn)
+static void nfp_net_write_mac_addr(struct nfp_net *nn, const u8 *addr)
 {
-   nn_writel(nn, NFP_NET_CFG_MACADDR + 0,
- get_unaligned_be32(nn->dp.netdev->dev_addr));
-   nn_writew(nn, NFP_NET_CFG_MACADDR + 6,
- get_unaligned_be16(nn->dp.netdev->dev_addr + 4));
+   nn_writel(nn, NFP_NET_CFG_MACADDR + 0, get_unaligned_be32(addr));
+   nn_writew(nn, NFP_NET_CFG_MACADDR + 6, get_unaligned_be16(addr + 4));
 }
 
 static void nfp_net_vec_clear_ring_data(struct nfp_net *nn, unsigned int idx)
@@ -2238,7 +2237,7 @@ static int nfp_net_set_config_and_enable(struct nfp_net 
*nn)
nn_writeq(nn, NFP_NET_CFG_RXRS_ENABLE, nn->dp.num_rx_rings == 64 ?
  0xULL : ((u64)1 << nn->dp.num_rx_rings) - 1);
 
-   nfp_net_write_mac_addr(nn);
+   nfp_net_write_mac_addr(nn, nn->dp.netdev->dev_addr);
 
nn_writel(nn, NFP_NET_CFG_MTU, nn->dp.netdev->mtu);
 
@@ -2997,6 +2996,27 @@ static int nfp_net_xdp(struct net_device *netdev, struct 
netdev_xdp *xdp)
}
 }
 
+static int nfp_net_set_mac_address(struct net_device *netdev, void *addr)
+{
+   struct nfp_net *nn = netdev_priv(netdev);
+   struct sockaddr *saddr = addr;
+   int err;
+
+   err = eth_prepare_mac_addr_change(netdev, addr);
+   if (err)
+   return err;
+
+   nfp_net_write_mac_addr(nn, saddr->sa_data);
+
+   err = nfp_net_reconfig(nn, NFP_NET_CFG_UPDATE_MACADDR);
+   if (err)
+   return err;
+
+   eth_commit_mac_addr_change(netdev, addr);
+
+   return 0;
+}
+
 const struct net_device_ops nfp_net_netdev_ops = {
.ndo_open   = nfp_net_netdev_open,
.ndo_stop   = nfp_net_netdev_close,
@@ -3006,7 +3026,7 @@ const struct net_device_ops nfp_net_netdev_ops = {
.ndo_tx_timeout = nfp_net_tx_timeout,
.ndo_set_rx_mode= nfp_net_set_rx_mode,
.ndo_change_mtu = nfp_net_change_mtu,
-   .ndo_set_mac_address= eth_mac_addr,
+   .ndo_set_mac_address= nfp_net_set_mac_address,
.ndo_set_features   = nfp_net_set_features,
.ndo_features_check = nfp_net_features_check,
.ndo_get_phys_port_name = nfp_port_get_phys_port_name,
@@ -3029,7 +3049,7 @@ void nfp_net_info(struct nfp_net *nn)
nn->fw_ver.resv, nn->fw_ver.class,
nn->fw_ver.major, nn->fw_ver.minor,
nn->max_mtu);
-   nn_info(nn, "CAP: %#x %s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n",
+   nn_info(nn, "CAP: %#x %s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n",
nn->cap,
nn->cap & NFP_NET_CFG_CTRL_PROMISC  ? "PROMISC "  : "",
nn->cap & NFP_NET_CFG_CTRL_L2BC ? "L2BCFILT " : "",
@@ -3051,7 +3071,8 @@ void nfp_net_info(struct nfp_net *nn)
nn->cap & NFP_NET_CFG_CTRL_NVGRE? "NVGRE ": "",
nfp_net_ebpf_capable(nn)? "BPF "  : "",
nn->cap & NFP_NET_CFG_CTRL_CSUM_COMPLETE ?
- "RXCSUM_COMPLETE " : "");
+ "RXCSUM_COMPLETE " : "",
+   nn->cap & NFP_NET_CFG_CTRL_LIVE_ADDR ? "LIVE_ADDR " : "");
 }
 
 /**
@@ -3211,7 +3232,7 @@ int nfp_net_init(struct nfp_net *nn)
if (nn->dp.chained_metadata_format && nn->fw_ver.major != 4)
nn->cap &= ~NFP_NET_CFG_CTRL_RSS;
 
-   nfp_net_write_mac_addr(nn);
+   nfp_net_write_mac_addr(nn, nn->dp.netdev->dev_addr);
 
/* Determine RX packet/metadata boundary offset */
if (nn->fw_ver.major >= 2) {
@@ -3241,6 +3262,9 @@ int nfp_net_init(struct nfp_net *nn)
 * and netdev->hw_features advertises which features are
 * supported.  By default we enable most fea

[PATCH net-next v2 11/13] nfp: fix print format for ring pointers in ring dumps

2017-05-28 Thread Jakub Kicinski
Ring pointers are unsigned.  Fix the print formats to avoid
showing users negative values.

Signed-off-by: Jakub Kicinski 
---
 drivers/net/ethernet/netronome/nfp/nfp_net_debugfs.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net_debugfs.c 
b/drivers/net/ethernet/netronome/nfp/nfp_net_debugfs.c
index 6cf1b234eecd..8c52c0e8379c 100644
--- a/drivers/net/ethernet/netronome/nfp/nfp_net_debugfs.c
+++ b/drivers/net/ethernet/netronome/nfp/nfp_net_debugfs.c
@@ -62,7 +62,7 @@ static int nfp_net_debugfs_rx_q_read(struct seq_file *file, 
void *data)
fl_rd_p = nfp_qcp_rd_ptr_read(rx_ring->qcp_fl);
fl_wr_p = nfp_qcp_wr_ptr_read(rx_ring->qcp_fl);
 
-   seq_printf(file, "RX[%02d,%02d]: cnt=%d dma=%pad host=%p   H_RD=%d 
H_WR=%d FL_RD=%d FL_WR=%d\n",
+   seq_printf(file, "RX[%02d,%02d]: cnt=%u dma=%pad host=%p   H_RD=%u 
H_WR=%u FL_RD=%u FL_WR=%u\n",
   rx_ring->idx, rx_ring->fl_qcidx,
   rx_ring->cnt, &rx_ring->dma, rx_ring->rxds,
   rx_ring->rd_p, rx_ring->wr_p, fl_rd_p, fl_wr_p);
@@ -146,7 +146,7 @@ static int nfp_net_debugfs_tx_q_read(struct seq_file *file, 
void *data)
d_rd_p = nfp_qcp_rd_ptr_read(tx_ring->qcp_q);
d_wr_p = nfp_qcp_wr_ptr_read(tx_ring->qcp_q);
 
-   seq_printf(file, "TX[%02d,%02d%s]: cnt=%d dma=%pad host=%p   H_RD=%d 
H_WR=%d D_RD=%d D_WR=%d\n",
+   seq_printf(file, "TX[%02d,%02d%s]: cnt=%u dma=%pad host=%p   H_RD=%u 
H_WR=%u D_RD=%u D_WR=%u\n",
   tx_ring->idx, tx_ring->qcidx,
   tx_ring == r_vec->tx_ring ? "" : "xdp",
   tx_ring->cnt, &tx_ring->dma, tx_ring->txds,
-- 
2.11.0



Re: [patch net-next 0/9] mlxsw: Support firmware flash

2017-05-28 Thread Jakub Kicinski
On Sun, 28 May 2017 10:26:49 +0300, Yotam Gigi wrote:
> On 05/23/2017 06:38 PM, David Miller wrote:
> > From: Yotam Gigi 
> > Date: Tue, 23 May 2017 18:14:15 +0300
> >  
> >> Sorry, I am not sure I understand. You think that drivers should not 
> >> implement
> >> ethtool's flash_device callback anymore? do you have an alternative for 
> >> firmware
> >> flash?  
> > As stated, export an MTD device.  
> 
> So, after we have been going over MTD, it seems like it does not fit our needs
> at all.
> 
> MTD device provides (erasable-)block access to a flash storage, where in our
> case the firmware burn process is just pouring a binary BLOB into the device.
> The driver is not aware of the internal storage used for storing the firmware 
> as
> it is not defined in our driver-hardware API.
> 
> Needless to say that block access has no meaning in our case, so any solution
> that will involve MTD device to burn our firmware (if there is a solution at
> all) will be a workaround and will not fit MTD purpose.
> 
> Apart for boot time firmware flash, which we have already pushed we would 
> really
> like to allow the user to ask for a specific firmware version. Do you have any
> other solution for us apart from "ethtool -f"?

Could you elaborate on what the requirements are for "allowing users to
ask for a specific firmware version"?  How do the FWs differ?  I'm
asking because we are currently lacking ABI for selecting device
"modes".  Netronome has this problem.  Cavium has recently posted a
patch which used module parameter to flip between "OvS" and "basic NIC"
firmwares.

For Netronome we will definitely want a way to switch between at least
three applications so far - basic, OvS and eBPF - but I also feel like
we shouldn't limit that list, since anyone can write their own FW for
programmable NICs.

I think you were primarily concerned with writing persistent storage so
far.  Does "allowing the user to ask..." means write flash and reboot or
also a runtime switch?  I think we probably need both?

> This problem is even more relevant in the Mellanox HCA driver team, which 
> would
> like to use that code in order to burn the HCA firmware, but not intend to
> trigger it on boot time, which means that must have a way for the user to
> trigger it.

What would the requirements for the HCA team be?  Is it about loading
different code or loading HW settings?


Re: [PATCH net-next 02/12] nfp: set driver VF limit

2017-05-28 Thread Jakub Kicinski
On Sun, 28 May 2017 14:49:58 +, Mintz, Yuval wrote:
> > pf->limit_vfs = nfp_rtsym_read_le(pf->cpp, "nfd_vf_cfg_max_vfs",
> > &err);
> > if (!err)
> > -   return;
> > +   return pci_sriov_set_totalvfs(pf->pdev, pf->limit_vfs);  
> 
> While you're at it, If you're going to enforce the limit at the PCI level,
> shouldn't you retire 'limit_vfs' altogether?

I don't think so, unfortunately.  Sometimes FW sets this value to 0,
which means no VFs should be used, but the PCIe subsystem uses 0 as
"driver limit not set" :(

I will put that in the commit message.
 
> BTW, under which conditions would you expect to find a difference
> in the maximal number of VFs?

It mostly comes down to how FW projects choose to partition PCIe-side
resources on the NFP.  Some project for which SR-IOV is not a priority
may want to disable it completely.  The NFP is very software-driven,
including most of PCIe interactions, descriptor formats etc.  It's
really up to particular projects to shape how the card works.


Re: [PATCH net-next 08/12] nfp: add hwmon support

2017-05-28 Thread kbuild test robot
Hi David,

[auto build test ERROR on net-next/master]

url:
https://github.com/0day-ci/linux/commits/Jakub-Kicinski/nfp-pci-core-hwmon-live-mac-addr-change/20170528-084341
config: x86_64-randconfig-s2-05282150 (attached as .config)
compiler: gcc-4.4 (Debian 4.4.7-8) 4.4.7
reproduce:
# save the attached .config to linux build tree
make ARCH=x86_64 

All errors (new ones prefixed by >>):

   drivers/built-in.o: In function `nfp_devlink_port_unregister':
   (.text+0x25af99): undefined reference to `devlink_port_unregister'
   drivers/built-in.o: In function `nfp_devlink_port_register':
   (.text+0x25afe3): undefined reference to `devlink_port_type_eth_set'
   drivers/built-in.o: In function `nfp_devlink_port_register':
   (.text+0x25aff5): undefined reference to `devlink_port_split_set'
   drivers/built-in.o: In function `nfp_devlink_port_register':
   (.text+0x25b012): undefined reference to `devlink_port_register'
   drivers/built-in.o: In function `nfp_hwmon_unregister':
>> (.text+0x25b04e): undefined reference to `hwmon_device_unregister'
   drivers/built-in.o: In function `nfp_pci_remove':
   nfp_main.c:(.text+0x25b13f): undefined reference to `devlink_unregister'
   nfp_main.c:(.text+0x25b188): undefined reference to `devlink_free'
   drivers/built-in.o: In function `nfp_pci_probe':
   nfp_main.c:(.text+0x25b6f1): undefined reference to `devlink_alloc'
   nfp_main.c:(.text+0x25b87a): undefined reference to `devlink_unregister'
   nfp_main.c:(.text+0x25b8b2): undefined reference to `devlink_free'
   nfp_main.c:(.text+0x25b9a4): undefined reference to `devlink_register'

---
0-DAY kernel test infrastructureOpen Source Technology Center
https://lists.01.org/pipermail/kbuild-all   Intel Corporation


.config.gz
Description: application/gzip


Re: [PATCH v2 08/20] randstruct: Whitelist NIU struct page overloading

2017-05-28 Thread Kees Cook
[trying again with correct linux-mm address...]

On Sun, May 28, 2017 at 1:15 AM, Christoph Hellwig  wrote:
> On Fri, May 26, 2017 at 01:17:12PM -0700, Kees Cook wrote:
>> The NIU ethernet driver intentionally stores a page struct pointer on
>> top of the "mapping" field. Whitelist this case:
>>
>> drivers/net/ethernet/sun/niu.c: In function ‘niu_rx_pkt_ignore’:
>> drivers/net/ethernet/sun/niu.c:3402:10: note: found mismatched ssa struct 
>> pointer types: ‘struct page’ and ‘struct address_space’
>>
>> *link = (struct page *) page->mapping;
>> ~~^~~
>>
>> Cc: David S. Miller 
>> Signed-off-by: Kees Cook 
>
> The driver really needs to stop doing this anyway.  It would be good
> to send this out to linux-mm and netdev to come up with a better scheme.

Added to To. :) I couldn't understand why it was doing what it was
doing, hence the whitelist entry.

-Kees

-- 
Kees Cook
Pixel Security


Re: [PATCH v2 08/20] randstruct: Whitelist NIU struct page overloading

2017-05-28 Thread Kees Cook
On Sun, May 28, 2017 at 1:15 AM, Christoph Hellwig  wrote:
> On Fri, May 26, 2017 at 01:17:12PM -0700, Kees Cook wrote:
>> The NIU ethernet driver intentionally stores a page struct pointer on
>> top of the "mapping" field. Whitelist this case:
>>
>> drivers/net/ethernet/sun/niu.c: In function ‘niu_rx_pkt_ignore’:
>> drivers/net/ethernet/sun/niu.c:3402:10: note: found mismatched ssa struct 
>> pointer types: ‘struct page’ and ‘struct address_space’
>>
>> *link = (struct page *) page->mapping;
>> ~~^~~
>>
>> Cc: David S. Miller 
>> Signed-off-by: Kees Cook 
>
> The driver really needs to stop doing this anyway.  It would be good
> to send this out to linux-mm and netdev to come up with a better scheme.

Added to To. :) I couldn't understand why it was doing what it was
doing, hence the whitelist entry.

-Kees

-- 
Kees Cook
Pixel Security


Re: [PATCH v2 6/6] stmmac: pci: Remove setup handler indirection via stmmac_pci_info

2017-05-28 Thread Jan Kiszka
On 2017-05-27 15:38, Andy Shevchenko wrote:
> On Fri, May 26, 2017 at 7:07 PM, Jan Kiszka  wrote:
>> By now, stmmac_pci_info only contains a single entry.
> 
> _For now_.
> 
>> Register this
>> directly with the PCI device table, removing one indirection.
> 
> I am not sure this patch is needed.
> 
> Next time something comes up we would need to extend this and
> effectively revert this change.
> So, my vote is to leave it as is for now.

Therefore moved this to the end: may the maintainer pick it or not.

Jan

-- 
Siemens AG, Corporate Technology, CT RDA ITP SES-DE
Corporate Competence Center Embedded Linux


Re: [PATCH v2 5/6] stmmac: pci: Use dmi_system_id table for retrieving PHY addresses

2017-05-28 Thread Jan Kiszka
On 2017-05-27 15:28, Andy Shevchenko wrote:
> On Fri, May 26, 2017 at 7:07 PM, Jan Kiszka  wrote:
>> Avoids reimplementation of DMI matching in stmmac_pci_find_phy_addr.
> 
>>  struct stmmac_pci_dmi_data {
>> -   const char *name;
>> -   const char *asset_tag;
>> -   unsigned int func;
>> +   int func;
>> int phy_addr;
>>  };
> 
> Can we leave unsigned type here...
> 
>> -static struct stmmac_pci_dmi_data quark_pci_dmi_data[] = {
>> +static const struct stmmac_pci_dmi_data galileo_stmmac_dmi_data[] = {
> 
>> +   {-1, -1},
>> +};
> 
>> +static const struct stmmac_pci_dmi_data iot2040_stmmac_dmi_data[] = {
> 
>> +   {-1, -1},
>> +};
> 
> ...and avoid this not so standard terminators?

0 is a valid PCI function, thus can't be use as terminator. Therefore I
chose -1 as an obviously invalid value.

> 
>> +   .matches = {
>> +   DMI_EXACT_MATCH(DMI_BOARD_NAME, "GalileoGen2"),
>> +   },
> 
>> +   .driver_data = (void *)galileo_stmmac_dmi_data,
> 
> Can't be slightly better
> 
>  .driver_data = &galileo_stmmac_dmi_data,
> 
> ?
> 

Interesting, that removes the "const" as well. OK.

Jan

-- 
Siemens AG, Corporate Technology, CT RDA ITP SES-DE
Corporate Competence Center Embedded Linux


Re: [PATCH net-next 02/10] qed: Correct DCBx update scheme

2017-05-28 Thread kbuild test robot
Hi Sudarsana,

[auto build test ERROR on net-next/master]

url:
https://github.com/0day-ci/linux/commits/Yuval-Mintz/qed-DCBx-and-Attentions-series/20170528-232748
config: i386-randconfig-x072-05281806 (attached as .config)
compiler: gcc-6 (Debian 6.2.0-3) 6.2.0 20160901
reproduce:
# save the attached .config to linux build tree
make ARCH=i386 

Note: the 
linux-review/Yuval-Mintz/qed-DCBx-and-Attentions-series/20170528-232748 HEAD 
298544d8c8c2a0cfc79d2c73bb877b1a0644900a builds fine.
  It only hurts bisectibility.

All errors (new ones prefixed by >>):

   drivers/net//ethernet/qlogic/qed/qed_dcbx.c: In function 
'qed_dcbx_process_tlv':
>> drivers/net//ethernet/qlogic/qed/qed_dcbx.c:320:3: error: too many arguments 
>> to function 'qed_dcbx_update_app_info'
  qed_dcbx_update_app_info(p_data, p_hwfn, true, true,
  ^~~~
   drivers/net//ethernet/qlogic/qed/qed_dcbx.c:215:1: note: declared here
qed_dcbx_update_app_info(struct qed_dcbx_results *p_data,
^~~~

vim +/qed_dcbx_update_app_info +320 drivers/net//ethernet/qlogic/qed/qed_dcbx.c

39651abd Sudarsana Reddy Kalluru 2016-05-17  314 * data for RoCE-v2 not 
the default app data.
39651abd Sudarsana Reddy Kalluru 2016-05-17  315 */
39651abd Sudarsana Reddy Kalluru 2016-05-17  316if 
(!p_data->arr[DCBX_PROTOCOL_ROCE_V2].update &&
39651abd Sudarsana Reddy Kalluru 2016-05-17  317
p_data->arr[DCBX_PROTOCOL_ROCE].update) {
39651abd Sudarsana Reddy Kalluru 2016-05-17  318tc = 
p_data->arr[DCBX_PROTOCOL_ROCE].tc;
39651abd Sudarsana Reddy Kalluru 2016-05-17  319priority = 
p_data->arr[DCBX_PROTOCOL_ROCE].priority;
39651abd Sudarsana Reddy Kalluru 2016-05-17 @320
qed_dcbx_update_app_info(p_data, p_hwfn, true, true,
39651abd Sudarsana Reddy Kalluru 2016-05-17  321
 priority, tc, DCBX_PROTOCOL_ROCE_V2);
39651abd Sudarsana Reddy Kalluru 2016-05-17  322}
39651abd Sudarsana Reddy Kalluru 2016-05-17  323  

:: The code at line 320 was first introduced by commit
:: 39651abd28146fff2bfac63d68a7a56250a4aead qed: add support for dcbx.

:: TO: Sudarsana Reddy Kalluru 
:: CC: David S. Miller 

---
0-DAY kernel test infrastructureOpen Source Technology Center
https://lists.01.org/pipermail/kbuild-all   Intel Corporation


.config.gz
Description: application/gzip


Re: [PATCH net-next] net: dsa: mv88e6xxx: Add missing static to stub functions

2017-05-28 Thread David Miller
From: Andrew Lunn 
Date: Sun, 28 May 2017 17:25:14 +0200

> Stub functions in header files need to be static, or we can have
> multiple definitions errors.
> 
> Reported-by: kbuild test robot 
> Fixes: 6335e9f2446b ("net: dsa: mv88e6xxx: mv88e6390X SERDES support")
> Signed-off-by: Andrew Lunn 

Applied, thanks Andrew.


[PATCH net-next] net: dsa: mv88e6xxx: Add missing static to stub functions

2017-05-28 Thread Andrew Lunn
Stub functions in header files need to be static, or we can have
multiple definitions errors.

Reported-by: kbuild test robot 
Fixes: 6335e9f2446b ("net: dsa: mv88e6xxx: mv88e6390X SERDES support")
Signed-off-by: Andrew Lunn 
---
 drivers/net/dsa/mv88e6xxx/global2.h | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/net/dsa/mv88e6xxx/global2.h 
b/drivers/net/dsa/mv88e6xxx/global2.h
index 96046bb12ca1..d8d3c5abb2a1 100644
--- a/drivers/net/dsa/mv88e6xxx/global2.h
+++ b/drivers/net/dsa/mv88e6xxx/global2.h
@@ -114,13 +114,13 @@ static inline int mv88e6xxx_g2_set_eeprom16(struct 
mv88e6xxx_chip *chip,
return -EOPNOTSUPP;
 }
 
-int mv88e6xxx_g2_pvt_write(struct mv88e6xxx_chip *chip, int src_dev,
-  int src_port, u16 data)
+static int mv88e6xxx_g2_pvt_write(struct mv88e6xxx_chip *chip, int src_dev,
+ int src_port, u16 data)
 {
return -EOPNOTSUPP;
 }
 
-int mv88e6xxx_g2_misc_4_bit_port(struct mv88e6xxx_chip *chip)
+static int mv88e6xxx_g2_misc_4_bit_port(struct mv88e6xxx_chip *chip)
 {
return -EOPNOTSUPP;
 }
-- 
2.11.0



[PATCH net-next 08/10] qed: Print multi-bit attentions properly

2017-05-28 Thread Yuval Mintz
In strucuture reflecting the AEU hw block some entries
represent multiple HW bits, and the associated name is in fact
a pattern.
Today, whenever such an attention would be asserted the resulted
prints would show the pattern string instead of indicating which
of the possible bits was set.

Signed-off-by: Yuval Mintz 
---
 drivers/net/ethernet/qlogic/qed/qed_int.c | 38 +++
 1 file changed, 33 insertions(+), 5 deletions(-)

diff --git a/drivers/net/ethernet/qlogic/qed/qed_int.c 
b/drivers/net/ethernet/qlogic/qed/qed_int.c
index de6f60c..e19a002 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_int.c
+++ b/drivers/net/ethernet/qlogic/qed/qed_int.c
@@ -749,19 +749,19 @@ static void qed_int_attn_print(struct qed_hwfn *p_hwfn,
 qed_int_deassertion_aeu_bit(struct qed_hwfn *p_hwfn,
struct aeu_invert_reg_bit *p_aeu,
u32 aeu_en_reg,
-   u32 bitmask)
+   const char *p_bit_name, u32 bitmask)
 {
bool b_fatal = false;
int rc = -EINVAL;
u32 val;
 
DP_INFO(p_hwfn, "Deasserted attention `%s'[%08x]\n",
-   p_aeu->bit_name, bitmask);
+   p_bit_name, bitmask);
 
/* Call callback before clearing the interrupt status */
if (p_aeu->cb) {
DP_INFO(p_hwfn, "`%s (attention)': Calling Callback function\n",
-   p_aeu->bit_name);
+   p_bit_name);
rc = p_aeu->cb(p_hwfn);
}
 
@@ -782,7 +782,7 @@ static void qed_int_attn_print(struct qed_hwfn *p_hwfn,
val = qed_rd(p_hwfn, p_hwfn->p_dpc_ptt, aeu_en_reg);
qed_wr(p_hwfn, p_hwfn->p_dpc_ptt, aeu_en_reg, (val & ~bitmask));
DP_INFO(p_hwfn, "`%s' - Disabled future attentions\n",
-   p_aeu->bit_name);
+   p_bit_name);
 
 out:
return rc;
@@ -894,8 +894,8 @@ static int qed_int_deassertion(struct qed_hwfn  *p_hwfn,
 * previous assertion.
 */
for (j = 0, bit_idx = 0; bit_idx < 32; j++) {
+   long unsigned int bitmask;
u8 bit, bit_len;
-   u32 bitmask;
 
p_aeu = &sb_attn_sw->p_aeu_desc[i].bits[j];
p_aeu = qed_int_aeu_translate(p_hwfn, p_aeu);
@@ -909,11 +909,39 @@ static int qed_int_deassertion(struct qed_hwfn  *p_hwfn,
}
 
bitmask = bits & (((1 << bit_len) - 1) << bit);
+   bitmask >>= bit;
+
if (bitmask) {
+   u32 flags = p_aeu->flags;
+   char bit_name[30];
+   u8 num;
+
+   num = (u8)find_first_bit(&bitmask,
+bit_len);
+
+   /* Some bits represent more than a
+* a single interrupt. Correctly print
+* their name.
+*/
+   if (ATTENTION_LENGTH(flags) > 2 ||
+   ((flags & ATTENTION_PAR_INT) &&
+ATTENTION_LENGTH(flags) > 1))
+   snprintf(bit_name, 30,
+p_aeu->bit_name, num);
+   else
+   strncpy(bit_name,
+   p_aeu->bit_name, 30);
+
+   /* We now need to pass bitmask in its
+* correct position.
+*/
+   bitmask <<= bit;
+
/* Handle source of the attention */
qed_int_deassertion_aeu_bit(p_hwfn,
p_aeu,
aeu_en,
+   bit_name,
bitmask);
}
 
-- 
1.9.3



[PATCH net-next 09/10] qed: Mask parities after occurance

2017-05-28 Thread Yuval Mintz
Parities might exhibit a flood behavior since we re-enable the
attention line without preventing the parity from re-triggering the
assertion.
Mask the source in AEU until the parity would be handled.

Signed-off-by: Yuval Mintz 
---
 drivers/net/ethernet/qlogic/qed/qed_int.c | 36 ---
 1 file changed, 23 insertions(+), 13 deletions(-)

diff --git a/drivers/net/ethernet/qlogic/qed/qed_int.c 
b/drivers/net/ethernet/qlogic/qed/qed_int.c
index e19a002..6ac6d80 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_int.c
+++ b/drivers/net/ethernet/qlogic/qed/qed_int.c
@@ -793,16 +793,18 @@ static void qed_int_attn_print(struct qed_hwfn *p_hwfn,
  *
  * @param p_hwfn
  * @param p_aeu - descriptor of an AEU bit which caused the parity
+ * @param aeu_en_reg - address of the AEU enable register
  * @param bit_index
  */
 static void qed_int_deassertion_parity(struct qed_hwfn *p_hwfn,
   struct aeu_invert_reg_bit *p_aeu,
-  u8 bit_index)
+  u32 aeu_en_reg, u8 bit_index)
 {
-   u32 block_id = p_aeu->block_index;
+   u32 block_id = p_aeu->block_index, mask, val;
 
-   DP_INFO(p_hwfn->cdev, "%s[%d] parity attention is set\n",
-   p_aeu->bit_name, bit_index);
+   DP_NOTICE(p_hwfn->cdev,
+ "%s parity attention is set [address 0x%08x, bit %d]\n",
+ p_aeu->bit_name, aeu_en_reg, bit_index);
 
if (block_id != MAX_BLOCK_ID) {
qed_int_attn_print(p_hwfn, block_id, ATTN_TYPE_PARITY, false);
@@ -815,6 +817,13 @@ static void qed_int_deassertion_parity(struct qed_hwfn 
*p_hwfn,
   ATTN_TYPE_PARITY, false);
}
}
+
+   /* Prevent this parity error from being re-asserted */
+   mask = ~BIT(bit_index);
+   val = qed_rd(p_hwfn, p_hwfn->p_dpc_ptt, aeu_en_reg);
+   qed_wr(p_hwfn, p_hwfn->p_dpc_ptt, aeu_en_reg, val & mask);
+   DP_INFO(p_hwfn, "`%s' - Disabled future parity errors\n",
+   p_aeu->bit_name);
 }
 
 /**
@@ -829,7 +838,7 @@ static int qed_int_deassertion(struct qed_hwfn  *p_hwfn,
   u16 deasserted_bits)
 {
struct qed_sb_attn_info *sb_attn_sw = p_hwfn->p_sb_attn;
-   u32 aeu_inv_arr[NUM_ATTN_REGS], aeu_mask;
+   u32 aeu_inv_arr[NUM_ATTN_REGS], aeu_mask, aeu_en, en;
u8 i, j, k, bit_idx;
int rc = 0;
 
@@ -846,11 +855,11 @@ static int qed_int_deassertion(struct qed_hwfn  *p_hwfn,
/* Find parity attentions first */
for (i = 0; i < NUM_ATTN_REGS; i++) {
struct aeu_invert_reg *p_aeu = &sb_attn_sw->p_aeu_desc[i];
-   u32 en = qed_rd(p_hwfn, p_hwfn->p_dpc_ptt,
-   MISC_REG_AEU_ENABLE1_IGU_OUT_0 +
-   i * sizeof(u32));
u32 parities;
 
+   aeu_en = MISC_REG_AEU_ENABLE1_IGU_OUT_0 + i * sizeof(u32);
+   en = qed_rd(p_hwfn, p_hwfn->p_dpc_ptt, aeu_en);
+
/* Skip register in which no parity bit is currently set */
parities = sb_attn_sw->parity_mask[i] & aeu_inv_arr[i] & en;
if (!parities)
@@ -862,7 +871,7 @@ static int qed_int_deassertion(struct qed_hwfn  *p_hwfn,
if (qed_int_is_parity_flag(p_hwfn, p_bit) &&
!!(parities & BIT(bit_idx)))
qed_int_deassertion_parity(p_hwfn, p_bit,
-  bit_idx);
+  aeu_en, bit_idx);
 
bit_idx += ATTENTION_LENGTH(p_bit->flags);
}
@@ -877,10 +886,11 @@ static int qed_int_deassertion(struct qed_hwfn  *p_hwfn,
continue;
 
for (i = 0; i < NUM_ATTN_REGS; i++) {
-   u32 aeu_en = MISC_REG_AEU_ENABLE1_IGU_OUT_0 +
-i * sizeof(u32) +
-k * sizeof(u32) * NUM_ATTN_REGS;
-   u32 en, bits;
+   u32 bits;
+
+   aeu_en = MISC_REG_AEU_ENABLE1_IGU_OUT_0 +
+i * sizeof(u32) +
+k * sizeof(u32) * NUM_ATTN_REGS;
 
en = qed_rd(p_hwfn, p_hwfn->p_dpc_ptt, aeu_en);
bits = aeu_inv_arr[i] & en;
-- 
1.9.3



[PATCH net-next 10/10] qed: Cache alignemnt padding to match host

2017-05-28 Thread Yuval Mintz
Improve PCI performance by adjusting padding sizes to match those of the
host machine's cacheline.

Signed-off-by: Yuval Mintz 
---
 drivers/net/ethernet/qlogic/qed/qed_dev.c  | 15 +--
 drivers/net/ethernet/qlogic/qed/qed_reg_addr.h |  1 +
 2 files changed, 14 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/qlogic/qed/qed_dev.c 
b/drivers/net/ethernet/qlogic/qed/qed_dev.c
index 072d950..d73e3c2 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_dev.c
+++ b/drivers/net/ethernet/qlogic/qed/qed_dev.c
@@ -1227,6 +1227,10 @@ static void qed_init_cache_line_size(struct qed_hwfn 
*p_hwfn,
L1_CACHE_BYTES, wr_mbs);
 
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,
@@ -1433,8 +1437,15 @@ enum QED_ROCE_EDPM_MODE {
 static int qed_hw_init_port(struct qed_hwfn *p_hwfn,
struct qed_ptt *p_ptt, int hw_mode)
 {
-   return qed_init_run(p_hwfn, p_ptt, PHASE_PORT,
-   p_hwfn->port_id, hw_mode);
+   int rc = 0;
+
+   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,
diff --git a/drivers/net/ethernet/qlogic/qed/qed_reg_addr.h 
b/drivers/net/ethernet/qlogic/qed/qed_reg_addr.h
index 6abf918..67172d7 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_reg_addr.h
+++ b/drivers/net/ethernet/qlogic/qed/qed_reg_addr.h
@@ -1559,6 +1559,7 @@
 #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_F4_F0_K2 0x2aafa4UL
+#define PGLUE_B_REG_MASTER_WRITE_PAD_ENABLE 0x2aae30UL
 #define NIG_REG_TSGEN_FREECNT_UPDATE_K2 0x509008UL
 #define CNIG_REG_NIG_PORT0_CONF_K2 0x218200UL
 
-- 
1.9.3



[PATCH net-next 04/10] qed: QL41xxx VF MSI-x table

2017-05-28 Thread Yuval Mintz
The QL41xxx adapters' PCI allows a single configuration for the
MSI-x table size of all child VFs of a given PF.
The existing code wouldn't cause the management firmware to set
that value, meaning the VFs would retain the default MSI-x table
size.

Introduce a new scheme so that whenever a VF is enabled, driver
would set the number of MSI-x to be the maximum over the various
VFs' needs.

Signed-off-by: Yuval Mintz 
---
 drivers/net/ethernet/qlogic/qed/qed_hsi.h   |  3 ++-
 drivers/net/ethernet/qlogic/qed/qed_mcp.c   | 35 +++--
 drivers/net/ethernet/qlogic/qed/qed_sriov.c | 32 +-
 3 files changed, 66 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ethernet/qlogic/qed/qed_hsi.h 
b/drivers/net/ethernet/qlogic/qed/qed_hsi.h
index 802c162..f610e52 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_hsi.h
+++ b/drivers/net/ethernet/qlogic/qed/qed_hsi.h
@@ -11477,6 +11477,7 @@ struct public_drv_mb {
 #define DRV_MSG_CODE_INITIATE_PF_FLR0x0201
 #define DRV_MSG_CODE_VF_DISABLED_DONE  0xc000
 #define DRV_MSG_CODE_CFG_VF_MSIX   0xc001
+#define DRV_MSG_CODE_CFG_PF_VFS_MSIX   0xc002
 #define DRV_MSG_CODE_NVM_GET_FILE_ATT  0x0003
 #define DRV_MSG_CODE_NVM_READ_NVRAM0x0005
 #define DRV_MSG_CODE_MCP_RESET 0x0009
@@ -11640,7 +11641,7 @@ struct public_drv_mb {
 
 #define FW_MSG_CODE_OS_WOL_SUPPORTED0x0080
 #define FW_MSG_CODE_OS_WOL_NOT_SUPPORTED0x0081
-
+#define FW_MSG_CODE_DRV_CFG_PF_VFS_MSIX_DONE   0x0087
 #define FW_MSG_SEQ_NUMBER_MASK 0x
 
u32 fw_mb_param;
diff --git a/drivers/net/ethernet/qlogic/qed/qed_mcp.c 
b/drivers/net/ethernet/qlogic/qed/qed_mcp.c
index fc49c75e..24c9b71 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_mcp.c
+++ b/drivers/net/ethernet/qlogic/qed/qed_mcp.c
@@ -1801,8 +1801,9 @@ int qed_mcp_get_flash_size(struct qed_hwfn *p_hwfn,
return 0;
 }
 
-int qed_mcp_config_vf_msix(struct qed_hwfn *p_hwfn,
-  struct qed_ptt *p_ptt, u8 vf_id, u8 num)
+static int
+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;
int rc;
@@ -1832,6 +1833,36 @@ int qed_mcp_config_vf_msix(struct qed_hwfn *p_hwfn,
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
 qed_mcp_send_drv_version(struct qed_hwfn *p_hwfn,
 struct qed_ptt *p_ptt,
diff --git a/drivers/net/ethernet/qlogic/qed/qed_sriov.c 
b/drivers/net/ethernet/qlogic/qed/qed_sriov.c
index 71e392f..b6bda45d 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_sriov.c
+++ b/drivers/net/ethernet/qlogic/qed/qed_sriov.c
@@ -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);
 }
 
+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,
struct qed_ptt *p_ptt,
  

[PATCH net-next 05/10] qed: Support dynamic s-tag change

2017-05-28 Thread Yuval Mintz
In case management firmware indicates a change in the used S-tag,
propagate the configuration to HW and FW.

Signed-off-by: Yuval Mintz 
---
 drivers/net/ethernet/qlogic/qed/qed_hsi.h |  4 +++-
 drivers/net/ethernet/qlogic/qed/qed_mcp.c | 26 +++
 drivers/net/ethernet/qlogic/qed/qed_reg_addr.h|  2 ++
 drivers/net/ethernet/qlogic/qed/qed_sp.h  |  9 
 drivers/net/ethernet/qlogic/qed/qed_sp_commands.c | 24 +
 5 files changed, 64 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/qlogic/qed/qed_hsi.h 
b/drivers/net/ethernet/qlogic/qed/qed_hsi.h
index f610e52..24b1458 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_hsi.h
+++ b/drivers/net/ethernet/qlogic/qed/qed_hsi.h
@@ -11474,6 +11474,7 @@ struct public_drv_mb {
 
 #define DRV_MSG_CODE_BW_UPDATE_ACK 0x3200
 #define DRV_MSG_CODE_NIG_DRAIN 0x3000
+#define DRV_MSG_CODE_S_TAG_UPDATE_ACK  0x3b00
 #define DRV_MSG_CODE_INITIATE_PF_FLR0x0201
 #define DRV_MSG_CODE_VF_DISABLED_DONE  0xc000
 #define DRV_MSG_CODE_CFG_VF_MSIX   0xc001
@@ -11634,6 +11635,7 @@ struct public_drv_mb {
 #define FW_MSG_CODE_RESOURCE_ALLOC_OK   0x3400
 #define FW_MSG_CODE_RESOURCE_ALLOC_UNKNOWN  0x3500
 #define FW_MSG_CODE_RESOURCE_ALLOC_DEPRECATED   0x3600
+#define FW_MSG_CODE_S_TAG_UPDATE_ACK_DONE  0x3b00
 #define FW_MSG_CODE_DRV_CFG_VF_MSIX_DONE   0xb001
 
 #define FW_MSG_CODE_NVM_OK 0x0001
@@ -11681,7 +11683,7 @@ enum MFW_DRV_MSG_TYPE {
MFW_DRV_MSG_DCBX_OPERATIONAL_MIB_UPDATED,
MFW_DRV_MSG_RESERVED4,
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_FCOE_STATS,
MFW_DRV_MSG_GET_ISCSI_STATS,
diff --git a/drivers/net/ethernet/qlogic/qed/qed_mcp.c 
b/drivers/net/ethernet/qlogic/qed/qed_mcp.c
index 24c9b71..31c88e1 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_mcp.c
+++ b/drivers/net/ethernet/qlogic/qed/qed_mcp.c
@@ -1398,6 +1398,28 @@ static void qed_mcp_update_bw(struct qed_hwfn *p_hwfn, 
struct qed_ptt *p_ptt)
¶m);
 }
 
+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, ¶m);
+}
+
 int qed_mcp_handle_events(struct qed_hwfn *p_hwfn,
  struct qed_ptt *p_ptt)
 {
@@ -1453,6 +1475,10 @@ int qed_mcp_handle_events(struct qed_hwfn *p_hwfn,
case MFW_DRV_MSG_BW_UPDATE:
qed_mcp_update_bw(p_hwfn, p_ptt);
break;
+   case MFW_DRV_MSG_S_TAG_UPDATE:
+   qed_mcp_update_stag(p_hwfn, p_ptt);
+   break;
+   break;
default:
DP_INFO(p_hwfn, "Unimplemented MFW message %d\n", i);
rc = -EINVAL;
diff --git a/drivers/net/ethernet/qlogic/qed/qed_reg_addr.h 
b/drivers/net/ethernet/qlogic/qed/qed_reg_addr.h
index f14772b..6abf918 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_reg_addr.h
+++ b/drivers/net/ethernet/qlogic/qed/qed_reg_addr.h
@@ -242,6 +242,8 @@
0x50196cUL
 #define NIG_REG_LLH_CLS_TYPE_DUALMODE \
0x501964UL
+#define NIG_REG_LLH_FUNC_TAG_EN 0x5019b0UL
+#define NIG_REG_LLH_FUNC_TAG_VALUE 0x5019d0UL
 #define NIG_REG_LLH_FUNC_FILTER_VALUE \
0x501a00UL
 #define NIG_REG_LLH_FUNC_FILTER_VALUE_SIZE \
diff --git a/drivers/net/ethernet/qlogic/qed/qed_sp.h 
b/drivers/net/ethernet/qlogic/qed/qed_sp.h
index ef77de4..b9464f3 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_sp.h
+++ b/drivers/net/ethernet/qlogic/qed/qed_sp.h
@@ -418,6 +418,15 @@ int qed_sp_pf_start(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
  *
  * This ramrod is sent to close a Physical Function (PF). It is the last ramrod
diff --git a/drivers/net/etherne

[PATCH net-next 06/10] qed: Get rid of the attention-arrays

2017-05-28 Thread Yuval Mintz
We have almost all the necessary information regarding attentions
in the logic employed for taking register dumps.
Add some more and get rid of the seperate implementation we have today
for identifying & printing various attention sources.

Signed-off-by: Yuval Mintz 
---
 drivers/net/ethernet/qlogic/qed/qed_debug.c |  258 ++
 drivers/net/ethernet/qlogic/qed/qed_hsi.h   |   37 +
 drivers/net/ethernet/qlogic/qed/qed_int.c   | 1312 +--
 3 files changed, 320 insertions(+), 1287 deletions(-)

diff --git a/drivers/net/ethernet/qlogic/qed/qed_debug.c 
b/drivers/net/ethernet/qlogic/qed/qed_debug.c
index 87a1389..b7f820d 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_debug.c
+++ b/drivers/net/ethernet/qlogic/qed/qed_debug.c
@@ -5352,8 +5352,85 @@ enum dbg_status qed_dbg_fw_asserts_dump(struct qed_hwfn 
*p_hwfn,
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 **/
 
+struct block_info {
+   const char *name;
+   enum block_id id;
+};
+
 struct mcp_trace_format {
u32 data;
 #define MCP_TRACE_FORMAT_MODULE_MASK   0x
@@ -5534,6 +5611,97 @@ struct user_dbg_array {
 static struct user_dbg_array
 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},
+ 

[PATCH net-next 07/10] qed: Diffrentiate adapter-specific attentions

2017-05-28 Thread Yuval Mintz
There are 4 attention bits in AEU that have different meaning
for QL45xxx and QL41xxx adapters.

Instead of doing a massive infrastructure change in favor of these
bits, we implement a point fix where only those four would change
meaning dependent on the adapter involved.

Signed-off-by: Yuval Mintz 
---
 drivers/net/ethernet/qlogic/qed/qed_int.c | 80 ++-
 1 file changed, 69 insertions(+), 11 deletions(-)

diff --git a/drivers/net/ethernet/qlogic/qed/qed_int.c 
b/drivers/net/ethernet/qlogic/qed/qed_int.c
index 7f4f8e7..de6f60c 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_int.c
+++ b/drivers/net/ethernet/qlogic/qed/qed_int.c
@@ -90,6 +90,12 @@ struct aeu_invert_reg_bit {
 /* Multiple bits start with this offset */
 #define ATTENTION_OFFSET_MASK   (0x000ff000)
 #define ATTENTION_OFFSET_SHIFT  (12)
+
+#define ATTENTION_BB_MASK   (0x0070)
+#define ATTENTION_BB_SHIFT  (20)
+#define ATTENTION_BB(value) (value << ATTENTION_BB_SHIFT)
+#define ATTENTION_BB_DIFFERENT  BIT(23)
+
unsigned int flags;
 
/* Callback to call if attention will be triggered */
@@ -381,6 +387,25 @@ static int qed_dorq_attn_cb(struct qed_hwfn *p_hwfn)
return -EINVAL;
 }
 
+/* Instead of major changes to the data-structure, we have a some 'special'
+ * identifiers for sources that changed meaning between adapters.
+ */
+enum aeu_invert_reg_special_type {
+   AEU_INVERT_REG_SPECIAL_CNIG_0,
+   AEU_INVERT_REG_SPECIAL_CNIG_1,
+   AEU_INVERT_REG_SPECIAL_CNIG_2,
+   AEU_INVERT_REG_SPECIAL_CNIG_3,
+   AEU_INVERT_REG_SPECIAL_MAX,
+};
+
+static struct aeu_invert_reg_bit
+aeu_descs_special[AEU_INVERT_REG_SPECIAL_MAX] = {
+   {"CNIG port 0", ATTENTION_SINGLE, NULL, BLOCK_CNIG},
+   {"CNIG port 1", ATTENTION_SINGLE, NULL, BLOCK_CNIG},
+   {"CNIG port 2", ATTENTION_SINGLE, NULL, BLOCK_CNIG},
+   {"CNIG port 3", ATTENTION_SINGLE, NULL, BLOCK_CNIG},
+};
+
 /* Notice aeu_invert_reg must be defined in the same order of bits as HW;  */
 static struct aeu_invert_reg aeu_descs[NUM_ATTN_REGS] = {
{
@@ -427,8 +452,22 @@ static int qed_dorq_attn_cb(struct qed_hwfn *p_hwfn)
 (33 << ATTENTION_OFFSET_SHIFT), NULL, MAX_BLOCK_ID},
{"General Attention 35", ATTENTION_SINGLE,
 NULL, MAX_BLOCK_ID},
-   {"CNIG port %d", (4 << ATTENTION_LENGTH_SHIFT),
-NULL, BLOCK_CNIG},
+   {"NWS Parity",
+ATTENTION_PAR | ATTENTION_BB_DIFFERENT |
+ATTENTION_BB(AEU_INVERT_REG_SPECIAL_CNIG_0),
+NULL, BLOCK_NWS},
+   {"NWS Interrupt",
+ATTENTION_SINGLE | ATTENTION_BB_DIFFERENT |
+ATTENTION_BB(AEU_INVERT_REG_SPECIAL_CNIG_1),
+NULL, BLOCK_NWS},
+   {"NWM Parity",
+ATTENTION_PAR | ATTENTION_BB_DIFFERENT |
+ATTENTION_BB(AEU_INVERT_REG_SPECIAL_CNIG_2),
+NULL, BLOCK_NWM},
+   {"NWM Interrupt",
+ATTENTION_SINGLE | ATTENTION_BB_DIFFERENT |
+ATTENTION_BB(AEU_INVERT_REG_SPECIAL_CNIG_3),
+NULL, BLOCK_NWM},
{"MCP CPU", ATTENTION_SINGLE,
 qed_mcp_attn_cb, MAX_BLOCK_ID},
{"MCP Watchdog timer", ATTENTION_SINGLE,
@@ -566,6 +605,27 @@ static int qed_dorq_attn_cb(struct qed_hwfn *p_hwfn)
},
 };
 
+static struct aeu_invert_reg_bit *
+qed_int_aeu_translate(struct qed_hwfn *p_hwfn,
+ struct aeu_invert_reg_bit *p_bit)
+{
+   if (!QED_IS_BB(p_hwfn->cdev))
+   return p_bit;
+
+   if (!(p_bit->flags & ATTENTION_BB_DIFFERENT))
+   return p_bit;
+
+   return &aeu_descs_special[(p_bit->flags & ATTENTION_BB_MASK) >>
+ ATTENTION_BB_SHIFT];
+}
+
+static bool qed_int_is_parity_flag(struct qed_hwfn *p_hwfn,
+  struct aeu_invert_reg_bit *p_bit)
+{
+   return !!(qed_int_aeu_translate(p_hwfn, p_bit)->flags &
+  ATTENTION_PARITY);
+}
+
 #define ATTN_STATE_BITS (0xfff)
 #define ATTN_BITS_MASKABLE  (0x3ff)
 struct qed_sb_attn_info {
@@ -799,7 +859,7 @@ static int qed_int_deassertion(struct qed_hwfn  *p_hwfn,
for (j = 0, bit_idx = 0; bit_idx < 32; j++) {
struct aeu_invert_reg_bit *p_bit = &p_aeu->bits[j];
 
-   if ((p_bit->flags & ATTENTION_PARITY) &&
+   if (qed_int_is_parity_flag(p_hwfn, p_bit) &&
!!(parities & BIT(bit_idx)))
qed_int_deassertion_parity(p_hwfn, p_bit,
   bit_id

[PATCH net-next 03/10] qed: Don't inherit RoCE DCBx for V2

2017-05-28 Thread Yuval Mintz
From: Sudarsana Reddy Kalluru 

Older firmware used by device didn't distinguish between RoCE and RoCE
V2 from DCBx configuration perspective, and as a result we've used to
take a the RoCE-related configuration and apply to it for both.

Since we now support configuring each its own values, there's no reason
to reflect [& configure] that both are using the same.

Signed-off-by: Sudarsana Reddy Kalluru 
Signed-off-by: Yuval Mintz 
---
 drivers/net/ethernet/qlogic/qed/qed_dcbx.c | 11 ---
 1 file changed, 11 deletions(-)

diff --git a/drivers/net/ethernet/qlogic/qed/qed_dcbx.c 
b/drivers/net/ethernet/qlogic/qed/qed_dcbx.c
index af34638..e2a62c0 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_dcbx.c
+++ b/drivers/net/ethernet/qlogic/qed/qed_dcbx.c
@@ -310,17 +310,6 @@ static bool qed_dcbx_roce_v2_tlv(u32 app_info_bitmap, u16 
proto_id, bool ieee)
}
}
 
-   /* 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
 * with default info when corresponding APP TLV's are not detected.
 * The enabled field has a different logic for ethernet as only for
-- 
1.9.3



[PATCH net-next 01/10] qed: Add missing static/local dcbx info

2017-05-28 Thread Yuval Mintz
From: Sudarsana Reddy Kalluru 

Some getters are not getting filled with the correct information
regarding local DCBx.

Fixes: 49632b5822ea ("qed: Add support for static dcbx.")
Signed-off-by: Sudarsana Reddy Kalluru 
Signed-off-by: Yuval Mintz 
---
 drivers/net/ethernet/qlogic/qed/qed_dcbx.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/qlogic/qed/qed_dcbx.c 
b/drivers/net/ethernet/qlogic/qed/qed_dcbx.c
index b83fe1d..efe309e 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_dcbx.c
+++ b/drivers/net/ethernet/qlogic/qed/qed_dcbx.c
@@ -1460,7 +1460,7 @@ static u8 qed_dcbnl_getcap(struct qed_dev *cdev, int 
capid, u8 *cap)
break;
case DCB_CAP_ATTR_DCBX:
*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;
default:
*cap = false;
@@ -1534,6 +1534,8 @@ static u8 qed_dcbnl_getdcbx(struct qed_dev *cdev)
mode |= DCB_CAP_DCBX_VER_IEEE;
if (dcbx_info->operational.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);
kfree(dcbx_info);
-- 
1.9.3



[PATCH net-next 02/10] qed: Correct DCBx update scheme

2017-05-28 Thread Yuval Mintz
From: Sudarsana Reddy Kalluru 

Instead of using a boolean value that propagates to FW configuration,
use the proper firmware HSI values.

Signed-off-by: Sudarsana Reddy Kalluru 
Signed-off-by: Yuval Mintz 
---
 drivers/net/ethernet/qlogic/qed/qed_dcbx.c | 15 ---
 drivers/net/ethernet/qlogic/qed/qed_dcbx.h |  2 +-
 2 files changed, 9 insertions(+), 8 deletions(-)

diff --git a/drivers/net/ethernet/qlogic/qed/qed_dcbx.c 
b/drivers/net/ethernet/qlogic/qed/qed_dcbx.c
index efe309e..af34638 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_dcbx.c
+++ b/drivers/net/ethernet/qlogic/qed/qed_dcbx.c
@@ -191,17 +191,19 @@ static bool qed_dcbx_roce_v2_tlv(u32 app_info_bitmap, u16 
proto_id, bool ieee)
 qed_dcbx_set_params(struct qed_dcbx_results *p_data,
struct qed_hw_info *p_info,
bool enable,
-   bool update,
u8 prio,
u8 tc,
enum dcbx_protocol_type type,
enum qed_pci_personality personality)
 {
/* PF update ramrod data */
-   p_data->arr[type].update = update;
p_data->arr[type].enable = enable;
p_data->arr[type].priority = prio;
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 */
if (p_info->personality == personality)
@@ -213,7 +215,6 @@ static bool qed_dcbx_roce_v2_tlv(u32 app_info_bitmap, u16 
proto_id, bool ieee)
 qed_dcbx_update_app_info(struct qed_dcbx_results *p_data,
 struct qed_hwfn *p_hwfn,
 bool enable,
-bool update,
 u8 prio, u8 tc, enum dcbx_protocol_type type)
 {
struct qed_hw_info *p_info = &p_hwfn->hw_info;
@@ -231,7 +232,7 @@ static bool qed_dcbx_roce_v2_tlv(u32 app_info_bitmap, u16 
proto_id, bool ieee)
personality = qed_dcbx_app_update[i].personality;
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);
}
 }
@@ -304,7 +305,7 @@ static bool qed_dcbx_roce_v2_tlv(u32 app_info_bitmap, u16 
proto_id, bool ieee)
 */
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);
}
}
@@ -332,8 +333,8 @@ static bool qed_dcbx_roce_v2_tlv(u32 app_info_bitmap, u16 
proto_id, bool ieee)
if (p_data->arr[type].update)
continue;
 
-   enable = !(type == DCBX_PROTOCOL_ETH);
-   qed_dcbx_update_app_info(p_data, p_hwfn, enable, true,
+   enable = (type == DCBX_PROTOCOL_ETH) ? false : !!dcbx_version;
+   qed_dcbx_update_app_info(p_data, p_hwfn, enable,
 priority, tc, type);
}
 
diff --git a/drivers/net/ethernet/qlogic/qed/qed_dcbx.h 
b/drivers/net/ethernet/qlogic/qed/qed_dcbx.h
index 414e262..5feb90e 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_dcbx.h
+++ b/drivers/net/ethernet/qlogic/qed/qed_dcbx.h
@@ -52,7 +52,7 @@ enum qed_mib_read_type {
 
 struct qed_dcbx_app_data {
bool enable;/* DCB enabled */
-   bool update;/* Update indication */
+   u8 update;  /* Update indication */
u8 priority;/* Priority */
u8 tc;  /* Traffic Class */
 };
-- 
1.9.3



[PATCH net-next 00/10] qed: DCBx and Attentions series

2017-05-28 Thread Yuval Mintz
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.

Dave,

Please consider applying this series to `net-next'.

Thanks,
Yuval

Sudarsana Reddy Kalluru (3):
  qed: Add missing static/local dcbx info
  qed: Correct DCBx update scheme
  qed: Don't inherit RoCE DCBx for V2

Yuval Mintz (7):
  qed: QL41xxx VF MSI-x table
  qed: Support dynamic s-tag change
  qed: Get rid of the attention-arrays
  qed: Diffrentiate adapter-specific attentions
  qed: Print multi-bit attentions properly
  qed: Mask parities after occurance
  qed: Cache alignemnt padding to match host

 drivers/net/ethernet/qlogic/qed/qed_dcbx.c|   30 +-
 drivers/net/ethernet/qlogic/qed/qed_dcbx.h|2 +-
 drivers/net/ethernet/qlogic/qed/qed_debug.c   |  258 
 drivers/net/ethernet/qlogic/qed/qed_dev.c |   15 +-
 drivers/net/ethernet/qlogic/qed/qed_hsi.h |   44 +-
 drivers/net/ethernet/qlogic/qed/qed_int.c | 1466 +++--
 drivers/net/ethernet/qlogic/qed/qed_mcp.c |   61 +-
 drivers/net/ethernet/qlogic/qed/qed_reg_addr.h|3 +
 drivers/net/ethernet/qlogic/qed/qed_sp.h  |9 +
 drivers/net/ethernet/qlogic/qed/qed_sp_commands.c |   24 +
 drivers/net/ethernet/qlogic/qed/qed_sriov.c   |   32 +-
 11 files changed, 601 insertions(+), 1343 deletions(-)

-- 
1.9.3



RE: [PATCH net-next 02/12] nfp: set driver VF limit

2017-05-28 Thread Mintz, Yuval
>   pf->limit_vfs = nfp_rtsym_read_le(pf->cpp, "nfd_vf_cfg_max_vfs",
> &err);
>   if (!err)
> - return;
> + return pci_sriov_set_totalvfs(pf->pdev, pf->limit_vfs);

While you're at it, If you're going to enforce the limit at the PCI level,
shouldn't you retire 'limit_vfs' altogether?

BTW, under which conditions would you expect to find a difference
in the maximal number of VFs?


Error with printk and bpf_trace_printk

2017-05-28 Thread Adel Fuchs
Hi,

I have a working eBPF program, and I'm trying to add outputs to it.
I'm not able to use both printk and bpf_trace_printk functions. I get
this error:

ELF contains non-map related relo data in entry 0 pointing to section
8! Compiler bug?!

Prog section 'ingress' rejected: Invalid argument (22)!
 - Type: 3
 - Instructions: 16 (0 over limit)
 - License:  GPL

Verifier analysis:

0: (bf) r6 = r1
1: (18) r1 = 0x0
3: (85) call bpf_unspec#0
unknown func bpf_unspec#0

Error fetching program/map!
Failed to retrieve (e)BPF data!

Are there certain "includes" that I need to add?
In addition, I'm not sure I'm using the function correctly. I just
wrote: printk("hi")

Thanks!
Adel


GREETINGS BELOVED

2017-05-28 Thread mis.sbort...@ono.com
GREETINGS BELOVED

I AM BORTE ,I WAS  DIAGNOSE WITH OVARIAN CANCER,WHICH DOCTORS HAVE 
CONFIRMED THAT I HAVE ONLY FEW WEEKS TO LIVE, SO I HAVE DECIDED TO 
DONATE EVERYTHING I HAVE TO THE ORPHANAGE AND THE POOR WIDOWS THROUGH 
YOU .PLEASE KINDLY REPLY  ME ONLY ON MY  EMAIL ADDRES HERE 
(missboteogo...@gmail.com)  AS SOON AS POSIBLE TO ENABLE ME GIVE YOU 
MORE INFORMATION ABOUT MYSELF AND HOW TO GO ABOUT IT .


THANKS 

MISS BORTE


Re: [for-next 4/6] net/mlx5: FPGA, Add basic support for Innova

2017-05-28 Thread Or Gerlitz
On Fri, May 26, 2017 at 8:56 PM, Alexei Starovoitov
 wrote:
> On Fri, May 26, 2017 at 11:59:26AM +0300, Saeed Mahameed wrote:

>> But i agree with you some serious API brainstorming should be
>> considered, but not at this stage, this patch only tells the ConnectX card
>> (if you have FPGA, please enable it).

> serious api discussion needs be done before things like eswitch, fpga
> exposed to users otherwise we end up in the eswitch situation that
> drops packets based on its own invisible logic, but with hidden fpga
> it will be even more obscure.


Alexei,

ACK for your comment on e-switch, what we call the legacy mode for SRIOV in
Linux was a big mistake.

As you know, since 4.8 we're @ MLNX are working to fix it... we introduced a
model for VF port representors which has set the foundations for
e-switch data-path
to be programmed as an offload for kernel SW switching. We also
introduced the code
to offload TC flower base data-path and support that in for both
switch (Spectrum) ASIC
(mlxsw driver) and NIC ASIC (mlx5 driver)

Or.


vxlan: use after free error

2017-05-28 Thread Mark Bloch
Hi,

I'm getting a KASAN (use after free) error when doing:

ip link add vxlan1 type vxlan external
ip link set vxlan1 up
ip link set vxlan1 down
ip link del vxlan1

[  600.495331] 
==
[  600.509678] BUG: KASAN: use-after-free in vxlan_dellink+0x33d/0x390 [vxlan]
[  600.523083] Write of size 8 at addr 88056ce54018 by task ip/16216

[  600.542239] CPU: 12 PID: 16216 Comm: ip Not tainted 4.12.0-rc2 #24
[  600.554442] Hardware name: HP ProLiant DL380p Gen8, BIOS P70 08/02/2014
[  600.567013] Call Trace:
[  600.574742]  dump_stack+0x63/0x89
[  600.583458]  print_address_description+0x78/0x290
[  600.593612]  kasan_report+0x257/0x370
[  600.602857]  ? vxlan_dellink+0x33d/0x390 [vxlan]
[  600.612765]  __asan_report_store8_noabort+0x1c/0x20
[  600.622937]  vxlan_dellink+0x33d/0x390 [vxlan]
[  600.632636]  rtnl_delete_link+0xb9/0x110
[  600.641542]  ? rtnl_af_register+0xc0/0xc0
[  600.650898]  ? nla_parse+0x36/0x260
[  600.659558]  rtnl_dellink+0x1fb/0x780
[  600.668350]  ? unwind_dump+0x360/0x360
[  600.676802]  ? rtnl_bridge_getlink+0x620/0x620
[  600.686036]  ? __module_text_address+0x18/0x150
[  600.695300]  ? ns_capable_common+0xd4/0x110
[  600.704157]  ? sock_sendmsg+0xba/0xf0
[  600.712264]  ? ns_capable+0x13/0x20
[  600.720201]  ? __netlink_ns_capable+0xcc/0x100
[  600.729131]  rtnetlink_rcv_msg+0x255/0x6c0
[  600.737464]  ? rtnl_newlink+0x1640/0x1640
[  600.745604]  ? __read_once_size_nocheck.constprop.7+0x20/0x20
[  600.755882]  ? __read_once_size_nocheck.constprop.7+0x20/0x20
[  600.765963]  ? memset+0x31/0x40
[  600.772985]  netlink_rcv_skb+0x2de/0x460
[  600.780829]  ? rtnl_newlink+0x1640/0x1640
[  600.788755]  ? netlink_ack+0xaf0/0xaf0
[  600.796181]  ? __kmalloc_node_track_caller+0x205/0x2d0
[  600.805370]  ? __alloc_skb+0xdd/0x580
[  600.812646]  rtnetlink_rcv+0x28/0x30
[  600.819882]  netlink_unicast+0x430/0x620
[  600.827433]  ? netlink_attachskb+0x660/0x660
[  600.835211]  ? rw_copy_check_uvector+0x90/0x290
[  600.843097]  ? __module_text_address+0x18/0x150
[  600.850985]  netlink_sendmsg+0x7df/0xb90
[  600.858105]  ? netlink_unicast+0x620/0x620
[  600.865493]  ? kasan_alloc_pages+0x38/0x40
[  600.873060]  ? netlink_unicast+0x620/0x620
[  600.880458]  sock_sendmsg+0xba/0xf0
[  600.886784]  ___sys_sendmsg+0x6c9/0x8e0
[  600.893300]  ? copy_msghdr_from_user+0x520/0x520
[  600.901017]  ? memcg_write_event_control+0xd50/0xd50
[  600.908938]  ? __alloc_pages_slowpath+0x1ef0/0x1ef0
[  600.916082]  ? mem_cgroup_commit_charge+0xc4/0x1420
[  600.923049]  ? lru_cache_add_active_or_unevictable+0x7d/0x1a0
[  600.931943]  ? __handle_mm_fault+0x1bfe/0x2ba0
[  600.939255]  ? __pmd_alloc+0x240/0x240
[  600.944767]  __sys_sendmsg+0xce/0x160
[  600.950154]  ? __sys_sendmsg+0xce/0x160
[  600.956030]  ? SyS_shutdown+0x190/0x190
[  600.962546]  ? mntput+0x57/0x70
[  600.968576]  ? __fput+0x429/0x730
[  600.973526]  ? handle_mm_fault+0x28a/0x650
[  600.979844]  ? find_vma+0x1f/0x160
[  600.985801]  SyS_sendmsg+0x12/0x20
[  600.991857]  entry_SYSCALL_64_fastpath+0x1a/0xa5
[  600.999044] RIP: 0033:0x7fe11cd80037
[  601.005021] RSP: 002b:7ffe0e7fc738 EFLAGS: 0246 ORIG_RAX: 
002e
[  601.014890] RAX: ffda RBX:  RCX: 7fe11cd80037
[  601.024808] RDX:  RSI: 7ffe0e7fc780 RDI: 0003
[  601.035392] RBP: 7ffe0e7fc780 R08: 0001 R09: fefefeff77686d74
[  601.045517] R10: 05eb R11: 0246 R12: 7ffe0e7fc7c0
[  601.055590] R13: 00669400 R14: 7ffe0e804830 R15: 

[  601.069998] The buggy address belongs to the page:
[  601.078182] page:ea0015b39500 count:0 mapcount:-127 mapping:  
(null) index:0x0
[  601.089760] flags: 0x2f8000()
[  601.096304] raw: 002f8000   
ff80
[  601.107417] raw: ea00156b2020 ea001836cb20 0002 

[  601.118699] page dumped because: kasan: bad access detected

[  601.131352] Memory state around the buggy address:
[  601.139488]  88056ce53f00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
00
[  601.149179]  88056ce53f80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
00
[  601.159941] >88056ce54000: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 
ff
[  601.170313] ^
[  601.176429]  88056ce54080: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 
ff
[  601.187098]  88056ce54100: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 
ff
[  601.196978] 
==

The flow is something like this:
When we are upping the interface, we are calling vxlan_open() and after 
creating the
sockets (v4 & v6) we call vxlan_vs_add_dev() and add the vxlan device to each 
socket's list.

When we put down the interface, we call vxlan_stop() -> vxlan_sock_release() 
there
after calling __vxlan_sock_release_prep() we free each 

Fwd: running an eBPF program

2017-05-28 Thread Adel Fuchs
Hi,
Is there any way to run this eBPF program without that patch?
Alternatively, is there any other eBPF sample that does run properly?
I need to run a program that filters packets according to IP address
or port.
Thanks,
Adel

On Sun, May 28, 2017 at 8:08 AM, Y Song  wrote:
> On Sat, May 27, 2017 at 5:11 PM, David Miller  wrote:
>> From: Y Song 
>> Date: Sat, 27 May 2017 13:52:27 -0700
>>
>>> On Sat, May 27, 2017 at 1:23 PM, Y Song  wrote:

 From verifier error message:
 ==
 0: (bf) r6 = r1

 1: (18) r9 = 0xffee

 3: (69) r0 = *(u16 *)(r6 +16)

 invalid bpf_context access off=16 size=2
 ==

 The offset 16 of struct __sk_buff is hash.
 What instruction #3 tries to do is to access 2 bytes of the hash value
 instead of full 4 bytes.
 This is explicitly not allowed in verifier due to endianness issue.
>>>
>>>
>>> I can reproduce the issue now. My previous statement saying to access
>>> "hash" field is not correct. It is accessing the protocol field.
>>>
>>> static __inline__ bool flow_dissector(struct __sk_buff *skb,
>>>   struct flow_keys *flow)
>>> {
>>> int poff, nh_off = BPF_LL_OFF + ETH_HLEN;
>>> __be16 proto = skb->protocol;
>>> __u8 ip_proto;
>>>
>>> The plan so far is to see whether we can fix the issue in LLVM side.
>>
>> If the compiler properly asks for "__sk_buff + 16" on little-endian
>> and "__sk_buff + 20" on big-endian, the verifier should instead be
>> fixed to allow the access to pass.
>>
>> I can't see any reason why LLVM won't set the offset properly like
>> that, and it's a completely legitimate optimization that we shouldn't
>> try to stop LLVM from performing.
>
> I do agree that such optimization in LLVM is perfect fine and actually
> beneficial.
> The only reason I was thinking was to avoid introduce endianness into 
> verifier.
> Maybe not too much work there. Let me do some experiments and come with
> a patch for that.
>
> Thanks!
>
> Yonghong
>
>>
>> It also makes it so that we don't have to fix having absurdly defined
>> __sk_buff's protocol field as a u32.
>>
>> Thanks.


Re: [patch net-next 0/9] mlxsw: Support firmware flash

2017-05-28 Thread Yotam Gigi
On 05/23/2017 06:38 PM, David Miller wrote:
> From: Yotam Gigi 
> Date: Tue, 23 May 2017 18:14:15 +0300
>
>> Sorry, I am not sure I understand. You think that drivers should not 
>> implement
>> ethtool's flash_device callback anymore? do you have an alternative for 
>> firmware
>> flash?
> As stated, export an MTD device.

So, after we have been going over MTD, it seems like it does not fit our needs
at all.

MTD device provides (erasable-)block access to a flash storage, where in our
case the firmware burn process is just pouring a binary BLOB into the device.
The driver is not aware of the internal storage used for storing the firmware as
it is not defined in our driver-hardware API.

Needless to say that block access has no meaning in our case, so any solution
that will involve MTD device to burn our firmware (if there is a solution at
all) will be a workaround and will not fit MTD purpose.

Apart for boot time firmware flash, which we have already pushed we would really
like to allow the user to ask for a specific firmware version. Do you have any
other solution for us apart from "ethtool -f"?

This problem is even more relevant in the Mellanox HCA driver team, which would
like to use that code in order to burn the HCA firmware, but not intend to
trigger it on boot time, which means that must have a way for the user to
trigger it.



RE: [for-next 4/6] net/mlx5: FPGA, Add basic support for Innova

2017-05-28 Thread Ilan Tayari
> -Original Message-
> From: Jes Sorensen [mailto:jsoren...@fb.com]
> 
> On 05/26/2017 04:29 AM, Saeed Mahameed wrote:
> > On Thu, May 25, 2017 at 11:48 PM, Jes Sorensen  wrote:
> >> On 05/25/2017 06:40 AM, Saeed Mahameed wrote:
> > Hi Jes,
> >
> > No, It is clearly stated in the commit message :
> >
> > "The FPGA is a bump-on-the-wire and thus affects operation of
> > the mlx5_core driver on the ConnectX ASIC."
> >
> > Which means mlx5 FPGA user can only write logic which affects only
> > packets going in/out
> > A ConnectX chip - so it is only network stuff -.
> >
> >> We have this with other devices in the kernel where a primary device
> driver
> >> provides an interface for an additional sub-driver to access another
> device
> >> behind it. Like bt-coexist in some of the wifi drivers allowing access
> to a
> >> bluetooth device behind it.
> >
> > Blutooth over wifi or vise versa is a very good example to what you
> > are requesting.
> > But, it doesn't fit to what we are trying to do here. mlx5 FGPA is a
> > ConnectX card feature, not a new protocol.
> 
> In that case it would need to be an optional module that can be enabled
> or disabled at build time.

Jes,

It is already modular like that. See CONFIG_MLX5_FPGA.

Ilan.

> 
> Cheers,
> Jes
> 



RE: [for-next 4/6] net/mlx5: FPGA, Add basic support for Innova

2017-05-28 Thread Ilan Tayari
> -Original Message-
> From: Jason Gunthorpe [mailto:jguntho...@obsidianresearch.com]
> 
> On Fri, May 26, 2017 at 10:56:25AM -0700, Alexei Starovoitov wrote:
> 
> > > for that feature which is the originating place, before defining
> > > APIs/infrastructures,
> > > until the feature is complete and every body is happy about it.
> >
> > There is driver/fpga to manage fpga, but mlx fpga+nic combo
> > will be managed via mlx5/core/fpga/
> >
> > Adding fpga folks for visibility.
> 
> It would be good to use the existing fpga loading infrastructure to
> get the bitstream into the NIC, and to use the same Xilinx bitstream
> format as eg Zynq does for consistency.
> 
> I'm unclear how this works - there must be more to it than just a
> 'bump on the wire', there must be some communication channel between
> the FPGA and Linux to set operational data (eg load keys) etc.
> 
> If that is register mapped into a PCI-BAR someplace then it really
> should use the FPGA layer functions to manage binding drivers to that
> register window.
> 
> If it is mailbox command based then it is not as good of a fit.
> 

Hi Jason,
Thanks for taking the time to consider this!

This is neither PCI-bar mapped, nor mailbox command.
The FPGA is indeed a bump-on-the-wire.
(It has I2C to the CX4 chip, but that is for debug purposes, and too slow
to perform real programming)

The FPGA is programmed with RoCE packets. We are going to share a lot of
details about this in the IPSec offload patchset, so I don't want to 
repeat it here.
In short, we open a RoCEv2 QP between the connect and the FPGA chips.
Over this QP, we can communicate at high speed with the FPGA.

> Is this FPGA expected to be customer programmable? In that case you
> really need the full infrastructure to bind the right driver (possibly
> a customer driver) to the current FPGA, to expose the correct
> operational interface to the kernel.

Most of the Innova family of cards are not customer-programmable.
Over time, they may require an upgrade (essentially a FW upgrade) but not
with customer logic.

One flavor of the product, the Innova Flex, allows customer logic in the
FPGA. But even then it is "wrapped" by Mellanox shell logic.
We plan to have an in-kernel API for writing client drivers for Innova
Flex.

> 
> Jason