return rc;
 }
 
+void bnxt_del_one_rss_ctx(struct bnxt *bp, struct bnxt_rss_ctx *rss_ctx,
+                         bool all)
+{
+       if (!all)
+               return;
+
+       list_del(&rss_ctx->list);
+       bp->num_rss_ctx--;
+       clear_bit(rss_ctx->index, bp->rss_ctx_bmap);
+       kfree(rss_ctx);
+}
+
+struct bnxt_rss_ctx *bnxt_alloc_rss_ctx(struct bnxt *bp)
+{
+       struct bnxt_rss_ctx *rss_ctx = NULL;
+
+       rss_ctx = kzalloc(sizeof(*rss_ctx), GFP_KERNEL);
+       if (rss_ctx) {
+               rss_ctx->vnic.rss_ctx = rss_ctx;
+               list_add_tail(&rss_ctx->list, &bp->rss_ctx_list);
+               bp->num_rss_ctx++;
+       }
+       return rss_ctx;
+}
+
+void bnxt_clear_rss_ctxs(struct bnxt *bp, bool all)
+{
+       struct bnxt_rss_ctx *rss_ctx, *tmp;
+
+       list_for_each_entry_safe(rss_ctx, tmp, &bp->rss_ctx_list, list)
+               bnxt_del_one_rss_ctx(bp, rss_ctx, all);
+
+       if (all)
+               bitmap_free(bp->rss_ctx_bmap);
+}
+
+static void bnxt_init_multi_rss_ctx(struct bnxt *bp)
+{
+       bp->rss_ctx_bmap = bitmap_zalloc(BNXT_RSS_CTX_BMAP_LEN, GFP_KERNEL);
+       if (bp->rss_ctx_bmap) {
+               /* burn index 0 since we cannot have context 0 */
+               __set_bit(0, bp->rss_ctx_bmap);
+               INIT_LIST_HEAD(&bp->rss_ctx_list);
+               bp->rss_cap |= BNXT_RSS_CAP_MULTI_RSS_CTX;
+       }
+}
+
 /* Allow PF, trusted VFs and VFs with default VLAN to be in promiscuous mode */
 static bool bnxt_promisc_ok(struct bnxt *bp)
 {
        unregister_netdev(dev);
        bnxt_free_l2_filters(bp, true);
        bnxt_free_ntp_fltrs(bp, true);
+       if (BNXT_SUPPORTS_MULTI_RSS_CTX(bp))
+               bnxt_clear_rss_ctxs(bp, true);
        clear_bit(BNXT_STATE_IN_FW_RESET, &bp->state);
        /* Flush any pending tasks */
        cancel_work_sync(&bp->sp_task);
 
        INIT_LIST_HEAD(&bp->usr_fltr_list);
 
+       if (BNXT_SUPPORTS_NTUPLE_VNIC(bp))
+               bnxt_init_multi_rss_ctx(bp);
+
        rc = register_netdev(dev);
        if (rc)
                goto init_err_cleanup;
        bnxt_clear_int_mode(bp);
 
 init_err_pci_clean:
+       if (BNXT_SUPPORTS_MULTI_RSS_CTX(bp))
+               bnxt_clear_rss_ctxs(bp, true);
        bnxt_hwrm_func_drv_unrgtr(bp);
        bnxt_free_hwrm_resources(bp);
        bnxt_hwmon_uninit(bp);
 
 #define BNXT_VNIC_UCAST_FLAG   8
 #define BNXT_VNIC_RFS_NEW_RSS_FLAG     0x10
 #define BNXT_VNIC_NTUPLE_FLAG          0x20
+#define BNXT_VNIC_RSSCTX_FLAG          0x40
+       struct bnxt_rss_ctx     *rss_ctx;
        u32             vnic_id;
 };
 
+struct bnxt_rss_ctx {
+       struct list_head list;
+       struct bnxt_vnic_info vnic;
+       u16     *rss_indir_tbl;
+       u8      index;
+};
+
+#define BNXT_MAX_ETH_RSS_CTX   32
+#define BNXT_RSS_CTX_BMAP_LEN  (BNXT_MAX_ETH_RSS_CTX + 1)
+
 struct bnxt_hw_rings {
        int tx;
        int rx;
        /* grp_info indexed by completion ring index */
        struct bnxt_ring_grp_info       *grp_info;
        struct bnxt_vnic_info   *vnic_info;
+       struct list_head        rss_ctx_list;
+       unsigned long           *rss_ctx_bmap;
+       u32                     num_rss_ctx;
        int                     nr_vnics;
        u16                     *rss_indir_tbl;
        u16                     rss_indir_tbl_entries;
 #define BNXT_RSS_CAP_AH_V6_RSS_CAP             BIT(5)
 #define BNXT_RSS_CAP_ESP_V4_RSS_CAP            BIT(6)
 #define BNXT_RSS_CAP_ESP_V6_RSS_CAP            BIT(7)
+#define BNXT_RSS_CAP_MULTI_RSS_CTX             BIT(8)
 
        u8                      rss_hash_key[HW_HASH_KEY_SIZE];
        u8                      rss_hash_key_valid:1;
 #define BNXT_SUPPORTS_NTUPLE_VNIC(bp)  \
        (BNXT_PF(bp) && ((bp)->fw_cap & BNXT_FW_CAP_CFA_RFS_RING_TBL_IDX_V3))
 
+#define BNXT_SUPPORTS_MULTI_RSS_CTX(bp)                                \
+       (BNXT_PF(bp) && BNXT_SUPPORTS_NTUPLE_VNIC(bp) &&        \
+        ((bp)->rss_cap & BNXT_RSS_CAP_MULTI_RSS_CTX))
+
        u32                     hwrm_spec_code;
        u16                     hwrm_cmd_seq;
        u16                     hwrm_cmd_kong_seq;
 int bnxt_hwrm_func_qcaps(struct bnxt *bp);
 int bnxt_hwrm_fw_set_time(struct bnxt *);
 int bnxt_hwrm_vnic_rss_cfg_p5(struct bnxt *bp, struct bnxt_vnic_info *vnic);
+void bnxt_del_one_rss_ctx(struct bnxt *bp, struct bnxt_rss_ctx *rss_ctx,
+                         bool all);
+struct bnxt_rss_ctx *bnxt_alloc_rss_ctx(struct bnxt *bp);
+void bnxt_clear_rss_ctxs(struct bnxt *bp, bool all);
 int bnxt_open_nic(struct bnxt *, bool, bool);
 int bnxt_half_open_nic(struct bnxt *bp);
 void bnxt_half_close_nic(struct bnxt *bp);