LCOV - code coverage report
Current view: top level - drivers/net/sfc - sfc_repr_proxy.c (source / functions) Hit Total Coverage
Test: Code coverage Lines: 0 659 0.0 %
Date: 2025-03-01 20:23:48 Functions: 0 40 0.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 361 0.0 %

           Branch data     Line data    Source code
       1                 :            : /* SPDX-License-Identifier: BSD-3-Clause
       2                 :            :  *
       3                 :            :  * Copyright(c) 2019-2021 Xilinx, Inc.
       4                 :            :  * Copyright(c) 2019 Solarflare Communications Inc.
       5                 :            :  *
       6                 :            :  * This software was jointly developed between OKTET Labs (under contract
       7                 :            :  * for Solarflare) and Solarflare Communications, Inc.
       8                 :            :  */
       9                 :            : 
      10                 :            : #include <rte_service.h>
      11                 :            : #include <rte_service_component.h>
      12                 :            : 
      13                 :            : #include "sfc_log.h"
      14                 :            : #include "sfc_service.h"
      15                 :            : #include "sfc_repr_proxy.h"
      16                 :            : #include "sfc_repr_proxy_api.h"
      17                 :            : #include "sfc.h"
      18                 :            : #include "sfc_ev.h"
      19                 :            : #include "sfc_rx.h"
      20                 :            : #include "sfc_tx.h"
      21                 :            : #include "sfc_dp_rx.h"
      22                 :            : 
      23                 :            : /**
      24                 :            :  * Amount of time to wait for the representor proxy routine (which is
      25                 :            :  * running on a service core) to handle a request sent via mbox.
      26                 :            :  */
      27                 :            : #define SFC_REPR_PROXY_MBOX_POLL_TIMEOUT_MS     1000
      28                 :            : 
      29                 :            : /**
      30                 :            :  * Amount of time to wait for the representor proxy routine (which is
      31                 :            :  * running on a service core) to terminate after service core is stopped.
      32                 :            :  */
      33                 :            : #define SFC_REPR_PROXY_ROUTINE_TERMINATE_TIMEOUT_MS     10000
      34                 :            : 
      35                 :            : #define SFC_REPR_INVALID_ROUTE_PORT_ID  (UINT16_MAX)
      36                 :            : 
      37                 :            : static struct sfc_repr_proxy *
      38                 :            : sfc_repr_proxy_by_adapter(struct sfc_adapter *sa)
      39                 :            : {
      40                 :            :         return &sa->repr_proxy;
      41                 :            : }
      42                 :            : 
      43                 :            : static struct sfc_adapter *
      44                 :            : sfc_get_adapter_by_pf_port_id(uint16_t pf_port_id)
      45                 :            : {
      46                 :            :         struct rte_eth_dev *dev;
      47                 :            :         struct sfc_adapter *sa;
      48                 :            : 
      49                 :            :         SFC_ASSERT(pf_port_id < RTE_MAX_ETHPORTS);
      50                 :            : 
      51                 :            :         dev = &rte_eth_devices[pf_port_id];
      52                 :            :         sa = sfc_adapter_by_eth_dev(dev);
      53                 :            : 
      54                 :            :         return sa;
      55                 :            : }
      56                 :            : 
      57                 :            : static struct sfc_repr_proxy_port *
      58                 :            : sfc_repr_proxy_find_port(struct sfc_repr_proxy *rp, uint16_t repr_id)
      59                 :            : {
      60                 :            :         struct sfc_repr_proxy_port *port;
      61                 :            : 
      62   [ #  #  #  #  :          0 :         TAILQ_FOREACH(port, &rp->ports, entries) {
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  # ]
      63   [ #  #  #  #  :          0 :                 if (port->repr_id == repr_id)
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  # ]
      64                 :            :                         return port;
      65                 :            :         }
      66                 :            : 
      67                 :            :         return NULL;
      68                 :            : }
      69                 :            : 
      70                 :            : static int
      71                 :          0 : sfc_repr_proxy_mbox_send(struct sfc_repr_proxy_mbox *mbox,
      72                 :            :                          struct sfc_repr_proxy_port *port,
      73                 :            :                          enum sfc_repr_proxy_mbox_op op)
      74                 :            : {
      75                 :            :         const unsigned int wait_ms = SFC_REPR_PROXY_MBOX_POLL_TIMEOUT_MS;
      76                 :            :         unsigned int i;
      77                 :            : 
      78                 :          0 :         mbox->op = op;
      79                 :          0 :         mbox->port = port;
      80                 :          0 :         mbox->ack = false;
      81                 :            : 
      82                 :            :         /*
      83                 :            :          * Release ordering enforces marker set after data is populated.
      84                 :            :          * Paired with acquire ordering in sfc_repr_proxy_mbox_handle().
      85                 :            :          */
      86                 :          0 :         __atomic_store_n(&mbox->write_marker, true, __ATOMIC_RELEASE);
      87                 :            : 
      88                 :            :         /*
      89                 :            :          * Wait for the representor routine to process the request.
      90                 :            :          * Give up on timeout.
      91                 :            :          */
      92         [ #  # ]:          0 :         for (i = 0; i < wait_ms; i++) {
      93                 :            :                 /*
      94                 :            :                  * Paired with release ordering in sfc_repr_proxy_mbox_handle()
      95                 :            :                  * on acknowledge write.
      96                 :            :                  */
      97         [ #  # ]:          0 :                 if (__atomic_load_n(&mbox->ack, __ATOMIC_ACQUIRE))
      98                 :            :                         break;
      99                 :            : 
     100                 :            :                 rte_delay_ms(1);
     101                 :            :         }
     102                 :            : 
     103         [ #  # ]:          0 :         if (i == wait_ms) {
     104                 :          0 :                 SFC_GENERIC_LOG(ERR,
     105                 :            :                         "%s() failed to wait for representor proxy routine ack",
     106                 :            :                         __func__);
     107                 :          0 :                 return ETIMEDOUT;
     108                 :            :         }
     109                 :            : 
     110                 :            :         return 0;
     111                 :            : }
     112                 :            : 
     113                 :            : static void
     114                 :          0 : sfc_repr_proxy_mbox_handle(struct sfc_repr_proxy *rp)
     115                 :            : {
     116                 :            :         struct sfc_repr_proxy_mbox *mbox = &rp->mbox;
     117                 :            : 
     118                 :            :         /*
     119                 :            :          * Paired with release ordering in sfc_repr_proxy_mbox_send()
     120                 :            :          * on marker set.
     121                 :            :          */
     122         [ #  # ]:          0 :         if (!__atomic_load_n(&mbox->write_marker, __ATOMIC_ACQUIRE))
     123                 :            :                 return;
     124                 :            : 
     125                 :          0 :         mbox->write_marker = false;
     126                 :            : 
     127   [ #  #  #  #  :          0 :         switch (mbox->op) {
                      # ]
     128                 :          0 :         case SFC_REPR_PROXY_MBOX_ADD_PORT:
     129                 :          0 :                 TAILQ_INSERT_TAIL(&rp->ports, mbox->port, entries);
     130                 :          0 :                 break;
     131                 :          0 :         case SFC_REPR_PROXY_MBOX_DEL_PORT:
     132         [ #  # ]:          0 :                 TAILQ_REMOVE(&rp->ports, mbox->port, entries);
     133                 :          0 :                 break;
     134                 :          0 :         case SFC_REPR_PROXY_MBOX_START_PORT:
     135                 :          0 :                 mbox->port->started = true;
     136                 :          0 :                 break;
     137                 :          0 :         case SFC_REPR_PROXY_MBOX_STOP_PORT:
     138                 :          0 :                 mbox->port->started = false;
     139                 :          0 :                 break;
     140                 :            :         default:
     141                 :            :                 SFC_ASSERT(0);
     142                 :            :                 return;
     143                 :            :         }
     144                 :            : 
     145                 :            :         /*
     146                 :            :          * Paired with acquire ordering in sfc_repr_proxy_mbox_send()
     147                 :            :          * on acknowledge read.
     148                 :            :          */
     149                 :          0 :         __atomic_store_n(&mbox->ack, true, __ATOMIC_RELEASE);
     150                 :            : }
     151                 :            : 
     152                 :            : static void
     153                 :          0 : sfc_repr_proxy_handle_tx(struct sfc_repr_proxy_dp_txq *rp_txq,
     154                 :            :                          struct sfc_repr_proxy_txq *repr_txq)
     155                 :            : {
     156                 :            :         /*
     157                 :            :          * With multiple representor proxy queues configured it is
     158                 :            :          * possible that not all of the corresponding representor
     159                 :            :          * queues were created. Skip the queues that do not exist.
     160                 :            :          */
     161         [ #  # ]:          0 :         if (repr_txq->ring == NULL)
     162                 :            :                 return;
     163                 :            : 
     164         [ #  # ]:          0 :         if (rp_txq->available < RTE_DIM(rp_txq->tx_pkts)) {
     165                 :          0 :                 rp_txq->available +=
     166                 :          0 :                         rte_ring_sc_dequeue_burst(repr_txq->ring,
     167                 :          0 :                                 (void **)(&rp_txq->tx_pkts[rp_txq->available]),
     168                 :            :                                 RTE_DIM(rp_txq->tx_pkts) - rp_txq->available,
     169                 :            :                                 NULL);
     170                 :            : 
     171         [ #  # ]:          0 :                 if (rp_txq->available == rp_txq->transmitted)
     172                 :            :                         return;
     173                 :            :         }
     174                 :            : 
     175                 :          0 :         rp_txq->transmitted += rp_txq->pkt_burst(rp_txq->dp,
     176                 :            :                                 &rp_txq->tx_pkts[rp_txq->transmitted],
     177                 :          0 :                                 rp_txq->available - rp_txq->transmitted);
     178                 :            : 
     179         [ #  # ]:          0 :         if (rp_txq->available == rp_txq->transmitted) {
     180                 :          0 :                 rp_txq->available = 0;
     181                 :          0 :                 rp_txq->transmitted = 0;
     182                 :            :         }
     183                 :            : }
     184                 :            : 
     185                 :            : static struct sfc_repr_proxy_port *
     186                 :            : sfc_repr_proxy_rx_route_mbuf(struct sfc_repr_proxy *rp, struct rte_mbuf *m)
     187                 :            : {
     188                 :            :         struct sfc_repr_proxy_port *port;
     189                 :            :         efx_mport_id_t mport_id;
     190                 :            : 
     191                 :          0 :         mport_id.id = *RTE_MBUF_DYNFIELD(m, sfc_dp_mport_offset,
     192                 :            :                                          typeof(&((efx_mport_id_t *)0)->id));
     193                 :            : 
     194         [ #  # ]:          0 :         TAILQ_FOREACH(port, &rp->ports, entries) {
     195         [ #  # ]:          0 :                 if (port->egress_mport.id == mport_id.id) {
     196                 :          0 :                         m->port = port->rte_port_id;
     197                 :          0 :                         m->ol_flags &= ~sfc_dp_mport_override;
     198                 :          0 :                         return port;
     199                 :            :                 }
     200                 :            :         }
     201                 :            : 
     202                 :            :         return NULL;
     203                 :            : }
     204                 :            : 
     205                 :            : /*
     206                 :            :  * Returns true if a packet is encountered which should be forwarded to a
     207                 :            :  * port which is different from the one that is currently routed.
     208                 :            :  */
     209                 :            : static bool
     210                 :          0 : sfc_repr_proxy_rx_route(struct sfc_repr_proxy *rp,
     211                 :            :                         struct sfc_repr_proxy_dp_rxq *rp_rxq)
     212                 :            : {
     213                 :            :         unsigned int i;
     214                 :            : 
     215                 :          0 :         for (i = rp_rxq->routed;
     216   [ #  #  #  # ]:          0 :              i < rp_rxq->available && !rp_rxq->stop_route;
     217                 :          0 :              i++, rp_rxq->routed++) {
     218                 :            :                 struct sfc_repr_proxy_port *port;
     219                 :          0 :                 struct rte_mbuf *m = rp_rxq->pkts[i];
     220                 :            : 
     221                 :            :                 port = sfc_repr_proxy_rx_route_mbuf(rp, m);
     222                 :            :                 /* Cannot find destination representor */
     223         [ #  # ]:          0 :                 if (port == NULL) {
     224                 :            :                         /* Effectively drop the packet */
     225                 :          0 :                         rp_rxq->forwarded++;
     226                 :          0 :                         continue;
     227                 :            :                 }
     228                 :            : 
     229                 :            :                 /* Currently routed packets are mapped to a different port */
     230   [ #  #  #  # ]:          0 :                 if (port->repr_id != rp_rxq->route_port_id &&
     231                 :            :                     rp_rxq->route_port_id != SFC_REPR_INVALID_ROUTE_PORT_ID)
     232                 :            :                         return true;
     233                 :            : 
     234                 :          0 :                 rp_rxq->route_port_id = port->repr_id;
     235                 :            :         }
     236                 :            : 
     237                 :            :         return false;
     238                 :            : }
     239                 :            : 
     240                 :            : static void
     241                 :          0 : sfc_repr_proxy_rx_forward(struct sfc_repr_proxy *rp,
     242                 :            :                           struct sfc_repr_proxy_dp_rxq *rp_rxq)
     243                 :            : {
     244                 :            :         struct sfc_repr_proxy_port *port;
     245                 :            : 
     246         [ #  # ]:          0 :         if (rp_rxq->route_port_id != SFC_REPR_INVALID_ROUTE_PORT_ID) {
     247                 :            :                 port = sfc_repr_proxy_find_port(rp, rp_rxq->route_port_id);
     248                 :            : 
     249   [ #  #  #  # ]:          0 :                 if (port != NULL && port->started) {
     250                 :          0 :                         rp_rxq->forwarded +=
     251                 :          0 :                             rte_ring_sp_enqueue_burst(port->rxq[0].ring,
     252                 :          0 :                                 (void **)(&rp_rxq->pkts[rp_rxq->forwarded]),
     253                 :          0 :                                 rp_rxq->routed - rp_rxq->forwarded, NULL);
     254                 :            :                 } else {
     255                 :            :                         /* Drop all routed packets if the port is not started */
     256                 :          0 :                         rp_rxq->forwarded = rp_rxq->routed;
     257                 :            :                 }
     258                 :            :         }
     259                 :            : 
     260         [ #  # ]:          0 :         if (rp_rxq->forwarded == rp_rxq->routed) {
     261                 :          0 :                 rp_rxq->route_port_id = SFC_REPR_INVALID_ROUTE_PORT_ID;
     262                 :          0 :                 rp_rxq->stop_route = false;
     263                 :            :         } else {
     264                 :            :                 /* Stall packet routing if not all packets were forwarded */
     265                 :          0 :                 rp_rxq->stop_route = true;
     266                 :            :         }
     267                 :            : 
     268         [ #  # ]:          0 :         if (rp_rxq->available == rp_rxq->forwarded)
     269                 :          0 :                 rp_rxq->available = rp_rxq->forwarded = rp_rxq->routed = 0;
     270                 :          0 : }
     271                 :            : 
     272                 :            : static void
     273                 :          0 : sfc_repr_proxy_handle_rx(struct sfc_repr_proxy *rp,
     274                 :            :                          struct sfc_repr_proxy_dp_rxq *rp_rxq)
     275                 :            : {
     276                 :            :         bool route_again;
     277                 :            : 
     278         [ #  # ]:          0 :         if (rp_rxq->available < RTE_DIM(rp_rxq->pkts)) {
     279                 :          0 :                 rp_rxq->available += rp_rxq->pkt_burst(rp_rxq->dp,
     280                 :            :                                 &rp_rxq->pkts[rp_rxq->available],
     281                 :          0 :                                 RTE_DIM(rp_rxq->pkts) - rp_rxq->available);
     282         [ #  # ]:          0 :                 if (rp_rxq->available == rp_rxq->forwarded)
     283                 :            :                         return;
     284                 :            :         }
     285                 :            : 
     286                 :            :         do {
     287                 :          0 :                 route_again = sfc_repr_proxy_rx_route(rp, rp_rxq);
     288                 :          0 :                 sfc_repr_proxy_rx_forward(rp, rp_rxq);
     289   [ #  #  #  # ]:          0 :         } while (route_again && !rp_rxq->stop_route);
     290                 :            : }
     291                 :            : 
     292                 :            : static int32_t
     293                 :          0 : sfc_repr_proxy_routine(void *arg)
     294                 :            : {
     295                 :            :         struct sfc_repr_proxy_port *port;
     296                 :            :         struct sfc_repr_proxy *rp = arg;
     297                 :            :         unsigned int i;
     298                 :            : 
     299                 :          0 :         sfc_repr_proxy_mbox_handle(rp);
     300                 :            : 
     301         [ #  # ]:          0 :         TAILQ_FOREACH(port, &rp->ports, entries) {
     302         [ #  # ]:          0 :                 if (!port->started)
     303                 :          0 :                         continue;
     304                 :            : 
     305         [ #  # ]:          0 :                 for (i = 0; i < rp->nb_txq; i++)
     306                 :          0 :                         sfc_repr_proxy_handle_tx(&rp->dp_txq[i], &port->txq[i]);
     307                 :            :         }
     308                 :            : 
     309         [ #  # ]:          0 :         for (i = 0; i < rp->nb_rxq; i++)
     310                 :          0 :                 sfc_repr_proxy_handle_rx(rp, &rp->dp_rxq[i]);
     311                 :            : 
     312                 :          0 :         return 0;
     313                 :            : }
     314                 :            : 
     315                 :            : static struct sfc_txq_info *
     316                 :            : sfc_repr_proxy_txq_info_get(struct sfc_adapter *sa, unsigned int repr_queue_id)
     317                 :            : {
     318                 :            :         struct sfc_adapter_shared *sas = sfc_sa2shared(sa);
     319                 :            :         struct sfc_repr_proxy_dp_txq *dp_txq;
     320                 :            : 
     321                 :            :         SFC_ASSERT(repr_queue_id < sfc_repr_nb_txq(sas));
     322                 :            :         dp_txq = &sa->repr_proxy.dp_txq[repr_queue_id];
     323                 :            : 
     324                 :          0 :         return &sas->txq_info[dp_txq->sw_index];
     325                 :            : }
     326                 :            : 
     327                 :            : static int
     328                 :          0 : sfc_repr_proxy_txq_attach(struct sfc_adapter *sa)
     329                 :            : {
     330                 :            :         struct sfc_adapter_shared * const sas = sfc_sa2shared(sa);
     331                 :            :         struct sfc_repr_proxy *rp = &sa->repr_proxy;
     332                 :            :         unsigned int i;
     333                 :            : 
     334                 :          0 :         sfc_log_init(sa, "entry");
     335                 :            : 
     336         [ #  # ]:          0 :         for (i = 0; i < sfc_repr_nb_txq(sas); i++) {
     337                 :            :                 sfc_sw_index_t sw_index = sfc_repr_txq_sw_index(sas, i);
     338                 :            : 
     339                 :          0 :                 rp->dp_txq[i].sw_index = sw_index;
     340                 :            :         }
     341                 :            : 
     342                 :          0 :         sfc_log_init(sa, "done");
     343                 :            : 
     344                 :          0 :         return 0;
     345                 :            : }
     346                 :            : 
     347                 :            : static void
     348                 :          0 : sfc_repr_proxy_txq_detach(struct sfc_adapter *sa)
     349                 :            : {
     350                 :            :         struct sfc_adapter_shared * const sas = sfc_sa2shared(sa);
     351                 :            :         struct sfc_repr_proxy *rp = &sa->repr_proxy;
     352                 :            :         unsigned int i;
     353                 :            : 
     354                 :          0 :         sfc_log_init(sa, "entry");
     355                 :            : 
     356         [ #  # ]:          0 :         for (i = 0; i < sfc_repr_nb_txq(sas); i++)
     357                 :          0 :                 rp->dp_txq[i].sw_index = 0;
     358                 :            : 
     359                 :          0 :         sfc_log_init(sa, "done");
     360                 :          0 : }
     361                 :            : 
     362                 :            : int
     363                 :          0 : sfc_repr_proxy_txq_init(struct sfc_adapter *sa)
     364                 :            : {
     365                 :            :         struct sfc_adapter_shared * const sas = sfc_sa2shared(sa);
     366                 :            :         struct sfc_repr_proxy *rp = &sa->repr_proxy;
     367                 :          0 :         const struct rte_eth_txconf tx_conf = {
     368                 :            :                 .tx_free_thresh = SFC_REPR_PROXY_TXQ_FREE_THRESH,
     369                 :            :         };
     370                 :            :         struct sfc_txq_info *txq_info;
     371                 :            :         unsigned int init_i;
     372                 :            :         unsigned int i;
     373                 :            :         int rc;
     374                 :            : 
     375                 :          0 :         sfc_log_init(sa, "entry");
     376                 :            : 
     377         [ #  # ]:          0 :         if (!sfc_repr_available(sas)) {
     378                 :          0 :                 sfc_log_init(sa, "representors not supported - skip");
     379                 :          0 :                 return 0;
     380                 :            :         }
     381                 :            : 
     382         [ #  # ]:          0 :         for (init_i = 0; init_i < sfc_repr_nb_txq(sas); init_i++) {
     383                 :            :                 struct sfc_repr_proxy_dp_txq *txq = &rp->dp_txq[init_i];
     384                 :            : 
     385                 :          0 :                 txq_info = &sfc_sa2shared(sa)->txq_info[txq->sw_index];
     386         [ #  # ]:          0 :                 if (txq_info->state == SFC_TXQ_INITIALIZED) {
     387                 :          0 :                         sfc_log_init(sa,
     388                 :            :                                 "representor proxy TxQ %u is already initialized - skip",
     389                 :            :                                 init_i);
     390                 :          0 :                         continue;
     391                 :            :                 }
     392                 :            : 
     393                 :          0 :                 sfc_tx_qinit_info(sa, txq->sw_index);
     394                 :            : 
     395                 :          0 :                 rc = sfc_tx_qinit(sa, txq->sw_index,
     396                 :          0 :                                   SFC_REPR_PROXY_TX_DESC_COUNT, sa->socket_id,
     397                 :            :                                   &tx_conf);
     398                 :            : 
     399         [ #  # ]:          0 :                 if (rc != 0) {
     400                 :          0 :                         sfc_err(sa, "failed to init representor proxy TxQ %u",
     401                 :            :                                 init_i);
     402                 :          0 :                         goto fail_init;
     403                 :            :                 }
     404                 :            :         }
     405                 :            : 
     406                 :          0 :         sfc_log_init(sa, "done");
     407                 :            : 
     408                 :          0 :         return 0;
     409                 :            : 
     410                 :            : fail_init:
     411         [ #  # ]:          0 :         for (i = 0; i < init_i; i++) {
     412                 :            :                 struct sfc_repr_proxy_dp_txq *txq = &rp->dp_txq[i];
     413                 :            : 
     414                 :          0 :                 txq_info = &sfc_sa2shared(sa)->txq_info[txq->sw_index];
     415         [ #  # ]:          0 :                 if (txq_info->state == SFC_TXQ_INITIALIZED)
     416                 :          0 :                         sfc_tx_qfini(sa, txq->sw_index);
     417                 :            :         }
     418                 :          0 :         sfc_log_init(sa, "failed: %s", rte_strerror(rc));
     419                 :            : 
     420                 :          0 :         return rc;
     421                 :            : }
     422                 :            : 
     423                 :            : void
     424                 :          0 : sfc_repr_proxy_txq_fini(struct sfc_adapter *sa)
     425                 :            : {
     426                 :            :         struct sfc_adapter_shared * const sas = sfc_sa2shared(sa);
     427                 :            :         struct sfc_repr_proxy *rp = &sa->repr_proxy;
     428                 :            :         struct sfc_txq_info *txq_info;
     429                 :            :         unsigned int i;
     430                 :            : 
     431                 :          0 :         sfc_log_init(sa, "entry");
     432                 :            : 
     433         [ #  # ]:          0 :         if (!sfc_repr_available(sas)) {
     434                 :          0 :                 sfc_log_init(sa, "representors not supported - skip");
     435                 :          0 :                 return;
     436                 :            :         }
     437                 :            : 
     438         [ #  # ]:          0 :         for (i = 0; i < sfc_repr_nb_txq(sas); i++) {
     439                 :            :                 struct sfc_repr_proxy_dp_txq *txq = &rp->dp_txq[i];
     440                 :            : 
     441                 :          0 :                 txq_info = &sfc_sa2shared(sa)->txq_info[txq->sw_index];
     442         [ #  # ]:          0 :                 if (txq_info->state != SFC_TXQ_INITIALIZED) {
     443                 :          0 :                         sfc_log_init(sa,
     444                 :            :                                 "representor proxy TxQ %u is already finalized - skip",
     445                 :            :                                 i);
     446                 :          0 :                         continue;
     447                 :            :                 }
     448                 :            : 
     449                 :          0 :                 sfc_tx_qfini(sa, txq->sw_index);
     450                 :            :         }
     451                 :            : 
     452                 :          0 :         sfc_log_init(sa, "done");
     453                 :            : }
     454                 :            : 
     455                 :            : static int
     456                 :          0 : sfc_repr_proxy_txq_start(struct sfc_adapter *sa)
     457                 :            : {
     458                 :            :         struct sfc_adapter_shared * const sas = sfc_sa2shared(sa);
     459                 :            :         struct sfc_repr_proxy *rp = &sa->repr_proxy;
     460                 :            :         unsigned int i;
     461                 :            : 
     462                 :          0 :         sfc_log_init(sa, "entry");
     463                 :            : 
     464         [ #  # ]:          0 :         for (i = 0; i < sfc_repr_nb_txq(sas); i++) {
     465                 :            :                 struct sfc_repr_proxy_dp_txq *txq = &rp->dp_txq[i];
     466                 :            : 
     467                 :          0 :                 txq->dp = sfc_repr_proxy_txq_info_get(sa, i)->dp;
     468                 :          0 :                 txq->pkt_burst = sa->eth_dev->tx_pkt_burst;
     469                 :          0 :                 txq->available = 0;
     470                 :          0 :                 txq->transmitted = 0;
     471                 :            :         }
     472                 :            : 
     473                 :          0 :         sfc_log_init(sa, "done");
     474                 :            : 
     475                 :          0 :         return 0;
     476                 :            : }
     477                 :            : 
     478                 :            : static void
     479                 :          0 : sfc_repr_proxy_txq_stop(struct sfc_adapter *sa)
     480                 :            : {
     481                 :          0 :         sfc_log_init(sa, "entry");
     482                 :          0 :         sfc_log_init(sa, "done");
     483                 :          0 : }
     484                 :            : 
     485                 :            : static int
     486                 :          0 : sfc_repr_proxy_rxq_attach(struct sfc_adapter *sa)
     487                 :            : {
     488                 :            :         struct sfc_adapter_shared * const sas = sfc_sa2shared(sa);
     489                 :            :         struct sfc_repr_proxy *rp = &sa->repr_proxy;
     490                 :            :         unsigned int i;
     491                 :            : 
     492                 :          0 :         sfc_log_init(sa, "entry");
     493                 :            : 
     494         [ #  # ]:          0 :         for (i = 0; i < sfc_repr_nb_rxq(sas); i++) {
     495                 :            :                 sfc_sw_index_t sw_index = sfc_repr_rxq_sw_index(sas, i);
     496                 :            : 
     497                 :          0 :                 rp->dp_rxq[i].sw_index = sw_index;
     498                 :            :         }
     499                 :            : 
     500                 :          0 :         sfc_log_init(sa, "done");
     501                 :            : 
     502                 :          0 :         return 0;
     503                 :            : }
     504                 :            : 
     505                 :            : static void
     506                 :          0 : sfc_repr_proxy_rxq_detach(struct sfc_adapter *sa)
     507                 :            : {
     508                 :            :         struct sfc_adapter_shared * const sas = sfc_sa2shared(sa);
     509                 :            :         struct sfc_repr_proxy *rp = &sa->repr_proxy;
     510                 :            :         unsigned int i;
     511                 :            : 
     512                 :          0 :         sfc_log_init(sa, "entry");
     513                 :            : 
     514         [ #  # ]:          0 :         for (i = 0; i < sfc_repr_nb_rxq(sas); i++)
     515                 :          0 :                 rp->dp_rxq[i].sw_index = 0;
     516                 :            : 
     517                 :          0 :         sfc_log_init(sa, "done");
     518                 :          0 : }
     519                 :            : 
     520                 :            : static struct sfc_rxq_info *
     521                 :            : sfc_repr_proxy_rxq_info_get(struct sfc_adapter *sa, unsigned int repr_queue_id)
     522                 :            : {
     523                 :            :         struct sfc_adapter_shared *sas = sfc_sa2shared(sa);
     524                 :            :         struct sfc_repr_proxy_dp_rxq *dp_rxq;
     525                 :            : 
     526                 :            :         SFC_ASSERT(repr_queue_id < sfc_repr_nb_rxq(sas));
     527                 :            :         dp_rxq = &sa->repr_proxy.dp_rxq[repr_queue_id];
     528                 :            : 
     529                 :          0 :         return &sas->rxq_info[dp_rxq->sw_index];
     530                 :            : }
     531                 :            : 
     532                 :            : static int
     533                 :          0 : sfc_repr_proxy_rxq_init(struct sfc_adapter *sa,
     534                 :            :                         struct sfc_repr_proxy_dp_rxq *rxq)
     535                 :            : {
     536                 :            :         struct sfc_adapter_shared * const sas = sfc_sa2shared(sa);
     537                 :            :         uint16_t nb_rx_desc = SFC_REPR_PROXY_RX_DESC_COUNT;
     538                 :            :         struct sfc_rxq_info *rxq_info;
     539                 :          0 :         struct rte_eth_rxconf rxconf = {
     540                 :            :                 .rx_free_thresh = SFC_REPR_PROXY_RXQ_REFILL_LEVEL,
     541                 :            :                 .rx_drop_en = 1,
     542                 :            :         };
     543                 :            :         int rc;
     544                 :            : 
     545                 :          0 :         sfc_log_init(sa, "entry");
     546                 :            : 
     547                 :          0 :         rxq_info = &sas->rxq_info[rxq->sw_index];
     548         [ #  # ]:          0 :         if (rxq_info->state & SFC_RXQ_INITIALIZED) {
     549                 :          0 :                 sfc_log_init(sa, "RxQ is already initialized - skip");
     550                 :          0 :                 return 0;
     551                 :            :         }
     552                 :            : 
     553                 :          0 :         nb_rx_desc = RTE_MIN(nb_rx_desc, sa->rxq_max_entries);
     554                 :          0 :         nb_rx_desc = RTE_MAX(nb_rx_desc, sa->rxq_min_entries);
     555                 :            : 
     556                 :          0 :         rc = sfc_rx_qinit_info(sa, rxq->sw_index, EFX_RXQ_FLAG_INGRESS_MPORT);
     557         [ #  # ]:          0 :         if (rc != 0) {
     558                 :          0 :                 sfc_err(sa, "failed to init representor proxy RxQ info");
     559                 :          0 :                 goto fail_repr_rxq_init_info;
     560                 :            :         }
     561                 :            : 
     562                 :          0 :         rc = sfc_rx_qinit(sa, rxq->sw_index, nb_rx_desc, sa->socket_id, &rxconf,
     563                 :            :                           rxq->mp);
     564         [ #  # ]:          0 :         if (rc != 0) {
     565                 :          0 :                 sfc_err(sa, "failed to init representor proxy RxQ");
     566                 :          0 :                 goto fail_repr_rxq_init;
     567                 :            :         }
     568                 :            : 
     569                 :          0 :         sfc_log_init(sa, "done");
     570                 :            : 
     571                 :          0 :         return 0;
     572                 :            : 
     573                 :            : fail_repr_rxq_init:
     574                 :          0 : fail_repr_rxq_init_info:
     575                 :          0 :         sfc_log_init(sa, "failed: %s", rte_strerror(rc));
     576                 :            : 
     577                 :          0 :         return rc;
     578                 :            : }
     579                 :            : 
     580                 :            : static void
     581                 :          0 : sfc_repr_proxy_rxq_fini(struct sfc_adapter *sa)
     582                 :            : {
     583                 :            :         struct sfc_adapter_shared * const sas = sfc_sa2shared(sa);
     584                 :            :         struct sfc_repr_proxy *rp = &sa->repr_proxy;
     585                 :            :         struct sfc_rxq_info *rxq_info;
     586                 :            :         unsigned int i;
     587                 :            : 
     588                 :          0 :         sfc_log_init(sa, "entry");
     589                 :            : 
     590         [ #  # ]:          0 :         if (!sfc_repr_available(sas)) {
     591                 :          0 :                 sfc_log_init(sa, "representors not supported - skip");
     592                 :          0 :                 return;
     593                 :            :         }
     594                 :            : 
     595         [ #  # ]:          0 :         for (i = 0; i < sfc_repr_nb_rxq(sas); i++) {
     596                 :            :                 struct sfc_repr_proxy_dp_rxq *rxq = &rp->dp_rxq[i];
     597                 :            : 
     598                 :          0 :                 rxq_info = &sas->rxq_info[rxq->sw_index];
     599         [ #  # ]:          0 :                 if (rxq_info->state != SFC_RXQ_INITIALIZED) {
     600                 :          0 :                         sfc_log_init(sa,
     601                 :            :                                 "representor RxQ %u is already finalized - skip",
     602                 :            :                                 i);
     603                 :          0 :                         continue;
     604                 :            :                 }
     605                 :            : 
     606                 :          0 :                 sfc_rx_qfini(sa, rxq->sw_index);
     607                 :            :         }
     608                 :            : 
     609                 :          0 :         sfc_log_init(sa, "done");
     610                 :            : }
     611                 :            : 
     612                 :            : static void
     613                 :          0 : sfc_repr_proxy_rxq_stop(struct sfc_adapter *sa)
     614                 :            : {
     615                 :            :         struct sfc_adapter_shared * const sas = sfc_sa2shared(sa);
     616                 :            :         unsigned int i;
     617                 :            : 
     618                 :          0 :         sfc_log_init(sa, "entry");
     619                 :            : 
     620         [ #  # ]:          0 :         for (i = 0; i < sfc_repr_nb_rxq(sas); i++)
     621                 :          0 :                 sfc_rx_qstop(sa, sa->repr_proxy.dp_rxq[i].sw_index);
     622                 :            : 
     623                 :          0 :         sfc_repr_proxy_rxq_fini(sa);
     624                 :            : 
     625                 :          0 :         sfc_log_init(sa, "done");
     626                 :          0 : }
     627                 :            : 
     628                 :            : static int
     629                 :          0 : sfc_repr_proxy_rxq_start(struct sfc_adapter *sa)
     630                 :            : {
     631                 :            :         struct sfc_adapter_shared * const sas = sfc_sa2shared(sa);
     632                 :            :         struct sfc_repr_proxy *rp = &sa->repr_proxy;
     633                 :            :         unsigned int i;
     634                 :            :         int rc;
     635                 :            : 
     636                 :          0 :         sfc_log_init(sa, "entry");
     637                 :            : 
     638         [ #  # ]:          0 :         if (!sfc_repr_available(sas)) {
     639                 :          0 :                 sfc_log_init(sa, "representors not supported - skip");
     640                 :          0 :                 return 0;
     641                 :            :         }
     642                 :            : 
     643         [ #  # ]:          0 :         for (i = 0; i < sfc_repr_nb_rxq(sas); i++) {
     644                 :          0 :                 struct sfc_repr_proxy_dp_rxq *rxq = &rp->dp_rxq[i];
     645                 :            : 
     646                 :          0 :                 rc = sfc_repr_proxy_rxq_init(sa, rxq);
     647         [ #  # ]:          0 :                 if (rc != 0) {
     648                 :          0 :                         sfc_err(sa, "failed to init representor proxy RxQ %u",
     649                 :            :                                 i);
     650                 :          0 :                         goto fail_init;
     651                 :            :                 }
     652                 :            : 
     653                 :          0 :                 rc = sfc_rx_qstart(sa, rxq->sw_index);
     654         [ #  # ]:          0 :                 if (rc != 0) {
     655                 :          0 :                         sfc_err(sa, "failed to start representor proxy RxQ %u",
     656                 :            :                                 i);
     657                 :          0 :                         goto fail_start;
     658                 :            :                 }
     659                 :            : 
     660                 :          0 :                 rxq->dp = sfc_repr_proxy_rxq_info_get(sa, i)->dp;
     661                 :          0 :                 rxq->pkt_burst = sa->eth_dev->rx_pkt_burst;
     662                 :          0 :                 rxq->available = 0;
     663                 :          0 :                 rxq->routed = 0;
     664                 :          0 :                 rxq->forwarded = 0;
     665                 :          0 :                 rxq->stop_route = false;
     666                 :          0 :                 rxq->route_port_id = SFC_REPR_INVALID_ROUTE_PORT_ID;
     667                 :            :         }
     668                 :            : 
     669                 :          0 :         sfc_log_init(sa, "done");
     670                 :            : 
     671                 :          0 :         return 0;
     672                 :            : 
     673                 :            : fail_start:
     674                 :          0 : fail_init:
     675                 :          0 :         sfc_repr_proxy_rxq_stop(sa);
     676                 :          0 :         sfc_log_init(sa, "failed: %s", rte_strerror(rc));
     677                 :          0 :         return rc;
     678                 :            : }
     679                 :            : 
     680                 :            : static int
     681                 :          0 : sfc_repr_proxy_mae_rule_insert(struct sfc_adapter *sa,
     682                 :            :                                struct sfc_repr_proxy_port *port)
     683                 :            : {
     684                 :            :         int rc = EINVAL;
     685                 :            : 
     686                 :          0 :         sfc_log_init(sa, "entry");
     687                 :            : 
     688                 :          0 :         port->mae_rule = sfc_mae_repr_flow_create(sa,
     689                 :          0 :                                     SFC_MAE_RULE_PRIO_LOWEST, port->rte_port_id,
     690                 :            :                                     RTE_FLOW_ACTION_TYPE_PORT_REPRESENTOR,
     691                 :            :                                     RTE_FLOW_ITEM_TYPE_REPRESENTED_PORT);
     692         [ #  # ]:          0 :         if (port->mae_rule == NULL) {
     693                 :          0 :                 sfc_err(sa, "failed to insert MAE rule for repr %u",
     694                 :            :                         port->repr_id);
     695                 :          0 :                 goto fail_rule_add;
     696                 :            :         }
     697                 :            : 
     698                 :          0 :         sfc_log_init(sa, "done");
     699                 :            : 
     700                 :          0 :         return 0;
     701                 :            : 
     702                 :            : fail_rule_add:
     703                 :          0 :         sfc_log_init(sa, "failed: %s", rte_strerror(rc));
     704                 :          0 :         return rc;
     705                 :            : }
     706                 :            : 
     707                 :            : static void
     708                 :            : sfc_repr_proxy_mae_rule_remove(struct sfc_adapter *sa,
     709                 :            :                                struct sfc_repr_proxy_port *port)
     710                 :            : {
     711                 :          0 :         sfc_mae_repr_flow_destroy(sa, port->mae_rule);
     712                 :            : }
     713                 :            : 
     714                 :            : static int
     715                 :          0 : sfc_repr_proxy_mport_filter_insert(struct sfc_adapter *sa)
     716                 :            : {
     717                 :            :         struct sfc_adapter_shared * const sas = sfc_sa2shared(sa);
     718                 :            :         struct sfc_repr_proxy *rp = &sa->repr_proxy;
     719                 :            :         struct sfc_rxq *rxq_ctrl;
     720                 :            :         struct sfc_repr_proxy_filter *filter = &rp->mport_filter;
     721                 :            :         efx_mport_sel_t mport_alias_selector;
     722                 :            :         static const efx_filter_match_flags_t flags[RTE_DIM(filter->specs)] = {
     723                 :            :                 EFX_FILTER_MATCH_UNKNOWN_UCAST_DST,
     724                 :            :                 EFX_FILTER_MATCH_UNKNOWN_MCAST_DST };
     725                 :            :         unsigned int i;
     726                 :            :         int rc;
     727                 :            : 
     728                 :          0 :         sfc_log_init(sa, "entry");
     729                 :            : 
     730         [ #  # ]:          0 :         if (sfc_repr_nb_rxq(sas) == 1) {
     731                 :          0 :                 rxq_ctrl = &sa->rxq_ctrl[rp->dp_rxq[0].sw_index];
     732                 :            :         } else {
     733                 :          0 :                 sfc_err(sa, "multiple representor proxy RxQs not supported");
     734                 :            :                 rc = ENOTSUP;
     735                 :          0 :                 goto fail_multiple_queues;
     736                 :            :         }
     737                 :            : 
     738                 :          0 :         rc = efx_mae_mport_by_id(&rp->mport_alias, &mport_alias_selector);
     739         [ #  # ]:          0 :         if (rc != 0) {
     740                 :          0 :                 sfc_err(sa, "failed to get repr proxy mport by ID");
     741                 :          0 :                 goto fail_get_selector;
     742                 :            :         }
     743                 :            : 
     744                 :          0 :         memset(filter->specs, 0, sizeof(filter->specs));
     745         [ #  # ]:          0 :         for (i = 0; i < RTE_DIM(filter->specs); i++) {
     746                 :          0 :                 filter->specs[i].efs_priority = EFX_FILTER_PRI_MANUAL;
     747                 :          0 :                 filter->specs[i].efs_flags = EFX_FILTER_FLAG_RX;
     748                 :          0 :                 filter->specs[i].efs_dmaq_id = rxq_ctrl->hw_index;
     749                 :          0 :                 filter->specs[i].efs_match_flags = flags[i] |
     750                 :            :                                 EFX_FILTER_MATCH_MPORT;
     751                 :          0 :                 filter->specs[i].efs_ingress_mport = mport_alias_selector.sel;
     752                 :            : 
     753                 :          0 :                 rc = efx_filter_insert(sa->nic, &filter->specs[i]);
     754         [ #  # ]:          0 :                 if (rc != 0) {
     755                 :          0 :                         sfc_err(sa, "failed to insert repr proxy filter");
     756                 :          0 :                         goto fail_insert;
     757                 :            :                 }
     758                 :            :         }
     759                 :            : 
     760                 :          0 :         sfc_log_init(sa, "done");
     761                 :            : 
     762                 :          0 :         return 0;
     763                 :            : 
     764                 :            : fail_insert:
     765         [ #  # ]:          0 :         while (i-- > 0)
     766                 :          0 :                 efx_filter_remove(sa->nic, &filter->specs[i]);
     767                 :            : 
     768                 :          0 : fail_get_selector:
     769                 :          0 : fail_multiple_queues:
     770                 :          0 :         sfc_log_init(sa, "failed: %s", rte_strerror(rc));
     771                 :          0 :         return rc;
     772                 :            : }
     773                 :            : 
     774                 :            : static void
     775                 :            : sfc_repr_proxy_mport_filter_remove(struct sfc_adapter *sa)
     776                 :            : {
     777                 :            :         struct sfc_repr_proxy *rp = &sa->repr_proxy;
     778                 :            :         struct sfc_repr_proxy_filter *filter = &rp->mport_filter;
     779                 :            :         unsigned int i;
     780                 :            : 
     781         [ #  # ]:          0 :         for (i = 0; i < RTE_DIM(filter->specs); i++)
     782                 :          0 :                 efx_filter_remove(sa->nic, &filter->specs[i]);
     783                 :            : }
     784                 :            : 
     785                 :            : static int
     786                 :          0 : sfc_repr_proxy_port_rule_insert(struct sfc_adapter *sa,
     787                 :            :                                 struct sfc_repr_proxy_port *port)
     788                 :            : {
     789                 :            :         int rc;
     790                 :            : 
     791                 :          0 :         rc = sfc_repr_proxy_mae_rule_insert(sa, port);
     792         [ #  # ]:          0 :         if (rc != 0)
     793                 :          0 :                 goto fail_mae_rule_insert;
     794                 :            : 
     795                 :            :         return 0;
     796                 :            : 
     797                 :            : fail_mae_rule_insert:
     798                 :          0 :         return rc;
     799                 :            : }
     800                 :            : 
     801                 :            : static void
     802                 :            : sfc_repr_proxy_port_rule_remove(struct sfc_adapter *sa,
     803                 :            :                                 struct sfc_repr_proxy_port *port)
     804                 :            : {
     805                 :            :         sfc_repr_proxy_mae_rule_remove(sa, port);
     806                 :          0 : }
     807                 :            : 
     808                 :            : static int
     809                 :          0 : sfc_repr_proxy_ports_init(struct sfc_adapter *sa)
     810                 :            : {
     811                 :            :         struct sfc_repr_proxy *rp = &sa->repr_proxy;
     812                 :            :         int rc;
     813                 :            : 
     814                 :          0 :         sfc_log_init(sa, "entry");
     815                 :            : 
     816                 :          0 :         rc = efx_mcdi_mport_alloc_alias(sa->nic, &rp->mport_alias, NULL);
     817         [ #  # ]:          0 :         if (rc != 0) {
     818                 :          0 :                 sfc_err(sa, "failed to alloc mport alias: %s",
     819                 :            :                         rte_strerror(rc));
     820                 :          0 :                 goto fail_alloc_mport_alias;
     821                 :            :         }
     822                 :            : 
     823                 :          0 :         TAILQ_INIT(&rp->ports);
     824                 :            : 
     825                 :          0 :         sfc_log_init(sa, "done");
     826                 :            : 
     827                 :          0 :         return 0;
     828                 :            : 
     829                 :            : fail_alloc_mport_alias:
     830                 :            : 
     831                 :          0 :         sfc_log_init(sa, "failed: %s", rte_strerror(rc));
     832                 :          0 :         return rc;
     833                 :            : }
     834                 :            : 
     835                 :            : void
     836                 :          0 : sfc_repr_proxy_pre_detach(struct sfc_adapter *sa)
     837                 :            : {
     838                 :            :         struct sfc_repr_proxy *rp = &sa->repr_proxy;
     839                 :          0 :         bool close_ports[RTE_MAX_ETHPORTS] = {0};
     840                 :            :         struct sfc_repr_proxy_port *port;
     841                 :            :         unsigned int i;
     842                 :            : 
     843                 :            :         SFC_ASSERT(!sfc_adapter_is_locked(sa));
     844                 :            : 
     845                 :          0 :         sfc_adapter_lock(sa);
     846                 :            : 
     847         [ #  # ]:          0 :         if (sfc_repr_available(sfc_sa2shared(sa))) {
     848         [ #  # ]:          0 :                 TAILQ_FOREACH(port, &rp->ports, entries)
     849                 :          0 :                         close_ports[port->rte_port_id] = true;
     850                 :            :         } else {
     851                 :          0 :                 sfc_log_init(sa, "representors not supported - skip");
     852                 :            :         }
     853                 :            : 
     854                 :            :         sfc_adapter_unlock(sa);
     855                 :            : 
     856         [ #  # ]:          0 :         for (i = 0; i < RTE_DIM(close_ports); i++) {
     857         [ #  # ]:          0 :                 if (close_ports[i]) {
     858                 :          0 :                         rte_eth_dev_stop(i);
     859                 :          0 :                         rte_eth_dev_close(i);
     860                 :            :                 }
     861                 :            :         }
     862                 :          0 : }
     863                 :            : 
     864                 :            : static void
     865                 :            : sfc_repr_proxy_ports_fini(struct sfc_adapter *sa)
     866                 :            : {
     867                 :            :         struct sfc_repr_proxy *rp = &sa->repr_proxy;
     868                 :            : 
     869                 :          0 :         efx_mae_mport_free(sa->nic, &rp->mport_alias);
     870                 :          0 : }
     871                 :            : 
     872                 :            : int
     873                 :          0 : sfc_repr_proxy_attach(struct sfc_adapter *sa)
     874                 :            : {
     875                 :            :         struct sfc_adapter_shared * const sas = sfc_sa2shared(sa);
     876                 :          0 :         struct sfc_repr_proxy *rp = &sa->repr_proxy;
     877                 :            :         struct rte_service_spec service;
     878                 :            :         uint32_t cid;
     879                 :            :         uint32_t sid;
     880                 :            :         int rc;
     881                 :            : 
     882                 :          0 :         sfc_log_init(sa, "entry");
     883                 :            : 
     884         [ #  # ]:          0 :         if (!sfc_repr_available(sas)) {
     885                 :          0 :                 sfc_log_init(sa, "representors not supported - skip");
     886                 :          0 :                 return 0;
     887                 :            :         }
     888                 :            : 
     889                 :          0 :         rc = sfc_repr_proxy_rxq_attach(sa);
     890         [ #  # ]:          0 :         if (rc != 0)
     891                 :          0 :                 goto fail_rxq_attach;
     892                 :            : 
     893                 :          0 :         rc = sfc_repr_proxy_txq_attach(sa);
     894         [ #  # ]:          0 :         if (rc != 0)
     895                 :          0 :                 goto fail_txq_attach;
     896                 :            : 
     897                 :          0 :         rc = sfc_repr_proxy_ports_init(sa);
     898         [ #  # ]:          0 :         if (rc != 0)
     899                 :          0 :                 goto fail_ports_init;
     900                 :            : 
     901                 :          0 :         cid = sfc_get_service_lcore(sa->socket_id);
     902   [ #  #  #  # ]:          0 :         if (cid == RTE_MAX_LCORE && sa->socket_id != SOCKET_ID_ANY) {
     903                 :            :                 /* Warn and try to allocate on any NUMA node */
     904                 :          0 :                 sfc_warn(sa,
     905                 :            :                         "repr proxy: unable to get service lcore at socket %d",
     906                 :            :                         sa->socket_id);
     907                 :            : 
     908                 :          0 :                 cid = sfc_get_service_lcore(SOCKET_ID_ANY);
     909                 :            :         }
     910         [ #  # ]:          0 :         if (cid == RTE_MAX_LCORE) {
     911                 :            :                 rc = ENOTSUP;
     912                 :          0 :                 sfc_err(sa, "repr proxy: failed to get service lcore");
     913                 :          0 :                 goto fail_get_service_lcore;
     914                 :            :         }
     915                 :            : 
     916                 :            :         memset(&service, 0, sizeof(service));
     917                 :          0 :         snprintf(service.name, sizeof(service.name),
     918                 :          0 :                  "net_sfc_%hu_repr_proxy", sfc_sa2shared(sa)->port_id);
     919                 :          0 :         service.socket_id = rte_lcore_to_socket_id(cid);
     920                 :          0 :         service.callback = sfc_repr_proxy_routine;
     921                 :          0 :         service.callback_userdata = rp;
     922                 :            : 
     923                 :          0 :         rc = rte_service_component_register(&service, &sid);
     924         [ #  # ]:          0 :         if (rc != 0) {
     925                 :            :                 rc = ENOEXEC;
     926                 :          0 :                 sfc_err(sa, "repr proxy: failed to register service component");
     927                 :          0 :                 goto fail_register;
     928                 :            :         }
     929                 :            : 
     930                 :          0 :         rc = rte_service_map_lcore_set(sid, cid, 1);
     931         [ #  # ]:          0 :         if (rc != 0) {
     932                 :          0 :                 rc = -rc;
     933                 :          0 :                 sfc_err(sa, "repr proxy: failed to map lcore");
     934                 :          0 :                 goto fail_map_lcore;
     935                 :            :         }
     936                 :            : 
     937                 :          0 :         rp->service_core_id = cid;
     938                 :          0 :         rp->service_id = sid;
     939                 :            : 
     940                 :          0 :         sfc_log_init(sa, "done");
     941                 :            : 
     942                 :          0 :         return 0;
     943                 :            : 
     944                 :            : fail_map_lcore:
     945                 :          0 :         rte_service_component_unregister(sid);
     946                 :            : 
     947                 :          0 : fail_register:
     948                 :            :         /*
     949                 :            :          * No need to rollback service lcore get since
     950                 :            :          * it just makes socket_id based search and remembers it.
     951                 :            :          */
     952                 :            : 
     953                 :          0 : fail_get_service_lcore:
     954                 :            :         sfc_repr_proxy_ports_fini(sa);
     955                 :            : 
     956                 :          0 : fail_ports_init:
     957                 :          0 :         sfc_repr_proxy_txq_detach(sa);
     958                 :            : 
     959                 :          0 : fail_txq_attach:
     960                 :          0 :         sfc_repr_proxy_rxq_detach(sa);
     961                 :            : 
     962                 :          0 : fail_rxq_attach:
     963                 :          0 :         sfc_log_init(sa, "failed: %s", rte_strerror(rc));
     964                 :          0 :         return rc;
     965                 :            : }
     966                 :            : 
     967                 :            : void
     968                 :          0 : sfc_repr_proxy_detach(struct sfc_adapter *sa)
     969                 :            : {
     970                 :            :         struct sfc_adapter_shared * const sas = sfc_sa2shared(sa);
     971                 :            :         struct sfc_repr_proxy *rp = &sa->repr_proxy;
     972                 :            : 
     973                 :          0 :         sfc_log_init(sa, "entry");
     974                 :            : 
     975         [ #  # ]:          0 :         if (!sfc_repr_available(sas)) {
     976                 :          0 :                 sfc_log_init(sa, "representors not supported - skip");
     977                 :          0 :                 return;
     978                 :            :         }
     979                 :            : 
     980                 :          0 :         rte_service_map_lcore_set(rp->service_id, rp->service_core_id, 0);
     981                 :          0 :         rte_service_component_unregister(rp->service_id);
     982                 :            :         sfc_repr_proxy_ports_fini(sa);
     983                 :          0 :         sfc_repr_proxy_rxq_detach(sa);
     984                 :          0 :         sfc_repr_proxy_txq_detach(sa);
     985                 :            : 
     986                 :          0 :         sfc_log_init(sa, "done");
     987                 :            : }
     988                 :            : 
     989                 :            : static int
     990                 :          0 : sfc_repr_proxy_do_start_port(struct sfc_adapter *sa,
     991                 :            :                            struct sfc_repr_proxy_port *port)
     992                 :            : {
     993                 :            :         struct sfc_repr_proxy *rp = &sa->repr_proxy;
     994                 :            :         int rc;
     995                 :            : 
     996                 :          0 :         rc = sfc_repr_proxy_port_rule_insert(sa, port);
     997         [ #  # ]:          0 :         if (rc != 0)
     998                 :          0 :                 goto fail_filter_insert;
     999                 :            : 
    1000         [ #  # ]:          0 :         if (rp->started) {
    1001                 :          0 :                 rc = sfc_repr_proxy_mbox_send(&rp->mbox, port,
    1002                 :            :                                               SFC_REPR_PROXY_MBOX_START_PORT);
    1003         [ #  # ]:          0 :                 if (rc != 0) {
    1004                 :          0 :                         sfc_err(sa, "failed to start proxy port %u",
    1005                 :            :                                 port->repr_id);
    1006                 :          0 :                         goto fail_port_start;
    1007                 :            :                 }
    1008                 :            :         } else {
    1009                 :          0 :                 port->started = true;
    1010                 :            :         }
    1011                 :            : 
    1012                 :            :         return 0;
    1013                 :            : 
    1014                 :            : fail_port_start:
    1015                 :            :         sfc_repr_proxy_port_rule_remove(sa, port);
    1016                 :          0 : fail_filter_insert:
    1017                 :          0 :         sfc_err(sa, "%s() failed %s", __func__, rte_strerror(rc));
    1018                 :            : 
    1019                 :          0 :         return rc;
    1020                 :            : }
    1021                 :            : 
    1022                 :            : static int
    1023                 :          0 : sfc_repr_proxy_do_stop_port(struct sfc_adapter *sa,
    1024                 :            :                           struct sfc_repr_proxy_port *port)
    1025                 :            : 
    1026                 :            : {
    1027                 :            :         struct sfc_repr_proxy *rp = &sa->repr_proxy;
    1028                 :            :         int rc;
    1029                 :            : 
    1030         [ #  # ]:          0 :         if (rp->started) {
    1031                 :          0 :                 rc = sfc_repr_proxy_mbox_send(&rp->mbox, port,
    1032                 :            :                                               SFC_REPR_PROXY_MBOX_STOP_PORT);
    1033         [ #  # ]:          0 :                 if (rc != 0) {
    1034                 :          0 :                         sfc_err(sa, "failed to stop proxy port %u: %s",
    1035                 :            :                                 port->repr_id, rte_strerror(rc));
    1036                 :          0 :                         return rc;
    1037                 :            :                 }
    1038                 :            :         } else {
    1039                 :          0 :                 port->started = false;
    1040                 :            :         }
    1041                 :            : 
    1042                 :            :         sfc_repr_proxy_port_rule_remove(sa, port);
    1043                 :            : 
    1044                 :          0 :         return 0;
    1045                 :            : }
    1046                 :            : 
    1047                 :            : static bool
    1048                 :            : sfc_repr_proxy_port_enabled(struct sfc_repr_proxy_port *port)
    1049                 :            : {
    1050   [ #  #  #  #  :          0 :         return port->rte_port_id != RTE_MAX_ETHPORTS && port->enabled;
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  # ]
    1051                 :            : }
    1052                 :            : 
    1053                 :            : static bool
    1054                 :            : sfc_repr_proxy_ports_disabled(struct sfc_repr_proxy *rp)
    1055                 :            : {
    1056                 :            :         struct sfc_repr_proxy_port *port;
    1057                 :            : 
    1058   [ #  #  #  #  :          0 :         TAILQ_FOREACH(port, &rp->ports, entries) {
                   #  # ]
    1059   [ #  #  #  #  :          0 :                 if (sfc_repr_proxy_port_enabled(port))
                   #  # ]
    1060                 :            :                         return false;
    1061                 :            :         }
    1062                 :            : 
    1063                 :            :         return true;
    1064                 :            : }
    1065                 :            : 
    1066                 :            : int
    1067                 :          0 : sfc_repr_proxy_start(struct sfc_adapter *sa)
    1068                 :            : {
    1069                 :            :         struct sfc_adapter_shared * const sas = sfc_sa2shared(sa);
    1070                 :            :         struct sfc_repr_proxy *rp = &sa->repr_proxy;
    1071                 :            :         struct sfc_repr_proxy_port *last_port = NULL;
    1072                 :            :         struct sfc_repr_proxy_port *port;
    1073                 :            :         int rc;
    1074                 :            : 
    1075                 :          0 :         sfc_log_init(sa, "entry");
    1076                 :            : 
    1077                 :            :         /* Representor proxy is not started when no representors are started */
    1078         [ #  # ]:          0 :         if (!sfc_repr_available(sas)) {
    1079                 :          0 :                 sfc_log_init(sa, "representors not supported - skip");
    1080                 :          0 :                 return 0;
    1081                 :            :         }
    1082                 :            : 
    1083         [ #  # ]:          0 :         if (sfc_repr_proxy_ports_disabled(rp)) {
    1084                 :          0 :                 sfc_log_init(sa, "no started representor ports - skip");
    1085                 :          0 :                 return 0;
    1086                 :            :         }
    1087                 :            : 
    1088                 :          0 :         rc = sfc_repr_proxy_rxq_start(sa);
    1089         [ #  # ]:          0 :         if (rc != 0)
    1090                 :          0 :                 goto fail_rxq_start;
    1091                 :            : 
    1092                 :          0 :         rc = sfc_repr_proxy_txq_start(sa);
    1093         [ #  # ]:          0 :         if (rc != 0)
    1094                 :          0 :                 goto fail_txq_start;
    1095                 :            : 
    1096                 :          0 :         rp->nb_txq = sfc_repr_nb_txq(sas);
    1097                 :          0 :         rp->nb_rxq = sfc_repr_nb_rxq(sas);
    1098                 :            : 
    1099                 :            :         /* Service core may be in "stopped" state, start it */
    1100                 :          0 :         rc = rte_service_lcore_start(rp->service_core_id);
    1101         [ #  # ]:          0 :         if (rc != 0 && rc != -EALREADY) {
    1102                 :          0 :                 rc = -rc;
    1103                 :          0 :                 sfc_err(sa, "failed to start service core for %s: %s",
    1104                 :            :                         rte_service_get_name(rp->service_id),
    1105                 :            :                         rte_strerror(rc));
    1106                 :          0 :                 goto fail_start_core;
    1107                 :            :         }
    1108                 :            : 
    1109                 :            :         /* Run the service */
    1110                 :          0 :         rc = rte_service_component_runstate_set(rp->service_id, 1);
    1111         [ #  # ]:          0 :         if (rc < 0) {
    1112                 :          0 :                 rc = -rc;
    1113                 :          0 :                 sfc_err(sa, "failed to run %s component: %s",
    1114                 :            :                         rte_service_get_name(rp->service_id),
    1115                 :            :                         rte_strerror(rc));
    1116                 :          0 :                 goto fail_component_runstate_set;
    1117                 :            :         }
    1118                 :          0 :         rc = rte_service_runstate_set(rp->service_id, 1);
    1119         [ #  # ]:          0 :         if (rc < 0) {
    1120                 :          0 :                 rc = -rc;
    1121                 :          0 :                 sfc_err(sa, "failed to run %s: %s",
    1122                 :            :                         rte_service_get_name(rp->service_id),
    1123                 :            :                         rte_strerror(rc));
    1124                 :          0 :                 goto fail_runstate_set;
    1125                 :            :         }
    1126                 :            : 
    1127         [ #  # ]:          0 :         TAILQ_FOREACH(port, &rp->ports, entries) {
    1128         [ #  # ]:          0 :                 if (sfc_repr_proxy_port_enabled(port)) {
    1129                 :          0 :                         rc = sfc_repr_proxy_do_start_port(sa, port);
    1130         [ #  # ]:          0 :                         if (rc != 0)
    1131                 :          0 :                                 goto fail_start_id;
    1132                 :            : 
    1133                 :            :                         last_port = port;
    1134                 :            :                 }
    1135                 :            :         }
    1136                 :            : 
    1137                 :          0 :         rc = sfc_repr_proxy_mport_filter_insert(sa);
    1138         [ #  # ]:          0 :         if (rc != 0)
    1139                 :          0 :                 goto fail_mport_filter_insert;
    1140                 :            : 
    1141                 :          0 :         rp->started = true;
    1142                 :            : 
    1143                 :          0 :         sfc_log_init(sa, "done");
    1144                 :            : 
    1145                 :          0 :         return 0;
    1146                 :            : 
    1147                 :            : fail_mport_filter_insert:
    1148                 :          0 : fail_start_id:
    1149         [ #  # ]:          0 :         if (last_port != NULL) {
    1150         [ #  # ]:          0 :                 TAILQ_FOREACH(port, &rp->ports, entries) {
    1151         [ #  # ]:          0 :                         if (sfc_repr_proxy_port_enabled(port)) {
    1152                 :          0 :                                 (void)sfc_repr_proxy_do_stop_port(sa, port);
    1153         [ #  # ]:          0 :                                 if (port == last_port)
    1154                 :            :                                         break;
    1155                 :            :                         }
    1156                 :            :                 }
    1157                 :            :         }
    1158                 :            : 
    1159                 :          0 :         rte_service_runstate_set(rp->service_id, 0);
    1160                 :            : 
    1161                 :          0 : fail_runstate_set:
    1162                 :          0 :         rte_service_component_runstate_set(rp->service_id, 0);
    1163                 :            : 
    1164                 :          0 : fail_component_runstate_set:
    1165                 :            :         /* Service lcore may be shared and we never stop it */
    1166                 :            : 
    1167                 :          0 : fail_start_core:
    1168                 :          0 :         sfc_repr_proxy_txq_stop(sa);
    1169                 :            : 
    1170                 :          0 : fail_txq_start:
    1171                 :          0 :         sfc_repr_proxy_rxq_stop(sa);
    1172                 :            : 
    1173                 :          0 : fail_rxq_start:
    1174                 :          0 :         sfc_log_init(sa, "failed: %s", rte_strerror(rc));
    1175                 :          0 :         return rc;
    1176                 :            : }
    1177                 :            : 
    1178                 :            : void
    1179                 :          0 : sfc_repr_proxy_stop(struct sfc_adapter *sa)
    1180                 :            : {
    1181                 :            :         struct sfc_adapter_shared * const sas = sfc_sa2shared(sa);
    1182                 :            :         struct sfc_repr_proxy *rp = &sa->repr_proxy;
    1183                 :            :         struct sfc_repr_proxy_port *port;
    1184                 :            :         const unsigned int wait_ms_total =
    1185                 :            :                 SFC_REPR_PROXY_ROUTINE_TERMINATE_TIMEOUT_MS;
    1186                 :            :         unsigned int i;
    1187                 :            :         int rc;
    1188                 :            : 
    1189                 :          0 :         sfc_log_init(sa, "entry");
    1190                 :            : 
    1191         [ #  # ]:          0 :         if (!sfc_repr_available(sas)) {
    1192                 :          0 :                 sfc_log_init(sa, "representors not supported - skip");
    1193                 :          0 :                 return;
    1194                 :            :         }
    1195                 :            : 
    1196         [ #  # ]:          0 :         if (sfc_repr_proxy_ports_disabled(rp)) {
    1197                 :          0 :                 sfc_log_init(sa, "no started representor ports - skip");
    1198                 :          0 :                 return;
    1199                 :            :         }
    1200                 :            : 
    1201         [ #  # ]:          0 :         TAILQ_FOREACH(port, &rp->ports, entries) {
    1202         [ #  # ]:          0 :                 if (sfc_repr_proxy_port_enabled(port)) {
    1203                 :          0 :                         rc = sfc_repr_proxy_do_stop_port(sa, port);
    1204         [ #  # ]:          0 :                         if (rc != 0) {
    1205                 :          0 :                                 sfc_err(sa,
    1206                 :            :                                         "failed to stop representor proxy port %u: %s",
    1207                 :            :                                         port->repr_id, rte_strerror(rc));
    1208                 :            :                         }
    1209                 :            :                 }
    1210                 :            :         }
    1211                 :            : 
    1212                 :            :         sfc_repr_proxy_mport_filter_remove(sa);
    1213                 :            : 
    1214                 :          0 :         rc = rte_service_runstate_set(rp->service_id, 0);
    1215         [ #  # ]:          0 :         if (rc < 0) {
    1216                 :          0 :                 sfc_err(sa, "failed to stop %s: %s",
    1217                 :            :                         rte_service_get_name(rp->service_id),
    1218                 :            :                         rte_strerror(-rc));
    1219                 :            :         }
    1220                 :            : 
    1221                 :          0 :         rc = rte_service_component_runstate_set(rp->service_id, 0);
    1222         [ #  # ]:          0 :         if (rc < 0) {
    1223                 :          0 :                 sfc_err(sa, "failed to stop %s component: %s",
    1224                 :            :                         rte_service_get_name(rp->service_id),
    1225                 :            :                         rte_strerror(-rc));
    1226                 :            :         }
    1227                 :            : 
    1228                 :            :         /* Service lcore may be shared and we never stop it */
    1229                 :            : 
    1230                 :            :         /*
    1231                 :            :          * Wait for the representor proxy routine to finish the last iteration.
    1232                 :            :          * Give up on timeout.
    1233                 :            :          */
    1234         [ #  # ]:          0 :         for (i = 0; i < wait_ms_total; i++) {
    1235         [ #  # ]:          0 :                 if (rte_service_may_be_active(rp->service_id) == 0)
    1236                 :            :                         break;
    1237                 :            : 
    1238                 :            :                 rte_delay_ms(1);
    1239                 :            :         }
    1240                 :            : 
    1241                 :          0 :         sfc_repr_proxy_rxq_stop(sa);
    1242                 :          0 :         sfc_repr_proxy_txq_stop(sa);
    1243                 :            : 
    1244                 :          0 :         rp->started = false;
    1245                 :            : 
    1246                 :          0 :         sfc_log_init(sa, "done");
    1247                 :            : }
    1248                 :            : 
    1249                 :            : int
    1250                 :          0 : sfc_repr_proxy_add_port(uint16_t pf_port_id, uint16_t repr_id,
    1251                 :            :                         uint16_t rte_port_id, const efx_mport_sel_t *mport_sel,
    1252                 :            :                         efx_pcie_interface_t intf, uint16_t pf, uint16_t vf)
    1253                 :            : {
    1254                 :            :         struct sfc_repr_proxy_port *port;
    1255                 :            :         struct sfc_repr_proxy *rp;
    1256                 :            :         struct sfc_adapter *sa;
    1257                 :            :         int rc;
    1258                 :            : 
    1259                 :          0 :         sa = sfc_get_adapter_by_pf_port_id(pf_port_id);
    1260                 :          0 :         sfc_adapter_lock(sa);
    1261                 :            :         rp = sfc_repr_proxy_by_adapter(sa);
    1262                 :            : 
    1263                 :          0 :         sfc_log_init(sa, "entry");
    1264         [ #  # ]:          0 :         TAILQ_FOREACH(port, &rp->ports, entries) {
    1265         [ #  # ]:          0 :                 if (port->rte_port_id == rte_port_id) {
    1266                 :            :                         rc = EEXIST;
    1267                 :          0 :                         sfc_err(sa, "%s() failed: port exists", __func__);
    1268                 :          0 :                         goto fail_port_exists;
    1269                 :            :                 }
    1270                 :            :         }
    1271                 :            : 
    1272                 :          0 :         port = rte_zmalloc("sfc-repr-proxy-port", sizeof(*port),
    1273                 :          0 :                            sa->socket_id);
    1274         [ #  # ]:          0 :         if (port == NULL) {
    1275                 :            :                 rc = ENOMEM;
    1276                 :          0 :                 sfc_err(sa, "failed to alloc memory for proxy port");
    1277                 :          0 :                 goto fail_alloc_port;
    1278                 :            :         }
    1279                 :            : 
    1280                 :          0 :         rc = efx_mae_mport_id_by_selector(sa->nic, mport_sel,
    1281                 :            :                                           &port->egress_mport);
    1282         [ #  # ]:          0 :         if (rc != 0) {
    1283                 :          0 :                 sfc_err(sa,
    1284                 :            :                         "failed get MAE mport id by selector (repr_id %u): %s",
    1285                 :            :                         repr_id, rte_strerror(rc));
    1286                 :          0 :                 goto fail_mport_id;
    1287                 :            :         }
    1288                 :            : 
    1289                 :          0 :         port->rte_port_id = rte_port_id;
    1290                 :          0 :         port->repr_id = repr_id;
    1291                 :            : 
    1292                 :          0 :         rc = efx_mcdi_get_client_handle(sa->nic, intf, pf, vf,
    1293                 :            :                                         &port->remote_vnic_mcdi_client_handle);
    1294         [ #  # ]:          0 :         if (rc != 0) {
    1295                 :          0 :                 sfc_err(sa, "failed to get the represented VNIC's MCDI handle (repr_id=%u): %s",
    1296                 :            :                         repr_id, rte_strerror(rc));
    1297                 :          0 :                 goto fail_client_handle;
    1298                 :            :         }
    1299                 :            : 
    1300         [ #  # ]:          0 :         if (rp->started) {
    1301                 :          0 :                 rc = sfc_repr_proxy_mbox_send(&rp->mbox, port,
    1302                 :            :                                               SFC_REPR_PROXY_MBOX_ADD_PORT);
    1303         [ #  # ]:          0 :                 if (rc != 0) {
    1304                 :          0 :                         sfc_err(sa, "failed to add proxy port %u",
    1305                 :            :                                 port->repr_id);
    1306                 :          0 :                         goto fail_port_add;
    1307                 :            :                 }
    1308                 :            :         } else {
    1309                 :          0 :                 TAILQ_INSERT_TAIL(&rp->ports, port, entries);
    1310                 :            :         }
    1311                 :            : 
    1312                 :          0 :         sfc_log_init(sa, "done");
    1313                 :            :         sfc_adapter_unlock(sa);
    1314                 :            : 
    1315                 :          0 :         return 0;
    1316                 :            : 
    1317                 :            : fail_port_add:
    1318                 :          0 : fail_client_handle:
    1319                 :          0 : fail_mport_id:
    1320                 :          0 :         rte_free(port);
    1321                 :          0 : fail_alloc_port:
    1322                 :          0 : fail_port_exists:
    1323                 :          0 :         sfc_log_init(sa, "failed: %s", rte_strerror(rc));
    1324                 :            :         sfc_adapter_unlock(sa);
    1325                 :            : 
    1326                 :          0 :         return rc;
    1327                 :            : }
    1328                 :            : 
    1329                 :            : int
    1330                 :          0 : sfc_repr_proxy_del_port(uint16_t pf_port_id, uint16_t repr_id)
    1331                 :            : {
    1332                 :            :         struct sfc_repr_proxy_port *port;
    1333                 :            :         struct sfc_repr_proxy *rp;
    1334                 :            :         struct sfc_adapter *sa;
    1335                 :            :         int rc;
    1336                 :            : 
    1337                 :          0 :         sa = sfc_get_adapter_by_pf_port_id(pf_port_id);
    1338                 :          0 :         sfc_adapter_lock(sa);
    1339                 :            :         rp = sfc_repr_proxy_by_adapter(sa);
    1340                 :            : 
    1341                 :          0 :         sfc_log_init(sa, "entry");
    1342                 :            : 
    1343                 :            :         port = sfc_repr_proxy_find_port(rp, repr_id);
    1344         [ #  # ]:          0 :         if (port == NULL) {
    1345                 :          0 :                 sfc_err(sa, "failed: no such port");
    1346                 :            :                 rc = ENOENT;
    1347                 :          0 :                 goto fail_no_port;
    1348                 :            :         }
    1349                 :            : 
    1350         [ #  # ]:          0 :         if (rp->started) {
    1351                 :          0 :                 rc = sfc_repr_proxy_mbox_send(&rp->mbox, port,
    1352                 :            :                                               SFC_REPR_PROXY_MBOX_DEL_PORT);
    1353         [ #  # ]:          0 :                 if (rc != 0) {
    1354                 :          0 :                         sfc_err(sa, "failed to remove proxy port %u",
    1355                 :            :                                 port->repr_id);
    1356                 :          0 :                         goto fail_port_remove;
    1357                 :            :                 }
    1358                 :            :         } else {
    1359         [ #  # ]:          0 :                 TAILQ_REMOVE(&rp->ports, port, entries);
    1360                 :            :         }
    1361                 :            : 
    1362                 :          0 :         rte_free(port);
    1363                 :            : 
    1364                 :          0 :         sfc_log_init(sa, "done");
    1365                 :            : 
    1366                 :            :         sfc_adapter_unlock(sa);
    1367                 :            : 
    1368                 :          0 :         return 0;
    1369                 :            : 
    1370                 :            : fail_port_remove:
    1371                 :          0 : fail_no_port:
    1372                 :          0 :         sfc_log_init(sa, "failed: %s", rte_strerror(rc));
    1373                 :            :         sfc_adapter_unlock(sa);
    1374                 :            : 
    1375                 :          0 :         return rc;
    1376                 :            : }
    1377                 :            : 
    1378                 :            : int
    1379                 :          0 : sfc_repr_proxy_add_rxq(uint16_t pf_port_id, uint16_t repr_id,
    1380                 :            :                        uint16_t queue_id, struct rte_ring *rx_ring,
    1381                 :            :                        struct rte_mempool *mp)
    1382                 :            : {
    1383                 :            :         struct sfc_repr_proxy_port *port;
    1384                 :            :         struct sfc_repr_proxy_rxq *rxq;
    1385                 :            :         struct sfc_repr_proxy *rp;
    1386                 :            :         struct sfc_adapter *sa;
    1387                 :            : 
    1388                 :          0 :         sa = sfc_get_adapter_by_pf_port_id(pf_port_id);
    1389                 :          0 :         sfc_adapter_lock(sa);
    1390                 :            :         rp = sfc_repr_proxy_by_adapter(sa);
    1391                 :            : 
    1392                 :          0 :         sfc_log_init(sa, "entry");
    1393                 :            : 
    1394                 :            :         port = sfc_repr_proxy_find_port(rp, repr_id);
    1395         [ #  # ]:          0 :         if (port == NULL) {
    1396                 :          0 :                 sfc_err(sa, "%s() failed: no such port", __func__);
    1397                 :            :                 sfc_adapter_unlock(sa);
    1398                 :          0 :                 return ENOENT;
    1399                 :            :         }
    1400                 :            : 
    1401                 :          0 :         rxq = &port->rxq[queue_id];
    1402   [ #  #  #  # ]:          0 :         if (rp->dp_rxq[queue_id].mp != NULL && rp->dp_rxq[queue_id].mp != mp) {
    1403                 :          0 :                 sfc_err(sa, "multiple mempools per queue are not supported");
    1404                 :            :                 sfc_adapter_unlock(sa);
    1405                 :          0 :                 return ENOTSUP;
    1406                 :            :         }
    1407                 :            : 
    1408                 :          0 :         rxq->ring = rx_ring;
    1409                 :          0 :         rxq->mb_pool = mp;
    1410                 :          0 :         rp->dp_rxq[queue_id].mp = mp;
    1411                 :          0 :         rp->dp_rxq[queue_id].ref_count++;
    1412                 :            : 
    1413                 :          0 :         sfc_log_init(sa, "done");
    1414                 :            :         sfc_adapter_unlock(sa);
    1415                 :            : 
    1416                 :          0 :         return 0;
    1417                 :            : }
    1418                 :            : 
    1419                 :            : void
    1420                 :          0 : sfc_repr_proxy_del_rxq(uint16_t pf_port_id, uint16_t repr_id,
    1421                 :            :                        uint16_t queue_id)
    1422                 :            : {
    1423                 :            :         struct sfc_repr_proxy_port *port;
    1424                 :            :         struct sfc_repr_proxy_rxq *rxq;
    1425                 :            :         struct sfc_repr_proxy *rp;
    1426                 :            :         struct sfc_adapter *sa;
    1427                 :            : 
    1428                 :          0 :         sa = sfc_get_adapter_by_pf_port_id(pf_port_id);
    1429                 :          0 :         sfc_adapter_lock(sa);
    1430                 :            :         rp = sfc_repr_proxy_by_adapter(sa);
    1431                 :            : 
    1432                 :          0 :         sfc_log_init(sa, "entry");
    1433                 :            : 
    1434                 :            :         port = sfc_repr_proxy_find_port(rp, repr_id);
    1435         [ #  # ]:          0 :         if (port == NULL) {
    1436                 :          0 :                 sfc_err(sa, "%s() failed: no such port", __func__);
    1437                 :            :                 sfc_adapter_unlock(sa);
    1438                 :          0 :                 return;
    1439                 :            :         }
    1440                 :            : 
    1441                 :          0 :         rxq = &port->rxq[queue_id];
    1442                 :            : 
    1443                 :          0 :         rxq->ring = NULL;
    1444                 :          0 :         rxq->mb_pool = NULL;
    1445                 :          0 :         rp->dp_rxq[queue_id].ref_count--;
    1446         [ #  # ]:          0 :         if (rp->dp_rxq[queue_id].ref_count == 0)
    1447                 :          0 :                 rp->dp_rxq[queue_id].mp = NULL;
    1448                 :            : 
    1449                 :          0 :         sfc_log_init(sa, "done");
    1450                 :            :         sfc_adapter_unlock(sa);
    1451                 :            : }
    1452                 :            : 
    1453                 :            : int
    1454                 :          0 : sfc_repr_proxy_add_txq(uint16_t pf_port_id, uint16_t repr_id,
    1455                 :            :                        uint16_t queue_id, struct rte_ring *tx_ring,
    1456                 :            :                        efx_mport_id_t *egress_mport)
    1457                 :            : {
    1458                 :            :         struct sfc_repr_proxy_port *port;
    1459                 :            :         struct sfc_repr_proxy_txq *txq;
    1460                 :            :         struct sfc_repr_proxy *rp;
    1461                 :            :         struct sfc_adapter *sa;
    1462                 :            : 
    1463                 :          0 :         sa = sfc_get_adapter_by_pf_port_id(pf_port_id);
    1464                 :          0 :         sfc_adapter_lock(sa);
    1465                 :            :         rp = sfc_repr_proxy_by_adapter(sa);
    1466                 :            : 
    1467                 :          0 :         sfc_log_init(sa, "entry");
    1468                 :            : 
    1469                 :            :         port = sfc_repr_proxy_find_port(rp, repr_id);
    1470         [ #  # ]:          0 :         if (port == NULL) {
    1471                 :          0 :                 sfc_err(sa, "%s() failed: no such port", __func__);
    1472                 :            :                 sfc_adapter_unlock(sa);
    1473                 :          0 :                 return ENOENT;
    1474                 :            :         }
    1475                 :            : 
    1476                 :          0 :         txq = &port->txq[queue_id];
    1477                 :            : 
    1478                 :          0 :         txq->ring = tx_ring;
    1479                 :            : 
    1480                 :          0 :         *egress_mport = port->egress_mport;
    1481                 :            : 
    1482                 :          0 :         sfc_log_init(sa, "done");
    1483                 :            :         sfc_adapter_unlock(sa);
    1484                 :            : 
    1485                 :          0 :         return 0;
    1486                 :            : }
    1487                 :            : 
    1488                 :            : void
    1489                 :          0 : sfc_repr_proxy_del_txq(uint16_t pf_port_id, uint16_t repr_id,
    1490                 :            :                        uint16_t queue_id)
    1491                 :            : {
    1492                 :            :         struct sfc_repr_proxy_port *port;
    1493                 :            :         struct sfc_repr_proxy_txq *txq;
    1494                 :            :         struct sfc_repr_proxy *rp;
    1495                 :            :         struct sfc_adapter *sa;
    1496                 :            : 
    1497                 :          0 :         sa = sfc_get_adapter_by_pf_port_id(pf_port_id);
    1498                 :          0 :         sfc_adapter_lock(sa);
    1499                 :            :         rp = sfc_repr_proxy_by_adapter(sa);
    1500                 :            : 
    1501                 :          0 :         sfc_log_init(sa, "entry");
    1502                 :            : 
    1503                 :            :         port = sfc_repr_proxy_find_port(rp, repr_id);
    1504         [ #  # ]:          0 :         if (port == NULL) {
    1505                 :          0 :                 sfc_err(sa, "%s() failed: no such port", __func__);
    1506                 :            :                 sfc_adapter_unlock(sa);
    1507                 :          0 :                 return;
    1508                 :            :         }
    1509                 :            : 
    1510                 :          0 :         txq = &port->txq[queue_id];
    1511                 :            : 
    1512                 :          0 :         txq->ring = NULL;
    1513                 :            : 
    1514                 :          0 :         sfc_log_init(sa, "done");
    1515                 :            :         sfc_adapter_unlock(sa);
    1516                 :            : }
    1517                 :            : 
    1518                 :            : int
    1519                 :          0 : sfc_repr_proxy_start_repr(uint16_t pf_port_id, uint16_t repr_id)
    1520                 :            : {
    1521                 :            :         bool proxy_start_required = false;
    1522                 :            :         struct sfc_repr_proxy_port *port;
    1523                 :            :         struct sfc_repr_proxy *rp;
    1524                 :            :         struct sfc_adapter *sa;
    1525                 :            :         int rc;
    1526                 :            : 
    1527                 :          0 :         sa = sfc_get_adapter_by_pf_port_id(pf_port_id);
    1528                 :          0 :         sfc_adapter_lock(sa);
    1529                 :            :         rp = sfc_repr_proxy_by_adapter(sa);
    1530                 :            : 
    1531                 :          0 :         sfc_log_init(sa, "entry");
    1532                 :            : 
    1533                 :          0 :         port = sfc_repr_proxy_find_port(rp, repr_id);
    1534         [ #  # ]:          0 :         if (port == NULL) {
    1535                 :          0 :                 sfc_err(sa, "%s() failed: no such port", __func__);
    1536                 :            :                 rc = ENOENT;
    1537                 :          0 :                 goto fail_not_found;
    1538                 :            :         }
    1539                 :            : 
    1540         [ #  # ]:          0 :         if (port->enabled) {
    1541                 :            :                 rc = EALREADY;
    1542                 :          0 :                 sfc_err(sa, "failed: repr %u proxy port already started",
    1543                 :            :                         repr_id);
    1544                 :          0 :                 goto fail_already_started;
    1545                 :            :         }
    1546                 :            : 
    1547         [ #  # ]:          0 :         if (sa->state == SFC_ETHDEV_STARTED) {
    1548         [ #  # ]:          0 :                 if (sfc_repr_proxy_ports_disabled(rp)) {
    1549                 :            :                         proxy_start_required = true;
    1550                 :            :                 } else {
    1551                 :          0 :                         rc = sfc_repr_proxy_do_start_port(sa, port);
    1552         [ #  # ]:          0 :                         if (rc != 0) {
    1553                 :          0 :                                 sfc_err(sa,
    1554                 :            :                                         "failed to start repr %u proxy port",
    1555                 :            :                                         repr_id);
    1556                 :          0 :                                 goto fail_start_id;
    1557                 :            :                         }
    1558                 :            :                 }
    1559                 :            :         }
    1560                 :            : 
    1561                 :          0 :         port->enabled = true;
    1562                 :            : 
    1563                 :            :         if (proxy_start_required) {
    1564                 :          0 :                 rc = sfc_repr_proxy_start(sa);
    1565         [ #  # ]:          0 :                 if (rc != 0) {
    1566                 :          0 :                         sfc_err(sa, "failed to start proxy");
    1567                 :          0 :                         goto fail_proxy_start;
    1568                 :            :                 }
    1569                 :            :         }
    1570                 :            : 
    1571                 :          0 :         sfc_log_init(sa, "done");
    1572                 :            :         sfc_adapter_unlock(sa);
    1573                 :            : 
    1574                 :          0 :         return 0;
    1575                 :            : 
    1576                 :            : fail_proxy_start:
    1577                 :          0 :         port->enabled = false;
    1578                 :            : 
    1579                 :          0 : fail_start_id:
    1580                 :          0 : fail_already_started:
    1581                 :          0 : fail_not_found:
    1582                 :          0 :         sfc_err(sa, "failed to start repr %u proxy port: %s", repr_id,
    1583                 :            :                 rte_strerror(rc));
    1584                 :            :         sfc_adapter_unlock(sa);
    1585                 :            : 
    1586                 :          0 :         return rc;
    1587                 :            : }
    1588                 :            : 
    1589                 :            : int
    1590                 :          0 : sfc_repr_proxy_stop_repr(uint16_t pf_port_id, uint16_t repr_id)
    1591                 :            : {
    1592                 :            :         struct sfc_repr_proxy_port *port;
    1593                 :            :         struct sfc_repr_proxy_port *p;
    1594                 :            :         struct sfc_repr_proxy *rp;
    1595                 :            :         struct sfc_adapter *sa;
    1596                 :            :         int rc;
    1597                 :            : 
    1598                 :          0 :         sa = sfc_get_adapter_by_pf_port_id(pf_port_id);
    1599                 :          0 :         sfc_adapter_lock(sa);
    1600                 :            :         rp = sfc_repr_proxy_by_adapter(sa);
    1601                 :            : 
    1602                 :          0 :         sfc_log_init(sa, "entry");
    1603                 :            : 
    1604                 :          0 :         port = sfc_repr_proxy_find_port(rp, repr_id);
    1605         [ #  # ]:          0 :         if (port == NULL) {
    1606                 :          0 :                 sfc_err(sa, "%s() failed: no such port", __func__);
    1607                 :            :                 sfc_adapter_unlock(sa);
    1608                 :          0 :                 return ENOENT;
    1609                 :            :         }
    1610                 :            : 
    1611         [ #  # ]:          0 :         if (!port->enabled) {
    1612                 :          0 :                 sfc_log_init(sa, "repr %u proxy port is not started - skip",
    1613                 :            :                              repr_id);
    1614                 :            :                 sfc_adapter_unlock(sa);
    1615                 :          0 :                 return 0;
    1616                 :            :         }
    1617                 :            : 
    1618         [ #  # ]:          0 :         if (sa->state == SFC_ETHDEV_STARTED) {
    1619                 :            :                 bool last_enabled = true;
    1620                 :            : 
    1621         [ #  # ]:          0 :                 TAILQ_FOREACH(p, &rp->ports, entries) {
    1622         [ #  # ]:          0 :                         if (p == port)
    1623                 :          0 :                                 continue;
    1624                 :            : 
    1625         [ #  # ]:          0 :                         if (sfc_repr_proxy_port_enabled(p)) {
    1626                 :            :                                 last_enabled = false;
    1627                 :            :                                 break;
    1628                 :            :                         }
    1629                 :            :                 }
    1630                 :            : 
    1631                 :            :                 rc = 0;
    1632         [ #  # ]:          0 :                 if (last_enabled)
    1633                 :          0 :                         sfc_repr_proxy_stop(sa);
    1634                 :            :                 else
    1635                 :          0 :                         rc = sfc_repr_proxy_do_stop_port(sa, port);
    1636                 :            : 
    1637         [ #  # ]:          0 :                 if (rc != 0) {
    1638                 :          0 :                         sfc_err(sa,
    1639                 :            :                                 "failed to stop representor proxy TxQ %u: %s",
    1640                 :            :                                 repr_id, rte_strerror(rc));
    1641                 :            :                         sfc_adapter_unlock(sa);
    1642                 :          0 :                         return rc;
    1643                 :            :                 }
    1644                 :            :         }
    1645                 :            : 
    1646                 :          0 :         port->enabled = false;
    1647                 :            : 
    1648                 :          0 :         sfc_log_init(sa, "done");
    1649                 :            :         sfc_adapter_unlock(sa);
    1650                 :            : 
    1651                 :          0 :         return 0;
    1652                 :            : }
    1653                 :            : 
    1654                 :            : int
    1655                 :          0 : sfc_repr_proxy_repr_entity_mac_addr_set(uint16_t pf_port_id, uint16_t repr_id,
    1656                 :            :                                         const struct rte_ether_addr *mac_addr)
    1657                 :            : {
    1658                 :            :         struct sfc_repr_proxy_port *port;
    1659                 :            :         struct sfc_repr_proxy *rp;
    1660                 :            :         struct sfc_adapter *sa;
    1661                 :            :         int rc;
    1662                 :            : 
    1663                 :          0 :         sa = sfc_get_adapter_by_pf_port_id(pf_port_id);
    1664                 :          0 :         sfc_adapter_lock(sa);
    1665                 :            :         rp = sfc_repr_proxy_by_adapter(sa);
    1666                 :            : 
    1667                 :          0 :         port = sfc_repr_proxy_find_port(rp, repr_id);
    1668         [ #  # ]:          0 :         if (port == NULL) {
    1669                 :          0 :                 sfc_err(sa, "%s() failed: no such port (repr_id=%u)",
    1670                 :            :                         __func__, repr_id);
    1671                 :            :                 sfc_adapter_unlock(sa);
    1672                 :          0 :                 return ENOENT;
    1673                 :            :         }
    1674                 :            : 
    1675                 :          0 :         rc = efx_mcdi_client_mac_addr_set(sa->nic,
    1676                 :            :                                           port->remote_vnic_mcdi_client_handle,
    1677                 :          0 :                                           mac_addr->addr_bytes);
    1678         [ #  # ]:          0 :         if (rc != 0) {
    1679                 :          0 :                 sfc_err(sa, "%s() failed: cannot set MAC address (repr_id=%u): %s",
    1680                 :            :                         __func__, repr_id, rte_strerror(rc));
    1681                 :            :         }
    1682                 :            : 
    1683                 :            :         sfc_adapter_unlock(sa);
    1684                 :            : 
    1685                 :          0 :         return rc;
    1686                 :            : }
    1687                 :            : 
    1688                 :            : void
    1689                 :          0 : sfc_repr_proxy_mport_alias_get(uint16_t pf_port_id, efx_mport_id_t *mport_alias)
    1690                 :            : {
    1691                 :            :         const struct sfc_repr_proxy *rp;
    1692                 :            :         struct sfc_adapter *sa;
    1693                 :            : 
    1694                 :          0 :         sa = sfc_get_adapter_by_pf_port_id(pf_port_id);
    1695                 :          0 :         sfc_adapter_lock(sa);
    1696                 :            :         rp = sfc_repr_proxy_by_adapter(sa);
    1697                 :            : 
    1698                 :          0 :         memcpy(mport_alias, &rp->mport_alias, sizeof(*mport_alias));
    1699                 :            : 
    1700                 :            :         sfc_adapter_unlock(sa);
    1701                 :          0 : }

Generated by: LCOV version 1.14