dpdk/drivers/common/cnxk/roc_nix_ops.c
<<
>>
Prefs
   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
   8static inline struct mbox *
   9get_mbox(struct roc_nix *roc_nix)
  10{
  11        struct nix *nix = roc_nix_to_nix_priv(roc_nix);
  12        struct dev *dev = &nix->dev;
  13
  14        return dev->mbox;
  15}
  16
  17static void
  18nix_lso_tcp(struct nix_lso_format_cfg *req, bool v4)
  19{
  20        __io struct nix_lso_format *field;
  21
  22        /* Format works only with TCP packet marked by OL3/OL4 */
  23        field = (__io struct nix_lso_format *)&req->fields[0];
  24        req->field_mask = NIX_LSO_FIELD_MASK;
  25        /* Outer IPv4/IPv6 */
  26        field->layer = NIX_TXLAYER_OL3;
  27        field->offset = v4 ? 2 : 4;
  28        field->sizem1 = 1; /* 2B */
  29        field->alg = NIX_LSOALG_ADD_PAYLEN;
  30        field++;
  31        if (v4) {
  32                /* IPID field */
  33                field->layer = NIX_TXLAYER_OL3;
  34                field->offset = 4;
  35                field->sizem1 = 1;
  36                /* Incremented linearly per segment */
  37                field->alg = NIX_LSOALG_ADD_SEGNUM;
  38                field++;
  39        }
  40
  41        /* TCP sequence number update */
  42        field->layer = NIX_TXLAYER_OL4;
  43        field->offset = 4;
  44        field->sizem1 = 3; /* 4 bytes */
  45        field->alg = NIX_LSOALG_ADD_OFFSET;
  46        field++;
  47        /* TCP flags field */
  48        field->layer = NIX_TXLAYER_OL4;
  49        field->offset = 12;
  50        field->sizem1 = 1;
  51        field->alg = NIX_LSOALG_TCP_FLAGS;
  52        field++;
  53}
  54
  55static void
  56nix_lso_udp_tun_tcp(struct nix_lso_format_cfg *req, bool outer_v4,
  57                    bool inner_v4)
  58{
  59        __io struct nix_lso_format *field;
  60
  61        field = (__io struct nix_lso_format *)&req->fields[0];
  62        req->field_mask = NIX_LSO_FIELD_MASK;
  63        /* Outer IPv4/IPv6 len */
  64        field->layer = NIX_TXLAYER_OL3;
  65        field->offset = outer_v4 ? 2 : 4;
  66        field->sizem1 = 1; /* 2B */
  67        field->alg = NIX_LSOALG_ADD_PAYLEN;
  68        field++;
  69        if (outer_v4) {
  70                /* IPID */
  71                field->layer = NIX_TXLAYER_OL3;
  72                field->offset = 4;
  73                field->sizem1 = 1;
  74                /* Incremented linearly per segment */
  75                field->alg = NIX_LSOALG_ADD_SEGNUM;
  76                field++;
  77        }
  78
  79        /* Outer UDP length */
  80        field->layer = NIX_TXLAYER_OL4;
  81        field->offset = 4;
  82        field->sizem1 = 1;
  83        field->alg = NIX_LSOALG_ADD_PAYLEN;
  84        field++;
  85
  86        /* Inner IPv4/IPv6 */
  87        field->layer = NIX_TXLAYER_IL3;
  88        field->offset = inner_v4 ? 2 : 4;
  89        field->sizem1 = 1; /* 2B */
  90        field->alg = NIX_LSOALG_ADD_PAYLEN;
  91        field++;
  92        if (inner_v4) {
  93                /* IPID field */
  94                field->layer = NIX_TXLAYER_IL3;
  95                field->offset = 4;
  96                field->sizem1 = 1;
  97                /* Incremented linearly per segment */
  98                field->alg = NIX_LSOALG_ADD_SEGNUM;
  99                field++;
 100        }
 101
 102        /* TCP sequence number update */
 103        field->layer = NIX_TXLAYER_IL4;
 104        field->offset = 4;
 105        field->sizem1 = 3; /* 4 bytes */
 106        field->alg = NIX_LSOALG_ADD_OFFSET;
 107        field++;
 108
 109        /* TCP flags field */
 110        field->layer = NIX_TXLAYER_IL4;
 111        field->offset = 12;
 112        field->sizem1 = 1;
 113        field->alg = NIX_LSOALG_TCP_FLAGS;
 114        field++;
 115}
 116
 117static void
 118nix_lso_tun_tcp(struct nix_lso_format_cfg *req, bool outer_v4, bool inner_v4)
 119{
 120        __io struct nix_lso_format *field;
 121
 122        field = (__io struct nix_lso_format *)&req->fields[0];
 123        req->field_mask = NIX_LSO_FIELD_MASK;
 124        /* Outer IPv4/IPv6 len */
 125        field->layer = NIX_TXLAYER_OL3;
 126        field->offset = outer_v4 ? 2 : 4;
 127        field->sizem1 = 1; /* 2B */
 128        field->alg = NIX_LSOALG_ADD_PAYLEN;
 129        field++;
 130        if (outer_v4) {
 131                /* IPID */
 132                field->layer = NIX_TXLAYER_OL3;
 133                field->offset = 4;
 134                field->sizem1 = 1;
 135                /* Incremented linearly per segment */
 136                field->alg = NIX_LSOALG_ADD_SEGNUM;
 137                field++;
 138        }
 139
 140        /* Inner IPv4/IPv6 */
 141        field->layer = NIX_TXLAYER_IL3;
 142        field->offset = inner_v4 ? 2 : 4;
 143        field->sizem1 = 1; /* 2B */
 144        field->alg = NIX_LSOALG_ADD_PAYLEN;
 145        field++;
 146        if (inner_v4) {
 147                /* IPID field */
 148                field->layer = NIX_TXLAYER_IL3;
 149                field->offset = 4;
 150                field->sizem1 = 1;
 151                /* Incremented linearly per segment */
 152                field->alg = NIX_LSOALG_ADD_SEGNUM;
 153                field++;
 154        }
 155
 156        /* TCP sequence number update */
 157        field->layer = NIX_TXLAYER_IL4;
 158        field->offset = 4;
 159        field->sizem1 = 3; /* 4 bytes */
 160        field->alg = NIX_LSOALG_ADD_OFFSET;
 161        field++;
 162
 163        /* TCP flags field */
 164        field->layer = NIX_TXLAYER_IL4;
 165        field->offset = 12;
 166        field->sizem1 = 1;
 167        field->alg = NIX_LSOALG_TCP_FLAGS;
 168        field++;
 169}
 170
 171int
 172roc_nix_lso_custom_fmt_setup(struct roc_nix *roc_nix,
 173                             struct nix_lso_format *fields, uint16_t nb_fields)
 174{
 175        struct mbox *mbox = get_mbox(roc_nix);
 176        struct nix_lso_format_cfg_rsp *rsp;
 177        struct nix_lso_format_cfg *req;
 178        int rc = -ENOSPC;
 179
 180        if (nb_fields > NIX_LSO_FIELD_MAX)
 181                return -EINVAL;
 182
 183        req = mbox_alloc_msg_nix_lso_format_cfg(mbox);
 184        if (req == NULL)
 185                return rc;
 186
 187        req->field_mask = NIX_LSO_FIELD_MASK;
 188        mbox_memcpy(req->fields, fields,
 189                    sizeof(struct nix_lso_format) * nb_fields);
 190
 191        rc = mbox_process_msg(mbox, (void *)&rsp);
 192        if (rc)
 193                return rc;
 194
 195        plt_nix_dbg("Setup custom format %u", rsp->lso_format_idx);
 196        return rsp->lso_format_idx;
 197}
 198
 199int
 200roc_nix_lso_fmt_setup(struct roc_nix *roc_nix)
 201{
 202        struct nix *nix = roc_nix_to_nix_priv(roc_nix);
 203        struct mbox *mbox = get_mbox(roc_nix);
 204        struct nix_lso_format_cfg_rsp *rsp;
 205        struct nix_lso_format_cfg *req;
 206        int rc = -ENOSPC;
 207
 208        /*
 209         * IPv4/TCP LSO
 210         */
 211        req = mbox_alloc_msg_nix_lso_format_cfg(mbox);
 212        if (req == NULL)
 213                return rc;
 214        nix_lso_tcp(req, true);
 215        rc = mbox_process_msg(mbox, (void *)&rsp);
 216        if (rc)
 217                return rc;
 218
 219        if (rsp->lso_format_idx != NIX_LSO_FORMAT_IDX_TSOV4)
 220                return NIX_ERR_INTERNAL;
 221
 222        plt_nix_dbg("tcpv4 lso fmt=%u\n", rsp->lso_format_idx);
 223
 224        /*
 225         * IPv6/TCP LSO
 226         */
 227        req = mbox_alloc_msg_nix_lso_format_cfg(mbox);
 228        if (req == NULL)
 229                return -ENOSPC;
 230        nix_lso_tcp(req, false);
 231        rc = mbox_process_msg(mbox, (void *)&rsp);
 232        if (rc)
 233                return rc;
 234
 235        if (rsp->lso_format_idx != NIX_LSO_FORMAT_IDX_TSOV6)
 236                return NIX_ERR_INTERNAL;
 237
 238        plt_nix_dbg("tcpv6 lso fmt=%u\n", rsp->lso_format_idx);
 239
 240        /*
 241         * IPv4/UDP/TUN HDR/IPv4/TCP LSO
 242         */
 243        req = mbox_alloc_msg_nix_lso_format_cfg(mbox);
 244        if (req == NULL)
 245                return -ENOSPC;
 246        nix_lso_udp_tun_tcp(req, true, true);
 247        rc = mbox_process_msg(mbox, (void *)&rsp);
 248        if (rc)
 249                return rc;
 250
 251        nix->lso_udp_tun_idx[ROC_NIX_LSO_TUN_V4V4] = rsp->lso_format_idx;
 252        plt_nix_dbg("udp tun v4v4 fmt=%u\n", rsp->lso_format_idx);
 253
 254        /*
 255         * IPv4/UDP/TUN HDR/IPv6/TCP LSO
 256         */
 257        req = mbox_alloc_msg_nix_lso_format_cfg(mbox);
 258        if (req == NULL)
 259                return -ENOSPC;
 260        nix_lso_udp_tun_tcp(req, true, false);
 261        rc = mbox_process_msg(mbox, (void *)&rsp);
 262        if (rc)
 263                return rc;
 264
 265        nix->lso_udp_tun_idx[ROC_NIX_LSO_TUN_V4V6] = rsp->lso_format_idx;
 266        plt_nix_dbg("udp tun v4v6 fmt=%u\n", rsp->lso_format_idx);
 267
 268        /*
 269         * IPv6/UDP/TUN HDR/IPv4/TCP LSO
 270         */
 271        req = mbox_alloc_msg_nix_lso_format_cfg(mbox);
 272        if (req == NULL)
 273                return -ENOSPC;
 274        nix_lso_udp_tun_tcp(req, false, true);
 275        rc = mbox_process_msg(mbox, (void *)&rsp);
 276        if (rc)
 277                return rc;
 278
 279        nix->lso_udp_tun_idx[ROC_NIX_LSO_TUN_V6V4] = rsp->lso_format_idx;
 280        plt_nix_dbg("udp tun v6v4 fmt=%u\n", rsp->lso_format_idx);
 281
 282        /*
 283         * IPv6/UDP/TUN HDR/IPv6/TCP LSO
 284         */
 285        req = mbox_alloc_msg_nix_lso_format_cfg(mbox);
 286        if (req == NULL)
 287                return -ENOSPC;
 288        nix_lso_udp_tun_tcp(req, false, false);
 289        rc = mbox_process_msg(mbox, (void *)&rsp);
 290        if (rc)
 291                return rc;
 292
 293        nix->lso_udp_tun_idx[ROC_NIX_LSO_TUN_V6V6] = rsp->lso_format_idx;
 294        plt_nix_dbg("udp tun v6v6 fmt=%u\n", rsp->lso_format_idx);
 295
 296        /*
 297         * IPv4/TUN HDR/IPv4/TCP LSO
 298         */
 299        req = mbox_alloc_msg_nix_lso_format_cfg(mbox);
 300        if (req == NULL)
 301                return -ENOSPC;
 302        nix_lso_tun_tcp(req, true, true);
 303        rc = mbox_process_msg(mbox, (void *)&rsp);
 304        if (rc)
 305                return rc;
 306
 307        nix->lso_tun_idx[ROC_NIX_LSO_TUN_V4V4] = rsp->lso_format_idx;
 308        plt_nix_dbg("tun v4v4 fmt=%u\n", rsp->lso_format_idx);
 309
 310        /*
 311         * IPv4/TUN HDR/IPv6/TCP LSO
 312         */
 313        req = mbox_alloc_msg_nix_lso_format_cfg(mbox);
 314        if (req == NULL)
 315                return -ENOSPC;
 316        nix_lso_tun_tcp(req, true, false);
 317        rc = mbox_process_msg(mbox, (void *)&rsp);
 318        if (rc)
 319                return rc;
 320
 321        nix->lso_tun_idx[ROC_NIX_LSO_TUN_V4V6] = rsp->lso_format_idx;
 322        plt_nix_dbg("tun v4v6 fmt=%u\n", rsp->lso_format_idx);
 323
 324        /*
 325         * IPv6/TUN HDR/IPv4/TCP LSO
 326         */
 327        req = mbox_alloc_msg_nix_lso_format_cfg(mbox);
 328        if (req == NULL)
 329                return -ENOSPC;
 330        nix_lso_tun_tcp(req, false, true);
 331        rc = mbox_process_msg(mbox, (void *)&rsp);
 332        if (rc)
 333                return rc;
 334
 335        nix->lso_tun_idx[ROC_NIX_LSO_TUN_V6V4] = rsp->lso_format_idx;
 336        plt_nix_dbg("tun v6v4 fmt=%u\n", rsp->lso_format_idx);
 337
 338        /*
 339         * IPv6/TUN HDR/IPv6/TCP LSO
 340         */
 341        req = mbox_alloc_msg_nix_lso_format_cfg(mbox);
 342        if (req == NULL)
 343                return -ENOSPC;
 344        nix_lso_tun_tcp(req, false, false);
 345        rc = mbox_process_msg(mbox, (void *)&rsp);
 346        if (rc)
 347                return rc;
 348
 349        nix->lso_tun_idx[ROC_NIX_LSO_TUN_V6V6] = rsp->lso_format_idx;
 350        plt_nix_dbg("tun v6v6 fmt=%u\n", rsp->lso_format_idx);
 351        return 0;
 352}
 353
 354int
 355roc_nix_lso_fmt_get(struct roc_nix *roc_nix,
 356                    uint8_t udp_tun[ROC_NIX_LSO_TUN_MAX],
 357                    uint8_t tun[ROC_NIX_LSO_TUN_MAX])
 358{
 359        struct nix *nix = roc_nix_to_nix_priv(roc_nix);
 360
 361        memcpy(udp_tun, nix->lso_udp_tun_idx, ROC_NIX_LSO_TUN_MAX);
 362        memcpy(tun, nix->lso_tun_idx, ROC_NIX_LSO_TUN_MAX);
 363        return 0;
 364}
 365
 366int
 367roc_nix_switch_hdr_set(struct roc_nix *roc_nix, uint64_t switch_header_type)
 368{
 369        struct mbox *mbox = get_mbox(roc_nix);
 370        struct npc_set_pkind *req;
 371        struct msg_resp *rsp;
 372        int rc = -ENOSPC;
 373
 374        if (switch_header_type == 0)
 375                switch_header_type = ROC_PRIV_FLAGS_DEFAULT;
 376
 377        if (switch_header_type != ROC_PRIV_FLAGS_DEFAULT &&
 378            switch_header_type != ROC_PRIV_FLAGS_EDSA &&
 379            switch_header_type != ROC_PRIV_FLAGS_HIGIG &&
 380            switch_header_type != ROC_PRIV_FLAGS_LEN_90B &&
 381            switch_header_type != ROC_PRIV_FLAGS_EXDSA &&
 382            switch_header_type != ROC_PRIV_FLAGS_VLAN_EXDSA &&
 383            switch_header_type != ROC_PRIV_FLAGS_CUSTOM) {
 384                plt_err("switch header type is not supported");
 385                return NIX_ERR_PARAM;
 386        }
 387
 388        if (switch_header_type == ROC_PRIV_FLAGS_LEN_90B &&
 389            !roc_nix_is_sdp(roc_nix)) {
 390                plt_err("chlen90b is not supported on non-SDP device");
 391                return NIX_ERR_PARAM;
 392        }
 393
 394        if (switch_header_type == ROC_PRIV_FLAGS_HIGIG &&
 395            roc_nix_is_vf_or_sdp(roc_nix)) {
 396                plt_err("higig2 is supported on PF devices only");
 397                return NIX_ERR_PARAM;
 398        }
 399
 400        req = mbox_alloc_msg_npc_set_pkind(mbox);
 401        if (req == NULL)
 402                return rc;
 403        req->mode = switch_header_type;
 404
 405        if (switch_header_type == ROC_PRIV_FLAGS_LEN_90B) {
 406                req->mode = ROC_PRIV_FLAGS_CUSTOM;
 407                req->pkind = NPC_RX_CHLEN90B_PKIND;
 408        } else if (switch_header_type == ROC_PRIV_FLAGS_EXDSA) {
 409                req->mode = ROC_PRIV_FLAGS_CUSTOM;
 410                req->pkind = NPC_RX_EXDSA_PKIND;
 411        } else if (switch_header_type == ROC_PRIV_FLAGS_VLAN_EXDSA) {
 412                req->mode = ROC_PRIV_FLAGS_CUSTOM;
 413                req->pkind = NPC_RX_VLAN_EXDSA_PKIND;
 414        }
 415
 416        req->dir = PKIND_RX;
 417        rc = mbox_process_msg(mbox, (void *)&rsp);
 418        if (rc)
 419                return rc;
 420
 421        req = mbox_alloc_msg_npc_set_pkind(mbox);
 422        if (req == NULL)
 423                return -ENOSPC;
 424        req->mode = switch_header_type;
 425        req->dir = PKIND_TX;
 426        return mbox_process_msg(mbox, (void *)&rsp);
 427}
 428
 429int
 430roc_nix_eeprom_info_get(struct roc_nix *roc_nix,
 431                        struct roc_nix_eeprom_info *info)
 432{
 433        struct mbox *mbox = get_mbox(roc_nix);
 434        struct cgx_fw_data *rsp = NULL;
 435        int rc;
 436
 437        if (!info) {
 438                plt_err("Input buffer is NULL");
 439                return NIX_ERR_PARAM;
 440        }
 441
 442        mbox_alloc_msg_cgx_get_aux_link_info(mbox);
 443        rc = mbox_process_msg(mbox, (void *)&rsp);
 444        if (rc) {
 445                plt_err("Failed to get fw data: %d", rc);
 446                return rc;
 447        }
 448
 449        info->sff_id = rsp->fwdata.sfp_eeprom.sff_id;
 450        mbox_memcpy(info->buf, rsp->fwdata.sfp_eeprom.buf, SFP_EEPROM_SIZE);
 451        return 0;
 452}
 453
 454int
 455roc_nix_rx_drop_re_set(struct roc_nix *roc_nix, bool ena)
 456{
 457        struct nix *nix = roc_nix_to_nix_priv(roc_nix);
 458        struct mbox *mbox = get_mbox(roc_nix);
 459        struct nix_rx_cfg *req;
 460        int rc = -EIO;
 461
 462        /* No-op if no change */
 463        if (ena == !!(nix->rx_cfg & ROC_NIX_LF_RX_CFG_DROP_RE))
 464                return 0;
 465
 466        req = mbox_alloc_msg_nix_set_rx_cfg(mbox);
 467        if (req == NULL)
 468                return rc;
 469
 470        if (ena)
 471                req->len_verify |= NIX_RX_DROP_RE;
 472        /* Keep other flags intact */
 473        if (nix->rx_cfg & ROC_NIX_LF_RX_CFG_LEN_OL3)
 474                req->len_verify |= NIX_RX_OL3_VERIFY;
 475
 476        if (nix->rx_cfg & ROC_NIX_LF_RX_CFG_LEN_OL4)
 477                req->len_verify |= NIX_RX_OL4_VERIFY;
 478
 479        if (nix->rx_cfg & ROC_NIX_LF_RX_CFG_CSUM_OL4)
 480                req->csum_verify |= NIX_RX_CSUM_OL4_VERIFY;
 481
 482        rc = mbox_process(mbox);
 483        if (rc)
 484                return rc;
 485
 486        if (ena)
 487                nix->rx_cfg |= ROC_NIX_LF_RX_CFG_DROP_RE;
 488        else
 489                nix->rx_cfg &= ~ROC_NIX_LF_RX_CFG_DROP_RE;
 490        return 0;
 491}
 492