Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'bnxt_en-ptp-and-rss-updates'

Michael Chan says:

====================
bnxt_en: PTP and RSS updates

The first 2 patches are v2 of the PTP patches posted about 3 weeks ago:

https://lore.kernel.org/netdev/20240229070202.107488-1-michael.chan@broadcom.com/

The devlink parameter is dropped and v2 is just to increase the timeout
accuracy and to use a default timeout of 1 second.

Patches 3 to 12 implement additional RSS contexts and ntuple filters for
the RSS contexts.
====================

Link: https://lore.kernel.org/r/20240325222902.220712-1-michael.chan@broadcom.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

+509 -136
+241 -107
drivers/net/ethernet/broadcom/bnxt/bnxt.c
··· 4241 4241 int j; 4242 4242 4243 4243 vnic->fw_vnic_id = INVALID_HW_RING_ID; 4244 + vnic->vnic_id = i; 4244 4245 for (j = 0; j < BNXT_MAX_CTX_PER_VNIC; j++) 4245 4246 vnic->fw_rss_cos_lb_ctx[j] = INVALID_HW_RING_ID; 4246 4247 ··· 5789 5788 static void 5790 5789 bnxt_cfg_rfs_ring_tbl_idx(struct bnxt *bp, 5791 5790 struct hwrm_cfa_ntuple_filter_alloc_input *req, 5792 - u16 rxq) 5791 + struct bnxt_ntuple_filter *fltr) 5793 5792 { 5793 + struct bnxt_rss_ctx *rss_ctx, *tmp; 5794 + u16 rxq = fltr->base.rxq; 5795 + 5796 + if (fltr->base.flags & BNXT_ACT_RSS_CTX) { 5797 + list_for_each_entry_safe(rss_ctx, tmp, &bp->rss_ctx_list, list) { 5798 + if (rss_ctx->index == fltr->base.fw_vnic_id) { 5799 + struct bnxt_vnic_info *vnic = &rss_ctx->vnic; 5800 + 5801 + req->dst_id = cpu_to_le16(vnic->fw_vnic_id); 5802 + break; 5803 + } 5804 + } 5805 + return; 5806 + } 5794 5807 if (BNXT_SUPPORTS_NTUPLE_VNIC(bp)) { 5795 5808 struct bnxt_vnic_info *vnic; 5796 5809 u32 enables; ··· 5845 5830 req->flags = 5846 5831 cpu_to_le32(CFA_NTUPLE_FILTER_ALLOC_REQ_FLAGS_DROP); 5847 5832 } else if (bp->fw_cap & BNXT_FW_CAP_CFA_RFS_RING_TBL_IDX_V2) { 5848 - bnxt_cfg_rfs_ring_tbl_idx(bp, req, fltr->base.rxq); 5833 + bnxt_cfg_rfs_ring_tbl_idx(bp, req, fltr); 5849 5834 } else { 5850 5835 vnic = &bp->vnic_info[fltr->base.rxq + 1]; 5851 5836 req->dst_id = cpu_to_le16(vnic->fw_vnic_id); ··· 5953 5938 req->tnl_tpa_en_bitmap = cpu_to_le32(tunl_tpa_bmap); 5954 5939 } 5955 5940 5956 - static int bnxt_hwrm_vnic_set_tpa(struct bnxt *bp, u16 vnic_id, u32 tpa_flags) 5941 + int bnxt_hwrm_vnic_set_tpa(struct bnxt *bp, struct bnxt_vnic_info *vnic, 5942 + u32 tpa_flags) 5957 5943 { 5958 - struct bnxt_vnic_info *vnic = &bp->vnic_info[vnic_id]; 5959 5944 u16 max_aggs = VNIC_TPA_CFG_REQ_MAX_AGGS_MAX; 5960 5945 struct hwrm_vnic_tpa_cfg_input *req; 5961 5946 int rc; ··· 6040 6025 return bnxt_cp_ring_from_grp(bp, &txr->tx_ring_struct); 6041 6026 } 6042 6027 6043 - static int bnxt_alloc_rss_indir_tbl(struct bnxt *bp) 6028 + int bnxt_alloc_rss_indir_tbl(struct bnxt *bp, struct bnxt_rss_ctx *rss_ctx) 6044 6029 { 6045 6030 int entries; 6031 + u16 *tbl; 6046 6032 6047 6033 if (bp->flags & BNXT_FLAG_CHIP_P5_PLUS) 6048 6034 entries = BNXT_MAX_RSS_TABLE_ENTRIES_P5; ··· 6051 6035 entries = HW_HASH_INDEX_SIZE; 6052 6036 6053 6037 bp->rss_indir_tbl_entries = entries; 6054 - bp->rss_indir_tbl = kmalloc_array(entries, sizeof(*bp->rss_indir_tbl), 6055 - GFP_KERNEL); 6056 - if (!bp->rss_indir_tbl) 6038 + tbl = kmalloc_array(entries, sizeof(*bp->rss_indir_tbl), GFP_KERNEL); 6039 + if (!tbl) 6057 6040 return -ENOMEM; 6041 + 6042 + if (rss_ctx) 6043 + rss_ctx->rss_indir_tbl = tbl; 6044 + else 6045 + bp->rss_indir_tbl = tbl; 6046 + 6058 6047 return 0; 6059 6048 } 6060 6049 6061 - static void bnxt_set_dflt_rss_indir_tbl(struct bnxt *bp) 6050 + void bnxt_set_dflt_rss_indir_tbl(struct bnxt *bp, struct bnxt_rss_ctx *rss_ctx) 6062 6051 { 6063 6052 u16 max_rings, max_entries, pad, i; 6053 + u16 *rss_indir_tbl; 6064 6054 6065 6055 if (!bp->rx_nr_rings) 6066 6056 return; ··· 6077 6055 max_rings = bp->rx_nr_rings; 6078 6056 6079 6057 max_entries = bnxt_get_rxfh_indir_size(bp->dev); 6058 + if (rss_ctx) 6059 + rss_indir_tbl = &rss_ctx->rss_indir_tbl[0]; 6060 + else 6061 + rss_indir_tbl = &bp->rss_indir_tbl[0]; 6080 6062 6081 6063 for (i = 0; i < max_entries; i++) 6082 - bp->rss_indir_tbl[i] = ethtool_rxfh_indir_default(i, max_rings); 6064 + rss_indir_tbl[i] = ethtool_rxfh_indir_default(i, max_rings); 6083 6065 6084 6066 pad = bp->rss_indir_tbl_entries - max_entries; 6085 6067 if (pad) 6086 - memset(&bp->rss_indir_tbl[i], 0, pad * sizeof(u16)); 6068 + memset(&rss_indir_tbl[i], 0, pad * sizeof(u16)); 6087 6069 } 6088 6070 6089 6071 static u16 bnxt_get_max_rss_ring(struct bnxt *bp) ··· 6143 6117 6144 6118 if (vnic->flags & BNXT_VNIC_NTUPLE_FLAG) 6145 6119 j = ethtool_rxfh_indir_default(i, bp->rx_nr_rings); 6120 + else if (vnic->flags & BNXT_VNIC_RSSCTX_FLAG) 6121 + j = vnic->rss_ctx->rss_indir_tbl[i]; 6146 6122 else 6147 6123 j = bp->rss_indir_tbl[i]; 6148 6124 rxr = &bp->rx_ring[j]; ··· 6182 6154 req->hash_key_tbl_addr = cpu_to_le64(vnic->rss_hash_key_dma_addr); 6183 6155 } 6184 6156 6185 - static int bnxt_hwrm_vnic_set_rss(struct bnxt *bp, u16 vnic_id, bool set_rss) 6157 + static int bnxt_hwrm_vnic_set_rss(struct bnxt *bp, struct bnxt_vnic_info *vnic, 6158 + bool set_rss) 6186 6159 { 6187 - struct bnxt_vnic_info *vnic = &bp->vnic_info[vnic_id]; 6188 6160 struct hwrm_vnic_rss_cfg_input *req; 6189 6161 int rc; 6190 6162 ··· 6202 6174 return hwrm_req_send(bp, req); 6203 6175 } 6204 6176 6205 - static int bnxt_hwrm_vnic_set_rss_p5(struct bnxt *bp, u16 vnic_id, bool set_rss) 6177 + static int bnxt_hwrm_vnic_set_rss_p5(struct bnxt *bp, 6178 + struct bnxt_vnic_info *vnic, bool set_rss) 6206 6179 { 6207 - struct bnxt_vnic_info *vnic = &bp->vnic_info[vnic_id]; 6208 6180 struct hwrm_vnic_rss_cfg_input *req; 6209 6181 dma_addr_t ring_tbl_map; 6210 6182 u32 i, nr_ctxs; ··· 6257 6229 hwrm_req_drop(bp, req); 6258 6230 } 6259 6231 6260 - static int bnxt_hwrm_vnic_set_hds(struct bnxt *bp, u16 vnic_id) 6232 + static int bnxt_hwrm_vnic_set_hds(struct bnxt *bp, struct bnxt_vnic_info *vnic) 6261 6233 { 6262 - struct bnxt_vnic_info *vnic = &bp->vnic_info[vnic_id]; 6263 6234 struct hwrm_vnic_plcmodes_cfg_input *req; 6264 6235 int rc; 6265 6236 ··· 6283 6256 return hwrm_req_send(bp, req); 6284 6257 } 6285 6258 6286 - static void bnxt_hwrm_vnic_ctx_free_one(struct bnxt *bp, u16 vnic_id, 6259 + static void bnxt_hwrm_vnic_ctx_free_one(struct bnxt *bp, 6260 + struct bnxt_vnic_info *vnic, 6287 6261 u16 ctx_idx) 6288 6262 { 6289 6263 struct hwrm_vnic_rss_cos_lb_ctx_free_input *req; ··· 6293 6265 return; 6294 6266 6295 6267 req->rss_cos_lb_ctx_id = 6296 - cpu_to_le16(bp->vnic_info[vnic_id].fw_rss_cos_lb_ctx[ctx_idx]); 6268 + cpu_to_le16(vnic->fw_rss_cos_lb_ctx[ctx_idx]); 6297 6269 6298 6270 hwrm_req_send(bp, req); 6299 - bp->vnic_info[vnic_id].fw_rss_cos_lb_ctx[ctx_idx] = INVALID_HW_RING_ID; 6271 + vnic->fw_rss_cos_lb_ctx[ctx_idx] = INVALID_HW_RING_ID; 6300 6272 } 6301 6273 6302 6274 static void bnxt_hwrm_vnic_ctx_free(struct bnxt *bp) ··· 6308 6280 6309 6281 for (j = 0; j < BNXT_MAX_CTX_PER_VNIC; j++) { 6310 6282 if (vnic->fw_rss_cos_lb_ctx[j] != INVALID_HW_RING_ID) 6311 - bnxt_hwrm_vnic_ctx_free_one(bp, i, j); 6283 + bnxt_hwrm_vnic_ctx_free_one(bp, vnic, j); 6312 6284 } 6313 6285 } 6314 6286 bp->rsscos_nr_ctxs = 0; 6315 6287 } 6316 6288 6317 - static int bnxt_hwrm_vnic_ctx_alloc(struct bnxt *bp, u16 vnic_id, u16 ctx_idx) 6289 + static int bnxt_hwrm_vnic_ctx_alloc(struct bnxt *bp, 6290 + struct bnxt_vnic_info *vnic, u16 ctx_idx) 6318 6291 { 6319 6292 struct hwrm_vnic_rss_cos_lb_ctx_alloc_output *resp; 6320 6293 struct hwrm_vnic_rss_cos_lb_ctx_alloc_input *req; ··· 6328 6299 resp = hwrm_req_hold(bp, req); 6329 6300 rc = hwrm_req_send(bp, req); 6330 6301 if (!rc) 6331 - bp->vnic_info[vnic_id].fw_rss_cos_lb_ctx[ctx_idx] = 6302 + vnic->fw_rss_cos_lb_ctx[ctx_idx] = 6332 6303 le16_to_cpu(resp->rss_cos_lb_ctx_id); 6333 6304 hwrm_req_drop(bp, req); 6334 6305 ··· 6342 6313 return VNIC_CFG_REQ_FLAGS_ROCE_DUAL_VNIC_MODE; 6343 6314 } 6344 6315 6345 - int bnxt_hwrm_vnic_cfg(struct bnxt *bp, u16 vnic_id) 6316 + int bnxt_hwrm_vnic_cfg(struct bnxt *bp, struct bnxt_vnic_info *vnic) 6346 6317 { 6347 6318 struct bnxt_vnic_info *vnic0 = &bp->vnic_info[BNXT_VNIC_DEFAULT]; 6348 - struct bnxt_vnic_info *vnic = &bp->vnic_info[vnic_id]; 6349 6319 struct hwrm_vnic_cfg_input *req; 6350 6320 unsigned int ring = 0, grp_idx; 6351 6321 u16 def_vlan = 0; ··· 6392 6364 if (vnic->flags & BNXT_VNIC_RSS_FLAG) 6393 6365 ring = 0; 6394 6366 else if (vnic->flags & BNXT_VNIC_RFS_FLAG) 6395 - ring = vnic_id - 1; 6396 - else if ((vnic_id == 1) && BNXT_CHIP_TYPE_NITRO_A0(bp)) 6367 + ring = vnic->vnic_id - 1; 6368 + else if ((vnic->vnic_id == 1) && BNXT_CHIP_TYPE_NITRO_A0(bp)) 6397 6369 ring = bp->rx_nr_rings - 1; 6398 6370 6399 6371 grp_idx = bp->rx_ring[ring].bnapi->index; ··· 6409 6381 #endif 6410 6382 if ((bp->flags & BNXT_FLAG_STRIP_VLAN) || def_vlan) 6411 6383 req->flags |= cpu_to_le32(VNIC_CFG_REQ_FLAGS_VLAN_STRIP_MODE); 6412 - if (!vnic_id && bnxt_ulp_registered(bp->edev)) 6384 + if (vnic->vnic_id == BNXT_VNIC_DEFAULT && bnxt_ulp_registered(bp->edev)) 6413 6385 req->flags |= cpu_to_le32(bnxt_get_roce_vnic_mode(bp)); 6414 6386 6415 6387 return hwrm_req_send(bp, req); 6416 6388 } 6417 6389 6418 - static void bnxt_hwrm_vnic_free_one(struct bnxt *bp, u16 vnic_id) 6390 + static void bnxt_hwrm_vnic_free_one(struct bnxt *bp, 6391 + struct bnxt_vnic_info *vnic) 6419 6392 { 6420 - if (bp->vnic_info[vnic_id].fw_vnic_id != INVALID_HW_RING_ID) { 6393 + if (vnic->fw_vnic_id != INVALID_HW_RING_ID) { 6421 6394 struct hwrm_vnic_free_input *req; 6422 6395 6423 6396 if (hwrm_req_init(bp, req, HWRM_VNIC_FREE)) 6424 6397 return; 6425 6398 6426 - req->vnic_id = 6427 - cpu_to_le32(bp->vnic_info[vnic_id].fw_vnic_id); 6399 + req->vnic_id = cpu_to_le32(vnic->fw_vnic_id); 6428 6400 6429 6401 hwrm_req_send(bp, req); 6430 - bp->vnic_info[vnic_id].fw_vnic_id = INVALID_HW_RING_ID; 6402 + vnic->fw_vnic_id = INVALID_HW_RING_ID; 6431 6403 } 6432 6404 } 6433 6405 ··· 6436 6408 u16 i; 6437 6409 6438 6410 for (i = 0; i < bp->nr_vnics; i++) 6439 - bnxt_hwrm_vnic_free_one(bp, i); 6411 + bnxt_hwrm_vnic_free_one(bp, &bp->vnic_info[i]); 6440 6412 } 6441 6413 6442 - static int bnxt_hwrm_vnic_alloc(struct bnxt *bp, u16 vnic_id, 6443 - unsigned int start_rx_ring_idx, 6444 - unsigned int nr_rings) 6414 + int bnxt_hwrm_vnic_alloc(struct bnxt *bp, struct bnxt_vnic_info *vnic, 6415 + unsigned int start_rx_ring_idx, 6416 + unsigned int nr_rings) 6445 6417 { 6446 6418 unsigned int i, j, grp_idx, end_idx = start_rx_ring_idx + nr_rings; 6447 - struct bnxt_vnic_info *vnic = &bp->vnic_info[vnic_id]; 6448 6419 struct hwrm_vnic_alloc_output *resp; 6449 6420 struct hwrm_vnic_alloc_input *req; 6450 6421 int rc; ··· 6469 6442 vnic_no_ring_grps: 6470 6443 for (i = 0; i < BNXT_MAX_CTX_PER_VNIC; i++) 6471 6444 vnic->fw_rss_cos_lb_ctx[i] = INVALID_HW_RING_ID; 6472 - if (vnic_id == BNXT_VNIC_DEFAULT) 6445 + if (vnic->vnic_id == BNXT_VNIC_DEFAULT) 6473 6446 req->flags = cpu_to_le32(VNIC_ALLOC_REQ_FLAGS_DEFAULT); 6474 6447 6475 6448 resp = hwrm_req_hold(bp, req); ··· 7368 7341 if (hw_resc->resv_rx_rings != bp->rx_nr_rings) { 7369 7342 hw_resc->resv_rx_rings = bp->rx_nr_rings; 7370 7343 if (!netif_is_rxfh_configured(bp->dev)) 7371 - bnxt_set_dflt_rss_indir_tbl(bp); 7344 + bnxt_set_dflt_rss_indir_tbl(bp, NULL); 7372 7345 } 7373 7346 } 7374 7347 ··· 7376 7349 { 7377 7350 if (bp->flags & BNXT_FLAG_RFS) { 7378 7351 if (BNXT_SUPPORTS_NTUPLE_VNIC(bp)) 7379 - return 2; 7352 + return 2 + bp->num_rss_ctx; 7380 7353 if (!(bp->flags & BNXT_FLAG_CHIP_P5_PLUS)) 7381 7354 return rx_rings + 1; 7382 7355 } ··· 7524 7497 return -ENOMEM; 7525 7498 7526 7499 if (!netif_is_rxfh_configured(bp->dev)) 7527 - bnxt_set_dflt_rss_indir_tbl(bp); 7500 + bnxt_set_dflt_rss_indir_tbl(bp, NULL); 7528 7501 7529 7502 return rc; 7530 7503 } ··· 9703 9676 else if (BNXT_NO_FW_ACCESS(bp)) 9704 9677 return 0; 9705 9678 for (i = 0; i < bp->nr_vnics; i++) { 9706 - rc = bnxt_hwrm_vnic_set_tpa(bp, i, tpa_flags); 9679 + rc = bnxt_hwrm_vnic_set_tpa(bp, &bp->vnic_info[i], tpa_flags); 9707 9680 if (rc) { 9708 9681 netdev_err(bp->dev, "hwrm vnic set tpa failure rc for vnic %d: %x\n", 9709 9682 i, rc); ··· 9718 9691 int i; 9719 9692 9720 9693 for (i = 0; i < bp->nr_vnics; i++) 9721 - bnxt_hwrm_vnic_set_rss(bp, i, false); 9694 + bnxt_hwrm_vnic_set_rss(bp, &bp->vnic_info[i], false); 9722 9695 } 9723 9696 9724 9697 static void bnxt_clear_vnic(struct bnxt *bp) ··· 9796 9769 return hwrm_req_send(bp, req); 9797 9770 } 9798 9771 9799 - static int __bnxt_setup_vnic(struct bnxt *bp, u16 vnic_id) 9772 + static int __bnxt_setup_vnic(struct bnxt *bp, struct bnxt_vnic_info *vnic) 9800 9773 { 9801 - struct bnxt_vnic_info *vnic = &bp->vnic_info[vnic_id]; 9802 9774 int rc; 9803 9775 9804 9776 if (vnic->flags & BNXT_VNIC_RFS_NEW_RSS_FLAG) 9805 9777 goto skip_rss_ctx; 9806 9778 9807 9779 /* allocate context for vnic */ 9808 - rc = bnxt_hwrm_vnic_ctx_alloc(bp, vnic_id, 0); 9780 + rc = bnxt_hwrm_vnic_ctx_alloc(bp, vnic, 0); 9809 9781 if (rc) { 9810 9782 netdev_err(bp->dev, "hwrm vnic %d alloc failure rc: %x\n", 9811 - vnic_id, rc); 9783 + vnic->vnic_id, rc); 9812 9784 goto vnic_setup_err; 9813 9785 } 9814 9786 bp->rsscos_nr_ctxs++; 9815 9787 9816 9788 if (BNXT_CHIP_TYPE_NITRO_A0(bp)) { 9817 - rc = bnxt_hwrm_vnic_ctx_alloc(bp, vnic_id, 1); 9789 + rc = bnxt_hwrm_vnic_ctx_alloc(bp, vnic, 1); 9818 9790 if (rc) { 9819 9791 netdev_err(bp->dev, "hwrm vnic %d cos ctx alloc failure rc: %x\n", 9820 - vnic_id, rc); 9792 + vnic->vnic_id, rc); 9821 9793 goto vnic_setup_err; 9822 9794 } 9823 9795 bp->rsscos_nr_ctxs++; ··· 9824 9798 9825 9799 skip_rss_ctx: 9826 9800 /* configure default vnic, ring grp */ 9827 - rc = bnxt_hwrm_vnic_cfg(bp, vnic_id); 9801 + rc = bnxt_hwrm_vnic_cfg(bp, vnic); 9828 9802 if (rc) { 9829 9803 netdev_err(bp->dev, "hwrm vnic %d cfg failure rc: %x\n", 9830 - vnic_id, rc); 9804 + vnic->vnic_id, rc); 9831 9805 goto vnic_setup_err; 9832 9806 } 9833 9807 9834 9808 /* Enable RSS hashing on vnic */ 9835 - rc = bnxt_hwrm_vnic_set_rss(bp, vnic_id, true); 9809 + rc = bnxt_hwrm_vnic_set_rss(bp, vnic, true); 9836 9810 if (rc) { 9837 9811 netdev_err(bp->dev, "hwrm vnic %d set rss failure rc: %x\n", 9838 - vnic_id, rc); 9812 + vnic->vnic_id, rc); 9839 9813 goto vnic_setup_err; 9840 9814 } 9841 9815 9842 9816 if (bp->flags & BNXT_FLAG_AGG_RINGS) { 9843 - rc = bnxt_hwrm_vnic_set_hds(bp, vnic_id); 9817 + rc = bnxt_hwrm_vnic_set_hds(bp, vnic); 9844 9818 if (rc) { 9845 9819 netdev_err(bp->dev, "hwrm vnic %d set hds failure rc: %x\n", 9846 - vnic_id, rc); 9820 + vnic->vnic_id, rc); 9847 9821 } 9848 9822 } 9849 9823 ··· 9851 9825 return rc; 9852 9826 } 9853 9827 9854 - static int __bnxt_setup_vnic_p5(struct bnxt *bp, u16 vnic_id) 9828 + int bnxt_hwrm_vnic_rss_cfg_p5(struct bnxt *bp, struct bnxt_vnic_info *vnic) 9829 + { 9830 + int rc; 9831 + 9832 + rc = bnxt_hwrm_vnic_set_rss_p5(bp, vnic, true); 9833 + if (rc) { 9834 + netdev_err(bp->dev, "hwrm vnic %d set rss failure rc: %d\n", 9835 + vnic->vnic_id, rc); 9836 + return rc; 9837 + } 9838 + rc = bnxt_hwrm_vnic_cfg(bp, vnic); 9839 + if (rc) 9840 + netdev_err(bp->dev, "hwrm vnic %d cfg failure rc: %x\n", 9841 + vnic->vnic_id, rc); 9842 + return rc; 9843 + } 9844 + 9845 + int __bnxt_setup_vnic_p5(struct bnxt *bp, struct bnxt_vnic_info *vnic) 9855 9846 { 9856 9847 int rc, i, nr_ctxs; 9857 9848 9858 9849 nr_ctxs = bnxt_get_nr_rss_ctxs(bp, bp->rx_nr_rings); 9859 9850 for (i = 0; i < nr_ctxs; i++) { 9860 - rc = bnxt_hwrm_vnic_ctx_alloc(bp, vnic_id, i); 9851 + rc = bnxt_hwrm_vnic_ctx_alloc(bp, vnic, i); 9861 9852 if (rc) { 9862 9853 netdev_err(bp->dev, "hwrm vnic %d ctx %d alloc failure rc: %x\n", 9863 - vnic_id, i, rc); 9854 + vnic->vnic_id, i, rc); 9864 9855 break; 9865 9856 } 9866 9857 bp->rsscos_nr_ctxs++; ··· 9885 9842 if (i < nr_ctxs) 9886 9843 return -ENOMEM; 9887 9844 9888 - rc = bnxt_hwrm_vnic_set_rss_p5(bp, vnic_id, true); 9889 - if (rc) { 9890 - netdev_err(bp->dev, "hwrm vnic %d set rss failure rc: %d\n", 9891 - vnic_id, rc); 9845 + rc = bnxt_hwrm_vnic_rss_cfg_p5(bp, vnic); 9846 + if (rc) 9892 9847 return rc; 9893 - } 9894 - rc = bnxt_hwrm_vnic_cfg(bp, vnic_id); 9895 - if (rc) { 9896 - netdev_err(bp->dev, "hwrm vnic %d cfg failure rc: %x\n", 9897 - vnic_id, rc); 9898 - return rc; 9899 - } 9848 + 9900 9849 if (bp->flags & BNXT_FLAG_AGG_RINGS) { 9901 - rc = bnxt_hwrm_vnic_set_hds(bp, vnic_id); 9850 + rc = bnxt_hwrm_vnic_set_hds(bp, vnic); 9902 9851 if (rc) { 9903 9852 netdev_err(bp->dev, "hwrm vnic %d set hds failure rc: %x\n", 9904 - vnic_id, rc); 9853 + vnic->vnic_id, rc); 9905 9854 } 9906 9855 } 9907 9856 return rc; 9908 9857 } 9909 9858 9910 - static int bnxt_setup_vnic(struct bnxt *bp, u16 vnic_id) 9859 + static int bnxt_setup_vnic(struct bnxt *bp, struct bnxt_vnic_info *vnic) 9911 9860 { 9912 9861 if (bp->flags & BNXT_FLAG_CHIP_P5_PLUS) 9913 - return __bnxt_setup_vnic_p5(bp, vnic_id); 9862 + return __bnxt_setup_vnic_p5(bp, vnic); 9914 9863 else 9915 - return __bnxt_setup_vnic(bp, vnic_id); 9864 + return __bnxt_setup_vnic(bp, vnic); 9916 9865 } 9917 9866 9918 - static int bnxt_alloc_and_setup_vnic(struct bnxt *bp, u16 vnic_id, 9867 + static int bnxt_alloc_and_setup_vnic(struct bnxt *bp, 9868 + struct bnxt_vnic_info *vnic, 9919 9869 u16 start_rx_ring_idx, int rx_rings) 9920 9870 { 9921 9871 int rc; 9922 9872 9923 - rc = bnxt_hwrm_vnic_alloc(bp, vnic_id, start_rx_ring_idx, rx_rings); 9873 + rc = bnxt_hwrm_vnic_alloc(bp, vnic, start_rx_ring_idx, rx_rings); 9924 9874 if (rc) { 9925 9875 netdev_err(bp->dev, "hwrm vnic %d alloc failure rc: %x\n", 9926 - vnic_id, rc); 9876 + vnic->vnic_id, rc); 9927 9877 return rc; 9928 9878 } 9929 - return bnxt_setup_vnic(bp, vnic_id); 9879 + return bnxt_setup_vnic(bp, vnic); 9930 9880 } 9931 9881 9932 9882 static int bnxt_alloc_rfs_vnics(struct bnxt *bp) 9933 9883 { 9884 + struct bnxt_vnic_info *vnic; 9934 9885 int i, rc = 0; 9935 9886 9936 - if (BNXT_SUPPORTS_NTUPLE_VNIC(bp)) 9937 - return bnxt_alloc_and_setup_vnic(bp, BNXT_VNIC_NTUPLE, 0, 9938 - bp->rx_nr_rings); 9887 + if (BNXT_SUPPORTS_NTUPLE_VNIC(bp)) { 9888 + vnic = &bp->vnic_info[BNXT_VNIC_NTUPLE]; 9889 + return bnxt_alloc_and_setup_vnic(bp, vnic, 0, bp->rx_nr_rings); 9890 + } 9939 9891 9940 9892 if (bp->flags & BNXT_FLAG_CHIP_P5_PLUS) 9941 9893 return 0; 9942 9894 9943 9895 for (i = 0; i < bp->rx_nr_rings; i++) { 9944 - struct bnxt_vnic_info *vnic; 9945 9896 u16 vnic_id = i + 1; 9946 9897 u16 ring_id = i; 9947 9898 ··· 9946 9909 vnic->flags |= BNXT_VNIC_RFS_FLAG; 9947 9910 if (bp->rss_cap & BNXT_RSS_CAP_NEW_RSS_CAP) 9948 9911 vnic->flags |= BNXT_VNIC_RFS_NEW_RSS_FLAG; 9949 - if (bnxt_alloc_and_setup_vnic(bp, vnic_id, ring_id, 1)) 9912 + if (bnxt_alloc_and_setup_vnic(bp, &bp->vnic_info[vnic_id], ring_id, 1)) 9950 9913 break; 9951 9914 } 9952 9915 return rc; 9916 + } 9917 + 9918 + void bnxt_del_one_rss_ctx(struct bnxt *bp, struct bnxt_rss_ctx *rss_ctx, 9919 + bool all) 9920 + { 9921 + struct bnxt_vnic_info *vnic = &rss_ctx->vnic; 9922 + struct bnxt_filter_base *usr_fltr, *tmp; 9923 + struct bnxt_ntuple_filter *ntp_fltr; 9924 + int i; 9925 + 9926 + bnxt_hwrm_vnic_free_one(bp, &rss_ctx->vnic); 9927 + for (i = 0; i < BNXT_MAX_CTX_PER_VNIC; i++) { 9928 + if (vnic->fw_rss_cos_lb_ctx[i] != INVALID_HW_RING_ID) 9929 + bnxt_hwrm_vnic_ctx_free_one(bp, vnic, i); 9930 + } 9931 + if (!all) 9932 + return; 9933 + 9934 + list_for_each_entry_safe(usr_fltr, tmp, &bp->usr_fltr_list, list) { 9935 + if ((usr_fltr->flags & BNXT_ACT_RSS_CTX) && 9936 + usr_fltr->fw_vnic_id == rss_ctx->index) { 9937 + ntp_fltr = container_of(usr_fltr, 9938 + struct bnxt_ntuple_filter, 9939 + base); 9940 + bnxt_hwrm_cfa_ntuple_filter_free(bp, ntp_fltr); 9941 + bnxt_del_ntp_filter(bp, ntp_fltr); 9942 + bnxt_del_one_usr_fltr(bp, usr_fltr); 9943 + } 9944 + } 9945 + 9946 + if (vnic->rss_table) 9947 + dma_free_coherent(&bp->pdev->dev, vnic->rss_table_size, 9948 + vnic->rss_table, 9949 + vnic->rss_table_dma_addr); 9950 + kfree(rss_ctx->rss_indir_tbl); 9951 + list_del(&rss_ctx->list); 9952 + bp->num_rss_ctx--; 9953 + clear_bit(rss_ctx->index, bp->rss_ctx_bmap); 9954 + kfree(rss_ctx); 9955 + } 9956 + 9957 + static void bnxt_hwrm_realloc_rss_ctx_vnic(struct bnxt *bp) 9958 + { 9959 + bool set_tpa = !!(bp->flags & BNXT_FLAG_TPA); 9960 + struct bnxt_rss_ctx *rss_ctx, *tmp; 9961 + 9962 + list_for_each_entry_safe(rss_ctx, tmp, &bp->rss_ctx_list, list) { 9963 + struct bnxt_vnic_info *vnic = &rss_ctx->vnic; 9964 + 9965 + if (bnxt_hwrm_vnic_alloc(bp, vnic, 0, bp->rx_nr_rings) || 9966 + bnxt_hwrm_vnic_set_tpa(bp, vnic, set_tpa) || 9967 + __bnxt_setup_vnic_p5(bp, vnic)) { 9968 + netdev_err(bp->dev, "Failed to restore RSS ctx %d\n", 9969 + rss_ctx->index); 9970 + bnxt_del_one_rss_ctx(bp, rss_ctx, true); 9971 + } 9972 + } 9973 + } 9974 + 9975 + struct bnxt_rss_ctx *bnxt_alloc_rss_ctx(struct bnxt *bp) 9976 + { 9977 + struct bnxt_rss_ctx *rss_ctx = NULL; 9978 + 9979 + rss_ctx = kzalloc(sizeof(*rss_ctx), GFP_KERNEL); 9980 + if (rss_ctx) { 9981 + rss_ctx->vnic.rss_ctx = rss_ctx; 9982 + list_add_tail(&rss_ctx->list, &bp->rss_ctx_list); 9983 + bp->num_rss_ctx++; 9984 + } 9985 + return rss_ctx; 9986 + } 9987 + 9988 + void bnxt_clear_rss_ctxs(struct bnxt *bp, bool all) 9989 + { 9990 + struct bnxt_rss_ctx *rss_ctx, *tmp; 9991 + 9992 + list_for_each_entry_safe(rss_ctx, tmp, &bp->rss_ctx_list, list) 9993 + bnxt_del_one_rss_ctx(bp, rss_ctx, all); 9994 + 9995 + if (all) 9996 + bitmap_free(bp->rss_ctx_bmap); 9997 + } 9998 + 9999 + static void bnxt_init_multi_rss_ctx(struct bnxt *bp) 10000 + { 10001 + bp->rss_ctx_bmap = bitmap_zalloc(BNXT_RSS_CTX_BMAP_LEN, GFP_KERNEL); 10002 + if (bp->rss_ctx_bmap) { 10003 + /* burn index 0 since we cannot have context 0 */ 10004 + __set_bit(0, bp->rss_ctx_bmap); 10005 + INIT_LIST_HEAD(&bp->rss_ctx_list); 10006 + bp->rss_cap |= BNXT_RSS_CAP_MULTI_RSS_CTX; 10007 + } 9953 10008 } 9954 10009 9955 10010 /* Allow PF, trusted VFs and VFs with default VLAN to be in promiscuous mode */ ··· 10056 9927 10057 9928 static int bnxt_setup_nitroa0_vnic(struct bnxt *bp) 10058 9929 { 9930 + struct bnxt_vnic_info *vnic = &bp->vnic_info[1]; 10059 9931 unsigned int rc = 0; 10060 9932 10061 - rc = bnxt_hwrm_vnic_alloc(bp, 1, bp->rx_nr_rings - 1, 1); 9933 + rc = bnxt_hwrm_vnic_alloc(bp, vnic, bp->rx_nr_rings - 1, 1); 10062 9934 if (rc) { 10063 9935 netdev_err(bp->dev, "Cannot allocate special vnic for NS2 A0: %x\n", 10064 9936 rc); 10065 9937 return rc; 10066 9938 } 10067 9939 10068 - rc = bnxt_hwrm_vnic_cfg(bp, 1); 9940 + rc = bnxt_hwrm_vnic_cfg(bp, vnic); 10069 9941 if (rc) { 10070 9942 netdev_err(bp->dev, "Cannot allocate special vnic for NS2 A0: %x\n", 10071 9943 rc); ··· 10109 9979 rx_nr_rings--; 10110 9980 10111 9981 /* default vnic 0 */ 10112 - rc = bnxt_hwrm_vnic_alloc(bp, BNXT_VNIC_DEFAULT, 0, rx_nr_rings); 9982 + rc = bnxt_hwrm_vnic_alloc(bp, vnic, 0, rx_nr_rings); 10113 9983 if (rc) { 10114 9984 netdev_err(bp->dev, "hwrm vnic alloc failure rc: %x\n", rc); 10115 9985 goto err_out; ··· 10118 9988 if (BNXT_VF(bp)) 10119 9989 bnxt_hwrm_func_qcfg(bp); 10120 9990 10121 - rc = bnxt_setup_vnic(bp, BNXT_VNIC_DEFAULT); 9991 + rc = bnxt_setup_vnic(bp, vnic); 10122 9992 if (rc) 10123 9993 goto err_out; 10124 9994 if (bp->rss_cap & BNXT_RSS_CAP_RSS_HASH_TYPE_DELTA) ··· 11890 11760 bnxt_vf_reps_open(bp); 11891 11761 bnxt_ptp_init_rtc(bp, true); 11892 11762 bnxt_ptp_cfg_tstamp_filters(bp); 11763 + if (BNXT_SUPPORTS_MULTI_RSS_CTX(bp)) 11764 + bnxt_hwrm_realloc_rss_ctx_vnic(bp); 11893 11765 bnxt_cfg_usr_fltrs(bp); 11894 11766 return 0; 11895 11767 ··· 12040 11908 while (bnxt_drv_busy(bp)) 12041 11909 msleep(20); 12042 11910 11911 + if (BNXT_SUPPORTS_MULTI_RSS_CTX(bp)) 11912 + bnxt_clear_rss_ctxs(bp, false); 12043 11913 /* Flush rings and disable interrupts */ 12044 11914 bnxt_shutdown_nic(bp, irq_re_init); 12045 11915 ··· 12539 12405 } 12540 12406 12541 12407 /* If runtime conditions support RFS */ 12542 - static bool bnxt_rfs_capable(struct bnxt *bp) 12408 + bool bnxt_rfs_capable(struct bnxt *bp, bool new_rss_ctx) 12543 12409 { 12544 12410 struct bnxt_hw_rings hwr = {0}; 12545 12411 int max_vnics, max_rss_ctxs; 12546 12412 12547 - hwr.rss_ctx = 1; 12548 - if (BNXT_SUPPORTS_NTUPLE_VNIC(bp)) { 12549 - /* 2 VNICS: default + Ntuple */ 12550 - hwr.vnic = 2; 12551 - hwr.rss_ctx = bnxt_get_nr_rss_ctxs(bp, bp->rx_nr_rings) * 12552 - hwr.vnic; 12553 - goto check_reserve_vnic; 12554 - } 12555 - if (bp->flags & BNXT_FLAG_CHIP_P5_PLUS) 12413 + if ((bp->flags & BNXT_FLAG_CHIP_P5_PLUS) && 12414 + !BNXT_SUPPORTS_NTUPLE_VNIC(bp)) 12556 12415 return bnxt_rfs_supported(bp); 12416 + 12557 12417 if (!(bp->flags & BNXT_FLAG_MSIX_CAP) || !bnxt_can_reserve_rings(bp) || !bp->rx_nr_rings) 12558 12418 return false; 12559 12419 12560 - hwr.vnic = 1 + bp->rx_nr_rings; 12561 - check_reserve_vnic: 12420 + hwr.grp = bp->rx_nr_rings; 12421 + hwr.vnic = bnxt_get_total_vnics(bp, bp->rx_nr_rings); 12422 + if (new_rss_ctx) 12423 + hwr.vnic++; 12424 + hwr.rss_ctx = bnxt_get_total_rss_ctxs(bp, &hwr); 12562 12425 max_vnics = bnxt_get_max_func_vnics(bp); 12563 12426 max_rss_ctxs = bnxt_get_max_func_rss_ctxs(bp); 12564 - 12565 - if (!(bp->flags & BNXT_FLAG_CHIP_P5_PLUS) && 12566 - !(bp->rss_cap & BNXT_RSS_CAP_NEW_RSS_CAP)) 12567 - hwr.rss_ctx = hwr.vnic; 12568 12427 12569 12428 if (hwr.vnic > max_vnics || hwr.rss_ctx > max_rss_ctxs) { 12570 12429 if (bp->rx_nr_rings > 1) ··· 12592 12465 struct bnxt *bp = netdev_priv(dev); 12593 12466 netdev_features_t vlan_features; 12594 12467 12595 - if ((features & NETIF_F_NTUPLE) && !bnxt_rfs_capable(bp)) 12468 + if ((features & NETIF_F_NTUPLE) && !bnxt_rfs_capable(bp, false)) 12596 12469 features &= ~NETIF_F_NTUPLE; 12597 12470 12598 12471 if ((bp->flags & BNXT_FLAG_NO_AGG_RINGS) || bp->xdp_prog) ··· 13728 13601 bp->flags &= ~BNXT_FLAG_RFS; 13729 13602 if (bnxt_rfs_supported(bp)) { 13730 13603 dev->hw_features |= NETIF_F_NTUPLE; 13731 - if (bnxt_rfs_capable(bp)) { 13604 + if (bnxt_rfs_capable(bp, false)) { 13732 13605 bp->flags |= BNXT_FLAG_RFS; 13733 13606 dev->features |= NETIF_F_NTUPLE; 13734 13607 } ··· 14728 14601 unregister_netdev(dev); 14729 14602 bnxt_free_l2_filters(bp, true); 14730 14603 bnxt_free_ntp_fltrs(bp, true); 14604 + if (BNXT_SUPPORTS_MULTI_RSS_CTX(bp)) 14605 + bnxt_clear_rss_ctxs(bp, true); 14731 14606 clear_bit(BNXT_STATE_IN_FW_RESET, &bp->state); 14732 14607 /* Flush any pending tasks */ 14733 14608 cancel_work_sync(&bp->sp_task); ··· 15188 15059 bp->flags |= BNXT_FLAG_CHIP_P7; 15189 15060 } 15190 15061 15191 - rc = bnxt_alloc_rss_indir_tbl(bp); 15062 + rc = bnxt_alloc_rss_indir_tbl(bp, NULL); 15192 15063 if (rc) 15193 15064 goto init_err_pci_clean; 15194 15065 ··· 15341 15212 15342 15213 INIT_LIST_HEAD(&bp->usr_fltr_list); 15343 15214 15215 + if (BNXT_SUPPORTS_NTUPLE_VNIC(bp)) 15216 + bnxt_init_multi_rss_ctx(bp); 15217 + 15344 15218 rc = register_netdev(dev); 15345 15219 if (rc) 15346 15220 goto init_err_cleanup; ··· 15364 15232 bnxt_clear_int_mode(bp); 15365 15233 15366 15234 init_err_pci_clean: 15235 + if (BNXT_SUPPORTS_MULTI_RSS_CTX(bp)) 15236 + bnxt_clear_rss_ctxs(bp, true); 15367 15237 bnxt_hwrm_func_drv_unrgtr(bp); 15368 15238 bnxt_free_hwrm_resources(bp); 15369 15239 bnxt_hwmon_uninit(bp);
+38 -1
drivers/net/ethernet/broadcom/bnxt/bnxt.h
··· 1256 1256 #define BNXT_VNIC_UCAST_FLAG 8 1257 1257 #define BNXT_VNIC_RFS_NEW_RSS_FLAG 0x10 1258 1258 #define BNXT_VNIC_NTUPLE_FLAG 0x20 1259 + #define BNXT_VNIC_RSSCTX_FLAG 0x40 1260 + struct bnxt_rss_ctx *rss_ctx; 1261 + u32 vnic_id; 1259 1262 }; 1263 + 1264 + struct bnxt_rss_ctx { 1265 + struct list_head list; 1266 + struct bnxt_vnic_info vnic; 1267 + u16 *rss_indir_tbl; 1268 + u8 index; 1269 + }; 1270 + 1271 + #define BNXT_MAX_ETH_RSS_CTX 32 1272 + #define BNXT_RSS_CTX_BMAP_LEN (BNXT_MAX_ETH_RSS_CTX + 1) 1273 + #define BNXT_VNIC_ID_INVALID 0xffffffff 1260 1274 1261 1275 struct bnxt_hw_rings { 1262 1276 int tx; ··· 1374 1360 #define BNXT_ACT_RING_DST 2 1375 1361 #define BNXT_ACT_FUNC_DST 4 1376 1362 #define BNXT_ACT_NO_AGING 8 1363 + #define BNXT_ACT_RSS_CTX 0x10 1377 1364 u16 sw_id; 1378 1365 u16 rxq; 1379 1366 u16 fw_vnic_id; ··· 2242 2227 /* grp_info indexed by completion ring index */ 2243 2228 struct bnxt_ring_grp_info *grp_info; 2244 2229 struct bnxt_vnic_info *vnic_info; 2230 + struct list_head rss_ctx_list; 2231 + unsigned long *rss_ctx_bmap; 2232 + u32 num_rss_ctx; 2245 2233 int nr_vnics; 2246 2234 u16 *rss_indir_tbl; 2247 2235 u16 rss_indir_tbl_entries; ··· 2259 2241 #define BNXT_RSS_CAP_AH_V6_RSS_CAP BIT(5) 2260 2242 #define BNXT_RSS_CAP_ESP_V4_RSS_CAP BIT(6) 2261 2243 #define BNXT_RSS_CAP_ESP_V6_RSS_CAP BIT(7) 2244 + #define BNXT_RSS_CAP_MULTI_RSS_CTX BIT(8) 2262 2245 2263 2246 u8 rss_hash_key[HW_HASH_KEY_SIZE]; 2264 2247 u8 rss_hash_key_valid:1; ··· 2358 2339 ((bp)->fw_cap & BNXT_FW_CAP_PTP_RTC)) 2359 2340 #define BNXT_SUPPORTS_NTUPLE_VNIC(bp) \ 2360 2341 (BNXT_PF(bp) && ((bp)->fw_cap & BNXT_FW_CAP_CFA_RFS_RING_TBL_IDX_V3)) 2342 + 2343 + #define BNXT_SUPPORTS_MULTI_RSS_CTX(bp) \ 2344 + (BNXT_PF(bp) && BNXT_SUPPORTS_NTUPLE_VNIC(bp) && \ 2345 + ((bp)->rss_cap & BNXT_RSS_CAP_MULTI_RSS_CTX)) 2361 2346 2362 2347 u32 hwrm_spec_code; 2363 2348 u16 hwrm_cmd_seq; ··· 2716 2693 struct bnxt_ntuple_filter *fltr); 2717 2694 int bnxt_hwrm_cfa_ntuple_filter_alloc(struct bnxt *bp, 2718 2695 struct bnxt_ntuple_filter *fltr); 2696 + int bnxt_hwrm_vnic_set_tpa(struct bnxt *bp, struct bnxt_vnic_info *vnic, 2697 + u32 tpa_flags); 2719 2698 void bnxt_fill_ipv6_mask(__be32 mask[4]); 2699 + int bnxt_alloc_rss_indir_tbl(struct bnxt *bp, struct bnxt_rss_ctx *rss_ctx); 2700 + void bnxt_set_dflt_rss_indir_tbl(struct bnxt *bp, struct bnxt_rss_ctx *rss_ctx); 2720 2701 int bnxt_get_nr_rss_ctxs(struct bnxt *bp, int rx_rings); 2721 - int bnxt_hwrm_vnic_cfg(struct bnxt *bp, u16 vnic_id); 2702 + int bnxt_hwrm_vnic_cfg(struct bnxt *bp, struct bnxt_vnic_info *vnic); 2703 + int bnxt_hwrm_vnic_alloc(struct bnxt *bp, struct bnxt_vnic_info *vnic, 2704 + unsigned int start_rx_ring_idx, 2705 + unsigned int nr_rings); 2722 2706 int __bnxt_hwrm_get_tx_rings(struct bnxt *bp, u16 fid, int *tx_rings); 2723 2707 int bnxt_nq_rings_in_use(struct bnxt *bp); 2724 2708 int bnxt_hwrm_set_coal(struct bnxt *); ··· 2751 2721 int bnxt_hwrm_func_resc_qcaps(struct bnxt *bp, bool all); 2752 2722 int bnxt_hwrm_func_qcaps(struct bnxt *bp); 2753 2723 int bnxt_hwrm_fw_set_time(struct bnxt *); 2724 + int bnxt_hwrm_vnic_rss_cfg_p5(struct bnxt *bp, struct bnxt_vnic_info *vnic); 2725 + int __bnxt_setup_vnic_p5(struct bnxt *bp, struct bnxt_vnic_info *vnic); 2726 + void bnxt_del_one_rss_ctx(struct bnxt *bp, struct bnxt_rss_ctx *rss_ctx, 2727 + bool all); 2728 + struct bnxt_rss_ctx *bnxt_alloc_rss_ctx(struct bnxt *bp); 2729 + void bnxt_clear_rss_ctxs(struct bnxt *bp, bool all); 2754 2730 int bnxt_open_nic(struct bnxt *, bool, bool); 2755 2731 int bnxt_half_open_nic(struct bnxt *bp); 2756 2732 void bnxt_half_close_nic(struct bnxt *bp); ··· 2764 2728 void bnxt_close_nic(struct bnxt *, bool, bool); 2765 2729 void bnxt_get_ring_err_stats(struct bnxt *bp, 2766 2730 struct bnxt_total_ring_err_stats *stats); 2731 + bool bnxt_rfs_capable(struct bnxt *bp, bool new_rss_ctx); 2767 2732 int bnxt_dbg_hwrm_rd_reg(struct bnxt *bp, u32 reg_off, u16 num_words, 2768 2733 u32 *reg_buf); 2769 2734 void bnxt_fw_exception(struct bnxt *bp);
+198 -23
drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c
··· 969 969 } 970 970 971 971 bnxt_clear_usr_fltrs(bp, true); 972 + if (BNXT_SUPPORTS_MULTI_RSS_CTX(bp)) 973 + bnxt_clear_rss_ctxs(bp, false); 972 974 if (netif_running(dev)) { 973 975 if (BNXT_PF(bp)) { 974 976 /* TODO CHIMP_FW: Send message to all VF's ··· 1207 1205 return rc; 1208 1206 } 1209 1207 1208 + static struct bnxt_rss_ctx *bnxt_get_rss_ctx_from_index(struct bnxt *bp, 1209 + u32 index) 1210 + { 1211 + struct bnxt_rss_ctx *rss_ctx, *tmp; 1212 + 1213 + list_for_each_entry_safe(rss_ctx, tmp, &bp->rss_ctx_list, list) 1214 + if (rss_ctx->index == index) 1215 + return rss_ctx; 1216 + return NULL; 1217 + } 1218 + 1219 + static int bnxt_alloc_rss_ctx_rss_table(struct bnxt *bp, 1220 + struct bnxt_rss_ctx *rss_ctx) 1221 + { 1222 + int size = L1_CACHE_ALIGN(BNXT_MAX_RSS_TABLE_SIZE_P5); 1223 + struct bnxt_vnic_info *vnic = &rss_ctx->vnic; 1224 + 1225 + vnic->rss_table_size = size + HW_HASH_KEY_SIZE; 1226 + vnic->rss_table = dma_alloc_coherent(&bp->pdev->dev, 1227 + vnic->rss_table_size, 1228 + &vnic->rss_table_dma_addr, 1229 + GFP_KERNEL); 1230 + if (!vnic->rss_table) 1231 + return -ENOMEM; 1232 + 1233 + vnic->rss_hash_key = ((void *)vnic->rss_table) + size; 1234 + vnic->rss_hash_key_dma_addr = vnic->rss_table_dma_addr + size; 1235 + return 0; 1236 + } 1237 + 1210 1238 static int bnxt_add_l2_cls_rule(struct bnxt *bp, 1211 1239 struct ethtool_rx_flow_spec *fs) 1212 1240 { ··· 1312 1280 } 1313 1281 1314 1282 static int bnxt_add_ntuple_cls_rule(struct bnxt *bp, 1315 - struct ethtool_rx_flow_spec *fs) 1283 + struct ethtool_rxnfc *cmd) 1316 1284 { 1317 - u8 vf = ethtool_get_flow_spec_ring_vf(fs->ring_cookie); 1318 - u32 ring = ethtool_get_flow_spec_ring(fs->ring_cookie); 1285 + struct ethtool_rx_flow_spec *fs = &cmd->fs; 1319 1286 struct bnxt_ntuple_filter *new_fltr, *fltr; 1287 + u32 flow_type = fs->flow_type & 0xff; 1320 1288 struct bnxt_l2_filter *l2_fltr; 1321 1289 struct bnxt_flow_masks *fmasks; 1322 - u32 flow_type = fs->flow_type; 1323 1290 struct flow_keys *fkeys; 1324 - u32 idx; 1291 + u32 idx, ring; 1325 1292 int rc; 1293 + u8 vf; 1326 1294 1327 1295 if (!bp->vnic_info) 1328 1296 return -EAGAIN; 1329 1297 1330 - if ((flow_type & (FLOW_MAC_EXT | FLOW_EXT)) || vf) 1298 + vf = ethtool_get_flow_spec_ring_vf(fs->ring_cookie); 1299 + ring = ethtool_get_flow_spec_ring(fs->ring_cookie); 1300 + if ((fs->flow_type & (FLOW_MAC_EXT | FLOW_EXT)) || vf) 1331 1301 return -EOPNOTSUPP; 1332 1302 1333 1303 if (flow_type == IP_USER_FLOW) { ··· 1437 1403 rcu_read_unlock(); 1438 1404 1439 1405 new_fltr->base.flags = BNXT_ACT_NO_AGING; 1406 + if (fs->flow_type & FLOW_RSS) { 1407 + struct bnxt_rss_ctx *rss_ctx; 1408 + 1409 + new_fltr->base.fw_vnic_id = 0; 1410 + new_fltr->base.flags |= BNXT_ACT_RSS_CTX; 1411 + rss_ctx = bnxt_get_rss_ctx_from_index(bp, cmd->rss_context); 1412 + if (rss_ctx) { 1413 + new_fltr->base.fw_vnic_id = rss_ctx->index; 1414 + } else { 1415 + rc = -EINVAL; 1416 + goto ntuple_err; 1417 + } 1418 + } 1440 1419 if (fs->ring_cookie == RX_CLS_FLOW_DISC) 1441 1420 new_fltr->base.flags |= BNXT_ACT_DROP; 1442 1421 else ··· 1491 1444 flow_type == IPV6_USER_FLOW) && 1492 1445 !(bp->fw_cap & BNXT_FW_CAP_CFA_NTUPLE_RX_EXT_IP_PROTO)) 1493 1446 return -EOPNOTSUPP; 1494 - if (flow_type & (FLOW_MAC_EXT | FLOW_RSS)) 1447 + if (flow_type & FLOW_MAC_EXT) 1495 1448 return -EINVAL; 1496 1449 flow_type &= ~FLOW_EXT; 1497 1450 1498 1451 if (fs->ring_cookie == RX_CLS_FLOW_DISC && flow_type != ETHER_FLOW) 1499 - return bnxt_add_ntuple_cls_rule(bp, fs); 1452 + return bnxt_add_ntuple_cls_rule(bp, cmd); 1500 1453 1501 1454 ring = ethtool_get_flow_spec_ring(fs->ring_cookie); 1502 1455 vf = ethtool_get_flow_spec_ring_vf(fs->ring_cookie); ··· 1510 1463 if (flow_type == ETHER_FLOW) 1511 1464 rc = bnxt_add_l2_cls_rule(bp, fs); 1512 1465 else 1513 - rc = bnxt_add_ntuple_cls_rule(bp, fs); 1466 + rc = bnxt_add_ntuple_cls_rule(bp, cmd); 1514 1467 return rc; 1515 1468 } 1516 1469 ··· 1801 1754 static int bnxt_get_rxfh(struct net_device *dev, 1802 1755 struct ethtool_rxfh_param *rxfh) 1803 1756 { 1757 + u32 rss_context = rxfh->rss_context; 1758 + struct bnxt_rss_ctx *rss_ctx = NULL; 1804 1759 struct bnxt *bp = netdev_priv(dev); 1760 + u16 *indir_tbl = bp->rss_indir_tbl; 1805 1761 struct bnxt_vnic_info *vnic; 1806 1762 u32 i, tbl_size; 1807 1763 ··· 1814 1764 return 0; 1815 1765 1816 1766 vnic = &bp->vnic_info[BNXT_VNIC_DEFAULT]; 1817 - if (rxfh->indir && bp->rss_indir_tbl) { 1767 + if (rxfh->rss_context) { 1768 + rss_ctx = bnxt_get_rss_ctx_from_index(bp, rss_context); 1769 + if (!rss_ctx) 1770 + return -EINVAL; 1771 + indir_tbl = rss_ctx->rss_indir_tbl; 1772 + vnic = &rss_ctx->vnic; 1773 + } 1774 + 1775 + if (rxfh->indir && indir_tbl) { 1818 1776 tbl_size = bnxt_get_rxfh_indir_size(dev); 1819 1777 for (i = 0; i < tbl_size; i++) 1820 - rxfh->indir[i] = bp->rss_indir_tbl[i]; 1778 + rxfh->indir[i] = indir_tbl[i]; 1821 1779 } 1822 1780 1823 1781 if (rxfh->key && vnic->rss_hash_key) 1824 1782 memcpy(rxfh->key, vnic->rss_hash_key, HW_HASH_KEY_SIZE); 1825 1783 1826 1784 return 0; 1785 + } 1786 + 1787 + static void bnxt_modify_rss(struct bnxt *bp, struct bnxt_rss_ctx *rss_ctx, 1788 + struct ethtool_rxfh_param *rxfh) 1789 + { 1790 + if (rxfh->key) { 1791 + if (rss_ctx) { 1792 + memcpy(rss_ctx->vnic.rss_hash_key, rxfh->key, 1793 + HW_HASH_KEY_SIZE); 1794 + } else { 1795 + memcpy(bp->rss_hash_key, rxfh->key, HW_HASH_KEY_SIZE); 1796 + bp->rss_hash_key_updated = true; 1797 + } 1798 + } 1799 + if (rxfh->indir) { 1800 + u32 i, pad, tbl_size = bnxt_get_rxfh_indir_size(bp->dev); 1801 + u16 *indir_tbl = bp->rss_indir_tbl; 1802 + 1803 + if (rss_ctx) 1804 + indir_tbl = rss_ctx->rss_indir_tbl; 1805 + for (i = 0; i < tbl_size; i++) 1806 + indir_tbl[i] = rxfh->indir[i]; 1807 + pad = bp->rss_indir_tbl_entries - tbl_size; 1808 + if (pad) 1809 + memset(&bp->rss_indir_tbl[i], 0, pad * sizeof(u16)); 1810 + } 1811 + } 1812 + 1813 + static int bnxt_set_rxfh_context(struct bnxt *bp, 1814 + struct ethtool_rxfh_param *rxfh, 1815 + struct netlink_ext_ack *extack) 1816 + { 1817 + u32 *rss_context = &rxfh->rss_context; 1818 + struct bnxt_rss_ctx *rss_ctx; 1819 + struct bnxt_vnic_info *vnic; 1820 + bool modify = false; 1821 + int bit_id; 1822 + int rc; 1823 + 1824 + if (!BNXT_SUPPORTS_MULTI_RSS_CTX(bp)) { 1825 + NL_SET_ERR_MSG_MOD(extack, "RSS contexts not supported"); 1826 + return -EOPNOTSUPP; 1827 + } 1828 + 1829 + if (*rss_context != ETH_RXFH_CONTEXT_ALLOC) { 1830 + rss_ctx = bnxt_get_rss_ctx_from_index(bp, *rss_context); 1831 + if (!rss_ctx) { 1832 + NL_SET_ERR_MSG_FMT_MOD(extack, "RSS context %u not found", 1833 + *rss_context); 1834 + return -EINVAL; 1835 + } 1836 + if (*rss_context && rxfh->rss_delete) { 1837 + bnxt_del_one_rss_ctx(bp, rss_ctx, true); 1838 + return 0; 1839 + } 1840 + modify = true; 1841 + vnic = &rss_ctx->vnic; 1842 + goto modify_context; 1843 + } 1844 + 1845 + if (bp->num_rss_ctx >= BNXT_MAX_ETH_RSS_CTX) { 1846 + NL_SET_ERR_MSG_FMT_MOD(extack, "Out of RSS contexts, maximum %u", 1847 + BNXT_MAX_ETH_RSS_CTX); 1848 + return -EINVAL; 1849 + } 1850 + 1851 + if (!bnxt_rfs_capable(bp, true)) { 1852 + NL_SET_ERR_MSG_MOD(extack, "Out hardware resources"); 1853 + return -ENOMEM; 1854 + } 1855 + 1856 + rss_ctx = bnxt_alloc_rss_ctx(bp); 1857 + if (!rss_ctx) 1858 + return -ENOMEM; 1859 + 1860 + vnic = &rss_ctx->vnic; 1861 + vnic->flags |= BNXT_VNIC_RSSCTX_FLAG; 1862 + vnic->vnic_id = BNXT_VNIC_ID_INVALID; 1863 + rc = bnxt_alloc_rss_ctx_rss_table(bp, rss_ctx); 1864 + if (rc) 1865 + goto out; 1866 + 1867 + rc = bnxt_alloc_rss_indir_tbl(bp, rss_ctx); 1868 + if (rc) 1869 + goto out; 1870 + 1871 + bnxt_set_dflt_rss_indir_tbl(bp, rss_ctx); 1872 + memcpy(vnic->rss_hash_key, bp->rss_hash_key, HW_HASH_KEY_SIZE); 1873 + 1874 + rc = bnxt_hwrm_vnic_alloc(bp, vnic, 0, bp->rx_nr_rings); 1875 + if (rc) { 1876 + NL_SET_ERR_MSG_MOD(extack, "Unable to allocate VNIC"); 1877 + goto out; 1878 + } 1879 + 1880 + rc = bnxt_hwrm_vnic_set_tpa(bp, vnic, bp->flags & BNXT_FLAG_TPA); 1881 + if (rc) { 1882 + NL_SET_ERR_MSG_MOD(extack, "Unable to setup TPA"); 1883 + goto out; 1884 + } 1885 + modify_context: 1886 + bnxt_modify_rss(bp, rss_ctx, rxfh); 1887 + 1888 + if (modify) 1889 + return bnxt_hwrm_vnic_rss_cfg_p5(bp, vnic); 1890 + 1891 + rc = __bnxt_setup_vnic_p5(bp, vnic); 1892 + if (rc) { 1893 + NL_SET_ERR_MSG_MOD(extack, "Unable to setup TPA"); 1894 + goto out; 1895 + } 1896 + 1897 + bit_id = bitmap_find_free_region(bp->rss_ctx_bmap, 1898 + BNXT_RSS_CTX_BMAP_LEN, 0); 1899 + if (bit_id < 0) { 1900 + rc = -ENOMEM; 1901 + goto out; 1902 + } 1903 + rss_ctx->index = (u16)bit_id; 1904 + *rss_context = rss_ctx->index; 1905 + 1906 + return 0; 1907 + out: 1908 + bnxt_del_one_rss_ctx(bp, rss_ctx, true); 1909 + return rc; 1827 1910 } 1828 1911 1829 1912 static int bnxt_set_rxfh(struct net_device *dev, ··· 1969 1786 if (rxfh->hfunc && rxfh->hfunc != ETH_RSS_HASH_TOP) 1970 1787 return -EOPNOTSUPP; 1971 1788 1972 - if (rxfh->key) { 1973 - memcpy(bp->rss_hash_key, rxfh->key, HW_HASH_KEY_SIZE); 1974 - bp->rss_hash_key_updated = true; 1975 - } 1789 + if (rxfh->rss_context) 1790 + return bnxt_set_rxfh_context(bp, rxfh, extack); 1976 1791 1977 - if (rxfh->indir) { 1978 - u32 i, pad, tbl_size = bnxt_get_rxfh_indir_size(dev); 1792 + bnxt_modify_rss(bp, NULL, rxfh); 1979 1793 1980 - for (i = 0; i < tbl_size; i++) 1981 - bp->rss_indir_tbl[i] = rxfh->indir[i]; 1982 - pad = bp->rss_indir_tbl_entries - tbl_size; 1983 - if (pad) 1984 - memset(&bp->rss_indir_tbl[i], 0, pad * sizeof(u16)); 1985 - } 1986 1794 bnxt_clear_usr_fltrs(bp, false); 1987 1795 if (netif_running(bp->dev)) { 1988 1796 bnxt_close_nic(bp, false, false); ··· 5245 5071 5246 5072 const struct ethtool_ops bnxt_ethtool_ops = { 5247 5073 .cap_link_lanes_supported = 1, 5074 + .cap_rss_ctx_supported = 1, 5248 5075 .supported_coalesce_params = ETHTOOL_COALESCE_USECS | 5249 5076 ETHTOOL_COALESCE_MAX_FRAMES | 5250 5077 ETHTOOL_COALESCE_USECS_IRQ |
+26 -4
drivers/net/ethernet/broadcom/bnxt/bnxt_ptp.c
··· 109 109 spin_unlock_bh(&ptp->ptp_lock); 110 110 } 111 111 112 - static int bnxt_hwrm_port_ts_query(struct bnxt *bp, u32 flags, u64 *ts) 112 + static int bnxt_hwrm_port_ts_query(struct bnxt *bp, u32 flags, u64 *ts, 113 + u32 txts_tmo) 113 114 { 114 115 struct hwrm_port_ts_query_output *resp; 115 116 struct hwrm_port_ts_query_input *req; ··· 123 122 req->flags = cpu_to_le32(flags); 124 123 if ((flags & PORT_TS_QUERY_REQ_FLAGS_PATH) == 125 124 PORT_TS_QUERY_REQ_FLAGS_PATH_TX) { 125 + u32 tmo_us = txts_tmo * 1000; 126 + 126 127 req->enables = cpu_to_le16(BNXT_PTP_QTS_TX_ENABLES); 127 128 req->ptp_seq_id = cpu_to_le32(bp->ptp_cfg->tx_seqid); 128 129 req->ptp_hdr_offset = cpu_to_le16(bp->ptp_cfg->tx_hdr_off); 129 - req->ts_req_timeout = cpu_to_le16(BNXT_PTP_QTS_TIMEOUT); 130 + if (!tmo_us) 131 + tmo_us = BNXT_PTP_QTS_TIMEOUT; 132 + tmo_us = min(tmo_us, BNXT_PTP_QTS_MAX_TMO_US); 133 + req->ts_req_timeout = cpu_to_le16(txts_tmo); 130 134 } 131 135 resp = hwrm_req_hold(bp, req); 132 136 ··· 678 672 { 679 673 struct bnxt_ptp_cfg *ptp = bp->ptp_cfg; 680 674 struct skb_shared_hwtstamps timestamp; 675 + unsigned long now = jiffies; 681 676 u64 ts = 0, ns = 0; 677 + u32 tmo = 0; 682 678 int rc; 683 679 684 - rc = bnxt_hwrm_port_ts_query(bp, PORT_TS_QUERY_REQ_FLAGS_PATH_TX, &ts); 680 + if (!ptp->txts_pending) 681 + ptp->abs_txts_tmo = now + msecs_to_jiffies(ptp->txts_tmo); 682 + if (!time_after_eq(now, ptp->abs_txts_tmo)) 683 + tmo = jiffies_to_msecs(ptp->abs_txts_tmo - now); 684 + rc = bnxt_hwrm_port_ts_query(bp, PORT_TS_QUERY_REQ_FLAGS_PATH_TX, &ts, 685 + tmo); 685 686 if (!rc) { 686 687 memset(&timestamp, 0, sizeof(timestamp)); 687 688 spin_lock_bh(&ptp->ptp_lock); ··· 697 684 timestamp.hwtstamp = ns_to_ktime(ns); 698 685 skb_tstamp_tx(ptp->tx_skb, &timestamp); 699 686 } else { 687 + if (!time_after_eq(jiffies, ptp->abs_txts_tmo)) { 688 + ptp->txts_pending = true; 689 + return; 690 + } 700 691 netdev_warn_once(bp->dev, 701 692 "TS query for TX timer failed rc = %x\n", rc); 702 693 } ··· 708 691 dev_kfree_skb_any(ptp->tx_skb); 709 692 ptp->tx_skb = NULL; 710 693 atomic_inc(&ptp->tx_avail); 694 + ptp->txts_pending = false; 711 695 } 712 696 713 697 static long bnxt_ptp_ts_aux_work(struct ptp_clock_info *ptp_info) ··· 732 714 spin_unlock_bh(&ptp->ptp_lock); 733 715 ptp->next_overflow_check = now + BNXT_PHC_OVERFLOW_PERIOD; 734 716 } 717 + if (ptp->txts_pending) 718 + return 0; 735 719 return HZ; 736 720 } 737 721 ··· 911 891 if (rc) 912 892 return rc; 913 893 } else { 914 - rc = bnxt_hwrm_port_ts_query(bp, PORT_TS_QUERY_REQ_FLAGS_CURRENT_TIME, &ns); 894 + rc = bnxt_hwrm_port_ts_query(bp, PORT_TS_QUERY_REQ_FLAGS_CURRENT_TIME, 895 + &ns, 0); 915 896 if (rc) 916 897 return rc; 917 898 } ··· 986 965 spin_unlock_bh(&ptp->ptp_lock); 987 966 ptp_schedule_worker(ptp->ptp_clock, 0); 988 967 } 968 + ptp->txts_tmo = BNXT_PTP_DFLT_TX_TMO; 989 969 return 0; 990 970 991 971 out:
+5
drivers/net/ethernet/broadcom/bnxt/bnxt_ptp.h
··· 22 22 #define BNXT_LO_TIMER_MASK 0x0000ffffffffUL 23 23 #define BNXT_HI_TIMER_MASK 0xffff00000000UL 24 24 25 + #define BNXT_PTP_DFLT_TX_TMO 1000 /* ms */ 25 26 #define BNXT_PTP_QTS_TIMEOUT 1000 27 + #define BNXT_PTP_QTS_MAX_TMO_US 65535 26 28 #define BNXT_PTP_QTS_TX_ENABLES (PORT_TS_QUERY_REQ_ENABLES_PTP_SEQ_ID | \ 27 29 PORT_TS_QUERY_REQ_ENABLES_TS_REQ_TIMEOUT | \ 28 30 PORT_TS_QUERY_REQ_ENABLES_PTP_HDR_OFFSET) ··· 117 115 BNXT_PTP_MSG_PDELAY_REQ | \ 118 116 BNXT_PTP_MSG_PDELAY_RESP) 119 117 u8 tx_tstamp_en:1; 118 + u8 txts_pending:1; 120 119 int rx_filter; 121 120 u32 tstamp_filters; 122 121 123 122 u32 refclk_regs[2]; 124 123 u32 refclk_mapped_regs[2]; 124 + u32 txts_tmo; 125 + unsigned long abs_txts_tmo; 125 126 }; 126 127 127 128 #if BITS_PER_LONG == 32
+1 -1
drivers/net/ethernet/broadcom/bnxt/bnxt_ulp.c
··· 71 71 rcu_assign_pointer(ulp->ulp_ops, ulp_ops); 72 72 73 73 if (test_bit(BNXT_STATE_OPEN, &bp->state)) 74 - bnxt_hwrm_vnic_cfg(bp, 0); 74 + bnxt_hwrm_vnic_cfg(bp, &bp->vnic_info[BNXT_VNIC_DEFAULT]); 75 75 76 76 bnxt_fill_msix_vecs(bp, bp->edev->msix_entries); 77 77 edev->flags |= BNXT_EN_FLAG_MSIX_REQUESTED;