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

Generated by: LCOV version 1.14