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