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_cn10k_rss_reta_set(struct nix *nix, uint8_t group, uint16_t reta[ROC_NIX_RSS_RETA_MAX], 119 uint8_t lock_rx_ctx, uint16_t pf_func) 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 if (pf_func) 142 req->hdr.pcifunc = pf_func; 143 144 req->rss.rq = reta[idx]; 145 /* Fill AQ info */ 146 req->qidx = (group * nix->reta_sz) + idx; 147 req->ctype = NIX_AQ_CTYPE_RSS; 148 req->op = NIX_AQ_INSTOP_INIT; 149 150 if (!lock_rx_ctx) 151 continue; 152 153 req = mbox_alloc_msg_nix_cn10k_aq_enq(mbox); 154 if (!req) { 155 /* The shared memory buffer can be full. 156 * Flush it and retry 157 */ 158 rc = mbox_process(mbox); 159 if (rc < 0) 160 goto exit; 161 req = mbox_alloc_msg_nix_cn10k_aq_enq(mbox); 162 if (!req) { 163 rc = NIX_ERR_NO_MEM; 164 goto exit; 165 } 166 } 167 if (pf_func) 168 req->hdr.pcifunc = pf_func; 169 req->rss.rq = reta[idx]; 170 /* Fill AQ info */ 171 req->qidx = (group * nix->reta_sz) + idx; 172 req->ctype = NIX_AQ_CTYPE_RSS; 173 req->op = NIX_AQ_INSTOP_LOCK; 174 } 175 176 rc = mbox_process(mbox); 177 if (rc < 0) 178 goto exit; 179 180 rc = 0; 181 exit: 182 mbox_put(mbox); 183 return rc; 184 } 185 186 static int 187 nix_rss_reta_set(struct nix *nix, uint8_t group, uint16_t reta[ROC_NIX_RSS_RETA_MAX], 188 uint8_t lock_rx_ctx, uint16_t pf_func) 189 { 190 struct mbox *mbox = mbox_get((&nix->dev)->mbox); 191 struct nix_cn20k_aq_enq_req *req; 192 uint16_t idx; 193 int rc; 194 195 for (idx = 0; idx < nix->reta_sz; idx++) { 196 req = mbox_alloc_msg_nix_cn20k_aq_enq(mbox); 197 if (!req) { 198 /* The shared memory buffer can be full. 199 * Flush it and retry 200 */ 201 rc = mbox_process(mbox); 202 if (rc < 0) 203 goto exit; 204 req = mbox_alloc_msg_nix_cn20k_aq_enq(mbox); 205 if (!req) { 206 rc = NIX_ERR_NO_MEM; 207 goto exit; 208 } 209 } 210 req->rss.rq = reta[idx]; 211 /* Fill AQ info */ 212 req->qidx = (group * nix->reta_sz) + idx; 213 req->ctype = NIX_AQ_CTYPE_RSS; 214 req->op = NIX_AQ_INSTOP_INIT; 215 216 if (!lock_rx_ctx) 217 continue; 218 219 req = mbox_alloc_msg_nix_cn20k_aq_enq(mbox); 220 if (!req) { 221 /* The shared memory buffer can be full. 222 * Flush it and retry 223 */ 224 rc = mbox_process(mbox); 225 if (rc < 0) 226 goto exit; 227 req = mbox_alloc_msg_nix_cn20k_aq_enq(mbox); 228 if (!req) { 229 rc = NIX_ERR_NO_MEM; 230 goto exit; 231 } 232 } 233 if (pf_func) 234 req->hdr.pcifunc = pf_func; 235 req->rss.rq = reta[idx]; 236 /* Fill AQ info */ 237 req->qidx = (group * nix->reta_sz) + idx; 238 req->ctype = NIX_AQ_CTYPE_RSS; 239 req->op = NIX_AQ_INSTOP_LOCK; 240 } 241 242 rc = mbox_process(mbox); 243 if (rc < 0) 244 goto exit; 245 246 rc = 0; 247 exit: 248 mbox_put(mbox); 249 return rc; 250 } 251 252 int 253 nix_rss_reta_pffunc_set(struct roc_nix *roc_nix, uint8_t group, uint16_t reta[ROC_NIX_RSS_RETA_MAX], 254 uint16_t pf_func) 255 { 256 struct nix *nix = roc_nix_to_nix_priv(roc_nix); 257 int rc; 258 259 if (group >= ROC_NIX_RSS_GRPS) 260 return NIX_ERR_PARAM; 261 262 if (roc_model_is_cn9k()) 263 rc = nix_cn9k_rss_reta_set(nix, group, reta, roc_nix->lock_rx_ctx); 264 else if (roc_model_is_cn10k()) 265 rc = nix_cn10k_rss_reta_set(nix, group, reta, roc_nix->lock_rx_ctx, pf_func); 266 else 267 rc = nix_rss_reta_set(nix, group, reta, roc_nix->lock_rx_ctx, pf_func); 268 if (rc) 269 return rc; 270 271 memcpy(&nix->reta[group], reta, sizeof(uint16_t) * ROC_NIX_RSS_RETA_MAX); 272 return 0; 273 } 274 275 int 276 roc_nix_rss_reta_set(struct roc_nix *roc_nix, uint8_t group, uint16_t reta[ROC_NIX_RSS_RETA_MAX]) 277 { 278 return nix_rss_reta_pffunc_set(roc_nix, group, reta, 0); 279 } 280 281 int 282 roc_nix_rss_reta_get(struct roc_nix *roc_nix, uint8_t group, uint16_t reta[ROC_NIX_RSS_RETA_MAX]) 283 { 284 struct nix *nix = roc_nix_to_nix_priv(roc_nix); 285 286 if (group >= ROC_NIX_RSS_GRPS) 287 return NIX_ERR_PARAM; 288 289 memcpy(reta, &nix->reta[group], sizeof(uint16_t) * ROC_NIX_RSS_RETA_MAX); 290 return 0; 291 } 292 293 int 294 nix_rss_flowkey_pffunc_set(struct roc_nix *roc_nix, uint8_t *alg_idx, uint32_t flowkey, 295 uint8_t group, int mcam_index, uint16_t pf_func) 296 { 297 struct nix *nix = roc_nix_to_nix_priv(roc_nix); 298 struct nix_rss_flowkey_cfg_rsp *rss_rsp; 299 struct mbox *mbox = mbox_get((&nix->dev)->mbox); 300 struct nix_rss_flowkey_cfg *cfg; 301 int rc = -ENOSPC; 302 303 if (group >= ROC_NIX_RSS_GRPS) { 304 rc = NIX_ERR_PARAM; 305 goto exit; 306 } 307 308 cfg = mbox_alloc_msg_nix_rss_flowkey_cfg(mbox); 309 if (cfg == NULL) 310 goto exit; 311 if (pf_func) 312 cfg->hdr.pcifunc = pf_func; 313 314 cfg->flowkey_cfg = flowkey; 315 cfg->mcam_index = mcam_index; /* -1 indicates default group */ 316 cfg->group = group; /* 0 is default group */ 317 rc = mbox_process_msg(mbox, (void *)&rss_rsp); 318 if (rc) 319 goto exit; 320 if (alg_idx) 321 *alg_idx = rss_rsp->alg_idx; 322 323 exit: 324 mbox_put(mbox); 325 return rc; 326 } 327 328 int 329 roc_nix_rss_flowkey_set(struct roc_nix *roc_nix, uint8_t *alg_idx, uint32_t flowkey, uint8_t group, 330 int mcam_index) 331 { 332 return nix_rss_flowkey_pffunc_set(roc_nix, alg_idx, flowkey, group, mcam_index, 0); 333 } 334 335 int 336 roc_nix_rss_default_setup(struct roc_nix *roc_nix, uint32_t flowkey) 337 { 338 struct nix *nix = roc_nix_to_nix_priv(roc_nix); 339 uint16_t idx, qcnt = nix->nb_rx_queues; 340 uint16_t reta[ROC_NIX_RSS_RETA_MAX]; 341 uint8_t key[ROC_NIX_RSS_KEY_LEN]; 342 uint8_t alg_idx; 343 int rc; 344 345 roc_nix_rss_key_default_fill(roc_nix, key); 346 roc_nix_rss_key_set(roc_nix, key); 347 348 /* Update default RSS RETA */ 349 for (idx = 0; idx < nix->reta_sz; idx++) 350 reta[idx] = idx % qcnt; 351 rc = roc_nix_rss_reta_set(roc_nix, 0, reta); 352 if (rc) { 353 plt_err("Failed to set RSS reta table rc=%d", rc); 354 goto fail; 355 } 356 357 /* Update the default flowkey */ 358 rc = roc_nix_rss_flowkey_set(roc_nix, &alg_idx, flowkey, 359 ROC_NIX_RSS_GROUP_DEFAULT, -1); 360 if (rc) { 361 plt_err("Failed to set RSS flowkey rc=%d", rc); 362 goto fail; 363 } 364 365 nix->rss_alg_idx = alg_idx; 366 fail: 367 return rc; 368 } 369