diff options
-rw-r--r-- | drivers/net/ethernet/broadcom/bnxt/bnxt.c | 8 | ||||
-rw-r--r-- | drivers/net/ethernet/broadcom/bnxt/bnxt.h | 1 | ||||
-rw-r--r-- | drivers/net/ethernet/broadcom/bnxt/bnxt_tc.c | 74 | ||||
-rw-r--r-- | drivers/net/ethernet/broadcom/bnxt/bnxt_tc.h | 5 |
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 | |||
6665 | hwrm_ver_get_exit: | 6673 | hwrm_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 | ||
340 | static int bnxt_hwrm_cfa_flow_free(struct bnxt *bp, __le16 flow_handle) | 340 | static 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 | ||
419 | static int bnxt_hwrm_cfa_flow_alloc(struct bnxt *bp, struct bnxt_tc_flow *flow, | 422 | static 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 | ||
1270 | static 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 | |||
1253 | static void bnxt_tc_set_src_fid(struct bnxt *bp, struct bnxt_tc_flow *flow, | 1276 | static 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 | ||
1342 | hwrm_flow_free: | 1368 | hwrm_flow_free: |
1343 | bnxt_hwrm_cfa_flow_free(bp, new_node->flow_handle); | 1369 | bnxt_hwrm_cfa_flow_free(bp, new_node); |
1344 | put_tunnel: | 1370 | put_tunnel: |
1345 | bnxt_tc_put_tunnel_handle(bp, flow, new_node); | 1371 | bnxt_tc_put_tunnel_handle(bp, flow, new_node); |
1346 | put_l2: | 1372 | put_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 | ||
1430 | static 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 | |||
1404 | static int | 1456 | static int |
1405 | bnxt_hwrm_cfa_flow_stats_get(struct bnxt *bp, int num_flows, | 1457 | bnxt_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; |