bus/dpaa: introducing FMan configurations
[dpdk.git] / drivers / bus / dpaa / base / fman / fman.c
1 /*-
2  * This file is provided under a dual BSD/GPLv2 license. When using or
3  * redistributing this file, you may do so under either license.
4  *
5  *   BSD LICENSE
6  *
7  * Copyright 2010-2016 Freescale Semiconductor Inc.
8  * Copyright 2017 NXP.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions are met:
12  * * Redistributions of source code must retain the above copyright
13  * notice, this list of conditions and the following disclaimer.
14  * * Redistributions in binary form must reproduce the above copyright
15  * notice, this list of conditions and the following disclaimer in the
16  * documentation and/or other materials provided with the distribution.
17  * * Neither the name of the above-listed copyright holders nor the
18  * names of any contributors may be used to endorse or promote products
19  * derived from this software without specific prior written permission.
20  *
21  *   GPL LICENSE SUMMARY
22  *
23  * ALTERNATIVELY, this software may be distributed under the terms of the
24  * GNU General Public License ("GPL") as published by the Free Software
25  * Foundation, either version 2 of that License or (at your option) any
26  * later version.
27  *
28  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
29  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
30  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
31  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
32  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
33  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
34  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
35  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
36  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
37  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
38  * POSSIBILITY OF SUCH DAMAGE.
39  */
40
41 #include <sys/types.h>
42 #include <sys/ioctl.h>
43 #include <ifaddrs.h>
44
45 #include <rte_malloc.h>
46
47 /* This header declares the driver interface we implement */
48 #include <fman.h>
49 #include <of.h>
50 #include <rte_dpaa_logs.h>
51
52 #define QMI_PORT_REGS_OFFSET            0x400
53
54 /* CCSR map address to access ccsr based register */
55 void *fman_ccsr_map;
56 /* fman version info */
57 u16 fman_ip_rev;
58 static int get_once;
59 u32 fman_dealloc_bufs_mask_hi;
60 u32 fman_dealloc_bufs_mask_lo;
61
62 int fman_ccsr_map_fd = -1;
63 static COMPAT_LIST_HEAD(__ifs);
64
65 /* This is the (const) global variable that callers have read-only access to.
66  * Internally, we have read-write access directly to __ifs.
67  */
68 const struct list_head *fman_if_list = &__ifs;
69
70 static void
71 if_destructor(struct __fman_if *__if)
72 {
73         struct fman_if_bpool *bp, *tmpbp;
74
75         if (__if->__if.mac_type == fman_offline)
76                 goto cleanup;
77
78         list_for_each_entry_safe(bp, tmpbp, &__if->__if.bpool_list, node) {
79                 list_del(&bp->node);
80                 rte_free(bp);
81         }
82 cleanup:
83         rte_free(__if);
84 }
85
86 static int
87 fman_get_ip_rev(const struct device_node *fman_node)
88 {
89         const uint32_t *fman_addr;
90         uint64_t phys_addr;
91         uint64_t regs_size;
92         uint32_t ip_rev_1;
93         int _errno;
94
95         fman_addr = of_get_address(fman_node, 0, &regs_size, NULL);
96         if (!fman_addr) {
97                 pr_err("of_get_address cannot return fman address\n");
98                 return -EINVAL;
99         }
100         phys_addr = of_translate_address(fman_node, fman_addr);
101         if (!phys_addr) {
102                 pr_err("of_translate_address failed\n");
103                 return -EINVAL;
104         }
105         fman_ccsr_map = mmap(NULL, regs_size, PROT_READ | PROT_WRITE,
106                              MAP_SHARED, fman_ccsr_map_fd, phys_addr);
107         if (fman_ccsr_map == MAP_FAILED) {
108                 pr_err("Can not map FMan ccsr base");
109                 return -EINVAL;
110         }
111
112         ip_rev_1 = in_be32(fman_ccsr_map + FMAN_IP_REV_1);
113         fman_ip_rev = (ip_rev_1 & FMAN_IP_REV_1_MAJOR_MASK) >>
114                         FMAN_IP_REV_1_MAJOR_SHIFT;
115
116         _errno = munmap(fman_ccsr_map, regs_size);
117         if (_errno)
118                 pr_err("munmap() of FMan ccsr failed");
119
120         return 0;
121 }
122
123 static int
124 fman_get_mac_index(uint64_t regs_addr_host, uint8_t *mac_idx)
125 {
126         int ret = 0;
127
128         /*
129          * MAC1 : E_0000h
130          * MAC2 : E_2000h
131          * MAC3 : E_4000h
132          * MAC4 : E_6000h
133          * MAC5 : E_8000h
134          * MAC6 : E_A000h
135          * MAC7 : E_C000h
136          * MAC8 : E_E000h
137          * MAC9 : F_0000h
138          * MAC10: F_2000h
139          */
140         switch (regs_addr_host) {
141         case 0xE0000:
142                 *mac_idx = 1;
143                 break;
144         case 0xE2000:
145                 *mac_idx = 2;
146                 break;
147         case 0xE4000:
148                 *mac_idx = 3;
149                 break;
150         case 0xE6000:
151                 *mac_idx = 4;
152                 break;
153         case 0xE8000:
154                 *mac_idx = 5;
155                 break;
156         case 0xEA000:
157                 *mac_idx = 6;
158                 break;
159         case 0xEC000:
160                 *mac_idx = 7;
161                 break;
162         case 0xEE000:
163                 *mac_idx = 8;
164                 break;
165         case 0xF0000:
166                 *mac_idx = 9;
167                 break;
168         case 0xF2000:
169                 *mac_idx = 10;
170                 break;
171         default:
172                 ret = -EINVAL;
173         }
174
175         return ret;
176 }
177
178 static int
179 fman_if_init(const struct device_node *dpa_node)
180 {
181         const char *rprop, *mprop;
182         uint64_t phys_addr;
183         struct __fman_if *__if;
184         struct fman_if_bpool *bpool;
185
186         const phandle *mac_phandle, *ports_phandle, *pools_phandle;
187         const phandle *tx_channel_id = NULL, *mac_addr, *cell_idx;
188         const phandle *rx_phandle, *tx_phandle;
189         uint64_t tx_phandle_host[4] = {0};
190         uint64_t rx_phandle_host[4] = {0};
191         uint64_t regs_addr_host = 0;
192         uint64_t cell_idx_host = 0;
193
194         const struct device_node *mac_node = NULL, *tx_node;
195         const struct device_node *pool_node, *fman_node, *rx_node;
196         const uint32_t *regs_addr = NULL;
197         const char *mname, *fname;
198         const char *dname = dpa_node->full_name;
199         size_t lenp;
200         int _errno;
201         const char *char_prop;
202         uint32_t na;
203
204         if (of_device_is_available(dpa_node) == false)
205                 return 0;
206
207         rprop = "fsl,qman-frame-queues-rx";
208         mprop = "fsl,fman-mac";
209
210         /* Allocate an object for this network interface */
211         __if = rte_malloc(NULL, sizeof(*__if), RTE_CACHE_LINE_SIZE);
212         if (!__if) {
213                 FMAN_ERR(-ENOMEM, "malloc(%zu)\n", sizeof(*__if));
214                 goto err;
215         }
216         memset(__if, 0, sizeof(*__if));
217         INIT_LIST_HEAD(&__if->__if.bpool_list);
218         strncpy(__if->node_path, dpa_node->full_name, PATH_MAX - 1);
219         __if->node_path[PATH_MAX - 1] = '\0';
220
221         /* Obtain the MAC node used by this interface except macless */
222         mac_phandle = of_get_property(dpa_node, mprop, &lenp);
223         if (!mac_phandle) {
224                 FMAN_ERR(-EINVAL, "%s: no %s\n", dname, mprop);
225                 goto err;
226         }
227         assert(lenp == sizeof(phandle));
228         mac_node = of_find_node_by_phandle(*mac_phandle);
229         if (!mac_node) {
230                 FMAN_ERR(-ENXIO, "%s: bad 'fsl,fman-mac\n", dname);
231                 goto err;
232         }
233         mname = mac_node->full_name;
234
235         /* Map the CCSR regs for the MAC node */
236         regs_addr = of_get_address(mac_node, 0, &__if->regs_size, NULL);
237         if (!regs_addr) {
238                 FMAN_ERR(-EINVAL, "of_get_address(%s)\n", mname);
239                 goto err;
240         }
241         phys_addr = of_translate_address(mac_node, regs_addr);
242         if (!phys_addr) {
243                 FMAN_ERR(-EINVAL, "of_translate_address(%s, %p)\n",
244                          mname, regs_addr);
245                 goto err;
246         }
247         __if->ccsr_map = mmap(NULL, __if->regs_size,
248                               PROT_READ | PROT_WRITE, MAP_SHARED,
249                               fman_ccsr_map_fd, phys_addr);
250         if (__if->ccsr_map == MAP_FAILED) {
251                 FMAN_ERR(-errno, "mmap(0x%"PRIx64")\n", phys_addr);
252                 goto err;
253         }
254         na = of_n_addr_cells(mac_node);
255         /* Get rid of endianness (issues). Convert to host byte order */
256         regs_addr_host = of_read_number(regs_addr, na);
257
258
259         /* Get the index of the Fman this i/f belongs to */
260         fman_node = of_get_parent(mac_node);
261         na = of_n_addr_cells(mac_node);
262         if (!fman_node) {
263                 FMAN_ERR(-ENXIO, "of_get_parent(%s)\n", mname);
264                 goto err;
265         }
266         fname = fman_node->full_name;
267         cell_idx = of_get_property(fman_node, "cell-index", &lenp);
268         if (!cell_idx) {
269                 FMAN_ERR(-ENXIO, "%s: no cell-index)\n", fname);
270                 goto err;
271         }
272         assert(lenp == sizeof(*cell_idx));
273         cell_idx_host = of_read_number(cell_idx, lenp / sizeof(phandle));
274         __if->__if.fman_idx = cell_idx_host;
275         if (!get_once) {
276                 _errno = fman_get_ip_rev(fman_node);
277                 if (_errno) {
278                         FMAN_ERR(-ENXIO, "%s: ip_rev is not available\n",
279                                  fname);
280                         goto err;
281                 }
282         }
283
284         if (fman_ip_rev >= FMAN_V3) {
285                 /*
286                  * Set A2V, OVOM, EBD bits in contextA to allow external
287                  * buffer deallocation by fman.
288                  */
289                 fman_dealloc_bufs_mask_hi = FMAN_V3_CONTEXTA_EN_A2V |
290                                                 FMAN_V3_CONTEXTA_EN_OVOM;
291                 fman_dealloc_bufs_mask_lo = FMAN_V3_CONTEXTA_EN_EBD;
292         } else {
293                 fman_dealloc_bufs_mask_hi = 0;
294                 fman_dealloc_bufs_mask_lo = 0;
295         }
296         /* Is the MAC node 1G, 10G? */
297         __if->__if.is_memac = 0;
298
299         if (of_device_is_compatible(mac_node, "fsl,fman-1g-mac"))
300                 __if->__if.mac_type = fman_mac_1g;
301         else if (of_device_is_compatible(mac_node, "fsl,fman-10g-mac"))
302                 __if->__if.mac_type = fman_mac_10g;
303         else if (of_device_is_compatible(mac_node, "fsl,fman-memac")) {
304                 __if->__if.is_memac = 1;
305                 char_prop = of_get_property(mac_node, "phy-connection-type",
306                                             NULL);
307                 if (!char_prop) {
308                         printf("memac: unknown MII type assuming 1G\n");
309                         /* Right now forcing memac to 1g in case of error*/
310                         __if->__if.mac_type = fman_mac_1g;
311                 } else {
312                         if (strstr(char_prop, "sgmii"))
313                                 __if->__if.mac_type = fman_mac_1g;
314                         else if (strstr(char_prop, "rgmii")) {
315                                 __if->__if.mac_type = fman_mac_1g;
316                                 __if->__if.is_rgmii = 1;
317                         } else if (strstr(char_prop, "xgmii"))
318                                 __if->__if.mac_type = fman_mac_10g;
319                 }
320         } else {
321                 FMAN_ERR(-EINVAL, "%s: unknown MAC type\n", mname);
322                 goto err;
323         }
324
325         /*
326          * For MAC ports, we cannot rely on cell-index. In
327          * T2080, two of the 10G ports on single FMAN have same
328          * duplicate cell-indexes as the other two 10G ports on
329          * same FMAN. Hence, we now rely upon addresses of the
330          * ports from device tree to deduce the index.
331          */
332
333         _errno = fman_get_mac_index(regs_addr_host, &__if->__if.mac_idx);
334         if (_errno) {
335                 FMAN_ERR(-EINVAL, "Invalid register address: %lu",
336                          regs_addr_host);
337                 goto err;
338         }
339
340         /* Extract the MAC address for private and shared interfaces */
341         mac_addr = of_get_property(mac_node, "local-mac-address",
342                                    &lenp);
343         if (!mac_addr) {
344                 FMAN_ERR(-EINVAL, "%s: no local-mac-address\n",
345                          mname);
346                 goto err;
347         }
348         memcpy(&__if->__if.mac_addr, mac_addr, ETHER_ADDR_LEN);
349
350         /* Extract the Tx port (it's the second of the two port handles)
351          * and get its channel ID
352          */
353         ports_phandle = of_get_property(mac_node, "fsl,port-handles",
354                                         &lenp);
355         if (!ports_phandle)
356                 ports_phandle = of_get_property(mac_node, "fsl,fman-ports",
357                                                 &lenp);
358         if (!ports_phandle) {
359                 FMAN_ERR(-EINVAL, "%s: no fsl,port-handles\n",
360                          mname);
361                 goto err;
362         }
363         assert(lenp == (2 * sizeof(phandle)));
364         tx_node = of_find_node_by_phandle(ports_phandle[1]);
365         if (!tx_node) {
366                 FMAN_ERR(-ENXIO, "%s: bad fsl,port-handle[1]\n", mname);
367                 goto err;
368         }
369         /* Extract the channel ID (from tx-port-handle) */
370         tx_channel_id = of_get_property(tx_node, "fsl,qman-channel-id",
371                                         &lenp);
372         if (!tx_channel_id) {
373                 FMAN_ERR(-EINVAL, "%s: no fsl-qman-channel-id\n",
374                          tx_node->full_name);
375                 goto err;
376         }
377
378         rx_node = of_find_node_by_phandle(ports_phandle[0]);
379         if (!rx_node) {
380                 FMAN_ERR(-ENXIO, "%s: bad fsl,port-handle[0]\n", mname);
381                 goto err;
382         }
383         regs_addr = of_get_address(rx_node, 0, &__if->regs_size, NULL);
384         if (!regs_addr) {
385                 FMAN_ERR(-EINVAL, "of_get_address(%s)\n", mname);
386                 goto err;
387         }
388         phys_addr = of_translate_address(rx_node, regs_addr);
389         if (!phys_addr) {
390                 FMAN_ERR(-EINVAL, "of_translate_address(%s, %p)\n",
391                          mname, regs_addr);
392                 goto err;
393         }
394         __if->bmi_map = mmap(NULL, __if->regs_size,
395                                  PROT_READ | PROT_WRITE, MAP_SHARED,
396                                  fman_ccsr_map_fd, phys_addr);
397         if (__if->bmi_map == MAP_FAILED) {
398                 FMAN_ERR(-errno, "mmap(0x%"PRIx64")\n", phys_addr);
399                 goto err;
400         }
401
402         /* No channel ID for MAC-less */
403         assert(lenp == sizeof(*tx_channel_id));
404         na = of_n_addr_cells(mac_node);
405         __if->__if.tx_channel_id = of_read_number(tx_channel_id, na);
406
407         /* Extract the Rx FQIDs. (Note, the device representation is silly,
408          * there are "counts" that must always be 1.)
409          */
410         rx_phandle = of_get_property(dpa_node, rprop, &lenp);
411         if (!rx_phandle) {
412                 FMAN_ERR(-EINVAL, "%s: no fsl,qman-frame-queues-rx\n", dname);
413                 goto err;
414         }
415
416         assert(lenp == (4 * sizeof(phandle)));
417
418         na = of_n_addr_cells(mac_node);
419         /* Get rid of endianness (issues). Convert to host byte order */
420         rx_phandle_host[0] = of_read_number(&rx_phandle[0], na);
421         rx_phandle_host[1] = of_read_number(&rx_phandle[1], na);
422         rx_phandle_host[2] = of_read_number(&rx_phandle[2], na);
423         rx_phandle_host[3] = of_read_number(&rx_phandle[3], na);
424
425         assert((rx_phandle_host[1] == 1) && (rx_phandle_host[3] == 1));
426         __if->__if.fqid_rx_err = rx_phandle_host[0];
427         __if->__if.fqid_rx_def = rx_phandle_host[2];
428
429         /* Extract the Tx FQIDs */
430         tx_phandle = of_get_property(dpa_node,
431                                      "fsl,qman-frame-queues-tx", &lenp);
432         if (!tx_phandle) {
433                 FMAN_ERR(-EINVAL, "%s: no fsl,qman-frame-queues-tx\n", dname);
434                 goto err;
435         }
436
437         assert(lenp == (4 * sizeof(phandle)));
438         /*TODO: Fix for other cases also */
439         na = of_n_addr_cells(mac_node);
440         /* Get rid of endianness (issues). Convert to host byte order */
441         tx_phandle_host[0] = of_read_number(&tx_phandle[0], na);
442         tx_phandle_host[1] = of_read_number(&tx_phandle[1], na);
443         tx_phandle_host[2] = of_read_number(&tx_phandle[2], na);
444         tx_phandle_host[3] = of_read_number(&tx_phandle[3], na);
445         assert((tx_phandle_host[1] == 1) && (tx_phandle_host[3] == 1));
446         __if->__if.fqid_tx_err = tx_phandle_host[0];
447         __if->__if.fqid_tx_confirm = tx_phandle_host[2];
448
449         /* Obtain the buffer pool nodes used by this interface */
450         pools_phandle = of_get_property(dpa_node, "fsl,bman-buffer-pools",
451                                         &lenp);
452         if (!pools_phandle) {
453                 FMAN_ERR(-EINVAL, "%s: no fsl,bman-buffer-pools\n", dname);
454                 goto err;
455         }
456         /* For each pool, parse the corresponding node and add a pool object
457          * to the interface's "bpool_list"
458          */
459         assert(lenp && !(lenp % sizeof(phandle)));
460         while (lenp) {
461                 size_t proplen;
462                 const phandle *prop;
463                 uint64_t bpid_host = 0;
464                 uint64_t bpool_host[6] = {0};
465                 const char *pname;
466                 /* Allocate an object for the pool */
467                 bpool = rte_malloc(NULL, sizeof(*bpool), RTE_CACHE_LINE_SIZE);
468                 if (!bpool) {
469                         FMAN_ERR(-ENOMEM, "malloc(%zu)\n", sizeof(*bpool));
470                         goto err;
471                 }
472                 /* Find the pool node */
473                 pool_node = of_find_node_by_phandle(*pools_phandle);
474                 if (!pool_node) {
475                         FMAN_ERR(-ENXIO, "%s: bad fsl,bman-buffer-pools\n",
476                                  dname);
477                         goto err;
478                 }
479                 pname = pool_node->full_name;
480                 /* Extract the BPID property */
481                 prop = of_get_property(pool_node, "fsl,bpid", &proplen);
482                 if (!prop) {
483                         FMAN_ERR(-EINVAL, "%s: no fsl,bpid\n", pname);
484                         goto err;
485                 }
486                 assert(proplen == sizeof(*prop));
487                 na = of_n_addr_cells(mac_node);
488                 /* Get rid of endianness (issues).
489                  * Convert to host byte-order
490                  */
491                 bpid_host = of_read_number(prop, na);
492                 bpool->bpid = bpid_host;
493                 /* Extract the cfg property (count/size/addr). "fsl,bpool-cfg"
494                  * indicates for the Bman driver to seed the pool.
495                  * "fsl,bpool-ethernet-cfg" is used by the network driver. The
496                  * two are mutually exclusive, so check for either of them.
497                  */
498                 prop = of_get_property(pool_node, "fsl,bpool-cfg",
499                                        &proplen);
500                 if (!prop)
501                         prop = of_get_property(pool_node,
502                                                "fsl,bpool-ethernet-cfg",
503                                                &proplen);
504                 if (!prop) {
505                         /* It's OK for there to be no bpool-cfg */
506                         bpool->count = bpool->size = bpool->addr = 0;
507                 } else {
508                         assert(proplen == (6 * sizeof(*prop)));
509                         na = of_n_addr_cells(mac_node);
510                         /* Get rid of endianness (issues).
511                          * Convert to host byte order
512                          */
513                         bpool_host[0] = of_read_number(&prop[0], na);
514                         bpool_host[1] = of_read_number(&prop[1], na);
515                         bpool_host[2] = of_read_number(&prop[2], na);
516                         bpool_host[3] = of_read_number(&prop[3], na);
517                         bpool_host[4] = of_read_number(&prop[4], na);
518                         bpool_host[5] = of_read_number(&prop[5], na);
519
520                         bpool->count = ((uint64_t)bpool_host[0] << 32) |
521                                         bpool_host[1];
522                         bpool->size = ((uint64_t)bpool_host[2] << 32) |
523                                         bpool_host[3];
524                         bpool->addr = ((uint64_t)bpool_host[4] << 32) |
525                                         bpool_host[5];
526                 }
527                 /* Parsing of the pool is complete, add it to the interface
528                  * list.
529                  */
530                 list_add_tail(&bpool->node, &__if->__if.bpool_list);
531                 lenp -= sizeof(phandle);
532                 pools_phandle++;
533         }
534
535         /* Parsing of the network interface is complete, add it to the list */
536         DPAA_BUS_LOG(DEBUG, "Found %s, Tx Channel = %x, FMAN = %x,"
537                     "Port ID = %x\n",
538                     dname, __if->__if.tx_channel_id, __if->__if.fman_idx,
539                     __if->__if.mac_idx);
540
541         list_add_tail(&__if->__if.node, &__ifs);
542         return 0;
543 err:
544         if_destructor(__if);
545         return _errno;
546 }
547
548 int
549 fman_init(void)
550 {
551         const struct device_node *dpa_node;
552         int _errno;
553
554         /* If multiple dependencies try to initialise the Fman driver, don't
555          * panic.
556          */
557         if (fman_ccsr_map_fd != -1)
558                 return 0;
559
560         fman_ccsr_map_fd = open(FMAN_DEVICE_PATH, O_RDWR);
561         if (unlikely(fman_ccsr_map_fd < 0)) {
562                 DPAA_BUS_LOG(ERR, "Unable to open (/dev/mem)");
563                 return fman_ccsr_map_fd;
564         }
565
566         for_each_compatible_node(dpa_node, NULL, "fsl,dpa-ethernet-init") {
567                 _errno = fman_if_init(dpa_node);
568                 if (_errno) {
569                         FMAN_ERR(_errno, "if_init(%s)\n", dpa_node->full_name);
570                         goto err;
571                 }
572         }
573
574         return 0;
575 err:
576         fman_finish();
577         return _errno;
578 }
579
580 void
581 fman_finish(void)
582 {
583         struct __fman_if *__if, *tmpif;
584
585         assert(fman_ccsr_map_fd != -1);
586
587         list_for_each_entry_safe(__if, tmpif, &__ifs, __if.node) {
588                 int _errno;
589
590                 /* disable Rx and Tx */
591                 if ((__if->__if.mac_type == fman_mac_1g) &&
592                     (!__if->__if.is_memac))
593                         out_be32(__if->ccsr_map + 0x100,
594                                  in_be32(__if->ccsr_map + 0x100) & ~(u32)0x5);
595                 else
596                         out_be32(__if->ccsr_map + 8,
597                                  in_be32(__if->ccsr_map + 8) & ~(u32)3);
598                 /* release the mapping */
599                 _errno = munmap(__if->ccsr_map, __if->regs_size);
600                 if (unlikely(_errno < 0))
601                         fprintf(stderr, "%s:%hu:%s(): munmap() = %d (%s)\n",
602                                 __FILE__, __LINE__, __func__,
603                                 -errno, strerror(errno));
604                 printf("Tearing down %s\n", __if->node_path);
605                 list_del(&__if->__if.node);
606                 rte_free(__if);
607         }
608
609         close(fman_ccsr_map_fd);
610         fman_ccsr_map_fd = -1;
611 }