aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/ethernet/broadcom/bnxt/bnxt.c8
-rw-r--r--drivers/net/ethernet/broadcom/bnxt/bnxt.h1
-rw-r--r--drivers/net/ethernet/broadcom/bnxt/bnxt_tc.c74
-rw-r--r--drivers/net/ethernet/broadcom/bnxt/bnxt_tc.h5
4 files changed, 78 insertions, 10 deletions
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
index d3287641ce51..6872db9ac301 100644
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
@@ -4055,6 +4055,10 @@ static int bnxt_hwrm_func_drv_rgtr(struct bnxt *bp)
4055 cpu_to_le32(FUNC_DRV_RGTR_REQ_ENABLES_VF_REQ_FWD); 4055 cpu_to_le32(FUNC_DRV_RGTR_REQ_ENABLES_VF_REQ_FWD);
4056 } 4056 }
4057 4057
4058 if (bp->fw_cap & BNXT_FW_CAP_OVS_64BIT_HANDLE)
4059 req.flags |= cpu_to_le32(
4060 FUNC_DRV_RGTR_REQ_FLAGS_FLOW_HANDLE_64BIT_MODE);
4061
4058 mutex_lock(&bp->hwrm_cmd_lock); 4062 mutex_lock(&bp->hwrm_cmd_lock);
4059 rc = _hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT); 4063 rc = _hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT);
4060 if (rc) 4064 if (rc)
@@ -6662,6 +6666,10 @@ static int bnxt_hwrm_ver_get(struct bnxt *bp)
6662 if (dev_caps_cfg & VER_GET_RESP_DEV_CAPS_CFG_KONG_MB_CHNL_SUPPORTED) 6666 if (dev_caps_cfg & VER_GET_RESP_DEV_CAPS_CFG_KONG_MB_CHNL_SUPPORTED)
6663 bp->fw_cap |= BNXT_FW_CAP_KONG_MB_CHNL; 6667 bp->fw_cap |= BNXT_FW_CAP_KONG_MB_CHNL;
6664 6668
6669 if (dev_caps_cfg &
6670 VER_GET_RESP_DEV_CAPS_CFG_FLOW_HANDLE_64BIT_SUPPORTED)
6671 bp->fw_cap |= BNXT_FW_CAP_OVS_64BIT_HANDLE;
6672
6665hwrm_ver_get_exit: 6673hwrm_ver_get_exit:
6666 mutex_unlock(&bp->hwrm_cmd_lock); 6674 mutex_unlock(&bp->hwrm_cmd_lock);
6667 return rc; 6675 return rc;
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.h b/drivers/net/ethernet/broadcom/bnxt/bnxt.h
index 61d07a4165d8..a451796deefe 100644
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.h
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.h
@@ -1478,6 +1478,7 @@ struct bnxt {
1478 #define BNXT_FW_CAP_NEW_RM 0x00000008 1478 #define BNXT_FW_CAP_NEW_RM 0x00000008
1479 #define BNXT_FW_CAP_IF_CHANGE 0x00000010 1479 #define BNXT_FW_CAP_IF_CHANGE 0x00000010
1480 #define BNXT_FW_CAP_KONG_MB_CHNL 0x00000080 1480 #define BNXT_FW_CAP_KONG_MB_CHNL 0x00000080
1481 #define BNXT_FW_CAP_OVS_64BIT_HANDLE 0x00000400
1481 1482
1482#define BNXT_NEW_RM(bp) ((bp)->fw_cap & BNXT_FW_CAP_NEW_RM) 1483#define BNXT_NEW_RM(bp) ((bp)->fw_cap & BNXT_FW_CAP_NEW_RM)
1483 u32 hwrm_spec_code; 1484 u32 hwrm_spec_code;
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_tc.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_tc.c
index b39584896392..c683b5e96b1d 100644
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt_tc.c
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_tc.c
@@ -337,18 +337,21 @@ static int bnxt_tc_parse_flow(struct bnxt *bp,
337 return bnxt_tc_parse_actions(bp, &flow->actions, tc_flow_cmd->exts); 337 return bnxt_tc_parse_actions(bp, &flow->actions, tc_flow_cmd->exts);
338} 338}
339 339
340static int bnxt_hwrm_cfa_flow_free(struct bnxt *bp, __le16 flow_handle) 340static int bnxt_hwrm_cfa_flow_free(struct bnxt *bp,
341 struct bnxt_tc_flow_node *flow_node)
341{ 342{
342 struct hwrm_cfa_flow_free_input req = { 0 }; 343 struct hwrm_cfa_flow_free_input req = { 0 };
343 int rc; 344 int rc;
344 345
345 bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_CFA_FLOW_FREE, -1, -1); 346 bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_CFA_FLOW_FREE, -1, -1);
346 req.flow_handle = flow_handle; 347 if (bp->fw_cap & BNXT_FW_CAP_OVS_64BIT_HANDLE)
348 req.ext_flow_handle = flow_node->ext_flow_handle;
349 else
350 req.flow_handle = flow_node->flow_handle;
347 351
348 rc = hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT); 352 rc = hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT);
349 if (rc) 353 if (rc)
350 netdev_info(bp->dev, "Error: %s: flow_handle=0x%x rc=%d", 354 netdev_info(bp->dev, "%s: Error rc=%d", __func__, rc);
351 __func__, flow_handle, rc);
352 355
353 if (rc) 356 if (rc)
354 rc = -EIO; 357 rc = -EIO;
@@ -418,7 +421,8 @@ static bool bits_set(void *key, int len)
418 421
419static int bnxt_hwrm_cfa_flow_alloc(struct bnxt *bp, struct bnxt_tc_flow *flow, 422static int bnxt_hwrm_cfa_flow_alloc(struct bnxt *bp, struct bnxt_tc_flow *flow,
420 __le16 ref_flow_handle, 423 __le16 ref_flow_handle,
421 __le32 tunnel_handle, __le16 *flow_handle) 424 __le32 tunnel_handle,
425 struct bnxt_tc_flow_node *flow_node)
422{ 426{
423 struct bnxt_tc_actions *actions = &flow->actions; 427 struct bnxt_tc_actions *actions = &flow->actions;
424 struct bnxt_tc_l3_key *l3_mask = &flow->l3_mask; 428 struct bnxt_tc_l3_key *l3_mask = &flow->l3_mask;
@@ -529,7 +533,20 @@ static int bnxt_hwrm_cfa_flow_alloc(struct bnxt *bp, struct bnxt_tc_flow *flow,
529 rc = _hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT); 533 rc = _hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT);
530 if (!rc) { 534 if (!rc) {
531 resp = bnxt_get_hwrm_resp_addr(bp, &req); 535 resp = bnxt_get_hwrm_resp_addr(bp, &req);
532 *flow_handle = resp->flow_handle; 536 /* CFA_FLOW_ALLOC response interpretation:
537 * fw with fw with
538 * 16-bit 64-bit
539 * flow handle flow handle
540 * =========== ===========
541 * flow_handle flow handle flow context id
542 * ext_flow_handle INVALID flow handle
543 * flow_id INVALID flow counter id
544 */
545 flow_node->flow_handle = resp->flow_handle;
546 if (bp->fw_cap & BNXT_FW_CAP_OVS_64BIT_HANDLE) {
547 flow_node->ext_flow_handle = resp->ext_flow_handle;
548 flow_node->flow_id = resp->flow_id;
549 }
533 } 550 }
534 mutex_unlock(&bp->hwrm_cmd_lock); 551 mutex_unlock(&bp->hwrm_cmd_lock);
535 552
@@ -1228,7 +1245,7 @@ static int __bnxt_tc_del_flow(struct bnxt *bp,
1228 int rc; 1245 int rc;
1229 1246
1230 /* send HWRM cmd to free the flow-id */ 1247 /* send HWRM cmd to free the flow-id */
1231 bnxt_hwrm_cfa_flow_free(bp, flow_node->flow_handle); 1248 bnxt_hwrm_cfa_flow_free(bp, flow_node);
1232 1249
1233 mutex_lock(&tc_info->lock); 1250 mutex_lock(&tc_info->lock);
1234 1251
@@ -1250,6 +1267,12 @@ static int __bnxt_tc_del_flow(struct bnxt *bp,
1250 return 0; 1267 return 0;
1251} 1268}
1252 1269
1270static void bnxt_tc_set_flow_dir(struct bnxt *bp, struct bnxt_tc_flow *flow,
1271 u16 src_fid)
1272{
1273 flow->dir = (bp->pf.fw_fid == src_fid) ? BNXT_DIR_RX : BNXT_DIR_TX;
1274}
1275
1253static void bnxt_tc_set_src_fid(struct bnxt *bp, struct bnxt_tc_flow *flow, 1276static void bnxt_tc_set_src_fid(struct bnxt *bp, struct bnxt_tc_flow *flow,
1254 u16 src_fid) 1277 u16 src_fid)
1255{ 1278{
@@ -1297,6 +1320,9 @@ static int bnxt_tc_add_flow(struct bnxt *bp, u16 src_fid,
1297 1320
1298 bnxt_tc_set_src_fid(bp, flow, src_fid); 1321 bnxt_tc_set_src_fid(bp, flow, src_fid);
1299 1322
1323 if (bp->fw_cap & BNXT_FW_CAP_OVS_64BIT_HANDLE)
1324 bnxt_tc_set_flow_dir(bp, flow, src_fid);
1325
1300 if (!bnxt_tc_can_offload(bp, flow)) { 1326 if (!bnxt_tc_can_offload(bp, flow)) {
1301 rc = -ENOSPC; 1327 rc = -ENOSPC;
1302 goto free_node; 1328 goto free_node;
@@ -1324,7 +1350,7 @@ static int bnxt_tc_add_flow(struct bnxt *bp, u16 src_fid,
1324 1350
1325 /* send HWRM cmd to alloc the flow */ 1351 /* send HWRM cmd to alloc the flow */
1326 rc = bnxt_hwrm_cfa_flow_alloc(bp, flow, ref_flow_handle, 1352 rc = bnxt_hwrm_cfa_flow_alloc(bp, flow, ref_flow_handle,
1327 tunnel_handle, &new_node->flow_handle); 1353 tunnel_handle, new_node);
1328 if (rc) 1354 if (rc)
1329 goto put_tunnel; 1355 goto put_tunnel;
1330 1356
@@ -1340,7 +1366,7 @@ static int bnxt_tc_add_flow(struct bnxt *bp, u16 src_fid,
1340 return 0; 1366 return 0;
1341 1367
1342hwrm_flow_free: 1368hwrm_flow_free:
1343 bnxt_hwrm_cfa_flow_free(bp, new_node->flow_handle); 1369 bnxt_hwrm_cfa_flow_free(bp, new_node);
1344put_tunnel: 1370put_tunnel:
1345 bnxt_tc_put_tunnel_handle(bp, flow, new_node); 1371 bnxt_tc_put_tunnel_handle(bp, flow, new_node);
1346put_l2: 1372put_l2:
@@ -1401,6 +1427,32 @@ static int bnxt_tc_get_flow_stats(struct bnxt *bp,
1401 return 0; 1427 return 0;
1402} 1428}
1403 1429
1430static void bnxt_fill_cfa_stats_req(struct bnxt *bp,
1431 struct bnxt_tc_flow_node *flow_node,
1432 __le16 *flow_handle, __le32 *flow_id)
1433{
1434 u16 handle;
1435
1436 if (bp->fw_cap & BNXT_FW_CAP_OVS_64BIT_HANDLE) {
1437 *flow_id = flow_node->flow_id;
1438
1439 /* If flow_id is used to fetch flow stats then:
1440 * 1. lower 12 bits of flow_handle must be set to all 1s.
1441 * 2. 15th bit of flow_handle must specify the flow
1442 * direction (TX/RX).
1443 */
1444 if (flow_node->flow.dir == BNXT_DIR_RX)
1445 handle = CFA_FLOW_INFO_REQ_FLOW_HANDLE_DIR_RX |
1446 CFA_FLOW_INFO_REQ_FLOW_HANDLE_MAX_MASK;
1447 else
1448 handle = CFA_FLOW_INFO_REQ_FLOW_HANDLE_MAX_MASK;
1449
1450 *flow_handle = cpu_to_le16(handle);
1451 } else {
1452 *flow_handle = flow_node->flow_handle;
1453 }
1454}
1455
1404static int 1456static int
1405bnxt_hwrm_cfa_flow_stats_get(struct bnxt *bp, int num_flows, 1457bnxt_hwrm_cfa_flow_stats_get(struct bnxt *bp, int num_flows,
1406 struct bnxt_tc_stats_batch stats_batch[]) 1458 struct bnxt_tc_stats_batch stats_batch[])
@@ -1408,6 +1460,7 @@ bnxt_hwrm_cfa_flow_stats_get(struct bnxt *bp, int num_flows,
1408 struct hwrm_cfa_flow_stats_input req = { 0 }; 1460 struct hwrm_cfa_flow_stats_input req = { 0 };
1409 struct hwrm_cfa_flow_stats_output *resp; 1461 struct hwrm_cfa_flow_stats_output *resp;
1410 __le16 *req_flow_handles = &req.flow_handle_0; 1462 __le16 *req_flow_handles = &req.flow_handle_0;
1463 __le32 *req_flow_ids = &req.flow_id_0;
1411 int rc, i; 1464 int rc, i;
1412 1465
1413 bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_CFA_FLOW_STATS, -1, -1); 1466 bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_CFA_FLOW_STATS, -1, -1);
@@ -1415,7 +1468,8 @@ bnxt_hwrm_cfa_flow_stats_get(struct bnxt *bp, int num_flows,
1415 for (i = 0; i < num_flows; i++) { 1468 for (i = 0; i < num_flows; i++) {
1416 struct bnxt_tc_flow_node *flow_node = stats_batch[i].flow_node; 1469 struct bnxt_tc_flow_node *flow_node = stats_batch[i].flow_node;
1417 1470
1418 req_flow_handles[i] = flow_node->flow_handle; 1471 bnxt_fill_cfa_stats_req(bp, flow_node,
1472 &req_flow_handles[i], &req_flow_ids[i]);
1419 } 1473 }
1420 1474
1421 mutex_lock(&bp->hwrm_cmd_lock); 1475 mutex_lock(&bp->hwrm_cmd_lock);
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_tc.h b/drivers/net/ethernet/broadcom/bnxt/bnxt_tc.h
index 97e09a880693..8a0968967bc5 100644
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt_tc.h
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_tc.h
@@ -98,6 +98,9 @@ struct bnxt_tc_flow {
98 98
99 /* flow applicable to pkts ingressing on this fid */ 99 /* flow applicable to pkts ingressing on this fid */
100 u16 src_fid; 100 u16 src_fid;
101 u8 dir;
102#define BNXT_DIR_RX 1
103#define BNXT_DIR_TX 0
101 struct bnxt_tc_l2_key l2_key; 104 struct bnxt_tc_l2_key l2_key;
102 struct bnxt_tc_l2_key l2_mask; 105 struct bnxt_tc_l2_key l2_mask;
103 struct bnxt_tc_l3_key l3_key; 106 struct bnxt_tc_l3_key l3_key;
@@ -170,7 +173,9 @@ struct bnxt_tc_flow_node {
170 173
171 struct bnxt_tc_flow flow; 174 struct bnxt_tc_flow flow;
172 175
176 __le64 ext_flow_handle;
173 __le16 flow_handle; 177 __le16 flow_handle;
178 __le32 flow_id;
174 179
175 /* L2 node in l2 hashtable that shares flow's l2 key */ 180 /* L2 node in l2 hashtable that shares flow's l2 key */
176 struct bnxt_tc_l2_node *l2_node; 181 struct bnxt_tc_l2_node *l2_node;