1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright(C) 2021 Marvell. 3 */ 4 5 #include "roc_api.h" 6 #include "roc_priv.h" 7 8 void 9 roc_nix_rss_key_default_fill(struct roc_nix *roc_nix, 10 uint8_t key[ROC_NIX_RSS_KEY_LEN]) 11 { 12 PLT_SET_USED(roc_nix); 13 const uint8_t default_key[ROC_NIX_RSS_KEY_LEN] = { 14 0xFE, 0xED, 0x0B, 0xAD, 0xFE, 0xED, 0x0B, 0xAD, 0xFE, 0xED, 15 0x0B, 0xAD, 0xFE, 0xED, 0x0B, 0xAD, 0xFE, 0xED, 0x0B, 0xAD, 16 0xFE, 0xED, 0x0B, 0xAD, 0xFE, 0xED, 0x0B, 0xAD, 0xFE, 0xED, 17 0x0B, 0xAD, 0xFE, 0xED, 0x0B, 0xAD, 0xFE, 0xED, 0x0B, 0xAD, 18 0xFE, 0xED, 0x0B, 0xAD, 0xFE, 0xED, 0x0B, 0xAD}; 19 20 memcpy(key, default_key, ROC_NIX_RSS_KEY_LEN); 21 } 22 23 void 24 roc_nix_rss_key_set(struct roc_nix *roc_nix, 25 const uint8_t key[ROC_NIX_RSS_KEY_LEN]) 26 { 27 struct nix *nix = roc_nix_to_nix_priv(roc_nix); 28 const uint64_t *keyptr; 29 uint64_t val; 30 uint32_t idx; 31 32 keyptr = (const uint64_t *)key; 33 for (idx = 0; idx < (ROC_NIX_RSS_KEY_LEN >> 3); idx++) { 34 val = plt_cpu_to_be_64(keyptr[idx]); 35 plt_write64(val, nix->base + NIX_LF_RX_SECRETX(idx)); 36 } 37 } 38 39 void 40 roc_nix_rss_key_get(struct roc_nix *roc_nix, uint8_t key[ROC_NIX_RSS_KEY_LEN]) 41 { 42 struct nix *nix = roc_nix_to_nix_priv(roc_nix); 43 uint64_t *keyptr = (uint64_t *)key; 44 uint64_t val; 45 uint32_t idx; 46 47 for (idx = 0; idx < (ROC_NIX_RSS_KEY_LEN >> 3); idx++) { 48 val = plt_read64(nix->base + NIX_LF_RX_SECRETX(idx)); 49 keyptr[idx] = plt_be_to_cpu_64(val); 50 } 51 } 52 53 static int 54 nix_cn9k_rss_reta_set(struct nix *nix, uint8_t group, 55 uint16_t reta[ROC_NIX_RSS_RETA_MAX], uint8_t lock_rx_ctx) 56 { 57 struct mbox *mbox = mbox_get((&nix->dev)->mbox); 58 struct nix_aq_enq_req *req; 59 uint16_t idx; 60 int rc; 61 62 for (idx = 0; idx < nix->reta_sz; idx++) { 63 req = mbox_alloc_msg_nix_aq_enq(mbox); 64 if (!req) { 65 /* The shared memory buffer can be full. 66 * Flush it and retry 67 */ 68 rc = mbox_process(mbox); 69 if (rc < 0) 70 goto exit; 71 req = mbox_alloc_msg_nix_aq_enq(mbox); 72 if (!req) { 73 rc = NIX_ERR_NO_MEM; 74 goto exit; 75 } 76 } 77 req->rss.rq = reta[idx]; 78 /* Fill AQ info */ 79 req->qidx = (group * nix->reta_sz) + idx; 80 req->ctype = NIX_AQ_CTYPE_RSS; 81 req->op = NIX_AQ_INSTOP_INIT; 82 83 if (!lock_rx_ctx) 84 continue; 85 86 req = mbox_alloc_msg_nix_aq_enq(mbox); 87 if (!req) { 88 /* The shared memory buffer can be full. 89 * Flush it and retry 90 */ 91 rc = mbox_process(mbox); 92 if (rc < 0) 93 goto exit; 94 req = mbox_alloc_msg_nix_aq_enq(mbox); 95 if (!req) { 96 rc = NIX_ERR_NO_MEM; 97 goto exit; 98 } 99 } 100 req->rss.rq = reta[idx]; 101 /* Fill AQ info */ 102 req->qidx = (group * nix->reta_sz) + idx; 103 req->ctype = NIX_AQ_CTYPE_RSS; 104 req->op = NIX_AQ_INSTOP_LOCK; 105 } 106 107 rc = mbox_process(mbox); 108 if (rc < 0) 109 goto exit; 110 111 rc = 0; 112 exit: 113 mbox_put(mbox); 114 return rc; 115 } 116 117 static int 118 nix_rss_reta_set(struct nix *nix, uint8_t group, 119 uint16_t reta[ROC_NIX_RSS_RETA_MAX], uint8_t lock_rx_ctx) 120 { 121 struct mbox *mbox = mbox_get((&nix->dev)->mbox); 122 struct nix_cn10k_aq_enq_req *req; 123 uint16_t idx; 124 int rc; 125 126 for (idx = 0; idx < nix->reta_sz; idx++) { 127 req = mbox_alloc_msg_nix_cn10k_aq_enq(mbox); 128 if (!req) { 129 /* The shared memory buffer can be full. 130 * Flush it and retry 131 */ 132 rc = mbox_process(mbox); 133 if (rc < 0) 134 goto exit; 135 req = mbox_alloc_msg_nix_cn10k_aq_enq(mbox); 136 if (!req) { 137 rc = NIX_ERR_NO_MEM; 138 goto exit; 139 } 140 } 141 req->rss.rq = reta[idx]; 142 /* Fill AQ info */ 143 req->qidx = (group * nix->reta_sz) + idx; 144 req->ctype = NIX_AQ_CTYPE_RSS; 145 req->op = NIX_AQ_INSTOP_INIT; 146 147 if (!lock_rx_ctx) 148 continue; 149 150 req = mbox_alloc_msg_nix_cn10k_aq_enq(mbox); 151 if (!req) { 152 /* The shared memory buffer can be full. 153 * Flush it and retry 154 */ 155 rc = mbox_process(mbox); 156 if (rc < 0) 157 goto exit; 158 req = mbox_alloc_msg_nix_cn10k_aq_enq(mbox); 159 if (!req) { 160 rc = NIX_ERR_NO_MEM; 161 goto exit; 162 } 163 } 164 req->rss.rq = reta[idx]; 165 /* Fill AQ info */ 166 req->qidx = (group * nix->reta_sz) + idx; 167 req->ctype = NIX_AQ_CTYPE_RSS; 168 req->op = NIX_AQ_INSTOP_LOCK; 169 } 170 171 rc = mbox_process(mbox); 172 if (rc < 0) 173 goto exit; 174 175 rc = 0; 176 exit: 177 mbox_put(mbox); 178 return rc; 179 } 180 181 int 182 roc_nix_rss_reta_set(struct roc_nix *roc_nix, uint8_t group, 183 uint16_t reta[ROC_NIX_RSS_RETA_MAX]) 184 { 185 struct nix *nix = roc_nix_to_nix_priv(roc_nix); 186 int rc; 187 188 if (group >= ROC_NIX_RSS_GRPS) 189 return NIX_ERR_PARAM; 190 191 if (roc_model_is_cn9k()) 192 rc = nix_cn9k_rss_reta_set(nix, group, reta, 193 roc_nix->lock_rx_ctx); 194 else 195 rc = nix_rss_reta_set(nix, group, reta, roc_nix->lock_rx_ctx); 196 if (rc) 197 return rc; 198 199 memcpy(&nix->reta[group], reta, sizeof(uint16_t) * ROC_NIX_RSS_RETA_MAX); 200 return 0; 201 } 202 203 int 204 roc_nix_rss_reta_get(struct roc_nix *roc_nix, uint8_t group, 205 uint16_t reta[ROC_NIX_RSS_RETA_MAX]) 206 { 207 struct nix *nix = roc_nix_to_nix_priv(roc_nix); 208 209 if (group >= ROC_NIX_RSS_GRPS) 210 return NIX_ERR_PARAM; 211 212 memcpy(reta, &nix->reta[group], sizeof(uint16_t) * ROC_NIX_RSS_RETA_MAX); 213 return 0; 214 } 215 216 int 217 roc_nix_rss_flowkey_set(struct roc_nix *roc_nix, uint8_t *alg_idx, 218 uint32_t flowkey, uint8_t group, int mcam_index) 219 { 220 struct nix *nix = roc_nix_to_nix_priv(roc_nix); 221 struct nix_rss_flowkey_cfg_rsp *rss_rsp; 222 struct mbox *mbox = mbox_get((&nix->dev)->mbox); 223 struct nix_rss_flowkey_cfg *cfg; 224 int rc = -ENOSPC; 225 226 if (group >= ROC_NIX_RSS_GRPS) { 227 rc = NIX_ERR_PARAM; 228 goto exit; 229 } 230 231 cfg = mbox_alloc_msg_nix_rss_flowkey_cfg(mbox); 232 if (cfg == NULL) 233 goto exit; 234 cfg->flowkey_cfg = flowkey; 235 cfg->mcam_index = mcam_index; /* -1 indicates default group */ 236 cfg->group = group; /* 0 is default group */ 237 rc = mbox_process_msg(mbox, (void *)&rss_rsp); 238 if (rc) 239 goto exit; 240 if (alg_idx) 241 *alg_idx = rss_rsp->alg_idx; 242 243 exit: 244 mbox_put(mbox); 245 return rc; 246 } 247 248 int 249 roc_nix_rss_default_setup(struct roc_nix *roc_nix, uint32_t flowkey) 250 { 251 struct nix *nix = roc_nix_to_nix_priv(roc_nix); 252 uint16_t idx, qcnt = nix->nb_rx_queues; 253 uint16_t reta[ROC_NIX_RSS_RETA_MAX]; 254 uint8_t key[ROC_NIX_RSS_KEY_LEN]; 255 uint8_t alg_idx; 256 int rc; 257 258 roc_nix_rss_key_default_fill(roc_nix, key); 259 roc_nix_rss_key_set(roc_nix, key); 260 261 /* Update default RSS RETA */ 262 for (idx = 0; idx < nix->reta_sz; idx++) 263 reta[idx] = idx % qcnt; 264 rc = roc_nix_rss_reta_set(roc_nix, 0, reta); 265 if (rc) { 266 plt_err("Failed to set RSS reta table rc=%d", rc); 267 goto fail; 268 } 269 270 /* Update the default flowkey */ 271 rc = roc_nix_rss_flowkey_set(roc_nix, &alg_idx, flowkey, 272 ROC_NIX_RSS_GROUP_DEFAULT, -1); 273 if (rc) { 274 plt_err("Failed to set RSS flowkey rc=%d", rc); 275 goto fail; 276 } 277 278 nix->rss_alg_idx = alg_idx; 279 fail: 280 return rc; 281 } 282