LCOV - code coverage report
Current view: top level - drivers/bus/dpaa/base/fman - fman.c (source / functions) Hit Total Coverage
Test: Code coverage Lines: 0 584 0.0 %
Date: 2025-10-01 17:51:42 Functions: 0 8 0.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 355 0.0 %

           Branch data     Line data    Source code
       1                 :            : /* SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0)
       2                 :            :  *
       3                 :            :  * Copyright 2010-2016 Freescale Semiconductor Inc.
       4                 :            :  * Copyright 2017-2024 NXP
       5                 :            :  *
       6                 :            :  */
       7                 :            : 
       8                 :            : #include <sys/types.h>
       9                 :            : #include <sys/ioctl.h>
      10                 :            : #include <ifaddrs.h>
      11                 :            : 
      12                 :            : /* This header declares the driver interface we implement */
      13                 :            : #include <fman.h>
      14                 :            : #include <dpaa_of.h>
      15                 :            : #include <rte_malloc.h>
      16                 :            : #include <rte_dpaa_logs.h>
      17                 :            : #include <rte_string_fns.h>
      18                 :            : 
      19                 :            : int fman_ccsr_map_fd = -1;
      20                 :            : static COMPAT_LIST_HEAD(__ifs);
      21                 :            : static COMPAT_LIST_HEAD(__fmans);
      22                 :            : 
      23                 :            : /* This is the (const) global variable that callers have read-only access to.
      24                 :            :  * Internally, we have read-write access directly to __ifs.
      25                 :            :  */
      26                 :            : const struct list_head *fman_if_list = &__ifs;
      27                 :            : const struct list_head *fman_list = &__fmans;
      28                 :            : 
      29                 :            : static void
      30                 :          0 : if_destructor(struct __fman_if *__if)
      31                 :            : {
      32                 :            :         struct fman_if_bpool *bp, *tmpbp;
      33                 :            : 
      34         [ #  # ]:          0 :         if (!__if)
      35                 :            :                 return;
      36                 :            : 
      37         [ #  # ]:          0 :         if (__if->__if.mac_type == fman_offline_internal)
      38                 :          0 :                 goto cleanup;
      39                 :            : 
      40         [ #  # ]:          0 :         list_for_each_entry_safe(bp, tmpbp, &__if->__if.bpool_list, node) {
      41                 :          0 :                 list_del(&bp->node);
      42                 :          0 :                 free(bp);
      43                 :            :         }
      44                 :          0 : cleanup:
      45                 :          0 :         rte_free(__if);
      46                 :            : }
      47                 :            : 
      48                 :            : static int
      49                 :          0 : _fman_init(const struct device_node *fman_node, int fd)
      50                 :            : {
      51                 :            :         const struct device_node *ptp_node;
      52                 :            :         const uint32_t *fman_addr, *ptp_addr, *cell_idx;
      53                 :            :         uint64_t phys_addr, regs_size;
      54                 :            :         void *vir_addr;
      55                 :            :         uint32_t ip_rev_1;
      56                 :            :         int _errno = 0;
      57                 :            :         struct __fman *fman;
      58                 :            :         size_t lenp;
      59                 :            : 
      60                 :          0 :         fman = rte_zmalloc(NULL, sizeof(struct __fman), 0);
      61         [ #  # ]:          0 :         if (!fman) {
      62                 :          0 :                 FMAN_ERR(-ENOMEM, "malloc fman");
      63                 :          0 :                 return -ENOMEM;
      64                 :            :         }
      65                 :            : 
      66                 :          0 :         cell_idx = of_get_property(fman_node, "cell-index", &lenp);
      67         [ #  # ]:          0 :         if (!cell_idx) {
      68                 :          0 :                 FMAN_ERR(-ENXIO, "%s: no cell-index", fman_node->full_name);
      69                 :          0 :                 return -ENXIO;
      70                 :            :         }
      71         [ #  # ]:          0 :         assert(lenp == sizeof(*cell_idx));
      72                 :          0 :         fman->idx = of_read_number(cell_idx, lenp / sizeof(phandle));
      73                 :            : 
      74                 :          0 :         fman_addr = of_get_address(fman_node, 0, &regs_size, NULL);
      75         [ #  # ]:          0 :         if (!fman_addr) {
      76                 :          0 :                 FMAN_ERR(-EINVAL, "Get fman's CCSR failed");
      77                 :          0 :                 return -EINVAL;
      78                 :            :         }
      79                 :          0 :         phys_addr = of_translate_address(fman_node, fman_addr);
      80         [ #  # ]:          0 :         if (!phys_addr) {
      81                 :          0 :                 FMAN_ERR(-EINVAL, "Translate fman's CCSR failed");
      82                 :          0 :                 return -EINVAL;
      83                 :            :         }
      84                 :          0 :         vir_addr = mmap(NULL, regs_size, PROT_READ | PROT_WRITE,
      85                 :            :                 MAP_SHARED, fd, phys_addr);
      86         [ #  # ]:          0 :         if (vir_addr == MAP_FAILED) {
      87                 :          0 :                 FMAN_ERR(-EINVAL, "Map fman's CCSR failed");
      88                 :          0 :                 return -EINVAL;
      89                 :            :         }
      90                 :          0 :         fman->ccsr_phy = phys_addr;
      91                 :          0 :         fman->ccsr_size = regs_size;
      92                 :          0 :         fman->ccsr_vir = vir_addr;
      93                 :            : 
      94                 :          0 :         fman->time_phy = 0;
      95         [ #  # ]:          0 :         for_each_compatible_node(ptp_node, NULL, "fsl,fman-ptp-timer") {
      96                 :          0 :                 ptp_addr = of_get_address(ptp_node, 0, &regs_size, NULL);
      97         [ #  # ]:          0 :                 if (!ptp_addr)
      98                 :          0 :                         continue;
      99                 :          0 :                 phys_addr = of_translate_address(ptp_node, ptp_addr);
     100         [ #  # ]:          0 :                 if (phys_addr != (fman->ccsr_phy + fman->ccsr_size))
     101                 :          0 :                         continue;
     102                 :          0 :                 vir_addr = mmap(NULL, regs_size, PROT_READ | PROT_WRITE,
     103                 :            :                         MAP_SHARED, fd, phys_addr);
     104         [ #  # ]:          0 :                 if (vir_addr == MAP_FAILED) {
     105                 :          0 :                         FMAN_ERR(-EINVAL, "Map fman's IEEE 1588 failed");
     106                 :          0 :                         return -EINVAL;
     107                 :            :                 }
     108                 :          0 :                 fman->time_phy = phys_addr;
     109                 :          0 :                 fman->time_size = regs_size;
     110                 :          0 :                 fman->time_vir = vir_addr;
     111                 :          0 :                 break;
     112                 :            :         }
     113                 :            : 
     114         [ #  # ]:          0 :         if (!fman->time_phy) {
     115                 :          0 :                 FMAN_ERR(-EINVAL, "Map fman's IEEE 1588 failed");
     116                 :          0 :                 return -EINVAL;
     117                 :            :         }
     118                 :            : 
     119                 :          0 :         ip_rev_1 = in_be32((uint8_t *)fman->ccsr_vir + FMAN_IP_REV_1);
     120                 :          0 :         fman->ip_rev = ip_rev_1 >> FMAN_IP_REV_1_MAJOR_SHIFT;
     121                 :          0 :         fman->ip_rev &=  FMAN_IP_REV_1_MAJOR_MASK;
     122                 :          0 :         DPAA_BUS_LOG(NOTICE, "FMan version is 0x%02x", fman->ip_rev);
     123                 :            : 
     124         [ #  # ]:          0 :         if (fman->ip_rev >= FMAN_V3) {
     125                 :            :                 /*
     126                 :            :                  * Set A2V, OVOM, EBD bits in contextA to allow external
     127                 :            :                  * buffer deallocation by fman.
     128                 :            :                  */
     129                 :          0 :                 fman->dealloc_bufs_mask_hi =
     130                 :            :                         DPAA_FQD_CTX_A_A2_FIELD_VALID |
     131                 :            :                         DPAA_FQD_CTX_A_OVERRIDE_OMB;
     132                 :          0 :                 fman->dealloc_bufs_mask_lo = DPAA_FQD_CTX_A2_EBD_BIT;
     133                 :            :         } else {
     134                 :          0 :                 fman->dealloc_bufs_mask_hi = 0;
     135                 :          0 :                 fman->dealloc_bufs_mask_lo = 0;
     136                 :            :         }
     137                 :            : 
     138                 :          0 :         fman->fman_node = fman_node;
     139                 :            : 
     140                 :          0 :         list_add_tail(&fman->node, &__fmans);
     141                 :            : 
     142                 :          0 :         return _errno;
     143                 :            : }
     144                 :            : 
     145                 :            : static int
     146                 :          0 : fman_get_mac_index(uint64_t regs_addr_host, uint8_t *mac_idx)
     147                 :            : {
     148                 :            :         int ret = 0;
     149                 :            : 
     150                 :            :         /*
     151                 :            :          * MAC1 : E_0000h
     152                 :            :          * MAC2 : E_2000h
     153                 :            :          * MAC3 : E_4000h
     154                 :            :          * MAC4 : E_6000h
     155                 :            :          * MAC5 : E_8000h
     156                 :            :          * MAC6 : E_A000h
     157                 :            :          * MAC7 : E_C000h
     158                 :            :          * MAC8 : E_E000h
     159                 :            :          * MAC9 : F_0000h
     160                 :            :          * MAC10: F_2000h
     161                 :            :          */
     162   [ #  #  #  #  :          0 :         switch (regs_addr_host) {
          #  #  #  #  #  
                   #  # ]
     163                 :          0 :         case 0xE0000:
     164                 :          0 :                 *mac_idx = 1;
     165                 :          0 :                 break;
     166                 :          0 :         case 0xE2000:
     167                 :          0 :                 *mac_idx = 2;
     168                 :          0 :                 break;
     169                 :          0 :         case 0xE4000:
     170                 :          0 :                 *mac_idx = 3;
     171                 :          0 :                 break;
     172                 :          0 :         case 0xE6000:
     173                 :          0 :                 *mac_idx = 4;
     174                 :          0 :                 break;
     175                 :          0 :         case 0xE8000:
     176                 :          0 :                 *mac_idx = 5;
     177                 :          0 :                 break;
     178                 :          0 :         case 0xEA000:
     179                 :          0 :                 *mac_idx = 6;
     180                 :          0 :                 break;
     181                 :          0 :         case 0xEC000:
     182                 :          0 :                 *mac_idx = 7;
     183                 :          0 :                 break;
     184                 :          0 :         case 0xEE000:
     185                 :          0 :                 *mac_idx = 8;
     186                 :          0 :                 break;
     187                 :          0 :         case 0xF0000:
     188                 :          0 :                 *mac_idx = 9;
     189                 :          0 :                 break;
     190                 :          0 :         case 0xF2000:
     191                 :          0 :                 *mac_idx = 10;
     192                 :          0 :                 break;
     193                 :            :         default:
     194                 :            :                 ret = -EINVAL;
     195                 :            :         }
     196                 :            : 
     197                 :          0 :         return ret;
     198                 :            : }
     199                 :            : 
     200                 :          0 : static void fman_if_vsp_init(struct __fman_if *__if)
     201                 :            : {
     202                 :            :         const phandle *prop;
     203                 :            :         int cell_index;
     204                 :            :         const struct device_node *dev;
     205                 :            :         size_t lenp;
     206                 :          0 :         const uint8_t mac_idx[] = {-1, 0, 1, 2, 3, 4, 5, 6, 7, 0, 1};
     207                 :            : 
     208         [ #  # ]:          0 :         if (__if->__if.mac_idx <= 8) {
     209         [ #  # ]:          0 :                 for_each_compatible_node(dev, NULL,
     210                 :            :                         "fsl,fman-port-1g-rx-extended-args") {
     211                 :          0 :                         prop = of_get_property(dev, "cell-index", &lenp);
     212         [ #  # ]:          0 :                         if (prop) {
     213                 :          0 :                                 cell_index = of_read_number(
     214                 :            :                                                 &prop[0],
     215                 :          0 :                                                 lenp / sizeof(phandle));
     216         [ #  # ]:          0 :                                 if (cell_index == mac_idx[__if->__if.mac_idx]) {
     217                 :          0 :                                         prop = of_get_property(
     218                 :            :                                                         dev,
     219                 :            :                                                         "vsp-window", &lenp);
     220         [ #  # ]:          0 :                                         if (prop) {
     221                 :          0 :                                                 __if->__if.num_profiles =
     222                 :            :                                                         of_read_number(
     223                 :            :                                                                 &prop[0], 1);
     224                 :          0 :                                                 __if->__if.base_profile_id =
     225                 :            :                                                         of_read_number(
     226                 :          0 :                                                                 &prop[1], 1);
     227                 :            :                                         }
     228                 :            :                                 }
     229                 :            :                         }
     230                 :            :                 }
     231                 :            : 
     232         [ #  # ]:          0 :                 for_each_compatible_node(dev, NULL,
     233                 :            :                                          "fsl,fman-port-op-extended-args") {
     234                 :          0 :                         prop = of_get_property(dev, "cell-index", &lenp);
     235                 :            : 
     236         [ #  # ]:          0 :                         if (prop) {
     237                 :          0 :                                 cell_index = of_read_number(&prop[0],
     238                 :          0 :                                                 lenp / sizeof(phandle));
     239                 :            : 
     240         [ #  # ]:          0 :                                 if (cell_index == __if->__if.mac_idx) {
     241                 :          0 :                                         prop = of_get_property(dev,
     242                 :            :                                                                "vsp-window",
     243                 :            :                                                                &lenp);
     244                 :            : 
     245         [ #  # ]:          0 :                                         if (prop) {
     246                 :          0 :                                                 __if->__if.num_profiles =
     247                 :            :                                                         of_read_number(&prop[0],
     248                 :            :                                                                        1);
     249                 :          0 :                                                 __if->__if.base_profile_id =
     250                 :          0 :                                                         of_read_number(&prop[1],
     251                 :            :                                                                        1);
     252                 :            :                                         }
     253                 :            :                                 }
     254                 :            :                         }
     255                 :            :                 }
     256                 :            :         } else {
     257         [ #  # ]:          0 :                 for_each_compatible_node(dev, NULL,
     258                 :            :                         "fsl,fman-port-10g-rx-extended-args") {
     259                 :          0 :                         prop = of_get_property(dev, "cell-index", &lenp);
     260         [ #  # ]:          0 :                         if (prop) {
     261                 :          0 :                                 cell_index = of_read_number(
     262                 :          0 :                                         &prop[0], lenp / sizeof(phandle));
     263         [ #  # ]:          0 :                                 if (cell_index == mac_idx[__if->__if.mac_idx]) {
     264                 :          0 :                                         prop = of_get_property(
     265                 :            :                                                 dev, "vsp-window", &lenp);
     266         [ #  # ]:          0 :                                         if (prop) {
     267                 :          0 :                                                 __if->__if.num_profiles =
     268                 :            :                                                         of_read_number(
     269                 :            :                                                                 &prop[0], 1);
     270                 :          0 :                                                 __if->__if.base_profile_id =
     271                 :            :                                                         of_read_number(
     272                 :          0 :                                                                 &prop[1], 1);
     273                 :            :                                         }
     274                 :            :                                 }
     275                 :            :                         }
     276                 :            :                 }
     277                 :            :         }
     278                 :          0 : }
     279                 :            : 
     280                 :            : static int
     281                 :          0 : fman_if_init(const struct device_node *dpa_node, int fd)
     282                 :            : {
     283                 :            :         const char *rprop, *mprop;
     284                 :            :         uint64_t phys_addr;
     285                 :            :         struct __fman_if *__if;
     286                 :            :         struct fman_if_bpool *bpool;
     287                 :            : 
     288                 :            :         const phandle *mac_phandle, *ports_phandle, *pools_phandle;
     289                 :            :         const phandle *tx_channel_id = NULL, *mac_addr, *cell_idx;
     290                 :            :         const phandle *rx_phandle, *tx_phandle;
     291                 :            :         const phandle *port_cell_idx, *ext_args_cell_idx;
     292                 :            :         const struct device_node *parent_node_ext_args;
     293                 :            :         uint64_t tx_phandle_host[4] = {0};
     294                 :            :         uint64_t rx_phandle_host[6] = {0};
     295                 :            :         uint64_t regs_addr_host = 0;
     296                 :            :         uint64_t cell_idx_host = 0;
     297                 :            :         uint64_t port_cell_idx_val = 0;
     298                 :            :         uint64_t ext_args_cell_idx_val = 0;
     299                 :            : 
     300                 :            :         const struct device_node *mac_node = NULL, *ext_args_node;
     301                 :            :         const struct device_node *pool_node, *fman_node;
     302                 :            :         const struct device_node *rx_node = NULL, *tx_node = NULL;
     303                 :            :         const struct device_node *oh_node = NULL;
     304                 :            :         const uint32_t *regs_addr = NULL;
     305                 :            :         const char *mname;
     306                 :          0 :         const char *dname = dpa_node->full_name;
     307                 :            :         size_t lenp;
     308                 :            :         int _errno, is_shared = 0, is_offline = 0, find_fman = false;
     309                 :            :         const char *char_prop;
     310                 :            :         uint32_t na;
     311                 :            :         struct __fman *fman, *tmp_fman;
     312                 :            : 
     313         [ #  # ]:          0 :         if (of_device_is_available(dpa_node) == false)
     314                 :            :                 return 0;
     315                 :            : 
     316         [ #  # ]:          0 :         if (of_device_is_compatible(dpa_node, "fsl,dpa-oh"))
     317                 :            :                 is_offline = 1;
     318                 :            : 
     319   [ #  #  #  # ]:          0 :         if (!of_device_is_compatible(dpa_node, "fsl,dpa-oh") &&
     320         [ #  # ]:          0 :             !of_device_is_compatible(dpa_node, "fsl,dpa-ethernet-init") &&
     321                 :          0 :             !of_device_is_compatible(dpa_node, "fsl,dpa-ethernet")) {
     322                 :            :                 return 0;
     323                 :            :         }
     324                 :            : 
     325         [ #  # ]:          0 :         rprop = is_offline ? "fsl,qman-frame-queues-oh" :
     326                 :            :                              "fsl,qman-frame-queues-rx";
     327         [ #  # ]:          0 :         mprop = is_offline ? "fsl,fman-oh-port" :
     328                 :            :                              "fsl,fman-mac";
     329                 :            : 
     330                 :            :         /* Obtain the MAC node used by this interface except macless */
     331                 :          0 :         mac_phandle = of_get_property(dpa_node, mprop, &lenp);
     332         [ #  # ]:          0 :         if (!mac_phandle) {
     333                 :          0 :                 FMAN_ERR(-EINVAL, "%s: no %s", dname, mprop);
     334                 :          0 :                 return -EINVAL;
     335                 :            :         }
     336         [ #  # ]:          0 :         assert(lenp == sizeof(phandle));
     337                 :          0 :         mac_node = of_find_node_by_phandle(*mac_phandle);
     338         [ #  # ]:          0 :         if (!mac_node) {
     339                 :          0 :                 FMAN_ERR(-ENXIO, "%s: bad 'fsl,fman-mac", dname);
     340                 :          0 :                 return -ENXIO;
     341                 :            :         }
     342                 :          0 :         mname = mac_node->full_name;
     343                 :            : 
     344         [ #  # ]:          0 :         if (!is_offline) {
     345                 :            :                 /* Extract the Rx and Tx ports */
     346                 :          0 :                 ports_phandle = of_get_property(mac_node, "fsl,port-handles",
     347                 :            :                                                 &lenp);
     348         [ #  # ]:          0 :                 if (!ports_phandle)
     349                 :          0 :                         ports_phandle = of_get_property(mac_node, "fsl,fman-ports",
     350                 :            :                                                         &lenp);
     351         [ #  # ]:          0 :                 if (!ports_phandle) {
     352                 :          0 :                         FMAN_ERR(-EINVAL, "%s: no fsl,port-handles",
     353                 :            :                                  mname);
     354                 :          0 :                         return -EINVAL;
     355                 :            :                 }
     356         [ #  # ]:          0 :                 assert(lenp == (2 * sizeof(phandle)));
     357                 :          0 :                 rx_node = of_find_node_by_phandle(ports_phandle[0]);
     358         [ #  # ]:          0 :                 if (!rx_node) {
     359                 :          0 :                         FMAN_ERR(-ENXIO, "%s: bad fsl,port-handle[0]", mname);
     360                 :          0 :                         return -ENXIO;
     361                 :            :                 }
     362                 :          0 :                 tx_node = of_find_node_by_phandle(ports_phandle[1]);
     363         [ #  # ]:          0 :                 if (!tx_node) {
     364                 :          0 :                         FMAN_ERR(-ENXIO, "%s: bad fsl,port-handle[1]", mname);
     365                 :          0 :                         return -ENXIO;
     366                 :            :                 }
     367                 :            :         } else {
     368                 :            :                 /* Extract the OH ports */
     369                 :          0 :                 ports_phandle = of_get_property(dpa_node, "fsl,fman-oh-port",
     370                 :            :                                                 &lenp);
     371         [ #  # ]:          0 :                 if (!ports_phandle) {
     372                 :          0 :                         FMAN_ERR(-EINVAL, "%s: no fsl,fman-oh-port", dname);
     373                 :          0 :                         return -EINVAL;
     374                 :            :                 }
     375         [ #  # ]:          0 :                 assert(lenp == (sizeof(phandle)));
     376                 :          0 :                 oh_node = of_find_node_by_phandle(ports_phandle[0]);
     377         [ #  # ]:          0 :                 if (!oh_node) {
     378                 :          0 :                         FMAN_ERR(-ENXIO, "%s: bad fsl,port-handle[0]", mname);
     379                 :          0 :                         return -ENXIO;
     380                 :            :                 }
     381                 :            :         }
     382                 :            : 
     383                 :            :         /* Check if the port is shared interface */
     384         [ #  # ]:          0 :         if (of_device_is_compatible(dpa_node, "fsl,dpa-ethernet")) {
     385                 :          0 :                 port_cell_idx = of_get_property(rx_node, "cell-index", &lenp);
     386         [ #  # ]:          0 :                 if (!port_cell_idx) {
     387                 :          0 :                         FMAN_ERR(-ENXIO, "%s: no cell-index for port", mname);
     388                 :          0 :                         return -ENXIO;
     389                 :            :                 }
     390         [ #  # ]:          0 :                 assert(lenp == sizeof(*port_cell_idx));
     391                 :            :                 port_cell_idx_val =
     392                 :            :                         of_read_number(port_cell_idx, lenp / sizeof(phandle));
     393                 :            : 
     394         [ #  # ]:          0 :                 if (of_device_is_compatible(rx_node, "fsl,fman-port-1g-rx"))
     395                 :          0 :                         port_cell_idx_val -= 0x8;
     396         [ #  # ]:          0 :                 else if (of_device_is_compatible(
     397                 :            :                                 rx_node, "fsl,fman-port-10g-rx"))
     398                 :          0 :                         port_cell_idx_val -= 0x10;
     399                 :            : 
     400                 :          0 :                 parent_node_ext_args = of_find_compatible_node(NULL,
     401                 :            :                         NULL, "fsl,fman-extended-args");
     402         [ #  # ]:          0 :                 if (!parent_node_ext_args)
     403                 :            :                         return 0;
     404                 :            : 
     405         [ #  # ]:          0 :                 for_each_child_node(parent_node_ext_args, ext_args_node) {
     406                 :          0 :                         ext_args_cell_idx = of_get_property(ext_args_node,
     407                 :            :                                 "cell-index", &lenp);
     408         [ #  # ]:          0 :                         if (!ext_args_cell_idx) {
     409                 :          0 :                                 FMAN_ERR(-ENXIO, "%s: no cell-index for ext args",
     410                 :            :                                          mname);
     411                 :          0 :                                 return -ENXIO;
     412                 :            :                         }
     413         [ #  # ]:          0 :                         assert(lenp == sizeof(*ext_args_cell_idx));
     414                 :            :                         ext_args_cell_idx_val =
     415                 :            :                                 of_read_number(ext_args_cell_idx, lenp /
     416                 :            :                                 sizeof(phandle));
     417                 :            : 
     418         [ #  # ]:          0 :                         if (port_cell_idx_val == ext_args_cell_idx_val) {
     419         [ #  # ]:          0 :                                 if (of_device_is_compatible(ext_args_node,
     420         [ #  # ]:          0 :                                         "fsl,fman-port-1g-rx-extended-args") &&
     421                 :          0 :                                         of_device_is_compatible(rx_node,
     422                 :            :                                         "fsl,fman-port-1g-rx")) {
     423         [ #  # ]:          0 :                                         if (of_get_property(ext_args_node,
     424                 :            :                                                 "vsp-window", &lenp))
     425                 :            :                                                 is_shared = 1;
     426                 :            :                                         break;
     427                 :            :                                 }
     428         [ #  # ]:          0 :                                 if (of_device_is_compatible(ext_args_node,
     429         [ #  # ]:          0 :                                         "fsl,fman-port-10g-rx-extended-args") &&
     430                 :          0 :                                         of_device_is_compatible(rx_node,
     431                 :            :                                         "fsl,fman-port-10g-rx")) {
     432         [ #  # ]:          0 :                                         if (of_get_property(ext_args_node,
     433                 :            :                                                 "vsp-window", &lenp))
     434                 :            :                                                 is_shared = 1;
     435                 :            :                                         break;
     436                 :            :                                 }
     437                 :            :                         }
     438                 :            :                 }
     439                 :            :                 if (!is_shared)
     440                 :          0 :                         return 0;
     441                 :            :         }
     442                 :            : 
     443                 :            :         /* Allocate an object for this network interface */
     444                 :          0 :         __if = rte_malloc(NULL, sizeof(*__if), RTE_CACHE_LINE_SIZE);
     445         [ #  # ]:          0 :         if (!__if) {
     446                 :          0 :                 FMAN_ERR(-ENOMEM, "malloc(%zu)", sizeof(*__if));
     447                 :          0 :                 goto err;
     448                 :            :         }
     449                 :            :         memset(__if, 0, sizeof(*__if));
     450                 :          0 :         INIT_LIST_HEAD(&__if->__if.bpool_list);
     451                 :          0 :         strlcpy(__if->node_name, dpa_node->name, IF_NAME_MAX_LEN - 1);
     452                 :          0 :         __if->node_name[IF_NAME_MAX_LEN - 1] = '\0';
     453                 :          0 :         strlcpy(__if->node_path, dpa_node->full_name, PATH_MAX - 1);
     454                 :          0 :         __if->node_path[PATH_MAX - 1] = '\0';
     455                 :            : 
     456                 :            :         /* Map the CCSR regs for the MAC node */
     457                 :          0 :         regs_addr = of_get_address(mac_node, 0, &__if->regs_size, NULL);
     458         [ #  # ]:          0 :         if (!regs_addr) {
     459                 :          0 :                 FMAN_ERR(-EINVAL, "of_get_address(%s)", mname);
     460                 :          0 :                 goto err;
     461                 :            :         }
     462                 :          0 :         phys_addr = of_translate_address(mac_node, regs_addr);
     463         [ #  # ]:          0 :         if (!phys_addr) {
     464                 :          0 :                 FMAN_ERR(-EINVAL, "of_translate_address(%s, %p)",
     465                 :            :                          mname, regs_addr);
     466                 :          0 :                 goto err;
     467                 :            :         }
     468                 :          0 :         __if->ccsr_map = mmap(NULL, __if->regs_size,
     469                 :            :                 PROT_READ | PROT_WRITE, MAP_SHARED, fd, phys_addr);
     470         [ #  # ]:          0 :         if (__if->ccsr_map == MAP_FAILED) {
     471                 :          0 :                 FMAN_ERR(-errno, "mmap(0x%"PRIx64")", phys_addr);
     472                 :          0 :                 goto err;
     473                 :            :         }
     474                 :          0 :         na = of_n_addr_cells(mac_node);
     475                 :            :         /* Get rid of endianness (issues). Convert to host byte order */
     476                 :          0 :         regs_addr_host = of_read_number(regs_addr, na);
     477                 :            : 
     478                 :            :         /* Get the index of the Fman this i/f belongs to */
     479                 :          0 :         fman_node = of_get_parent(mac_node);
     480         [ #  # ]:          0 :         list_for_each_entry_safe(fman, tmp_fman, &__fmans, node) {
     481         [ #  # ]:          0 :                 if (fman_node == fman->fman_node) {
     482                 :            :                         find_fman = true;
     483                 :            :                         break;
     484                 :            :                 }
     485                 :            :         }
     486         [ #  # ]:          0 :         if (!find_fman) {
     487                 :          0 :                 FMAN_ERR(-ENXIO, "Failed to get parent of %s", mname);
     488                 :          0 :                 goto err;
     489                 :            :         }
     490                 :          0 :         __if->__if.fman = fman;
     491                 :            : 
     492                 :            :         /* Is the MAC node 1G, 2.5G, 10G or offline? */
     493                 :          0 :         __if->__if.is_memac = 0;
     494                 :            : 
     495         [ #  # ]:          0 :         if (is_offline) {
     496                 :          0 :                 __if->__if.mac_type = fman_offline_internal;
     497         [ #  # ]:          0 :         } else if (of_device_is_compatible(mac_node, "fsl,fman-memac")) {
     498                 :          0 :                 __if->__if.is_memac = 1;
     499                 :          0 :                 char_prop = of_get_property(mac_node, "phy-connection-type",
     500                 :            :                                             NULL);
     501         [ #  # ]:          0 :                 if (!char_prop) {
     502                 :          0 :                         FMAN_ERR(-EINVAL, "memac: unknown MII type assuming 1G");
     503                 :            :                         /* Right now forcing memac to 1g in case of error*/
     504                 :          0 :                         __if->__if.mac_type = fman_mac_1g;
     505                 :            :                 } else {
     506         [ #  # ]:          0 :                         if (strstr(char_prop, "sgmii-2500"))
     507                 :          0 :                                 __if->__if.mac_type = fman_mac_2_5g;
     508         [ #  # ]:          0 :                         else if (strstr(char_prop, "sgmii"))
     509                 :          0 :                                 __if->__if.mac_type = fman_mac_1g;
     510         [ #  # ]:          0 :                         else if (strstr(char_prop, "rgmii")) {
     511                 :          0 :                                 __if->__if.mac_type = fman_mac_1g;
     512                 :          0 :                                 __if->__if.is_rgmii = 1;
     513         [ #  # ]:          0 :                         } else if (strstr(char_prop, "xgmii"))
     514                 :          0 :                                 __if->__if.mac_type = fman_mac_10g;
     515                 :            :                 }
     516                 :            :         } else {
     517                 :          0 :                 FMAN_ERR(-ENOTSUP, "%s: Unsupported MAC type", mname);
     518                 :          0 :                 goto err;
     519                 :            :         }
     520                 :            : 
     521         [ #  # ]:          0 :         if (!is_offline) {
     522                 :            :                 /*
     523                 :            :                  * For MAC ports, we cannot rely on cell-index. In
     524                 :            :                  * T2080, two of the 10G ports on single FMAN have same
     525                 :            :                  * duplicate cell-indexes as the other two 10G ports on
     526                 :            :                  * same FMAN. Hence, we now rely upon addresses of the
     527                 :            :                  * ports from device tree to deduce the index.
     528                 :            :                  */
     529                 :            : 
     530                 :          0 :                 _errno = fman_get_mac_index(regs_addr_host, &__if->__if.mac_idx);
     531         [ #  # ]:          0 :                 if (_errno) {
     532                 :          0 :                         FMAN_ERR(-EINVAL, "Invalid register address: %" PRIx64,
     533                 :            :                                  regs_addr_host);
     534                 :          0 :                         goto err;
     535                 :            :                 }
     536                 :            :         } else {
     537                 :          0 :                 cell_idx = of_get_property(oh_node, "cell-index", &lenp);
     538         [ #  # ]:          0 :                 if (!cell_idx) {
     539                 :          0 :                         FMAN_ERR(-ENXIO, "%s: no cell-index)",
     540                 :            :                                  oh_node->full_name);
     541                 :          0 :                         goto err;
     542                 :            :                 }
     543         [ #  # ]:          0 :                 assert(lenp == sizeof(*cell_idx));
     544                 :            :                 cell_idx_host = of_read_number(cell_idx,
     545                 :            :                                                lenp / sizeof(phandle));
     546                 :            : 
     547                 :          0 :                 __if->__if.mac_idx = cell_idx_host;
     548                 :            :         }
     549                 :            : 
     550         [ #  # ]:          0 :         if (!is_offline) {
     551                 :            :                 /* Extract the MAC address for private and shared interfaces */
     552                 :          0 :                 mac_addr = of_get_property(mac_node, "local-mac-address",
     553                 :            :                                            &lenp);
     554         [ #  # ]:          0 :                 if (!mac_addr) {
     555                 :          0 :                         FMAN_ERR(-EINVAL, "%s: no local-mac-address",
     556                 :            :                                  mname);
     557                 :          0 :                         goto err;
     558                 :            :                 }
     559                 :          0 :                 memcpy(&__if->__if.mac_addr, mac_addr, ETHER_ADDR_LEN);
     560                 :            : 
     561                 :            :                 /* Extract the channel ID (from tx-port-handle) */
     562                 :          0 :                 tx_channel_id = of_get_property(tx_node, "fsl,qman-channel-id",
     563                 :            :                                                 &lenp);
     564         [ #  # ]:          0 :                 if (!tx_channel_id) {
     565                 :          0 :                         FMAN_ERR(-EINVAL, "%s: no fsl-qman-channel-id",
     566                 :            :                                  tx_node->full_name);
     567                 :          0 :                         goto err;
     568                 :            :                 }
     569                 :            :         } else {
     570                 :            :                 /* Extract the channel ID (from mac) */
     571                 :          0 :                 tx_channel_id = of_get_property(mac_node, "fsl,qman-channel-id",
     572                 :            :                                                 &lenp);
     573         [ #  # ]:          0 :                 if (!tx_channel_id) {
     574                 :          0 :                         FMAN_ERR(-EINVAL, "%s: no fsl-qman-channel-id",
     575                 :            :                                  tx_node->full_name);
     576                 :          0 :                         goto err;
     577                 :            :                 }
     578                 :            :         }
     579                 :            : 
     580                 :          0 :         na = of_n_addr_cells(mac_node);
     581                 :          0 :         __if->__if.tx_channel_id = of_read_number(tx_channel_id, na);
     582                 :            : 
     583         [ #  # ]:          0 :         if (!is_offline)
     584                 :          0 :                 regs_addr = of_get_address(rx_node, 0, &__if->regs_size, NULL);
     585                 :            :         else
     586                 :          0 :                 regs_addr = of_get_address(oh_node, 0, &__if->regs_size, NULL);
     587         [ #  # ]:          0 :         if (!regs_addr) {
     588                 :          0 :                 FMAN_ERR(-EINVAL, "of_get_address(%s)", mname);
     589                 :          0 :                 goto err;
     590                 :            :         }
     591                 :            : 
     592         [ #  # ]:          0 :         if (!is_offline)
     593                 :          0 :                 phys_addr = of_translate_address(rx_node, regs_addr);
     594                 :            :         else
     595                 :          0 :                 phys_addr = of_translate_address(oh_node, regs_addr);
     596         [ #  # ]:          0 :         if (!phys_addr) {
     597                 :          0 :                 FMAN_ERR(-EINVAL, "of_translate_address(%s, %p)",
     598                 :            :                          mname, regs_addr);
     599                 :          0 :                 goto err;
     600                 :            :         }
     601                 :            : 
     602                 :          0 :         __if->bmi_map = mmap(NULL, __if->regs_size,
     603                 :            :                 PROT_READ | PROT_WRITE, MAP_SHARED, fd, phys_addr);
     604         [ #  # ]:          0 :         if (__if->bmi_map == MAP_FAILED) {
     605                 :          0 :                 FMAN_ERR(-errno, "mmap(0x%"PRIx64")", phys_addr);
     606                 :          0 :                 goto err;
     607                 :            :         }
     608                 :            : 
     609         [ #  # ]:          0 :         if (!is_offline) {
     610                 :          0 :                 regs_addr = of_get_address(tx_node, 0, &__if->regs_size, NULL);
     611         [ #  # ]:          0 :                 if (!regs_addr) {
     612                 :          0 :                         FMAN_ERR(-EINVAL, "of_get_address(%s)", mname);
     613                 :          0 :                         goto err;
     614                 :            :                 }
     615                 :            : 
     616                 :          0 :                 phys_addr = of_translate_address(tx_node, regs_addr);
     617         [ #  # ]:          0 :                 if (!phys_addr) {
     618                 :          0 :                         FMAN_ERR(-EINVAL, "of_translate_address(%s, %p)",
     619                 :            :                                  mname, regs_addr);
     620                 :          0 :                         goto err;
     621                 :            :                 }
     622                 :            : 
     623                 :          0 :                 __if->tx_bmi_map = mmap(NULL, __if->regs_size,
     624                 :            :                         PROT_READ | PROT_WRITE, MAP_SHARED, fd, phys_addr);
     625         [ #  # ]:          0 :                 if (__if->tx_bmi_map == MAP_FAILED) {
     626                 :          0 :                         FMAN_ERR(-errno, "mmap(0x%"PRIx64")", phys_addr);
     627                 :          0 :                         goto err;
     628                 :            :                 }
     629                 :            :         }
     630                 :            : 
     631                 :            :         /* Extract the Rx FQIDs. (Note, the device representation is silly,
     632                 :            :          * there are "counts" that must always be 1.)
     633                 :            :          */
     634                 :          0 :         rx_phandle = of_get_property(dpa_node, rprop, &lenp);
     635         [ #  # ]:          0 :         if (!rx_phandle) {
     636                 :          0 :                 FMAN_ERR(-EINVAL, "%s: no fsl,qman-frame-queues-rx", dname);
     637                 :          0 :                 goto err;
     638                 :            :         }
     639                 :            : 
     640                 :            :         /*
     641                 :            :          * Check if "fsl,qman-frame-queues-rx/oh" in dtb file is valid entry or
     642                 :            :          * not.
     643                 :            :          *
     644                 :            :          * A valid rx entry contains either 4 or 6 entries. Mandatory entries
     645                 :            :          * are rx_error_queue, rx_error_queue_count, fqid_rx_def and
     646                 :            :          * fqid_rx_def_count. Optional entries are fqid_rx_pcd and
     647                 :            :          * fqid_rx_pcd_count.
     648                 :            :          *
     649                 :            :          * A valid oh entry contains 4 entries. Those entries are
     650                 :            :          * rx_error_queue, rx_error_queue_count, fqid_rx_def and
     651                 :            :          * fqid_rx_def_count.
     652                 :            :          */
     653                 :            : 
     654         [ #  # ]:          0 :         if (!is_offline)
     655         [ #  # ]:          0 :                 assert(lenp == (4 * sizeof(phandle)) ||
     656                 :            :                        lenp == (6 * sizeof(phandle)));
     657                 :            :         else
     658         [ #  # ]:          0 :                 assert(lenp == (4 * sizeof(phandle)));
     659                 :            : 
     660                 :            :         /* Get rid of endianness (issues). Convert to host byte order */
     661                 :            :         rx_phandle_host[0] = of_read_number(&rx_phandle[0], na);
     662                 :          0 :         rx_phandle_host[1] = of_read_number(&rx_phandle[1], na);
     663                 :          0 :         rx_phandle_host[2] = of_read_number(&rx_phandle[2], na);
     664                 :          0 :         rx_phandle_host[3] = of_read_number(&rx_phandle[3], na);
     665                 :          0 :         rx_phandle_host[4] = of_read_number(&rx_phandle[4], na);
     666                 :          0 :         rx_phandle_host[5] = of_read_number(&rx_phandle[5], na);
     667                 :            : 
     668   [ #  #  #  # ]:          0 :         assert((rx_phandle_host[1] == 1) && (rx_phandle_host[3] == 1));
     669                 :          0 :         __if->__if.fqid_rx_err = rx_phandle_host[0];
     670                 :          0 :         __if->__if.fqid_rx_def = rx_phandle_host[2];
     671                 :            : 
     672                 :            :         /* If there are 6 entries in "fsl,qman-frame-queues-rx" in dtb file, it
     673                 :            :          * means PCD queues are also available. Hence, store that information.
     674                 :            :          */
     675         [ #  # ]:          0 :         if (lenp == 6 * sizeof(phandle)) {
     676                 :          0 :                 __if->__if.fqid_rx_pcd = rx_phandle_host[4];
     677                 :          0 :                 __if->__if.fqid_rx_pcd_count = rx_phandle_host[5];
     678                 :            :         }
     679                 :            : 
     680         [ #  # ]:          0 :         if (is_offline)
     681                 :          0 :                 goto oh_init_done;
     682                 :            : 
     683                 :            :         /* Extract the Tx FQIDs */
     684                 :          0 :         tx_phandle = of_get_property(dpa_node,
     685                 :            :                                      "fsl,qman-frame-queues-tx", &lenp);
     686         [ #  # ]:          0 :         if (!tx_phandle) {
     687                 :          0 :                 FMAN_ERR(-EINVAL, "%s: no fsl,qman-frame-queues-tx", dname);
     688                 :          0 :                 goto err;
     689                 :            :         }
     690                 :            : 
     691         [ #  # ]:          0 :         assert(lenp >= (4 * sizeof(phandle)));
     692                 :            :         /*TODO: Fix for other cases also */
     693                 :          0 :         na = of_n_addr_cells(mac_node);
     694                 :            :         /* Get rid of endianness (issues). Convert to host byte order */
     695                 :          0 :         tx_phandle_host[0] = of_read_number(&tx_phandle[0], na);
     696                 :          0 :         tx_phandle_host[1] = of_read_number(&tx_phandle[1], na);
     697                 :          0 :         tx_phandle_host[2] = of_read_number(&tx_phandle[2], na);
     698                 :          0 :         tx_phandle_host[3] = of_read_number(&tx_phandle[3], na);
     699   [ #  #  #  # ]:          0 :         assert((tx_phandle_host[1] == 1) && (tx_phandle_host[3] == 1));
     700                 :          0 :         __if->__if.fqid_tx_err = tx_phandle_host[0];
     701                 :          0 :         __if->__if.fqid_tx_confirm = tx_phandle_host[2];
     702                 :            : 
     703                 :            :         /* Obtain the buffer pool nodes used by this interface */
     704                 :          0 :         pools_phandle = of_get_property(dpa_node, "fsl,bman-buffer-pools",
     705                 :            :                                         &lenp);
     706         [ #  # ]:          0 :         if (!pools_phandle) {
     707                 :          0 :                 FMAN_ERR(-EINVAL, "%s: no fsl,bman-buffer-pools", dname);
     708                 :          0 :                 goto err;
     709                 :            :         }
     710                 :            :         /* For each pool, parse the corresponding node and add a pool object
     711                 :            :          * to the interface's "bpool_list"
     712                 :            :          */
     713   [ #  #  #  # ]:          0 :         assert(lenp && !(lenp % sizeof(phandle)));
     714         [ #  # ]:          0 :         while (lenp) {
     715                 :            :                 size_t proplen;
     716                 :            :                 const phandle *prop;
     717                 :            :                 uint64_t bpid_host = 0;
     718                 :            :                 uint64_t bpool_host[6] = {0};
     719                 :            :                 const char *pname;
     720                 :            :                 /* Allocate an object for the pool */
     721                 :          0 :                 bpool = rte_malloc(NULL, sizeof(*bpool), RTE_CACHE_LINE_SIZE);
     722         [ #  # ]:          0 :                 if (!bpool) {
     723                 :          0 :                         FMAN_ERR(-ENOMEM, "malloc(%zu)", sizeof(*bpool));
     724                 :          0 :                         goto err;
     725                 :            :                 }
     726                 :            :                 /* Find the pool node */
     727                 :          0 :                 pool_node = of_find_node_by_phandle(*pools_phandle);
     728         [ #  # ]:          0 :                 if (!pool_node) {
     729                 :          0 :                         FMAN_ERR(-ENXIO, "%s: bad fsl,bman-buffer-pools",
     730                 :            :                                  dname);
     731                 :          0 :                         rte_free(bpool);
     732                 :          0 :                         goto err;
     733                 :            :                 }
     734                 :          0 :                 pname = pool_node->full_name;
     735                 :            :                 /* Extract the BPID property */
     736                 :          0 :                 prop = of_get_property(pool_node, "fsl,bpid", &proplen);
     737         [ #  # ]:          0 :                 if (!prop) {
     738                 :          0 :                         FMAN_ERR(-EINVAL, "%s: no fsl,bpid", pname);
     739                 :          0 :                         rte_free(bpool);
     740                 :          0 :                         goto err;
     741                 :            :                 }
     742         [ #  # ]:          0 :                 assert(proplen == sizeof(*prop));
     743                 :          0 :                 na = of_n_addr_cells(mac_node);
     744                 :            :                 /* Get rid of endianness (issues).
     745                 :            :                  * Convert to host byte-order
     746                 :            :                  */
     747                 :          0 :                 bpid_host = of_read_number(prop, na);
     748                 :          0 :                 bpool->bpid = bpid_host;
     749                 :            :                 /* Extract the cfg property (count/size/addr). "fsl,bpool-cfg"
     750                 :            :                  * indicates for the Bman driver to seed the pool.
     751                 :            :                  * "fsl,bpool-ethernet-cfg" is used by the network driver. The
     752                 :            :                  * two are mutually exclusive, so check for either of them.
     753                 :            :                  */
     754                 :          0 :                 prop = of_get_property(pool_node, "fsl,bpool-cfg",
     755                 :            :                                        &proplen);
     756         [ #  # ]:          0 :                 if (!prop)
     757                 :          0 :                         prop = of_get_property(pool_node,
     758                 :            :                                                "fsl,bpool-ethernet-cfg",
     759                 :            :                                                &proplen);
     760         [ #  # ]:          0 :                 if (!prop) {
     761                 :            :                         /* It's OK for there to be no bpool-cfg */
     762                 :          0 :                         bpool->count = bpool->size = bpool->addr = 0;
     763                 :            :                 } else {
     764         [ #  # ]:          0 :                         assert(proplen == (6 * sizeof(*prop)));
     765                 :          0 :                         na = of_n_addr_cells(mac_node);
     766                 :            :                         /* Get rid of endianness (issues).
     767                 :            :                          * Convert to host byte order
     768                 :            :                          */
     769                 :          0 :                         bpool_host[0] = of_read_number(&prop[0], na);
     770                 :          0 :                         bpool_host[1] = of_read_number(&prop[1], na);
     771                 :          0 :                         bpool_host[2] = of_read_number(&prop[2], na);
     772                 :          0 :                         bpool_host[3] = of_read_number(&prop[3], na);
     773                 :          0 :                         bpool_host[4] = of_read_number(&prop[4], na);
     774                 :          0 :                         bpool_host[5] = of_read_number(&prop[5], na);
     775                 :            : 
     776                 :          0 :                         bpool->count = ((uint64_t)bpool_host[0] << 32) |
     777                 :            :                                         bpool_host[1];
     778                 :          0 :                         bpool->size = ((uint64_t)bpool_host[2] << 32) |
     779                 :            :                                         bpool_host[3];
     780                 :          0 :                         bpool->addr = ((uint64_t)bpool_host[4] << 32) |
     781                 :            :                                         bpool_host[5];
     782                 :            :                 }
     783                 :            :                 /* Parsing of the pool is complete, add it to the interface
     784                 :            :                  * list.
     785                 :            :                  */
     786                 :          0 :                 list_add_tail(&bpool->node, &__if->__if.bpool_list);
     787                 :          0 :                 lenp -= sizeof(phandle);
     788                 :          0 :                 pools_phandle++;
     789                 :            :         }
     790                 :            : 
     791         [ #  # ]:          0 :         if (is_shared)
     792                 :          0 :                 __if->__if.is_shared_mac = 1;
     793                 :            : 
     794                 :          0 : oh_init_done:
     795                 :          0 :         fman_if_vsp_init(__if);
     796                 :            : 
     797                 :            :         /* Parsing of the network interface is complete, add it to the list */
     798                 :          0 :         DPAA_BUS_LOG(DEBUG, "Found %s, Tx Channel = %x, FMAN = %x,"
     799                 :            :                     "Port ID = %x",
     800                 :            :                     dname, __if->__if.tx_channel_id, __if->__if.fman->idx,
     801                 :            :                     __if->__if.mac_idx);
     802                 :            : 
     803                 :            :         /* Don't add OH port to the port list since they will be used by ONIC
     804                 :            :          * ports.
     805                 :            :          */
     806         [ #  # ]:          0 :         if (!is_offline)
     807                 :          0 :                 list_add_tail(&__if->__if.node, &__ifs);
     808                 :            : 
     809                 :            :         return 0;
     810                 :          0 : err:
     811                 :          0 :         if_destructor(__if);
     812                 :          0 :         return _errno;
     813                 :            : }
     814                 :            : 
     815                 :          0 : static int fman_if_init_onic(const struct device_node *dpa_node)
     816                 :            : {
     817                 :            :         struct __fman_if *__if;
     818                 :            :         struct fman_if_bpool *bpool;
     819                 :            :         const phandle *tx_pools_phandle;
     820                 :            :         const phandle *tx_channel_id, *mac_addr, *cell_idx;
     821                 :            :         const phandle *rx_phandle;
     822                 :            :         const struct device_node *pool_node;
     823                 :            :         size_t lenp;
     824                 :            :         int _errno;
     825                 :            :         const phandle *p_onic_oh_nodes = NULL;
     826                 :            :         const struct device_node *rx_oh_node = NULL;
     827                 :            :         const struct device_node *tx_oh_node = NULL;
     828                 :            :         const phandle *p_fman_rx_oh_node = NULL, *p_fman_tx_oh_node = NULL;
     829                 :            :         const struct device_node *fman_rx_oh_node = NULL;
     830                 :            :         const struct device_node *fman_tx_oh_node = NULL;
     831                 :            :         const struct device_node *fman_node;
     832                 :            :         uint32_t na = OF_DEFAULT_NA;
     833                 :            :         uint64_t rx_phandle_host[4] = {0};
     834                 :            :         uint64_t cell_idx_host = 0;
     835                 :            :         struct __fman *fman, *tmp_fman;
     836                 :            :         int find_fman = false;
     837                 :            : 
     838         [ #  # ]:          0 :         if (of_device_is_available(dpa_node) == false)
     839                 :            :                 return 0;
     840                 :            : 
     841         [ #  # ]:          0 :         if (!of_device_is_compatible(dpa_node, "fsl,dpa-ethernet-generic"))
     842                 :            :                 return 0;
     843                 :            : 
     844                 :            :         /* Allocate an object for this network interface */
     845                 :          0 :         __if = rte_malloc(NULL, sizeof(*__if), RTE_CACHE_LINE_SIZE);
     846         [ #  # ]:          0 :         if (!__if) {
     847                 :          0 :                 FMAN_ERR(-ENOMEM, "malloc(%zu)", sizeof(*__if));
     848                 :          0 :                 goto err;
     849                 :            :         }
     850                 :            :         memset(__if, 0, sizeof(*__if));
     851                 :            : 
     852                 :          0 :         INIT_LIST_HEAD(&__if->__if.bpool_list);
     853                 :            : 
     854                 :          0 :         strlcpy(__if->node_name, dpa_node->name, IF_NAME_MAX_LEN - 1);
     855                 :          0 :         __if->node_name[IF_NAME_MAX_LEN - 1] = '\0';
     856                 :            : 
     857                 :          0 :         strlcpy(__if->node_path, dpa_node->full_name, PATH_MAX - 1);
     858                 :          0 :         __if->node_path[PATH_MAX - 1] = '\0';
     859                 :            : 
     860                 :            :         /* Mac node is onic */
     861                 :          0 :         __if->__if.is_memac = 0;
     862                 :          0 :         __if->__if.mac_type = fman_onic;
     863                 :            : 
     864                 :            :         /* Extract the MAC address for linux peer */
     865                 :          0 :         mac_addr = of_get_property(dpa_node, "local-mac-address", &lenp);
     866         [ #  # ]:          0 :         if (!mac_addr) {
     867                 :          0 :                 FMAN_ERR(-EINVAL, "%s: no local-mac-address",
     868                 :            :                          dpa_node->full_name);
     869                 :          0 :                 goto err;
     870                 :            :         }
     871                 :            : 
     872                 :          0 :         memcpy(&__if->__if.onic_info.peer_mac, mac_addr, ETHER_ADDR_LEN);
     873                 :            : 
     874                 :            :         /* Extract the Rx port (it's the first of the two port handles)
     875                 :            :          * and get its channel ID.
     876                 :            :          */
     877                 :          0 :         p_onic_oh_nodes = of_get_property(dpa_node, "fsl,oh-ports", &lenp);
     878         [ #  # ]:          0 :         if (!p_onic_oh_nodes) {
     879                 :          0 :                 FMAN_ERR(-EINVAL, "%s: couldn't get p_onic_oh_nodes",
     880                 :            :                          dpa_node->full_name);
     881                 :          0 :                 goto err;
     882                 :            :         }
     883                 :            : 
     884                 :          0 :         rx_oh_node = of_find_node_by_phandle(p_onic_oh_nodes[0]);
     885         [ #  # ]:          0 :         if (!rx_oh_node) {
     886                 :          0 :                 FMAN_ERR(-EINVAL, "%s: couldn't get rx_oh_node",
     887                 :            :                          dpa_node->full_name);
     888                 :          0 :                 goto err;
     889                 :            :         }
     890                 :            : 
     891                 :          0 :         p_fman_rx_oh_node = of_get_property(rx_oh_node, "fsl,fman-oh-port",
     892                 :            :                                             &lenp);
     893         [ #  # ]:          0 :         if (!p_fman_rx_oh_node) {
     894                 :          0 :                 FMAN_ERR(-EINVAL, "%s: couldn't get p_fman_rx_oh_node",
     895                 :            :                          rx_oh_node->full_name);
     896                 :          0 :                 goto err;
     897                 :            :         }
     898                 :            : 
     899                 :          0 :         fman_rx_oh_node = of_find_node_by_phandle(*p_fman_rx_oh_node);
     900         [ #  # ]:          0 :         if (!fman_rx_oh_node) {
     901                 :          0 :                 FMAN_ERR(-EINVAL, "%s: couldn't get fman_rx_oh_node",
     902                 :            :                          rx_oh_node->full_name);
     903                 :          0 :                 goto err;
     904                 :            :         }
     905                 :            : 
     906                 :          0 :         tx_channel_id = of_get_property(fman_rx_oh_node, "fsl,qman-channel-id",
     907                 :            :                                         &lenp);
     908         [ #  # ]:          0 :         if (!tx_channel_id) {
     909                 :          0 :                 FMAN_ERR(-EINVAL, "%s: no fsl-qman-channel-id",
     910                 :            :                          rx_oh_node->full_name);
     911                 :          0 :                 goto err;
     912                 :            :         }
     913         [ #  # ]:          0 :         assert(lenp == sizeof(*tx_channel_id));
     914                 :            : 
     915                 :          0 :         __if->__if.tx_channel_id = of_read_number(tx_channel_id, na);
     916                 :            : 
     917                 :            :         /* Extract the FQs from which oNIC driver in Linux is dequeuing */
     918                 :          0 :         rx_phandle = of_get_property(rx_oh_node, "fsl,qman-frame-queues-oh",
     919                 :            :                                      &lenp);
     920         [ #  # ]:          0 :         if (!rx_phandle) {
     921                 :          0 :                 FMAN_ERR(-EINVAL, "%s: no fsl,qman-frame-queues-oh",
     922                 :            :                          rx_oh_node->full_name);
     923                 :          0 :                 goto err;
     924                 :            :         }
     925         [ #  # ]:          0 :         assert(lenp == (4 * sizeof(phandle)));
     926                 :            : 
     927                 :          0 :         __if->__if.onic_info.rx_start = of_read_number(&rx_phandle[2], na);
     928                 :          0 :         __if->__if.onic_info.rx_count = of_read_number(&rx_phandle[3], na);
     929                 :            : 
     930                 :            :         /* Extract the Rx FQIDs */
     931                 :          0 :         tx_oh_node = of_find_node_by_phandle(p_onic_oh_nodes[1]);
     932         [ #  # ]:          0 :         if (!tx_oh_node) {
     933                 :          0 :                 FMAN_ERR(-EINVAL, "%s: couldn't get tx_oh_node",
     934                 :            :                          dpa_node->full_name);
     935                 :          0 :                 goto err;
     936                 :            :         }
     937                 :            : 
     938                 :          0 :         p_fman_tx_oh_node = of_get_property(tx_oh_node, "fsl,fman-oh-port",
     939                 :            :                                             &lenp);
     940         [ #  # ]:          0 :         if (!p_fman_tx_oh_node) {
     941                 :          0 :                 FMAN_ERR(-EINVAL, "%s: couldn't get p_fman_tx_oh_node",
     942                 :            :                          tx_oh_node->full_name);
     943                 :          0 :                 goto err;
     944                 :            :         }
     945                 :            : 
     946                 :          0 :         fman_tx_oh_node = of_find_node_by_phandle(*p_fman_tx_oh_node);
     947         [ #  # ]:          0 :         if (!fman_tx_oh_node) {
     948                 :          0 :                 FMAN_ERR(-EINVAL, "%s: couldn't get fman_tx_oh_node",
     949                 :            :                          tx_oh_node->full_name);
     950                 :          0 :                 goto err;
     951                 :            :         }
     952                 :            : 
     953                 :          0 :         cell_idx = of_get_property(fman_tx_oh_node, "cell-index", &lenp);
     954         [ #  # ]:          0 :         if (!cell_idx) {
     955                 :          0 :                 FMAN_ERR(-ENXIO, "%s: no cell-index)", tx_oh_node->full_name);
     956                 :          0 :                 goto err;
     957                 :            :         }
     958         [ #  # ]:          0 :         assert(lenp == sizeof(*cell_idx));
     959                 :            : 
     960                 :            :         cell_idx_host = of_read_number(cell_idx, lenp / sizeof(phandle));
     961                 :          0 :         __if->__if.mac_idx = cell_idx_host;
     962                 :            : 
     963                 :          0 :         fman_node = of_get_parent(fman_tx_oh_node);
     964         [ #  # ]:          0 :         list_for_each_entry_safe(fman, tmp_fman, &__fmans, node) {
     965         [ #  # ]:          0 :                 if (fman_node == fman->fman_node) {
     966                 :            :                         find_fman = true;
     967                 :            :                         break;
     968                 :            :                 }
     969                 :            :         }
     970         [ #  # ]:          0 :         if (!find_fman) {
     971                 :          0 :                 FMAN_ERR(-ENXIO, "Failed to get parent of %s",
     972                 :            :                         fman_tx_oh_node->full_name);
     973                 :          0 :                 goto err;
     974                 :            :         }
     975                 :          0 :         __if->__if.fman = fman;
     976                 :            : 
     977                 :          0 :         rx_phandle = of_get_property(tx_oh_node, "fsl,qman-frame-queues-oh",
     978                 :            :                                      &lenp);
     979         [ #  # ]:          0 :         if (!rx_phandle) {
     980                 :          0 :                 FMAN_ERR(-EINVAL, "%s: no fsl,qman-frame-queues-oh",
     981                 :            :                          dpa_node->full_name);
     982                 :          0 :                 goto err;
     983                 :            :         }
     984         [ #  # ]:          0 :         assert(lenp == (4 * sizeof(phandle)));
     985                 :            : 
     986                 :            :         rx_phandle_host[0] = of_read_number(&rx_phandle[0], na);
     987                 :          0 :         rx_phandle_host[1] = of_read_number(&rx_phandle[1], na);
     988                 :          0 :         rx_phandle_host[2] = of_read_number(&rx_phandle[2], na);
     989                 :          0 :         rx_phandle_host[3] = of_read_number(&rx_phandle[3], na);
     990                 :            : 
     991   [ #  #  #  # ]:          0 :         assert((rx_phandle_host[1] == 1) && (rx_phandle_host[3] == 1));
     992                 :            : 
     993                 :          0 :         __if->__if.fqid_rx_err = rx_phandle_host[0];
     994                 :          0 :         __if->__if.fqid_rx_def = rx_phandle_host[2];
     995                 :            : 
     996                 :            :         /* Don't Extract the Tx FQIDs */
     997                 :          0 :         __if->__if.fqid_tx_err = 0;
     998                 :          0 :         __if->__if.fqid_tx_confirm = 0;
     999                 :            : 
    1000                 :            :         /* Obtain the buffer pool nodes used by Tx OH port */
    1001                 :          0 :         tx_pools_phandle = of_get_property(tx_oh_node, "fsl,bman-buffer-pools",
    1002                 :            :                         &lenp);
    1003         [ #  # ]:          0 :         if (!tx_pools_phandle) {
    1004                 :          0 :                 FMAN_ERR(-EINVAL, "%s: no fsl,bman-buffer-pools",
    1005                 :            :                          tx_oh_node->full_name);
    1006                 :          0 :                 goto err;
    1007                 :            :         }
    1008   [ #  #  #  # ]:          0 :         assert(lenp && !(lenp % sizeof(phandle)));
    1009                 :            : 
    1010                 :            :         /* For each pool, parse the corresponding node and add a pool object to
    1011                 :            :          * the interface's "bpool_list".
    1012                 :            :          */
    1013                 :            : 
    1014         [ #  # ]:          0 :         while (lenp) {
    1015                 :            :                 size_t proplen;
    1016                 :            :                 const phandle *prop;
    1017                 :            :                 uint64_t bpool_host[6] = {0};
    1018                 :            : 
    1019                 :            :                 /* Allocate an object for the pool */
    1020                 :          0 :                 bpool = rte_malloc(NULL, sizeof(*bpool), RTE_CACHE_LINE_SIZE);
    1021         [ #  # ]:          0 :                 if (!bpool) {
    1022                 :          0 :                         FMAN_ERR(-ENOMEM, "malloc(%zu)", sizeof(*bpool));
    1023                 :          0 :                         goto err;
    1024                 :            :                 }
    1025                 :            : 
    1026                 :            :                 /* Find the pool node */
    1027                 :          0 :                 pool_node = of_find_node_by_phandle(*tx_pools_phandle);
    1028         [ #  # ]:          0 :                 if (!pool_node) {
    1029                 :          0 :                         FMAN_ERR(-ENXIO, "%s: bad fsl,bman-buffer-pools",
    1030                 :            :                                  tx_oh_node->full_name);
    1031                 :          0 :                         rte_free(bpool);
    1032                 :          0 :                         goto err;
    1033                 :            :                 }
    1034                 :            : 
    1035                 :            :                 /* Extract the BPID property */
    1036                 :          0 :                 prop = of_get_property(pool_node, "fsl,bpid", &proplen);
    1037         [ #  # ]:          0 :                 if (!prop) {
    1038                 :          0 :                         FMAN_ERR(-EINVAL, "%s: no fsl,bpid",
    1039                 :            :                                  pool_node->full_name);
    1040                 :          0 :                         rte_free(bpool);
    1041                 :          0 :                         goto err;
    1042                 :            :                 }
    1043         [ #  # ]:          0 :                 assert(proplen == sizeof(*prop));
    1044                 :            : 
    1045                 :          0 :                 bpool->bpid = of_read_number(prop, na);
    1046                 :            : 
    1047                 :            :                 /* Extract the cfg property (count/size/addr). "fsl,bpool-cfg"
    1048                 :            :                  * indicates for the Bman driver to seed the pool.
    1049                 :            :                  * "fsl,bpool-ethernet-cfg" is used by the network driver. The
    1050                 :            :                  * two are mutually exclusive, so check for either of them.
    1051                 :            :                  */
    1052                 :            : 
    1053                 :          0 :                 prop = of_get_property(pool_node, "fsl,bpool-cfg", &proplen);
    1054         [ #  # ]:          0 :                 if (!prop)
    1055                 :          0 :                         prop = of_get_property(pool_node,
    1056                 :            :                                                "fsl,bpool-ethernet-cfg",
    1057                 :            :                                                &proplen);
    1058         [ #  # ]:          0 :                 if (!prop) {
    1059                 :            :                         /* It's OK for there to be no bpool-cfg */
    1060                 :          0 :                         bpool->count = bpool->size = bpool->addr = 0;
    1061                 :            :                 } else {
    1062         [ #  # ]:          0 :                         assert(proplen == (6 * sizeof(*prop)));
    1063                 :            : 
    1064                 :            :                         bpool_host[0] = of_read_number(&prop[0], na);
    1065                 :          0 :                         bpool_host[1] = of_read_number(&prop[1], na);
    1066                 :          0 :                         bpool_host[2] = of_read_number(&prop[2], na);
    1067                 :          0 :                         bpool_host[3] = of_read_number(&prop[3], na);
    1068                 :          0 :                         bpool_host[4] = of_read_number(&prop[4], na);
    1069                 :          0 :                         bpool_host[5] = of_read_number(&prop[5], na);
    1070                 :            : 
    1071                 :          0 :                         bpool->count = ((uint64_t)bpool_host[0] << 32) |
    1072                 :            :                                        bpool_host[1];
    1073                 :          0 :                         bpool->size = ((uint64_t)bpool_host[2] << 32) |
    1074                 :            :                                       bpool_host[3];
    1075                 :          0 :                         bpool->addr = ((uint64_t)bpool_host[4] << 32) |
    1076                 :            :                                       bpool_host[5];
    1077                 :            :                 }
    1078                 :            : 
    1079                 :            :                 /* Parsing of the pool is complete, add it to the interface
    1080                 :            :                  * list.
    1081                 :            :                  */
    1082                 :          0 :                 list_add_tail(&bpool->node, &__if->__if.bpool_list);
    1083                 :          0 :                 lenp -= sizeof(phandle);
    1084                 :          0 :                 tx_pools_phandle++;
    1085                 :            :         }
    1086                 :            : 
    1087                 :          0 :         fman_if_vsp_init(__if);
    1088                 :            : 
    1089                 :            :         /* Parsing of the network interface is complete, add it to the list. */
    1090                 :          0 :         DPAA_BUS_DEBUG("Found %s, Tx Channel = %x, FMAN = %x, Port ID = %x",
    1091                 :            :                        dpa_node->full_name, __if->__if.tx_channel_id,
    1092                 :            :                        __if->__if.fman->idx, __if->__if.mac_idx);
    1093                 :            : 
    1094                 :          0 :         list_add_tail(&__if->__if.node, &__ifs);
    1095                 :          0 :         return 0;
    1096                 :          0 : err:
    1097                 :          0 :         if_destructor(__if);
    1098                 :          0 :         return _errno;
    1099                 :            : }
    1100                 :            : 
    1101                 :            : int
    1102                 :          0 : fman_init(void)
    1103                 :            : {
    1104                 :            :         const struct device_node *dpa_node, *parent_node, *fman_node;
    1105                 :            :         int _errno, fd, ret;
    1106                 :            : 
    1107         [ #  # ]:          0 :         if (fman_ccsr_map_fd >= 0)
    1108                 :            :                 return 0;
    1109                 :            : 
    1110                 :            :         fd = open(FMAN_DEVICE_PATH, O_RDWR);
    1111         [ #  # ]:          0 :         if (unlikely(fd < 0)) {
    1112                 :          0 :                 DPAA_BUS_LOG(ERR, "Unable to open %s: %s", FMAN_DEVICE_PATH, strerror(errno));
    1113                 :          0 :                 return fd;
    1114                 :            :         }
    1115                 :          0 :         fman_ccsr_map_fd = fd;
    1116                 :            : 
    1117                 :          0 :         parent_node = of_find_compatible_node(NULL, NULL, "fsl,dpaa");
    1118         [ #  # ]:          0 :         if (!parent_node) {
    1119                 :          0 :                 DPAA_BUS_LOG(ERR, "Unable to find fsl,dpaa node");
    1120                 :          0 :                 return -ENODEV;
    1121                 :            :         }
    1122                 :            : 
    1123         [ #  # ]:          0 :         for_each_compatible_node(fman_node, NULL, "fsl,fman") {
    1124                 :          0 :                 ret = _fman_init(fman_node, fd);
    1125         [ #  # ]:          0 :                 if (ret)
    1126                 :          0 :                         return ret;
    1127                 :            :         }
    1128                 :            : 
    1129         [ #  # ]:          0 :         for_each_child_node(parent_node, dpa_node) {
    1130                 :          0 :                 _errno = fman_if_init(dpa_node, fd);
    1131         [ #  # ]:          0 :                 if (_errno) {
    1132                 :          0 :                         FMAN_ERR(_errno, "if_init(%s)", dpa_node->full_name);
    1133                 :          0 :                         return _errno;
    1134                 :            :                 }
    1135                 :            :         }
    1136                 :            : 
    1137         [ #  # ]:          0 :         for_each_compatible_node(dpa_node, NULL, "fsl,dpa-ethernet-generic") {
    1138                 :            :                 /* it is a oNIC interface */
    1139                 :          0 :                 _errno = fman_if_init_onic(dpa_node);
    1140         [ #  # ]:          0 :                 if (_errno)
    1141                 :          0 :                         FMAN_ERR(_errno, "if_init(%s)", dpa_node->full_name);
    1142                 :            :         }
    1143                 :            : 
    1144                 :            :         return 0;
    1145                 :            : }
    1146                 :            : 
    1147                 :            : void
    1148                 :          0 : fman_finish(void)
    1149                 :            : {
    1150                 :            :         struct __fman_if *__if, *tmpif;
    1151                 :            :         struct __fman *fman, *tmpfman;
    1152                 :            :         int _errno;
    1153                 :            :         struct memac_regs *regs;
    1154                 :            :         uint32_t cfg;
    1155                 :            : 
    1156         [ #  # ]:          0 :         assert(fman_ccsr_map_fd != -1);
    1157                 :            : 
    1158         [ #  # ]:          0 :         list_for_each_entry_safe(__if, tmpif, &__ifs, __if.node) {
    1159                 :            :                 /* No need to disable Offline port */
    1160         [ #  # ]:          0 :                 if (__if->__if.mac_type == fman_offline_internal)
    1161                 :          0 :                         continue;
    1162                 :            : 
    1163         [ #  # ]:          0 :                 if (!__if->__if.is_memac) {
    1164                 :          0 :                         DPAA_BUS_ERR("FM%d-MAC%d's MAC is not memac!",
    1165                 :            :                                 __if->__if.fman->idx, __if->__if.mac_idx);
    1166                 :          0 :                         continue;
    1167                 :            :                 }
    1168                 :            : 
    1169                 :            :                 /* disable Rx and Tx */
    1170                 :          0 :                 regs = __if->ccsr_map;
    1171                 :            :                 cfg = in_be32(&regs->command_config);
    1172         [ #  # ]:          0 :                 out_be32(&regs->command_config,
    1173                 :            :                         cfg & (~(MEMAC_RX_ENABLE | MEMAC_TX_ENABLE)));
    1174                 :            : 
    1175                 :            :                 /* release the mapping */
    1176                 :          0 :                 _errno = munmap(__if->ccsr_map, __if->regs_size);
    1177         [ #  # ]:          0 :                 if (unlikely(_errno < 0))
    1178                 :          0 :                         FMAN_ERR(_errno, "munmap() = (%s)", strerror(errno));
    1179                 :          0 :                 DPAA_BUS_INFO("Tearing down %s", __if->node_path);
    1180                 :          0 :                 list_del(&__if->__if.node);
    1181                 :          0 :                 rte_free(__if);
    1182                 :            :         }
    1183                 :            : 
    1184         [ #  # ]:          0 :         list_for_each_entry_safe(fman, tmpfman, &__fmans, node) {
    1185                 :            :                 /* release the mapping */
    1186                 :          0 :                 _errno = munmap(fman->ccsr_vir, fman->ccsr_size);
    1187         [ #  # ]:          0 :                 if (unlikely(_errno < 0))
    1188                 :          0 :                         FMAN_ERR(_errno, "munmap() = (%s)", strerror(errno));
    1189                 :          0 :                 _errno = munmap(fman->time_vir, fman->time_size);
    1190         [ #  # ]:          0 :                 if (unlikely(_errno < 0))
    1191                 :          0 :                         FMAN_ERR(_errno, "munmap() = (%s)", strerror(errno));
    1192                 :          0 :                 list_del(&fman->node);
    1193                 :          0 :                 rte_free(fman);
    1194                 :            :         }
    1195                 :            : 
    1196                 :          0 :         close(fman_ccsr_map_fd);
    1197                 :          0 :         fman_ccsr_map_fd = -1;
    1198                 :          0 : }

Generated by: LCOV version 1.14