LCOV - code coverage report
Current view: top level - drivers/net/nfp/nfpcore - nfp_nsp_eth.c (source / functions) Hit Total Coverage
Test: Code coverage Lines: 0 206 0.0 %
Date: 2024-01-22 15:55:54 Functions: 0 16 0.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 90 0.0 %

           Branch data     Line data    Source code
       1                 :            : /* SPDX-License-Identifier: BSD-3-Clause
       2                 :            :  * Copyright(c) 2018 Netronome Systems, Inc.
       3                 :            :  * All rights reserved.
       4                 :            :  */
       5                 :            : 
       6                 :            : #include <nfp_platform.h>
       7                 :            : 
       8                 :            : #include "nfp_logs.h"
       9                 :            : #include "nfp_nsp.h"
      10                 :            : 
      11                 :            : #define NSP_ETH_NBI_PORT_COUNT          24
      12                 :            : #define NSP_ETH_MAX_COUNT               (2 * NSP_ETH_NBI_PORT_COUNT)
      13                 :            : #define NSP_ETH_TABLE_SIZE              (NSP_ETH_MAX_COUNT * sizeof(union eth_table_entry))
      14                 :            : 
      15                 :            : #define NSP_ETH_PORT_LANES              GENMASK_ULL(3, 0)
      16                 :            : #define NSP_ETH_PORT_INDEX              GENMASK_ULL(15, 8)
      17                 :            : #define NSP_ETH_PORT_LABEL              GENMASK_ULL(53, 48)
      18                 :            : #define NSP_ETH_PORT_PHYLABEL           GENMASK_ULL(59, 54)
      19                 :            : #define NSP_ETH_PORT_FEC_SUPP_BASER     RTE_BIT64(60)
      20                 :            : #define NSP_ETH_PORT_FEC_SUPP_RS        RTE_BIT64(61)
      21                 :            : #define NSP_ETH_PORT_SUPP_ANEG          RTE_BIT64(63)
      22                 :            : 
      23                 :            : #define NSP_ETH_PORT_LANES_MASK         rte_cpu_to_le_64(NSP_ETH_PORT_LANES)
      24                 :            : 
      25                 :            : #define NSP_ETH_STATE_CONFIGURED        RTE_BIT64(0)
      26                 :            : #define NSP_ETH_STATE_ENABLED           RTE_BIT64(1)
      27                 :            : #define NSP_ETH_STATE_TX_ENABLED        RTE_BIT64(2)
      28                 :            : #define NSP_ETH_STATE_RX_ENABLED        RTE_BIT64(3)
      29                 :            : #define NSP_ETH_STATE_RATE              GENMASK_ULL(11, 8)
      30                 :            : #define NSP_ETH_STATE_INTERFACE         GENMASK_ULL(19, 12)
      31                 :            : #define NSP_ETH_STATE_MEDIA             GENMASK_ULL(21, 20)
      32                 :            : #define NSP_ETH_STATE_OVRD_CHNG         RTE_BIT64(22)
      33                 :            : #define NSP_ETH_STATE_ANEG              GENMASK_ULL(25, 23)
      34                 :            : #define NSP_ETH_STATE_FEC               GENMASK_ULL(27, 26)
      35                 :            : #define NSP_ETH_STATE_ACT_FEC           GENMASK_ULL(29, 28)
      36                 :            : #define NSP_ETH_STATE_TX_PAUSE          RTE_BIT64(31)
      37                 :            : #define NSP_ETH_STATE_RX_PAUSE          RTE_BIT64(32)
      38                 :            : 
      39                 :            : #define NSP_ETH_CTRL_CONFIGURED         RTE_BIT64(0)
      40                 :            : #define NSP_ETH_CTRL_ENABLED            RTE_BIT64(1)
      41                 :            : #define NSP_ETH_CTRL_TX_ENABLED         RTE_BIT64(2)
      42                 :            : #define NSP_ETH_CTRL_RX_ENABLED         RTE_BIT64(3)
      43                 :            : #define NSP_ETH_CTRL_SET_RATE           RTE_BIT64(4)
      44                 :            : #define NSP_ETH_CTRL_SET_LANES          RTE_BIT64(5)
      45                 :            : #define NSP_ETH_CTRL_SET_ANEG           RTE_BIT64(6)
      46                 :            : #define NSP_ETH_CTRL_SET_FEC            RTE_BIT64(7)
      47                 :            : #define NSP_ETH_CTRL_SET_TX_PAUSE       RTE_BIT64(10)
      48                 :            : #define NSP_ETH_CTRL_SET_RX_PAUSE       RTE_BIT64(11)
      49                 :            : 
      50                 :            : /* Which connector port. */
      51                 :            : #define PORT_TP                 0x00
      52                 :            : #define PORT_AUI                0x01
      53                 :            : #define PORT_MII                0x02
      54                 :            : #define PORT_FIBRE              0x03
      55                 :            : #define PORT_BNC                0x04
      56                 :            : #define PORT_DA                 0x05
      57                 :            : #define PORT_NONE               0xef
      58                 :            : #define PORT_OTHER              0xff
      59                 :            : 
      60                 :            : enum nfp_eth_raw {
      61                 :            :         NSP_ETH_RAW_PORT = 0,
      62                 :            :         NSP_ETH_RAW_STATE,
      63                 :            :         NSP_ETH_RAW_MAC,
      64                 :            :         NSP_ETH_RAW_CONTROL,
      65                 :            :         NSP_ETH_NUM_RAW,
      66                 :            : };
      67                 :            : 
      68                 :            : enum nfp_eth_rate {
      69                 :            :         RATE_INVALID = 0,
      70                 :            :         RATE_10M,
      71                 :            :         RATE_100M,
      72                 :            :         RATE_1G,
      73                 :            :         RATE_10G,
      74                 :            :         RATE_25G,
      75                 :            : };
      76                 :            : 
      77                 :            : union eth_table_entry {
      78                 :            :         struct {
      79                 :            :                 uint64_t port;
      80                 :            :                 uint64_t state;
      81                 :            :                 uint8_t mac_addr[RTE_ETHER_ADDR_LEN];
      82                 :            :                 uint8_t resv[2];
      83                 :            :                 uint64_t control;
      84                 :            :         };
      85                 :            :         uint64_t raw[NSP_ETH_NUM_RAW];
      86                 :            : };
      87                 :            : 
      88                 :            : static const struct {
      89                 :            :         enum nfp_eth_rate rate;
      90                 :            :         uint32_t speed;
      91                 :            : } nsp_eth_rate_tbl[] = {
      92                 :            :         { RATE_INVALID, RTE_ETH_SPEED_NUM_NONE, },
      93                 :            :         { RATE_10M,     RTE_ETH_SPEED_NUM_10M, },
      94                 :            :         { RATE_100M,    RTE_ETH_SPEED_NUM_100M, },
      95                 :            :         { RATE_1G,      RTE_ETH_SPEED_NUM_1G, },
      96                 :            :         { RATE_10G,     RTE_ETH_SPEED_NUM_10G, },
      97                 :            :         { RATE_25G,     RTE_ETH_SPEED_NUM_25G, },
      98                 :            : };
      99                 :            : 
     100                 :            : static uint32_t
     101                 :            : nfp_eth_rate2speed(enum nfp_eth_rate rate)
     102                 :            : {
     103                 :            :         uint32_t i;
     104                 :            : 
     105         [ #  # ]:          0 :         for (i = 0; i < RTE_DIM(nsp_eth_rate_tbl); i++)
     106         [ #  # ]:          0 :                 if (nsp_eth_rate_tbl[i].rate == rate)
     107                 :          0 :                         return nsp_eth_rate_tbl[i].speed;
     108                 :            : 
     109                 :            :         return 0;
     110                 :            : }
     111                 :            : 
     112                 :            : static enum nfp_eth_rate
     113                 :            : nfp_eth_speed2rate(uint32_t speed)
     114                 :            : {
     115                 :            :         uint32_t i;
     116                 :            : 
     117         [ #  # ]:          0 :         for (i = 0; i < RTE_DIM(nsp_eth_rate_tbl); i++)
     118         [ #  # ]:          0 :                 if (nsp_eth_rate_tbl[i].speed == speed)
     119                 :          0 :                         return nsp_eth_rate_tbl[i].rate;
     120                 :            : 
     121                 :            :         return RATE_INVALID;
     122                 :            : }
     123                 :            : 
     124                 :            : static void
     125                 :            : nfp_eth_copy_mac_reverse(uint8_t *dst,
     126                 :            :                 const uint8_t *src)
     127                 :            : {
     128                 :            :         uint32_t i;
     129                 :            : 
     130         [ #  # ]:          0 :         for (i = 0; i < RTE_ETHER_ADDR_LEN; i++)
     131                 :          0 :                 dst[RTE_ETHER_ADDR_LEN - i - 1] = src[i];
     132                 :            : }
     133                 :            : 
     134                 :            : static void
     135                 :          0 : nfp_eth_port_translate(struct nfp_nsp *nsp,
     136                 :            :                 const union eth_table_entry *src,
     137                 :            :                 uint32_t index,
     138                 :            :                 struct nfp_eth_table_port *dst)
     139                 :            : {
     140                 :            :         uint32_t fec;
     141                 :            :         uint64_t port;
     142                 :            :         uint32_t rate;
     143                 :            :         uint64_t state;
     144                 :            : 
     145                 :          0 :         port = rte_le_to_cpu_64(src->port);
     146                 :          0 :         state = rte_le_to_cpu_64(src->state);
     147                 :            : 
     148                 :          0 :         dst->eth_index = FIELD_GET(NSP_ETH_PORT_INDEX, port);
     149                 :          0 :         dst->index = index;
     150                 :          0 :         dst->nbi = index / NSP_ETH_NBI_PORT_COUNT;
     151                 :          0 :         dst->base = index % NSP_ETH_NBI_PORT_COUNT;
     152                 :          0 :         dst->lanes = FIELD_GET(NSP_ETH_PORT_LANES, port);
     153                 :            : 
     154                 :          0 :         dst->enabled = FIELD_GET(NSP_ETH_STATE_ENABLED, state);
     155                 :          0 :         dst->tx_enabled = FIELD_GET(NSP_ETH_STATE_TX_ENABLED, state);
     156                 :          0 :         dst->rx_enabled = FIELD_GET(NSP_ETH_STATE_RX_ENABLED, state);
     157                 :            : 
     158                 :          0 :         rate = nfp_eth_rate2speed(FIELD_GET(NSP_ETH_STATE_RATE, state));
     159                 :          0 :         dst->speed = dst->lanes * rate;
     160                 :            : 
     161                 :          0 :         dst->interface = FIELD_GET(NSP_ETH_STATE_INTERFACE, state);
     162                 :          0 :         dst->media = FIELD_GET(NSP_ETH_STATE_MEDIA, state);
     163                 :            : 
     164                 :          0 :         nfp_eth_copy_mac_reverse(&dst->mac_addr.addr_bytes[0], src->mac_addr);
     165                 :            : 
     166                 :          0 :         dst->label_port = FIELD_GET(NSP_ETH_PORT_PHYLABEL, port);
     167                 :          0 :         dst->label_subport = FIELD_GET(NSP_ETH_PORT_LABEL, port);
     168                 :            : 
     169         [ #  # ]:          0 :         if (nfp_nsp_get_abi_ver_minor(nsp) < 17)
     170                 :            :                 return;
     171                 :            : 
     172                 :          0 :         dst->override_changed = FIELD_GET(NSP_ETH_STATE_OVRD_CHNG, state);
     173                 :          0 :         dst->aneg = FIELD_GET(NSP_ETH_STATE_ANEG, state);
     174                 :            : 
     175         [ #  # ]:          0 :         if (nfp_nsp_get_abi_ver_minor(nsp) < 22)
     176                 :            :                 return;
     177                 :            : 
     178                 :          0 :         fec = FIELD_GET(NSP_ETH_PORT_FEC_SUPP_BASER, port);
     179                 :          0 :         dst->fec_modes_supported |= fec << NFP_FEC_BASER_BIT;
     180                 :          0 :         fec = FIELD_GET(NSP_ETH_PORT_FEC_SUPP_RS, port);
     181                 :          0 :         dst->fec_modes_supported |= fec << NFP_FEC_REED_SOLOMON_BIT;
     182         [ #  # ]:          0 :         if (dst->fec_modes_supported != 0)
     183                 :          0 :                 dst->fec_modes_supported |= NFP_FEC_AUTO | NFP_FEC_DISABLED;
     184                 :            : 
     185                 :          0 :         dst->fec = FIELD_GET(NSP_ETH_STATE_FEC, state);
     186                 :          0 :         dst->act_fec = dst->fec;
     187                 :            : 
     188         [ #  # ]:          0 :         if (nfp_nsp_get_abi_ver_minor(nsp) < 33)
     189                 :            :                 return;
     190                 :            : 
     191                 :          0 :         dst->act_fec = FIELD_GET(NSP_ETH_STATE_ACT_FEC, state);
     192                 :          0 :         dst->supp_aneg = FIELD_GET(NSP_ETH_PORT_SUPP_ANEG, port);
     193                 :            : 
     194         [ #  # ]:          0 :         if (nfp_nsp_get_abi_ver_minor(nsp) < 37) {
     195                 :          0 :                 dst->tx_pause_enabled = true;
     196                 :          0 :                 dst->rx_pause_enabled = true;
     197                 :          0 :                 return;
     198                 :            :         }
     199                 :            : 
     200                 :          0 :         dst->tx_pause_enabled = FIELD_GET(NSP_ETH_STATE_TX_PAUSE, state);
     201                 :          0 :         dst->rx_pause_enabled = FIELD_GET(NSP_ETH_STATE_RX_PAUSE, state);
     202                 :            : }
     203                 :            : 
     204                 :            : static void
     205                 :          0 : nfp_eth_calc_port_geometry(struct nfp_eth_table *table)
     206                 :            : {
     207                 :            :         uint32_t i;
     208                 :            :         uint32_t j;
     209                 :            : 
     210         [ #  # ]:          0 :         for (i = 0; i < table->count; i++) {
     211                 :          0 :                 table->max_index = RTE_MAX(table->max_index,
     212                 :            :                                 table->ports[i].index);
     213                 :            : 
     214         [ #  # ]:          0 :                 for (j = 0; j < table->count; j++) {
     215                 :          0 :                         if (table->ports[i].label_port !=
     216         [ #  # ]:          0 :                                         table->ports[j].label_port)
     217                 :          0 :                                 continue;
     218                 :            : 
     219                 :          0 :                         table->ports[i].port_lanes += table->ports[j].lanes;
     220                 :            : 
     221         [ #  # ]:          0 :                         if (i == j)
     222                 :          0 :                                 continue;
     223                 :            : 
     224                 :          0 :                         if (table->ports[i].label_subport ==
     225         [ #  # ]:          0 :                                         table->ports[j].label_subport)
     226                 :          0 :                                 PMD_DRV_LOG(DEBUG, "Port %d subport %d is a duplicate",
     227                 :            :                                                 table->ports[i].label_port,
     228                 :            :                                                 table->ports[i].label_subport);
     229                 :            : 
     230                 :          0 :                         table->ports[i].is_split = true;
     231                 :            :                 }
     232                 :            :         }
     233                 :          0 : }
     234                 :            : 
     235                 :            : static void
     236                 :            : nfp_eth_calc_port_type(struct nfp_eth_table_port *entry)
     237                 :            : {
     238         [ #  # ]:          0 :         if (entry->interface == NFP_INTERFACE_NONE) {
     239                 :          0 :                 entry->port_type = PORT_NONE;
     240                 :          0 :                 return;
     241         [ #  # ]:          0 :         } else if (entry->interface == NFP_INTERFACE_RJ45) {
     242                 :          0 :                 entry->port_type = PORT_TP;
     243                 :          0 :                 return;
     244                 :            :         }
     245                 :            : 
     246         [ #  # ]:          0 :         if (entry->media == NFP_MEDIA_FIBRE)
     247                 :          0 :                 entry->port_type = PORT_FIBRE;
     248                 :            :         else
     249                 :          0 :                 entry->port_type = PORT_DA;
     250                 :            : }
     251                 :            : 
     252                 :            : static struct nfp_eth_table *
     253                 :          0 : nfp_eth_read_ports_real(struct nfp_nsp *nsp)
     254                 :            : {
     255                 :            :         int ret;
     256                 :            :         uint32_t i;
     257                 :            :         uint32_t j;
     258                 :            :         int cnt = 0;
     259                 :            :         uint32_t table_sz;
     260                 :            :         struct nfp_eth_table *table;
     261                 :            :         union eth_table_entry *entries;
     262                 :            : 
     263                 :          0 :         entries = malloc(NSP_ETH_TABLE_SIZE);
     264         [ #  # ]:          0 :         if (entries == NULL)
     265                 :            :                 return NULL;
     266                 :            : 
     267                 :            :         memset(entries, 0, NSP_ETH_TABLE_SIZE);
     268                 :          0 :         ret = nfp_nsp_read_eth_table(nsp, entries, NSP_ETH_TABLE_SIZE);
     269         [ #  # ]:          0 :         if (ret < 0) {
     270                 :          0 :                 PMD_DRV_LOG(ERR, "Reading port table failed %d", ret);
     271                 :          0 :                 goto err;
     272                 :            :         }
     273                 :            : 
     274         [ #  # ]:          0 :         for (i = 0; i < NSP_ETH_MAX_COUNT; i++)
     275         [ #  # ]:          0 :                 if ((entries[i].port & NSP_ETH_PORT_LANES_MASK) != 0)
     276                 :          0 :                         cnt++;
     277                 :            : 
     278                 :            :         /*
     279                 :            :          * Some versions of flash will give us 0 instead of port count. For
     280                 :            :          * those that give a port count, verify it against the value calculated
     281                 :            :          * above.
     282                 :            :          */
     283         [ #  # ]:          0 :         if (ret != 0 && ret != cnt) {
     284                 :          0 :                 PMD_DRV_LOG(ERR, "Table entry count (%d) unmatch entries present (%d)",
     285                 :            :                                 ret, cnt);
     286                 :          0 :                 goto err;
     287                 :            :         }
     288                 :            : 
     289                 :          0 :         table_sz = sizeof(*table) + sizeof(struct nfp_eth_table_port) * cnt;
     290                 :          0 :         table = malloc(table_sz);
     291         [ #  # ]:          0 :         if (table == NULL)
     292                 :          0 :                 goto err;
     293                 :            : 
     294                 :            :         memset(table, 0, table_sz);
     295                 :          0 :         table->count = cnt;
     296         [ #  # ]:          0 :         for (i = 0, j = 0; i < NSP_ETH_MAX_COUNT; i++) {
     297         [ #  # ]:          0 :                 if ((entries[i].port & NSP_ETH_PORT_LANES_MASK) != 0)
     298                 :          0 :                         nfp_eth_port_translate(nsp, &entries[i], i, &table->ports[j++]);
     299                 :            :         }
     300                 :            : 
     301                 :          0 :         nfp_eth_calc_port_geometry(table);
     302         [ #  # ]:          0 :         for (i = 0; i < table->count; i++)
     303                 :            :                 nfp_eth_calc_port_type(&table->ports[i]);
     304                 :            : 
     305                 :          0 :         free(entries);
     306                 :            : 
     307                 :          0 :         return table;
     308                 :            : 
     309                 :          0 : err:
     310                 :          0 :         free(entries);
     311                 :          0 :         return NULL;
     312                 :            : }
     313                 :            : 
     314                 :            : /**
     315                 :            :  * Read the port information from the device.
     316                 :            :  *
     317                 :            :  * Returned structure should be freed once no longer needed.
     318                 :            :  *
     319                 :            :  * @param cpp
     320                 :            :  *   NFP CPP handle
     321                 :            :  *
     322                 :            :  * @return
     323                 :            :  *   Populated ETH table or NULL on error.
     324                 :            :  */
     325                 :            : struct nfp_eth_table *
     326                 :          0 : nfp_eth_read_ports(struct nfp_cpp *cpp)
     327                 :            : {
     328                 :            :         struct nfp_nsp *nsp;
     329                 :            :         struct nfp_eth_table *ret;
     330                 :            : 
     331                 :          0 :         nsp = nfp_nsp_open(cpp);
     332         [ #  # ]:          0 :         if (nsp == NULL)
     333                 :            :                 return NULL;
     334                 :            : 
     335                 :          0 :         ret = nfp_eth_read_ports_real(nsp);
     336                 :          0 :         nfp_nsp_close(nsp);
     337                 :            : 
     338                 :          0 :         return ret;
     339                 :            : }
     340                 :            : 
     341                 :            : struct nfp_nsp *
     342                 :          0 : nfp_eth_config_start(struct nfp_cpp *cpp,
     343                 :            :                 uint32_t idx)
     344                 :            : {
     345                 :            :         int ret;
     346                 :            :         struct nfp_nsp *nsp;
     347                 :            :         union eth_table_entry *entries;
     348                 :            : 
     349                 :          0 :         entries = malloc(NSP_ETH_TABLE_SIZE);
     350         [ #  # ]:          0 :         if (entries == NULL)
     351                 :            :                 return NULL;
     352                 :            : 
     353                 :            :         memset(entries, 0, NSP_ETH_TABLE_SIZE);
     354                 :          0 :         nsp = nfp_nsp_open(cpp);
     355         [ #  # ]:          0 :         if (nsp == NULL) {
     356                 :          0 :                 free(entries);
     357                 :          0 :                 return nsp;
     358                 :            :         }
     359                 :            : 
     360                 :          0 :         ret = nfp_nsp_read_eth_table(nsp, entries, NSP_ETH_TABLE_SIZE);
     361         [ #  # ]:          0 :         if (ret < 0) {
     362                 :          0 :                 PMD_DRV_LOG(ERR, "Reading port table failed %d", ret);
     363                 :          0 :                 goto err;
     364                 :            :         }
     365                 :            : 
     366         [ #  # ]:          0 :         if ((entries[idx].port & NSP_ETH_PORT_LANES_MASK) == 0) {
     367                 :          0 :                 PMD_DRV_LOG(ERR, "Trying to set port state on disabled port %d", idx);
     368                 :          0 :                 goto err;
     369                 :            :         }
     370                 :            : 
     371                 :          0 :         nfp_nsp_config_set_state(nsp, entries, idx);
     372                 :          0 :         return nsp;
     373                 :            : 
     374                 :          0 : err:
     375                 :          0 :         nfp_nsp_close(nsp);
     376                 :          0 :         free(entries);
     377                 :          0 :         return NULL;
     378                 :            : }
     379                 :            : 
     380                 :            : void
     381                 :          0 : nfp_eth_config_cleanup_end(struct nfp_nsp *nsp)
     382                 :            : {
     383                 :          0 :         union eth_table_entry *entries = nfp_nsp_config_entries(nsp);
     384                 :            : 
     385                 :          0 :         nfp_nsp_config_set_modified(nsp, 0);
     386                 :          0 :         nfp_nsp_config_clear_state(nsp);
     387                 :          0 :         nfp_nsp_close(nsp);
     388                 :          0 :         free(entries);
     389                 :          0 : }
     390                 :            : 
     391                 :            : /**
     392                 :            :  * Perform the configuration which was requested with __nfp_eth_set_*()
     393                 :            :  * helpers and recorded in @nsp state. If device was already configured
     394                 :            :  * as requested or no __nfp_eth_set_*() operations were made, no NSP command
     395                 :            :  * will be performed.
     396                 :            :  *
     397                 :            :  * @param nsp
     398                 :            :  *   NFP NSP handle returned from nfp_eth_config_start()
     399                 :            :  *
     400                 :            :  * @return
     401                 :            :  *   - (0) Configuration successful
     402                 :            :  *   - (1) No changes were needed
     403                 :            :  *   - (-ERRNO) Configuration failed
     404                 :            :  */
     405                 :            : int
     406                 :          0 : nfp_eth_config_commit_end(struct nfp_nsp *nsp)
     407                 :            : {
     408                 :            :         int ret = 1;
     409                 :          0 :         union eth_table_entry *entries = nfp_nsp_config_entries(nsp);
     410                 :            : 
     411         [ #  # ]:          0 :         if (nfp_nsp_config_modified(nsp)) {
     412                 :          0 :                 ret = nfp_nsp_write_eth_table(nsp, entries, NSP_ETH_TABLE_SIZE);
     413                 :          0 :                 ret = ret < 0 ? ret : 0;
     414                 :            :         }
     415                 :            : 
     416                 :          0 :         nfp_eth_config_cleanup_end(nsp);
     417                 :            : 
     418                 :          0 :         return ret;
     419                 :            : }
     420                 :            : 
     421                 :            : /**
     422                 :            :  * Enable or disable PHY module (this usually means setting the TX lanes
     423                 :            :  * disable bits).
     424                 :            :  *
     425                 :            :  * @param cpp
     426                 :            :  *   NFP CPP handle
     427                 :            :  * @param idx
     428                 :            :  *   NFP chip-wide port index
     429                 :            :  * @param enable
     430                 :            :  *   Desired state
     431                 :            :  *
     432                 :            :  * @return
     433                 :            :  *   - (0) Configuration successful
     434                 :            :  *   - (1) No changes were needed
     435                 :            :  *   - (-ERRNO) Configuration failed
     436                 :            :  */
     437                 :            : int
     438                 :          0 : nfp_eth_set_mod_enable(struct nfp_cpp *cpp,
     439                 :            :                 uint32_t idx,
     440                 :            :                 bool enable)
     441                 :            : {
     442                 :            :         uint64_t reg;
     443                 :            :         struct nfp_nsp *nsp;
     444                 :            :         union eth_table_entry *entries;
     445                 :            : 
     446                 :          0 :         nsp = nfp_eth_config_start(cpp, idx);
     447         [ #  # ]:          0 :         if (nsp == NULL)
     448                 :            :                 return -EIO;
     449                 :            : 
     450                 :          0 :         entries = nfp_nsp_config_entries(nsp);
     451                 :            : 
     452                 :            :         /* Check if we are already in requested state */
     453                 :          0 :         reg = rte_le_to_cpu_64(entries[idx].state);
     454         [ #  # ]:          0 :         if (enable != (int)FIELD_GET(NSP_ETH_CTRL_ENABLED, reg)) {
     455                 :          0 :                 reg = rte_le_to_cpu_64(entries[idx].control);
     456                 :          0 :                 reg &= ~NSP_ETH_CTRL_ENABLED;
     457                 :          0 :                 reg |= FIELD_PREP(NSP_ETH_CTRL_ENABLED, enable);
     458                 :          0 :                 entries[idx].control = rte_cpu_to_le_64(reg);
     459                 :            : 
     460                 :          0 :                 nfp_nsp_config_set_modified(nsp, true);
     461                 :            :         }
     462                 :            : 
     463                 :          0 :         return nfp_eth_config_commit_end(nsp);
     464                 :            : }
     465                 :            : 
     466                 :            : /**
     467                 :            :  * Set the ifup/ifdown state on the PHY.
     468                 :            :  *
     469                 :            :  * @param cpp
     470                 :            :  *   NFP CPP handle
     471                 :            :  * @param idx
     472                 :            :  *   NFP chip-wide port index
     473                 :            :  * @param configured
     474                 :            :  *   Desired state
     475                 :            :  *
     476                 :            :  * @return
     477                 :            :  *   - (0) Configuration successful
     478                 :            :  *   - (1) No changes were needed
     479                 :            :  *   - (-ERRNO) Configuration failed
     480                 :            :  */
     481                 :            : int
     482                 :          0 : nfp_eth_set_configured(struct nfp_cpp *cpp,
     483                 :            :                 uint32_t idx,
     484                 :            :                 bool configured)
     485                 :            : {
     486                 :            :         uint64_t reg;
     487                 :            :         struct nfp_nsp *nsp;
     488                 :            :         union eth_table_entry *entries;
     489                 :            : 
     490                 :          0 :         nsp = nfp_eth_config_start(cpp, idx);
     491         [ #  # ]:          0 :         if (nsp == NULL)
     492                 :            :                 return -EIO;
     493                 :            : 
     494                 :            :         /*
     495                 :            :          * Older ABI versions did support this feature, however this has only
     496                 :            :          * been reliable since ABI 20.
     497                 :            :          */
     498         [ #  # ]:          0 :         if (nfp_nsp_get_abi_ver_minor(nsp) < 20) {
     499                 :          0 :                 nfp_eth_config_cleanup_end(nsp);
     500                 :          0 :                 return -EOPNOTSUPP;
     501                 :            :         }
     502                 :            : 
     503                 :          0 :         entries = nfp_nsp_config_entries(nsp);
     504                 :            : 
     505                 :            :         /* Check if we are already in requested state */
     506                 :          0 :         reg = rte_le_to_cpu_64(entries[idx].state);
     507         [ #  # ]:          0 :         if (configured != (int)FIELD_GET(NSP_ETH_STATE_CONFIGURED, reg)) {
     508                 :          0 :                 reg = rte_le_to_cpu_64(entries[idx].control);
     509                 :          0 :                 reg &= ~NSP_ETH_CTRL_CONFIGURED;
     510                 :          0 :                 reg |= FIELD_PREP(NSP_ETH_CTRL_CONFIGURED, configured);
     511                 :          0 :                 entries[idx].control = rte_cpu_to_le_64(reg);
     512                 :            : 
     513                 :          0 :                 nfp_nsp_config_set_modified(nsp, true);
     514                 :            :         }
     515                 :            : 
     516                 :          0 :         return nfp_eth_config_commit_end(nsp);
     517                 :            : }
     518                 :            : 
     519                 :            : static int
     520                 :          0 : nfp_eth_set_bit_config(struct nfp_nsp *nsp,
     521                 :            :                 uint32_t raw_idx,
     522                 :            :                 const uint64_t mask,
     523                 :            :                 const uint32_t shift,
     524                 :            :                 uint64_t val,
     525                 :            :                 const uint64_t ctrl_bit)
     526                 :            : {
     527                 :            :         uint64_t reg;
     528                 :          0 :         uint32_t idx = nfp_nsp_config_idx(nsp);
     529                 :          0 :         union eth_table_entry *entries = nfp_nsp_config_entries(nsp);
     530                 :            : 
     531                 :            :         /*
     532                 :            :          * Note: set features were added in ABI 0.14 but the error
     533                 :            :          * codes were initially not populated correctly.
     534                 :            :          */
     535         [ #  # ]:          0 :         if (nfp_nsp_get_abi_ver_minor(nsp) < 17) {
     536                 :          0 :                 PMD_DRV_LOG(ERR, "set operations not supported, please update flash");
     537                 :          0 :                 return -EOPNOTSUPP;
     538                 :            :         }
     539                 :            : 
     540                 :            :         /* Check if we are already in requested state */
     541                 :          0 :         reg = rte_le_to_cpu_64(entries[idx].raw[raw_idx]);
     542         [ #  # ]:          0 :         if (val == (reg & mask) >> shift)
     543                 :            :                 return 0;
     544                 :            : 
     545                 :            :         reg &= ~mask;
     546                 :          0 :         reg |= (val << shift) & mask;
     547                 :          0 :         entries[idx].raw[raw_idx] = rte_cpu_to_le_64(reg);
     548                 :            : 
     549                 :          0 :         entries[idx].control |= rte_cpu_to_le_64(ctrl_bit);
     550                 :            : 
     551                 :          0 :         nfp_nsp_config_set_modified(nsp, true);
     552                 :            : 
     553                 :          0 :         return 0;
     554                 :            : }
     555                 :            : 
     556                 :            : #define NFP_ETH_SET_BIT_CONFIG(nsp, raw_idx, mask, val, ctrl_bit)      \
     557                 :            :         (__extension__ ({                                              \
     558                 :            :                 typeof(mask) _x = (mask);                              \
     559                 :            :                 nfp_eth_set_bit_config(nsp, raw_idx, _x, __bf_shf(_x), \
     560                 :            :                                 val, ctrl_bit);                        \
     561                 :            :         }))
     562                 :            : 
     563                 :            : /**
     564                 :            :  * Allow/disallow PHY module to advertise/perform autonegotiation.
     565                 :            :  * Will write to hwinfo overrides in the flash (persistent config).
     566                 :            :  *
     567                 :            :  * @param nsp
     568                 :            :  *   NFP NSP handle returned from nfp_eth_config_start()
     569                 :            :  * @param mode
     570                 :            :  *   Desired autonegotiation mode
     571                 :            :  *
     572                 :            :  * @return
     573                 :            :  *   0 or -ERRNO
     574                 :            :  */
     575                 :            : int
     576                 :          0 : nfp_eth_set_aneg(struct nfp_nsp *nsp,
     577                 :            :                 enum nfp_eth_aneg mode)
     578                 :            : {
     579                 :          0 :         return NFP_ETH_SET_BIT_CONFIG(nsp, NSP_ETH_RAW_STATE,
     580                 :            :                         NSP_ETH_STATE_ANEG, mode, NSP_ETH_CTRL_SET_ANEG);
     581                 :            : }
     582                 :            : 
     583                 :            : /**
     584                 :            :  * Set the PHY module forward error correction mode.
     585                 :            :  * Will write to hwinfo overrides in the flash (persistent config).
     586                 :            :  *
     587                 :            :  * @param nsp
     588                 :            :  *   NFP NSP handle returned from nfp_eth_config_start()
     589                 :            :  * @param mode
     590                 :            :  *   Desired fec mode
     591                 :            :  *
     592                 :            :  * @return
     593                 :            :  *   0 or -ERRNO
     594                 :            :  */
     595                 :            : static int
     596                 :            : nfp_eth_set_fec_real(struct nfp_nsp *nsp,
     597                 :            :                 enum nfp_eth_fec mode)
     598                 :            : {
     599                 :          0 :         return NFP_ETH_SET_BIT_CONFIG(nsp, NSP_ETH_RAW_STATE,
     600                 :            :                         NSP_ETH_STATE_FEC, mode, NSP_ETH_CTRL_SET_FEC);
     601                 :            : }
     602                 :            : 
     603                 :            : /**
     604                 :            :  * Set PHY forward error correction control mode
     605                 :            :  *
     606                 :            :  * @param cpp
     607                 :            :  *   NFP CPP handle
     608                 :            :  * @param idx
     609                 :            :  *   NFP chip-wide port index
     610                 :            :  * @param mode
     611                 :            :  *   Desired fec mode
     612                 :            :  *
     613                 :            :  * @return
     614                 :            :  *   - (0) Configuration successful
     615                 :            :  *   - (1) No changes were needed
     616                 :            :  *   - (-ERRNO) Configuration failed
     617                 :            :  */
     618                 :            : int
     619                 :          0 : nfp_eth_set_fec(struct nfp_cpp *cpp,
     620                 :            :                 uint32_t idx,
     621                 :            :                 enum nfp_eth_fec mode)
     622                 :            : {
     623                 :            :         int err;
     624                 :            :         struct nfp_nsp *nsp;
     625                 :            : 
     626                 :          0 :         nsp = nfp_eth_config_start(cpp, idx);
     627         [ #  # ]:          0 :         if (nsp == NULL)
     628                 :            :                 return -EIO;
     629                 :            : 
     630                 :            :         err = nfp_eth_set_fec_real(nsp, mode);
     631         [ #  # ]:          0 :         if (err != 0) {
     632                 :          0 :                 nfp_eth_config_cleanup_end(nsp);
     633                 :          0 :                 return err;
     634                 :            :         }
     635                 :            : 
     636                 :          0 :         return nfp_eth_config_commit_end(nsp);
     637                 :            : }
     638                 :            : 
     639                 :            : /**
     640                 :            :  * Set lane speed.
     641                 :            :  * Provided @speed value should be subport speed divided by number of
     642                 :            :  * lanes this subport is spanning (i.e. 10000 for 40G, 25000 for 50G, etc.)
     643                 :            :  * Will write to hwinfo overrides in the flash (persistent config).
     644                 :            :  *
     645                 :            :  * @param nsp
     646                 :            :  *   NFP NSP handle returned from nfp_eth_config_start()
     647                 :            :  * @param speed
     648                 :            :  *   Desired speed (per lane)
     649                 :            :  *
     650                 :            :  * @return
     651                 :            :  *   0 or -ERRNO
     652                 :            :  */
     653                 :            : int
     654                 :          0 : nfp_eth_set_speed(struct nfp_nsp *nsp,
     655                 :            :                 uint32_t speed)
     656                 :            : {
     657                 :            :         enum nfp_eth_rate rate;
     658                 :            : 
     659                 :            :         rate = nfp_eth_speed2rate(speed);
     660         [ #  # ]:          0 :         if (rate == RATE_INVALID) {
     661                 :          0 :                 PMD_DRV_LOG(ERR, "Could not find matching lane rate for speed %u", speed);
     662                 :          0 :                 return -EINVAL;
     663                 :            :         }
     664                 :            : 
     665                 :          0 :         return NFP_ETH_SET_BIT_CONFIG(nsp, NSP_ETH_RAW_STATE,
     666                 :            :                         NSP_ETH_STATE_RATE, rate, NSP_ETH_CTRL_SET_RATE);
     667                 :            : }
     668                 :            : 
     669                 :            : /**
     670                 :            :  * Set number of lanes in the port.
     671                 :            :  * Will write to hwinfo overrides in the flash (persistent config).
     672                 :            :  *
     673                 :            :  * @param nsp
     674                 :            :  *   NFP NSP handle returned from nfp_eth_config_start()
     675                 :            :  * @param lanes
     676                 :            :  *   Desired lanes per port
     677                 :            :  *
     678                 :            :  * @return
     679                 :            :  *   0 or -ERRNO
     680                 :            :  */
     681                 :            : int
     682                 :          0 : nfp_eth_set_split(struct nfp_nsp *nsp,
     683                 :            :                 uint32_t lanes)
     684                 :            : {
     685                 :          0 :         return NFP_ETH_SET_BIT_CONFIG(nsp, NSP_ETH_RAW_PORT,
     686                 :            :                         NSP_ETH_PORT_LANES, lanes, NSP_ETH_CTRL_SET_LANES);
     687                 :            : }
     688                 :            : 
     689                 :            : /**
     690                 :            :  * Set TX pause switch.
     691                 :            :  *
     692                 :            :  * @param nsp
     693                 :            :  *    NFP NSP handle returned from nfp_eth_config_start()
     694                 :            :  * @param tx_pause
     695                 :            :  *   TX pause switch
     696                 :            :  *
     697                 :            :  * @return
     698                 :            :  *   0 or -ERRNO
     699                 :            :  */
     700                 :            : int
     701                 :          0 : nfp_eth_set_tx_pause(struct nfp_nsp *nsp,
     702                 :            :                 bool tx_pause)
     703                 :            : {
     704         [ #  # ]:          0 :         if (nfp_nsp_get_abi_ver_minor(nsp) < 37) {
     705                 :          0 :                 PMD_DRV_LOG(ERR, "Set frame pause operation not supported, please update flash.");
     706                 :          0 :                 return -EOPNOTSUPP;
     707                 :            :         }
     708                 :            : 
     709                 :          0 :         return NFP_ETH_SET_BIT_CONFIG(nsp, NSP_ETH_RAW_STATE,
     710                 :            :                         NSP_ETH_STATE_TX_PAUSE, tx_pause, NSP_ETH_CTRL_SET_TX_PAUSE);
     711                 :            : }
     712                 :            : 
     713                 :            : /**
     714                 :            :  * Set RX pause switch.
     715                 :            :  *
     716                 :            :  * @param nsp
     717                 :            :  *    NFP NSP handle returned from nfp_eth_config_start()
     718                 :            :  * @param rx_pause
     719                 :            :  *   RX pause switch
     720                 :            :  *
     721                 :            :  * @return
     722                 :            :  *   0 or -ERRNO
     723                 :            :  */
     724                 :            : int
     725                 :          0 : nfp_eth_set_rx_pause(struct nfp_nsp *nsp,
     726                 :            :                 bool rx_pause)
     727                 :            : {
     728         [ #  # ]:          0 :         if (nfp_nsp_get_abi_ver_minor(nsp) < 37) {
     729                 :          0 :                 PMD_DRV_LOG(ERR, "Set frame pause operation not supported, please update flash.");
     730                 :          0 :                 return -EOPNOTSUPP;
     731                 :            :         }
     732                 :            : 
     733                 :          0 :         return NFP_ETH_SET_BIT_CONFIG(nsp, NSP_ETH_RAW_STATE,
     734                 :            :                         NSP_ETH_STATE_RX_PAUSE, rx_pause, NSP_ETH_CTRL_SET_RX_PAUSE);
     735                 :            : }

Generated by: LCOV version 1.14