source: rtems-libbsd/linux/drivers/net/ethernet/freescale/fman/fman_port.c @ 28ee86a

55-freebsd-126-freebsd-12
Last change on this file since 28ee86a was 28ee86a, checked in by Sebastian Huber <sebastian.huber@…>, on 04/27/16 at 09:58:19

Import DPAA driver snapshot

Imported from Freescale Linux repository

git://git.freescale.com/ppc/upstream/linux.git

commit 2774c204cd8bfc56a200ff4dcdfc9cdf5b6fc161.

Linux compatibility layer is partly from FreeBSD.

  • Property mode set to 100644
File size: 49.6 KB
Line 
1#include <machine/rtems-bsd-kernel-space.h>
2
3#include <rtems/bsd/local/opt_dpaa.h>
4
5/*
6 * Copyright 2008 - 2015 Freescale Semiconductor Inc.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions are met:
10 *     * Redistributions of source code must retain the above copyright
11 *       notice, this list of conditions and the following disclaimer.
12 *     * Redistributions in binary form must reproduce the above copyright
13 *       notice, this list of conditions and the following disclaimer in the
14 *       documentation and/or other materials provided with the distribution.
15 *     * Neither the name of Freescale Semiconductor nor the
16 *       names of its contributors may be used to endorse or promote products
17 *       derived from this software without specific prior written permission.
18 *
19 *
20 * ALTERNATIVELY, this software may be distributed under the terms of the
21 * GNU General Public License ("GPL") as published by the Free Software
22 * Foundation, either version 2 of that License or (at your option) any
23 * later version.
24 *
25 * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
26 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
27 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
28 * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
29 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
30 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
31 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
32 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
33 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
34 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35 */
36
37#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
38
39#include "fman_port.h"
40#include "fman.h"
41#include "fman_sp.h"
42
43#include <asm/mpc85xx.h>
44#include <linux/io.h>
45#include <linux/slab.h>
46#include <linux/module.h>
47#include <linux/interrupt.h>
48#include <linux/of_platform.h>
49#include <linux/of_address.h>
50
51/* Queue ID */
52#define DFLT_FQ_ID              0x00FFFFFF
53
54/* General defines */
55#define PORT_BMI_FIFO_UNITS             0x100
56
57#define MAX_PORT_FIFO_SIZE(bmi_max_fifo_size)   \
58        min((u32)bmi_max_fifo_size, (u32)1024 * FMAN_BMI_FIFO_UNITS)
59
60#define PORT_CG_MAP_NUM                 8
61#define PORT_PRS_RESULT_WORDS_NUM       8
62#define PORT_IC_OFFSET_UNITS            0x10
63
64#define MIN_EXT_BUF_SIZE                64
65
66#define BMI_PORT_REGS_OFFSET                            0
67#define QMI_PORT_REGS_OFFSET                            0x400
68
69/* Default values */
70#define DFLT_PORT_BUFFER_PREFIX_CONTEXT_DATA_ALIGN              \
71        DFLT_FM_SP_BUFFER_PREFIX_CONTEXT_DATA_ALIGN
72
73#define DFLT_PORT_CUT_BYTES_FROM_END            4
74
75#define DFLT_PORT_ERRORS_TO_DISCARD             FM_PORT_FRM_ERR_CLS_DISCARD
76#define DFLT_PORT_MAX_FRAME_LENGTH              9600
77
78#define DFLT_PORT_RX_FIFO_PRI_ELEVATION_LEV(bmi_max_fifo_size)  \
79        MAX_PORT_FIFO_SIZE(bmi_max_fifo_size)
80
81#define DFLT_PORT_RX_FIFO_THRESHOLD(major, bmi_max_fifo_size)   \
82        (major == 6 ?                                           \
83        MAX_PORT_FIFO_SIZE(bmi_max_fifo_size) :         \
84        (MAX_PORT_FIFO_SIZE(bmi_max_fifo_size) * 3 / 4))        \
85
86#define DFLT_PORT_EXTRA_NUM_OF_FIFO_BUFS                0
87
88/* QMI defines */
89#define QMI_DEQ_CFG_SUBPORTAL_MASK              0x1f
90
91#define QMI_PORT_CFG_EN                         0x80000000
92#define QMI_PORT_STATUS_DEQ_FD_BSY              0x20000000
93
94#define QMI_DEQ_CFG_PRI                         0x80000000
95#define QMI_DEQ_CFG_TYPE1                       0x10000000
96#define QMI_DEQ_CFG_TYPE2                       0x20000000
97#define QMI_DEQ_CFG_TYPE3                       0x30000000
98#define QMI_DEQ_CFG_PREFETCH_PARTIAL            0x01000000
99#define QMI_DEQ_CFG_PREFETCH_FULL               0x03000000
100#define QMI_DEQ_CFG_SP_MASK                     0xf
101#define QMI_DEQ_CFG_SP_SHIFT                    20
102
103#define QMI_BYTE_COUNT_LEVEL_CONTROL(_type)     \
104        (_type == FMAN_PORT_TYPE_TX ? 0x1400 : 0x400)
105
106/* BMI defins */
107#define BMI_EBD_EN                              0x80000000
108
109#define BMI_PORT_CFG_EN                         0x80000000
110#define BMI_PORT_CFG_FDOVR                      0x02000000
111
112#define BMI_PORT_STATUS_BSY                     0x80000000
113
114#define BMI_DMA_ATTR_SWP_SHIFT                  FMAN_SP_DMA_ATTR_SWP_SHIFT
115#define BMI_DMA_ATTR_IC_STASH_ON                0x10000000
116#define BMI_DMA_ATTR_HDR_STASH_ON               0x04000000
117#define BMI_DMA_ATTR_SG_STASH_ON                0x01000000
118#define BMI_DMA_ATTR_WRITE_OPTIMIZE             FMAN_SP_DMA_ATTR_WRITE_OPTIMIZE
119
120#define BMI_RX_FIFO_PRI_ELEVATION_SHIFT 16
121#define BMI_RX_FIFO_THRESHOLD_ETHE              0x80000000
122
123#define BMI_FRAME_END_CS_IGNORE_SHIFT           24
124#define BMI_FRAME_END_CS_IGNORE_MASK            0x0000001f
125
126#define BMI_RX_FRAME_END_CUT_SHIFT              16
127#define BMI_RX_FRAME_END_CUT_MASK               0x0000001f
128
129#define BMI_IC_TO_EXT_SHIFT                     FMAN_SP_IC_TO_EXT_SHIFT
130#define BMI_IC_TO_EXT_MASK                      0x0000001f
131#define BMI_IC_FROM_INT_SHIFT                   FMAN_SP_IC_FROM_INT_SHIFT
132#define BMI_IC_FROM_INT_MASK                    0x0000000f
133#define BMI_IC_SIZE_MASK                        0x0000001f
134
135#define BMI_INT_BUF_MARG_SHIFT                  28
136#define BMI_INT_BUF_MARG_MASK                   0x0000000f
137#define BMI_EXT_BUF_MARG_START_SHIFT            FMAN_SP_EXT_BUF_MARG_START_SHIFT
138#define BMI_EXT_BUF_MARG_START_MASK             0x000001ff
139#define BMI_EXT_BUF_MARG_END_MASK               0x000001ff
140
141#define BMI_CMD_MR_LEAC                         0x00200000
142#define BMI_CMD_MR_SLEAC                        0x00100000
143#define BMI_CMD_MR_MA                           0x00080000
144#define BMI_CMD_MR_DEAS                         0x00040000
145#define BMI_CMD_RX_MR_DEF                       (BMI_CMD_MR_LEAC | \
146                                                BMI_CMD_MR_SLEAC | \
147                                                BMI_CMD_MR_MA | \
148                                                BMI_CMD_MR_DEAS)
149#define BMI_CMD_TX_MR_DEF                       0
150
151#define BMI_CMD_ATTR_ORDER                      0x80000000
152#define BMI_CMD_ATTR_SYNC                       0x02000000
153#define BMI_CMD_ATTR_COLOR_SHIFT                26
154
155#define BMI_FIFO_PIPELINE_DEPTH_SHIFT           12
156#define BMI_FIFO_PIPELINE_DEPTH_MASK            0x0000000f
157#define BMI_NEXT_ENG_FD_BITS_SHIFT              24
158
159#define BMI_EXT_BUF_POOL_VALID                  FMAN_SP_EXT_BUF_POOL_VALID
160#define BMI_EXT_BUF_POOL_EN_COUNTER             FMAN_SP_EXT_BUF_POOL_EN_COUNTER
161#define BMI_EXT_BUF_POOL_BACKUP         FMAN_SP_EXT_BUF_POOL_BACKUP
162#define BMI_EXT_BUF_POOL_ID_SHIFT               16
163#define BMI_EXT_BUF_POOL_ID_MASK                0x003F0000
164#define BMI_POOL_DEP_NUM_OF_POOLS_SHIFT 16
165
166#define BMI_TX_FIFO_MIN_FILL_SHIFT              16
167
168#define BMI_SG_DISABLE                          FMAN_SP_SG_DISABLE
169
170#define BMI_PRIORITY_ELEVATION_LEVEL ((0x3FF + 1) * PORT_BMI_FIFO_UNITS)
171#define BMI_FIFO_THRESHOLD            ((0x3FF + 1) * PORT_BMI_FIFO_UNITS)
172
173#define BMI_DEQUEUE_PIPELINE_DEPTH(_type, _speed)               \
174        ((_type == FMAN_PORT_TYPE_TX && _speed == 10000) ? 4 : 1)
175
176#define BMI_PORT_RFNE_FRWD_RPD                  0x40000000
177
178#define RX_ERRS_TO_ENQ                            \
179        (FM_PORT_FRM_ERR_DMA                    | \
180        FM_PORT_FRM_ERR_PHYSICAL                | \
181        FM_PORT_FRM_ERR_SIZE                    | \
182        FM_PORT_FRM_ERR_EXTRACTION              | \
183        FM_PORT_FRM_ERR_NO_SCHEME               | \
184        FM_PORT_FRM_ERR_PRS_TIMEOUT             | \
185        FM_PORT_FRM_ERR_PRS_ILL_INSTRUCT        | \
186        FM_PORT_FRM_ERR_BLOCK_LIMIT_EXCEEDED    | \
187        FM_PORT_FRM_ERR_PRS_HDR_ERR             | \
188        FM_PORT_FRM_ERR_KEYSIZE_OVERFLOW        | \
189        FM_PORT_FRM_ERR_IPRE)
190
191/* NIA defines */
192#define NIA_ORDER_RESTOR                                0x00800000
193#define NIA_ENG_FM_CTL                                  0x00000000
194#define NIA_ENG_BMI                                     0x00500000
195#define NIA_ENG_QMI_ENQ                                 0x00540000
196#define NIA_ENG_QMI_DEQ                                 0x00580000
197
198#define NIA_FM_CTL_AC_NO_IPACC_PRE_BMI_ENQ_FRAME        0x00000028
199#define NIA_BMI_AC_ENQ_FRAME                            0x00000002
200#define NIA_BMI_AC_TX_RELEASE                           0x000002C0
201#define NIA_BMI_AC_RELEASE                              0x000000C0
202#define NIA_BMI_AC_TX                                   0x00000274
203#define NIA_BMI_AC_FETCH_ALL_FRAME                      0x0000020c
204
205/* Port IDs */
206#define TX_10G_PORT_BASE                0x30
207#define RX_10G_PORT_BASE                0x10
208
209/* BMI Rx port register map */
210struct fman_port_rx_bmi_regs {
211        u32 fmbm_rcfg;          /* Rx Configuration */
212        u32 fmbm_rst;           /* Rx Status */
213        u32 fmbm_rda;           /* Rx DMA attributes */
214        u32 fmbm_rfp;           /* Rx FIFO Parameters */
215        u32 fmbm_rfed;          /* Rx Frame End Data */
216        u32 fmbm_ricp;          /* Rx Internal Context Parameters */
217        u32 fmbm_rim;           /* Rx Internal Buffer Margins */
218        u32 fmbm_rebm;          /* Rx External Buffer Margins */
219        u32 fmbm_rfne;          /* Rx Frame Next Engine */
220        u32 fmbm_rfca;          /* Rx Frame Command Attributes. */
221        u32 fmbm_rfpne;         /* Rx Frame Parser Next Engine */
222        u32 fmbm_rpso;          /* Rx Parse Start Offset */
223        u32 fmbm_rpp;           /* Rx Policer Profile  */
224        u32 fmbm_rccb;          /* Rx Coarse Classification Base */
225        u32 fmbm_reth;          /* Rx Excessive Threshold */
226        u32 reserved003c[1];    /* (0x03C 0x03F) */
227        u32 fmbm_rprai[PORT_PRS_RESULT_WORDS_NUM];
228        /* Rx Parse Results Array Init */
229        u32 fmbm_rfqid;         /* Rx Frame Queue ID */
230        u32 fmbm_refqid;        /* Rx Error Frame Queue ID */
231        u32 fmbm_rfsdm;         /* Rx Frame Status Discard Mask */
232        u32 fmbm_rfsem;         /* Rx Frame Status Error Mask */
233        u32 fmbm_rfene;         /* Rx Frame Enqueue Next Engine */
234        u32 reserved0074[0x2];  /* (0x074-0x07C)  */
235        u32 fmbm_rcmne;         /* Rx Frame Continuous Mode Next Engine */
236        u32 reserved0080[0x20]; /* (0x080 0x0FF)  */
237        u32 fmbm_ebmpi[FMAN_PORT_MAX_EXT_POOLS_NUM];
238        /* Buffer Manager pool Information- */
239        u32 fmbm_acnt[FMAN_PORT_MAX_EXT_POOLS_NUM];     /* Allocate Counter- */
240        u32 reserved0130[8];    /* 0x130/0x140 - 0x15F reserved - */
241        u32 fmbm_rcgm[PORT_CG_MAP_NUM]; /* Congestion Group Map */
242        u32 fmbm_mpd;           /* BM Pool Depletion  */
243        u32 reserved0184[0x1F]; /* (0x184 0x1FF) */
244        u32 fmbm_rstc;          /* Rx Statistics Counters */
245        u32 fmbm_rfrc;          /* Rx Frame Counter */
246        u32 fmbm_rfbc;          /* Rx Bad Frames Counter */
247        u32 fmbm_rlfc;          /* Rx Large Frames Counter */
248        u32 fmbm_rffc;          /* Rx Filter Frames Counter */
249        u32 fmbm_rfdc;          /* Rx Frame Discard Counter */
250        u32 fmbm_rfldec;                /* Rx Frames List DMA Error Counter */
251        u32 fmbm_rodc;          /* Rx Out of Buffers Discard nntr */
252        u32 fmbm_rbdc;          /* Rx Buffers Deallocate Counter */
253        u32 fmbm_rpec;          /* RX Prepare to enqueue Counte */
254        u32 reserved0224[0x16]; /* (0x224 0x27F) */
255        u32 fmbm_rpc;           /* Rx Performance Counters */
256        u32 fmbm_rpcp;          /* Rx Performance Count Parameters */
257        u32 fmbm_rccn;          /* Rx Cycle Counter */
258        u32 fmbm_rtuc;          /* Rx Tasks Utilization Counter */
259        u32 fmbm_rrquc;         /* Rx Receive Queue Utilization cntr */
260        u32 fmbm_rduc;          /* Rx DMA Utilization Counter */
261        u32 fmbm_rfuc;          /* Rx FIFO Utilization Counter */
262        u32 fmbm_rpac;          /* Rx Pause Activation Counter */
263        u32 reserved02a0[0x18]; /* (0x2A0 0x2FF) */
264        u32 fmbm_rdcfg[0x3];    /* Rx Debug Configuration */
265        u32 fmbm_rgpr;          /* Rx General Purpose Register */
266        u32 reserved0310[0x3a];
267};
268
269/* BMI Tx port register map */
270struct fman_port_tx_bmi_regs {
271        u32 fmbm_tcfg;          /* Tx Configuration */
272        u32 fmbm_tst;           /* Tx Status */
273        u32 fmbm_tda;           /* Tx DMA attributes */
274        u32 fmbm_tfp;           /* Tx FIFO Parameters */
275        u32 fmbm_tfed;          /* Tx Frame End Data */
276        u32 fmbm_ticp;          /* Tx Internal Context Parameters */
277        u32 fmbm_tfdne;         /* Tx Frame Dequeue Next Engine. */
278        u32 fmbm_tfca;          /* Tx Frame Command attribute. */
279        u32 fmbm_tcfqid;        /* Tx Confirmation Frame Queue ID. */
280        u32 fmbm_tefqid;        /* Tx Frame Error Queue ID */
281        u32 fmbm_tfene;         /* Tx Frame Enqueue Next Engine */
282        u32 fmbm_trlmts;        /* Tx Rate Limiter Scale */
283        u32 fmbm_trlmt;         /* Tx Rate Limiter */
284        u32 reserved0034[0x0e]; /* (0x034-0x6c) */
285        u32 fmbm_tccb;          /* Tx Coarse Classification base */
286        u32 fmbm_tfne;          /* Tx Frame Next Engine */
287        u32 fmbm_tpfcm[0x02];
288        /* Tx Priority based Flow Control (PFC) Mapping */
289        u32 fmbm_tcmne;         /* Tx Frame Continuous Mode Next Engine */
290        u32 reserved0080[0x60]; /* (0x080-0x200) */
291        u32 fmbm_tstc;          /* Tx Statistics Counters */
292        u32 fmbm_tfrc;          /* Tx Frame Counter */
293        u32 fmbm_tfdc;          /* Tx Frames Discard Counter */
294        u32 fmbm_tfledc;        /* Tx Frame len error discard cntr */
295        u32 fmbm_tfufdc;        /* Tx Frame unsprt frmt discard cntr */
296        u32 fmbm_tbdc;          /* Tx Buffers Deallocate Counter */
297        u32 reserved0218[0x1A]; /* (0x218-0x280) */
298        u32 fmbm_tpc;           /* Tx Performance Counters */
299        u32 fmbm_tpcp;          /* Tx Performance Count Parameters */
300        u32 fmbm_tccn;          /* Tx Cycle Counter */
301        u32 fmbm_ttuc;          /* Tx Tasks Utilization Counter */
302        u32 fmbm_ttcquc;        /* Tx Transmit conf Q util Counter */
303        u32 fmbm_tduc;          /* Tx DMA Utilization Counter */
304        u32 fmbm_tfuc;          /* Tx FIFO Utilization Counter */
305        u32 reserved029c[16];   /* (0x29C-0x2FF) */
306        u32 fmbm_tdcfg[0x3];    /* Tx Debug Configuration */
307        u32 fmbm_tgpr;          /* Tx General Purpose Register */
308        u32 reserved0310[0x3a]; /* (0x310-0x3FF) */
309};
310
311/* BMI port register map */
312union fman_port_bmi_regs {
313        struct fman_port_rx_bmi_regs rx;
314        struct fman_port_tx_bmi_regs tx;
315};
316
317/* QMI port register map */
318struct fman_port_qmi_regs {
319        u32 fmqm_pnc;           /* PortID n Configuration Register */
320        u32 fmqm_pns;           /* PortID n Status Register */
321        u32 fmqm_pnts;          /* PortID n Task Status Register */
322        u32 reserved00c[4];     /* 0xn00C - 0xn01B */
323        u32 fmqm_pnen;          /* PortID n Enqueue NIA Register */
324        u32 fmqm_pnetfc;                /* PortID n Enq Total Frame Counter */
325        u32 reserved024[2];     /* 0xn024 - 0x02B */
326        u32 fmqm_pndn;          /* PortID n Dequeue NIA Register */
327        u32 fmqm_pndc;          /* PortID n Dequeue Config Register */
328        u32 fmqm_pndtfc;                /* PortID n Dequeue tot Frame cntr */
329        u32 fmqm_pndfdc;                /* PortID n Dequeue FQID Dflt Cntr */
330        u32 fmqm_pndcc;         /* PortID n Dequeue Confirm Counter */
331};
332
333/* QMI dequeue prefetch modes */
334enum fman_port_deq_prefetch {
335        FMAN_PORT_DEQ_NO_PREFETCH, /* No prefetch mode */
336        FMAN_PORT_DEQ_PART_PREFETCH, /* Partial prefetch mode */
337        FMAN_PORT_DEQ_FULL_PREFETCH /* Full prefetch mode */
338};
339
340/* A structure for defining FM port resources */
341struct fman_port_rsrc {
342        u32 num; /* Committed required resource */
343        u32 extra; /* Extra (not committed) required resource */
344};
345
346enum fman_port_dma_swap {
347        FMAN_PORT_DMA_NO_SWAP,  /* No swap, transfer data as is */
348        FMAN_PORT_DMA_SWAP_LE,
349        /* The transferred data should be swapped in PPC Little Endian mode */
350        FMAN_PORT_DMA_SWAP_BE
351        /* The transferred data should be swapped in Big Endian mode */
352};
353
354/* Default port color */
355enum fman_port_color {
356        FMAN_PORT_COLOR_GREEN,  /* Default port color is green */
357        FMAN_PORT_COLOR_YELLOW, /* Default port color is yellow */
358        FMAN_PORT_COLOR_RED,            /* Default port color is red */
359        FMAN_PORT_COLOR_OVERRIDE        /* Ignore color */
360};
361
362/* QMI dequeue from the SP channel - types */
363enum fman_port_deq_type {
364        FMAN_PORT_DEQ_BY_PRI,
365        /* Priority precedence and Intra-Class scheduling */
366        FMAN_PORT_DEQ_ACTIVE_FQ,
367        /* Active FQ precedence and Intra-Class scheduling */
368        FMAN_PORT_DEQ_ACTIVE_FQ_NO_ICS
369        /* Active FQ precedence and override Intra-Class scheduling */
370};
371
372/* External buffer pools configuration */
373struct fman_port_bpools {
374        u8 count;                       /* Num of pools to set up */
375        bool counters_enable;           /* Enable allocate counters */
376        u8 grp_bp_depleted_num;
377        /* Number of depleted pools - if reached the BMI indicates
378         * the MAC to send a pause frame
379         */
380        struct {
381                u8 bpid;                /* BM pool ID */
382                u16 size;
383                /* Pool's size - must be in ascending order */
384                bool is_backup;
385                /* If this is a backup pool */
386                bool grp_bp_depleted;
387                /* Consider this buffer in multiple pools depletion criteria */
388                bool single_bp_depleted;
389                /* Consider this buffer in single pool depletion criteria */
390        } bpool[FMAN_PORT_MAX_EXT_POOLS_NUM];
391};
392
393struct fman_port_cfg {
394        u32 dflt_fqid;
395        u32 err_fqid;
396        u8 deq_sp;
397        bool deq_high_priority;
398        enum fman_port_deq_type deq_type;
399        enum fman_port_deq_prefetch deq_prefetch_option;
400        u16 deq_byte_cnt;
401        u8 cheksum_last_bytes_ignore;
402        u8 rx_cut_end_bytes;
403        struct fman_buf_pool_depletion buf_pool_depletion;
404        bool discard_override;
405        bool en_buf_pool_depletion;
406        struct fman_ext_pools ext_buf_pools;
407        u32 tx_fifo_min_level;
408        u32 tx_fifo_low_comf_level;
409        u32 rx_pri_elevation;
410        u32 rx_fifo_thr;
411        struct fman_sp_buf_margins buf_margins;
412        u32 int_buf_start_margin;
413        struct fman_sp_int_context_data_copy int_context;
414        u32 discard_mask;
415        u32 err_mask;
416        bool forward_reuse_int_context;
417        struct fman_buffer_prefix_content buffer_prefix_content;
418        bool dont_release_buf;
419        bool set_num_of_tasks;
420        bool set_num_of_open_dmas;
421        bool set_size_of_fifo;
422        bool bcb_workaround;
423
424        u8 rx_fd_bits;
425        u32 tx_fifo_deq_pipeline_depth;
426        bool errata_A006675;
427        bool errata_A006320;
428        bool excessive_threshold_register;
429        bool fmbm_rebm_has_sgd;
430        bool fmbm_tfne_has_features;
431        bool qmi_deq_options_support;
432
433        enum fman_port_dma_swap dma_swap_data;
434        bool dma_ic_stash_on;
435        bool dma_header_stash_on;
436        bool dma_sg_stash_on;
437        bool dma_write_optimize;
438        enum fman_port_color color;
439        bool sync_req;
440
441        bool no_scatter_gather;
442};
443
444struct fman_port_rx_pools_params {
445        u8 num_of_pools;
446        u16 second_largest_buf_size;
447        u16 largest_buf_size;
448};
449
450struct fman_port_dts_params {
451        void __iomem *base_addr;        /* FMan port virtual memory */
452        enum fman_port_type type;       /* Port type */
453        u16 speed;                      /* Port speed */
454        u8 id;                          /* HW Port Id */
455        u32 qman_channel_id;            /* QMan channel id (non RX only) */
456        struct fman *fman;              /* FMan Handle */
457};
458
459struct fman_port {
460        void *fm;
461        struct fman_rev_info rev_info;
462        u8 port_id;
463        enum fman_port_type port_type;
464        u16 port_speed;
465
466        union fman_port_bmi_regs __iomem *bmi_regs;
467        struct fman_port_qmi_regs __iomem *qmi_regs;
468
469        struct fman_sp_buffer_offsets buffer_offsets;
470
471        u8 internal_buf_offset;
472        struct fman_ext_pools ext_buf_pools;
473
474        u16 max_frame_length;
475        struct fman_port_rsrc open_dmas;
476        struct fman_port_rsrc tasks;
477        struct fman_port_rsrc fifo_bufs;
478        struct fman_port_rx_pools_params rx_pools_params;
479
480        struct fman_port_cfg *cfg;
481        struct fman_port_dts_params dts_params;
482
483        u8 ext_pools_num;
484        u32 max_port_fifo_size;
485        u32 max_num_of_ext_pools;
486        u32 max_num_of_sub_portals;
487        u32 bm_max_num_of_pools;
488};
489
490static int init_bmi_rx(struct fman_port *port)
491{
492        struct fman_port_rx_bmi_regs __iomem *regs = &port->bmi_regs->rx;
493        struct fman_port_cfg *cfg = port->cfg;
494        u32 tmp;
495
496        /* Rx Configuration register */
497        tmp = 0;
498        if (cfg->discard_override)
499                tmp |= BMI_PORT_CFG_FDOVR;
500        iowrite32be(tmp, &regs->fmbm_rcfg);
501
502        /* DMA attributes */
503        tmp = (u32)cfg->dma_swap_data << BMI_DMA_ATTR_SWP_SHIFT;
504        if (cfg->dma_ic_stash_on)
505                tmp |= BMI_DMA_ATTR_IC_STASH_ON;
506        if (cfg->dma_header_stash_on)
507                tmp |= BMI_DMA_ATTR_HDR_STASH_ON;
508        if (cfg->dma_sg_stash_on)
509                tmp |= BMI_DMA_ATTR_SG_STASH_ON;
510        if (cfg->dma_write_optimize)
511                tmp |= BMI_DMA_ATTR_WRITE_OPTIMIZE;
512        iowrite32be(tmp, &regs->fmbm_rda);
513
514        /* Rx FIFO parameters */
515        tmp = (cfg->rx_pri_elevation / PORT_BMI_FIFO_UNITS - 1) <<
516                BMI_RX_FIFO_PRI_ELEVATION_SHIFT;
517        tmp |= cfg->rx_fifo_thr / PORT_BMI_FIFO_UNITS - 1;
518        iowrite32be(tmp, &regs->fmbm_rfp);
519
520        if (cfg->excessive_threshold_register)
521                /* always allow access to the extra resources */
522                iowrite32be(BMI_RX_FIFO_THRESHOLD_ETHE, &regs->fmbm_reth);
523
524        /* Frame end data */
525        tmp = (cfg->cheksum_last_bytes_ignore & BMI_FRAME_END_CS_IGNORE_MASK) <<
526                BMI_FRAME_END_CS_IGNORE_SHIFT;
527        tmp |= (cfg->rx_cut_end_bytes & BMI_RX_FRAME_END_CUT_MASK) <<
528                BMI_RX_FRAME_END_CUT_SHIFT;
529        if (cfg->errata_A006320)
530                tmp &= 0xffe0ffff;
531        iowrite32be(tmp, &regs->fmbm_rfed);
532
533        /* Internal context parameters */
534        tmp = ((cfg->int_context.ext_buf_offset / PORT_IC_OFFSET_UNITS) &
535                BMI_IC_TO_EXT_MASK) << BMI_IC_TO_EXT_SHIFT;
536        tmp |= ((cfg->int_context.int_context_offset / PORT_IC_OFFSET_UNITS) &
537                BMI_IC_FROM_INT_MASK) << BMI_IC_FROM_INT_SHIFT;
538        tmp |= (cfg->int_context.size / PORT_IC_OFFSET_UNITS) &
539                BMI_IC_SIZE_MASK;
540        iowrite32be(tmp, &regs->fmbm_ricp);
541
542        /* Internal buffer offset */
543        tmp = ((cfg->int_buf_start_margin / PORT_IC_OFFSET_UNITS) &
544                BMI_INT_BUF_MARG_MASK) << BMI_INT_BUF_MARG_SHIFT;
545        iowrite32be(tmp, &regs->fmbm_rim);
546
547        /* External buffer margins */
548        tmp = (cfg->buf_margins.start_margins & BMI_EXT_BUF_MARG_START_MASK) <<
549                BMI_EXT_BUF_MARG_START_SHIFT;
550        tmp |= cfg->buf_margins.end_margins & BMI_EXT_BUF_MARG_END_MASK;
551        if (cfg->fmbm_rebm_has_sgd && cfg->no_scatter_gather)
552                tmp |= BMI_SG_DISABLE;
553        iowrite32be(tmp, &regs->fmbm_rebm);
554
555        /* Frame attributes */
556        tmp = BMI_CMD_RX_MR_DEF;
557        tmp |= BMI_CMD_ATTR_ORDER;
558        tmp |= (u32)cfg->color << BMI_CMD_ATTR_COLOR_SHIFT;
559        if (cfg->sync_req)
560                tmp |= BMI_CMD_ATTR_SYNC;
561
562        iowrite32be(tmp, &regs->fmbm_rfca);
563
564        /* NIA */
565        tmp = (u32)cfg->rx_fd_bits << BMI_NEXT_ENG_FD_BITS_SHIFT;
566
567        if (cfg->errata_A006675)
568                tmp |= NIA_ENG_FM_CTL |
569                       NIA_FM_CTL_AC_NO_IPACC_PRE_BMI_ENQ_FRAME;
570        else
571                tmp |= NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME;
572        iowrite32be(tmp, &regs->fmbm_rfne);
573
574        /* Enqueue NIA */
575        iowrite32be(NIA_ENG_QMI_ENQ | NIA_ORDER_RESTOR, &regs->fmbm_rfene);
576
577        /* Default/error queues */
578        iowrite32be((cfg->dflt_fqid & DFLT_FQ_ID), &regs->fmbm_rfqid);
579        iowrite32be((cfg->err_fqid & DFLT_FQ_ID), &regs->fmbm_refqid);
580
581        /* Discard/error masks */
582        iowrite32be(cfg->discard_mask, &regs->fmbm_rfsdm);
583        iowrite32be(cfg->err_mask, &regs->fmbm_rfsem);
584
585        return 0;
586}
587
588static int init_bmi_tx(struct fman_port *port)
589{
590        struct fman_port_tx_bmi_regs __iomem *regs = &port->bmi_regs->tx;
591        struct fman_port_cfg *cfg = port->cfg;
592        u32 tmp;
593
594        /* Tx Configuration register */
595        tmp = 0;
596        iowrite32be(tmp, &regs->fmbm_tcfg);
597
598        /* DMA attributes */
599        tmp = (u32)cfg->dma_swap_data << BMI_DMA_ATTR_SWP_SHIFT;
600        if (cfg->dma_ic_stash_on)
601                tmp |= BMI_DMA_ATTR_IC_STASH_ON;
602        if (cfg->dma_header_stash_on)
603                tmp |= BMI_DMA_ATTR_HDR_STASH_ON;
604        if (cfg->dma_sg_stash_on)
605                tmp |= BMI_DMA_ATTR_SG_STASH_ON;
606        iowrite32be(tmp, &regs->fmbm_tda);
607
608        /* Tx FIFO parameters */
609        tmp = (cfg->tx_fifo_min_level / PORT_BMI_FIFO_UNITS) <<
610                BMI_TX_FIFO_MIN_FILL_SHIFT;
611        tmp |= ((cfg->tx_fifo_deq_pipeline_depth - 1) &
612                BMI_FIFO_PIPELINE_DEPTH_MASK) << BMI_FIFO_PIPELINE_DEPTH_SHIFT;
613        tmp |= (cfg->tx_fifo_low_comf_level / PORT_BMI_FIFO_UNITS) - 1;
614        iowrite32be(tmp, &regs->fmbm_tfp);
615
616        /* Frame end data */
617        tmp = (cfg->cheksum_last_bytes_ignore & BMI_FRAME_END_CS_IGNORE_MASK) <<
618                BMI_FRAME_END_CS_IGNORE_SHIFT;
619        iowrite32be(tmp, &regs->fmbm_tfed);
620
621        /* Internal context parameters */
622        tmp = ((cfg->int_context.ext_buf_offset / PORT_IC_OFFSET_UNITS) &
623                BMI_IC_TO_EXT_MASK) << BMI_IC_TO_EXT_SHIFT;
624        tmp |= ((cfg->int_context.int_context_offset / PORT_IC_OFFSET_UNITS) &
625                BMI_IC_FROM_INT_MASK) << BMI_IC_FROM_INT_SHIFT;
626        tmp |= (cfg->int_context.size / PORT_IC_OFFSET_UNITS) &
627                BMI_IC_SIZE_MASK;
628        iowrite32be(tmp, &regs->fmbm_ticp);
629
630        /* Frame attributes */
631        tmp = BMI_CMD_TX_MR_DEF;
632        tmp |= BMI_CMD_ATTR_ORDER;
633        tmp |= (u32)cfg->color << BMI_CMD_ATTR_COLOR_SHIFT;
634        iowrite32be(tmp, &regs->fmbm_tfca);
635
636        /* Dequeue NIA + enqueue NIA */
637        iowrite32be(NIA_ENG_QMI_DEQ, &regs->fmbm_tfdne);
638        iowrite32be(NIA_ENG_QMI_ENQ | NIA_ORDER_RESTOR, &regs->fmbm_tfene);
639        if (cfg->fmbm_tfne_has_features)
640                iowrite32be(!cfg->dflt_fqid ?
641                            BMI_EBD_EN | NIA_BMI_AC_FETCH_ALL_FRAME :
642                            NIA_BMI_AC_FETCH_ALL_FRAME, &regs->fmbm_tfne);
643        if (!cfg->dflt_fqid && cfg->dont_release_buf) {
644                iowrite32be(DFLT_FQ_ID, &regs->fmbm_tcfqid);
645                iowrite32be(NIA_ENG_BMI | NIA_BMI_AC_TX_RELEASE,
646                            &regs->fmbm_tfene);
647                if (cfg->fmbm_tfne_has_features)
648                        iowrite32be(ioread32be(&regs->fmbm_tfne) & ~BMI_EBD_EN,
649                                    &regs->fmbm_tfne);
650        }
651
652        /* Confirmation/error queues */
653        if (cfg->dflt_fqid || !cfg->dont_release_buf)
654                iowrite32be(cfg->dflt_fqid & DFLT_FQ_ID, &regs->fmbm_tcfqid);
655        iowrite32be((cfg->err_fqid & DFLT_FQ_ID), &regs->fmbm_tefqid);
656
657        return 0;
658}
659
660static int init_qmi(struct fman_port *port)
661{
662        struct fman_port_qmi_regs __iomem *regs = port->qmi_regs;
663        struct fman_port_cfg *cfg = port->cfg;
664        u32 tmp;
665
666        /* Rx port configuration */
667        if (port->port_type == FMAN_PORT_TYPE_RX) {
668                /* Enqueue NIA */
669                iowrite32be(NIA_ENG_BMI | NIA_BMI_AC_RELEASE, &regs->fmqm_pnen);
670                return 0;
671        }
672
673        /* Continue with Tx port configuration */
674        if (port->port_type == FMAN_PORT_TYPE_TX) {
675                /* Enqueue NIA */
676                iowrite32be(NIA_ENG_BMI | NIA_BMI_AC_TX_RELEASE,
677                            &regs->fmqm_pnen);
678                /* Dequeue NIA */
679                iowrite32be(NIA_ENG_BMI | NIA_BMI_AC_TX, &regs->fmqm_pndn);
680        }
681
682        /* Dequeue Configuration register */
683        tmp = 0;
684        if (cfg->deq_high_priority)
685                tmp |= QMI_DEQ_CFG_PRI;
686
687        switch (cfg->deq_type) {
688        case FMAN_PORT_DEQ_BY_PRI:
689                tmp |= QMI_DEQ_CFG_TYPE1;
690                break;
691        case FMAN_PORT_DEQ_ACTIVE_FQ:
692                tmp |= QMI_DEQ_CFG_TYPE2;
693                break;
694        case FMAN_PORT_DEQ_ACTIVE_FQ_NO_ICS:
695                tmp |= QMI_DEQ_CFG_TYPE3;
696                break;
697        default:
698                return -EINVAL;
699        }
700
701        if (cfg->qmi_deq_options_support) {
702                switch (cfg->deq_prefetch_option) {
703                case FMAN_PORT_DEQ_NO_PREFETCH:
704                        break;
705                case FMAN_PORT_DEQ_PART_PREFETCH:
706                        tmp |= QMI_DEQ_CFG_PREFETCH_PARTIAL;
707                        break;
708                case FMAN_PORT_DEQ_FULL_PREFETCH:
709                        tmp |= QMI_DEQ_CFG_PREFETCH_FULL;
710                        break;
711                default:
712                        return -EINVAL;
713                }
714        }
715        tmp |= (cfg->deq_sp & QMI_DEQ_CFG_SP_MASK) << QMI_DEQ_CFG_SP_SHIFT;
716        tmp |= cfg->deq_byte_cnt;
717        iowrite32be(tmp, &regs->fmqm_pndc);
718
719        return 0;
720}
721
722static int init(struct fman_port *port)
723{
724        int err;
725
726        /* Init BMI registers */
727        switch (port->port_type) {
728        case FMAN_PORT_TYPE_RX:
729                err = init_bmi_rx(port);
730                break;
731        case FMAN_PORT_TYPE_TX:
732                err = init_bmi_tx(port);
733                break;
734        default:
735                return -EINVAL;
736        }
737
738        if (err)
739                return err;
740
741        /* Init QMI registers */
742        err = init_qmi(port);
743        return err;
744
745        return 0;
746}
747
748static int set_bpools(const struct fman_port *port,
749                      const struct fman_port_bpools *bp)
750{
751        u32 __iomem *bp_reg, *bp_depl_reg;
752        u32 tmp;
753        u8 i, max_bp_num;
754        bool grp_depl_used = false, rx_port;
755
756        switch (port->port_type) {
757        case FMAN_PORT_TYPE_RX:
758                max_bp_num = port->ext_pools_num;
759                rx_port = true;
760                bp_reg = port->bmi_regs->rx.fmbm_ebmpi;
761                bp_depl_reg = &port->bmi_regs->rx.fmbm_mpd;
762                break;
763        default:
764                return -EINVAL;
765        }
766
767        if (rx_port) {
768                /* Check buffers are provided in ascending order */
769                for (i = 0; (i < (bp->count - 1) &&
770                             (i < FMAN_PORT_MAX_EXT_POOLS_NUM - 1)); i++) {
771                        if (bp->bpool[i].size > bp->bpool[i + 1].size)
772                                return -EINVAL;
773                }
774        }
775
776        /* Set up external buffers pools */
777        for (i = 0; i < bp->count; i++) {
778                tmp = BMI_EXT_BUF_POOL_VALID;
779                tmp |= ((u32)bp->bpool[i].bpid <<
780                        BMI_EXT_BUF_POOL_ID_SHIFT) & BMI_EXT_BUF_POOL_ID_MASK;
781
782                if (rx_port) {
783                        if (bp->counters_enable)
784                                tmp |= BMI_EXT_BUF_POOL_EN_COUNTER;
785
786                        if (bp->bpool[i].is_backup)
787                                tmp |= BMI_EXT_BUF_POOL_BACKUP;
788
789                        tmp |= (u32)bp->bpool[i].size;
790                }
791
792                iowrite32be(tmp, &bp_reg[i]);
793        }
794
795        /* Clear unused pools */
796        for (i = bp->count; i < max_bp_num; i++)
797                iowrite32be(0, &bp_reg[i]);
798
799        /* Pools depletion */
800        tmp = 0;
801        for (i = 0; i < FMAN_PORT_MAX_EXT_POOLS_NUM; i++) {
802                if (bp->bpool[i].grp_bp_depleted) {
803                        grp_depl_used = true;
804                        tmp |= 0x80000000 >> i;
805                }
806
807                if (bp->bpool[i].single_bp_depleted)
808                        tmp |= 0x80 >> i;
809        }
810
811        if (grp_depl_used)
812                tmp |= ((u32)bp->grp_bp_depleted_num - 1) <<
813                    BMI_POOL_DEP_NUM_OF_POOLS_SHIFT;
814
815        iowrite32be(tmp, bp_depl_reg);
816        return 0;
817}
818
819static bool is_init_done(struct fman_port_cfg *cfg)
820{
821        /* Checks if FMan port driver parameters were initialized */
822        if (!cfg)
823                return true;
824
825        return false;
826}
827
828static int verify_size_of_fifo(struct fman_port *port)
829{
830        u32 min_fifo_size_required = 0, opt_fifo_size_for_b2b = 0;
831
832        /* TX Ports */
833        if (port->port_type == FMAN_PORT_TYPE_TX) {
834                min_fifo_size_required = (u32)
835                    (roundup(port->max_frame_length,
836                             FMAN_BMI_FIFO_UNITS) + (3 * FMAN_BMI_FIFO_UNITS));
837
838                min_fifo_size_required +=
839                    port->cfg->tx_fifo_deq_pipeline_depth *
840                    FMAN_BMI_FIFO_UNITS;
841
842                opt_fifo_size_for_b2b = min_fifo_size_required;
843
844                /* Add some margin for back-to-back capability to improve
845                 * performance, allows the hardware to pipeline new frame dma
846                 * while the previous frame not yet transmitted.
847                 */
848                if (port->port_speed == 10000)
849                        opt_fifo_size_for_b2b += 3 * FMAN_BMI_FIFO_UNITS;
850                else
851                        opt_fifo_size_for_b2b += 2 * FMAN_BMI_FIFO_UNITS;
852        }
853
854        /* RX Ports */
855        else if (port->port_type == FMAN_PORT_TYPE_RX) {
856                if (port->rev_info.major >= 6)
857                        min_fifo_size_required = (u32)
858                        (roundup(port->max_frame_length,
859                                 FMAN_BMI_FIFO_UNITS) +
860                                 (5 * FMAN_BMI_FIFO_UNITS));
861                        /* 4 according to spec + 1 for FOF>0 */
862                else
863                        min_fifo_size_required = (u32)
864                        (roundup(min(port->max_frame_length,
865                                     port->rx_pools_params.largest_buf_size),
866                                     FMAN_BMI_FIFO_UNITS) +
867                                     (7 * FMAN_BMI_FIFO_UNITS));
868
869                opt_fifo_size_for_b2b = min_fifo_size_required;
870
871                /* Add some margin for back-to-back capability to improve
872                 * performance,allows the hardware to pipeline new frame dma
873                 * while the previous frame not yet transmitted.
874                 */
875                if (port->port_speed == 10000)
876                        opt_fifo_size_for_b2b += 8 * FMAN_BMI_FIFO_UNITS;
877                else
878                        opt_fifo_size_for_b2b += 3 * FMAN_BMI_FIFO_UNITS;
879        }
880
881        WARN_ON(min_fifo_size_required <= 0);
882        WARN_ON(opt_fifo_size_for_b2b < min_fifo_size_required);
883
884        /* Verify the size  */
885        if (port->fifo_bufs.num < min_fifo_size_required)
886                pr_debug("FIFO size should be enlarged to %d bytes\n",
887                         min_fifo_size_required);
888        else if (port->fifo_bufs.num < opt_fifo_size_for_b2b)
889                pr_debug("For b2b processing,FIFO may be enlarged to %d bytes\n",
890                         opt_fifo_size_for_b2b);
891
892        return 0;
893}
894
895static int set_ext_buffer_pools(struct fman_port *port)
896{
897        struct fman_ext_pools *ext_buf_pools = &port->cfg->ext_buf_pools;
898        struct fman_buf_pool_depletion *buf_pool_depletion =
899        &port->cfg->buf_pool_depletion;
900        u8 ordered_array[FMAN_PORT_MAX_EXT_POOLS_NUM];
901        u16 sizes_array[BM_MAX_NUM_OF_POOLS];
902        int i = 0, j = 0, err;
903        struct fman_port_bpools bpools;
904
905        memset(&ordered_array, 0, sizeof(u8) * FMAN_PORT_MAX_EXT_POOLS_NUM);
906        memset(&sizes_array, 0, sizeof(u16) * BM_MAX_NUM_OF_POOLS);
907        memcpy(&port->ext_buf_pools, ext_buf_pools,
908               sizeof(struct fman_ext_pools));
909
910        fman_sp_set_buf_pools_in_asc_order_of_buf_sizes(ext_buf_pools,
911                                                        ordered_array,
912                                                        sizes_array);
913
914        memset(&bpools, 0, sizeof(struct fman_port_bpools));
915        bpools.count = ext_buf_pools->num_of_pools_used;
916        bpools.counters_enable = true;
917        for (i = 0; i < ext_buf_pools->num_of_pools_used; i++) {
918                bpools.bpool[i].bpid = ordered_array[i];
919                bpools.bpool[i].size = sizes_array[ordered_array[i]];
920        }
921
922        /* save pools parameters for later use */
923        port->rx_pools_params.num_of_pools = ext_buf_pools->num_of_pools_used;
924        port->rx_pools_params.largest_buf_size =
925            sizes_array[ordered_array[ext_buf_pools->num_of_pools_used - 1]];
926        port->rx_pools_params.second_largest_buf_size =
927            sizes_array[ordered_array[ext_buf_pools->num_of_pools_used - 2]];
928
929        /* FMBM_RMPD reg. - pool depletion */
930        if (buf_pool_depletion->pools_grp_mode_enable) {
931                bpools.grp_bp_depleted_num = buf_pool_depletion->num_of_pools;
932                for (i = 0; i < port->bm_max_num_of_pools; i++) {
933                        if (buf_pool_depletion->pools_to_consider[i]) {
934                                for (j = 0; j < ext_buf_pools->
935                                     num_of_pools_used; j++) {
936                                        if (i == ordered_array[j]) {
937                                                bpools.bpool[j].
938                                                    grp_bp_depleted = true;
939                                                break;
940                                        }
941                                }
942                        }
943                }
944        }
945
946        if (buf_pool_depletion->single_pool_mode_enable) {
947                for (i = 0; i < port->bm_max_num_of_pools; i++) {
948                        if (buf_pool_depletion->
949                            pools_to_consider_for_single_mode[i]) {
950                                for (j = 0; j < ext_buf_pools->
951                                     num_of_pools_used; j++) {
952                                        if (i == ordered_array[j]) {
953                                                bpools.bpool[j].
954                                                    single_bp_depleted = true;
955                                                break;
956                                        }
957                                }
958                        }
959                }
960        }
961
962        err = set_bpools(port, &bpools);
963        if (err != 0) {
964                pr_err("FMan port: set_bpools\n");
965                return -EINVAL;
966        }
967
968        return 0;
969}
970
971static int init_low_level_driver(struct fman_port *port)
972{
973        struct fman_port_cfg *cfg = port->cfg;
974        u32 tmp_val;
975
976        switch (port->port_type) {
977        case FMAN_PORT_TYPE_RX:
978                cfg->err_mask = (RX_ERRS_TO_ENQ & ~cfg->discard_mask);
979                if (cfg->forward_reuse_int_context)
980                        cfg->rx_fd_bits = (u8)(BMI_PORT_RFNE_FRWD_RPD >> 24);
981                break;
982        default:
983                break;
984        }
985
986        tmp_val = (u32)((port->internal_buf_offset % OFFSET_UNITS) ?
987                (port->internal_buf_offset / OFFSET_UNITS + 1) :
988                (port->internal_buf_offset / OFFSET_UNITS));
989        port->internal_buf_offset = (u8)(tmp_val * OFFSET_UNITS);
990        port->cfg->int_buf_start_margin = port->internal_buf_offset;
991
992        if (init(port) != 0) {
993                pr_err("fman_port_init\n");
994                return -ENODEV;
995        }
996
997        /* The code bellow is a trick so the FM will not release the buffer
998         * to BM nor will try to enqueue the frame to QM
999         */
1000        if (port->port_type == FMAN_PORT_TYPE_TX) {
1001                if (!cfg->dflt_fqid && cfg->dont_release_buf) {
1002                        /* override fmbm_tcfqid 0 with a false non-0 value.
1003                         * This will force FM to act according to tfene.
1004                         * Otherwise, if fmbm_tcfqid is 0 the FM will release
1005                         * buffers to BM regardless of fmbm_tfene
1006                         */
1007                        out_be32(&port->bmi_regs->tx.fmbm_tcfqid, 0xFFFFFF);
1008                        out_be32(&port->bmi_regs->tx.fmbm_tfene,
1009                                 NIA_ENG_BMI | NIA_BMI_AC_TX_RELEASE);
1010                }
1011        }
1012
1013        return 0;
1014}
1015
1016static int fill_soc_specific_params(struct fman_port *port)
1017{
1018        u32 bmi_max_fifo_size;
1019
1020        bmi_max_fifo_size = fman_get_bmi_max_fifo_size(port->fm);
1021        port->max_port_fifo_size = MAX_PORT_FIFO_SIZE(bmi_max_fifo_size);
1022        port->bm_max_num_of_pools = 64;
1023
1024        /* P4080 - Major 2
1025         * P2041/P3041/P5020/P5040 - Major 3
1026         * Tx/Bx - Major 6
1027         */
1028        switch (port->rev_info.major) {
1029        case 2:
1030        case 3:
1031                port->max_num_of_ext_pools              = 4;
1032                port->max_num_of_sub_portals            = 12;
1033                break;
1034
1035        case 6:
1036                port->max_num_of_ext_pools              = 8;
1037                port->max_num_of_sub_portals            = 16;
1038                break;
1039
1040        default:
1041                pr_err("Unsupported FMan version\n");
1042                return -EINVAL;
1043        }
1044
1045        return 0;
1046}
1047
1048static int get_dflt_fifo_deq_pipeline_depth(u8 major, enum fman_port_type type,
1049                                            u16 speed)
1050{
1051        switch (type) {
1052        case FMAN_PORT_TYPE_RX:
1053        case FMAN_PORT_TYPE_TX:
1054                switch (speed) {
1055                case 10000:
1056                        return 4;
1057                case 1000:
1058                        if (major >= 6)
1059                                return 2;
1060                        else
1061                                return 1;
1062                default:
1063                        return 0;
1064                }
1065        default:
1066                return 0;
1067        }
1068}
1069
1070static int get_dflt_num_of_tasks(u8 major, enum fman_port_type type,
1071                                 u16 speed)
1072{
1073        switch (type) {
1074        case FMAN_PORT_TYPE_RX:
1075        case FMAN_PORT_TYPE_TX:
1076                switch (speed) {
1077                case 10000:
1078                        return 16;
1079                case 1000:
1080                        if (major >= 6)
1081                                return 4;
1082                        else
1083                                return 3;
1084                default:
1085                        return 0;
1086                }
1087        default:
1088                return 0;
1089        }
1090}
1091
1092static int get_dflt_extra_num_of_tasks(u8 major, enum fman_port_type type,
1093                                       u16 speed)
1094{
1095        switch (type) {
1096        case FMAN_PORT_TYPE_RX:
1097                /* FMan V3 */
1098                if (major >= 6)
1099                        return 0;
1100
1101                /* FMan V2 */
1102                if (speed == 10000)
1103                        return 8;
1104                else
1105                        return 2;
1106        case FMAN_PORT_TYPE_TX:
1107        default:
1108                return 0;
1109        }
1110}
1111
1112static int get_dflt_num_of_open_dmas(u8 major, enum fman_port_type type,
1113                                     u16 speed)
1114{
1115        int val;
1116
1117        if (major >= 6) {
1118                switch (type) {
1119                case FMAN_PORT_TYPE_TX:
1120                        if (speed == 10000)
1121                                val = 12;
1122                        else
1123                                val = 3;
1124                        break;
1125                case FMAN_PORT_TYPE_RX:
1126                        if (speed == 10000)
1127                                val = 8;
1128                        else
1129                                val = 2;
1130                        break;
1131                default:
1132                        return 0;
1133                }
1134        } else {
1135                switch (type) {
1136                case FMAN_PORT_TYPE_TX:
1137                case FMAN_PORT_TYPE_RX:
1138                        if (speed == 10000)
1139                                val = 8;
1140                        else
1141                                val = 1;
1142                        break;
1143                default:
1144                        val = 0;
1145                }
1146        }
1147
1148        return val;
1149}
1150
1151static int get_dflt_extra_num_of_open_dmas(u8 major, enum fman_port_type type,
1152                                           u16 speed)
1153{
1154        /* FMan V3 */
1155        if (major >= 6)
1156                return 0;
1157
1158        /* FMan V2 */
1159        switch (type) {
1160        case FMAN_PORT_TYPE_RX:
1161        case FMAN_PORT_TYPE_TX:
1162                if (speed == 10000)
1163                        return 8;
1164                else
1165                        return 1;
1166        default:
1167                return 0;
1168        }
1169}
1170
1171static int get_dflt_num_of_fifo_bufs(u8 major, enum fman_port_type type,
1172                                     u16 speed)
1173{
1174        int val;
1175
1176        if (major >= 6) {
1177                switch (type) {
1178                case FMAN_PORT_TYPE_TX:
1179                        if (speed == 10000)
1180                                val = 64;
1181                        else
1182                                val = 50;
1183                        break;
1184                case FMAN_PORT_TYPE_RX:
1185                        if (speed == 10000)
1186                                val = 96;
1187                        else
1188                                val = 50;
1189                        break;
1190                default:
1191                        val = 0;
1192                }
1193        } else {
1194                switch (type) {
1195                case FMAN_PORT_TYPE_TX:
1196                        if (speed == 10000)
1197                                val = 48;
1198                        else
1199                                val = 44;
1200                        break;
1201                case FMAN_PORT_TYPE_RX:
1202                        if (speed == 10000)
1203                                val = 48;
1204                        else
1205                                val = 45;
1206                        break;
1207                default:
1208                        val = 0;
1209                }
1210        }
1211
1212        return val;
1213}
1214
1215static void set_dflt_cfg(struct fman_port *port,
1216                         struct fman_port_params *port_params)
1217{
1218        struct fman_port_cfg *cfg = port->cfg;
1219
1220        cfg->dma_swap_data = FMAN_PORT_DMA_NO_SWAP;
1221        cfg->dma_write_optimize = true;
1222        cfg->color = FMAN_PORT_COLOR_GREEN;
1223        cfg->rx_cut_end_bytes = DFLT_PORT_CUT_BYTES_FROM_END;
1224        cfg->rx_pri_elevation = BMI_PRIORITY_ELEVATION_LEVEL;
1225        cfg->rx_fifo_thr = BMI_FIFO_THRESHOLD;
1226        cfg->tx_fifo_low_comf_level = (5 * 1024);
1227        cfg->deq_type = FMAN_PORT_DEQ_BY_PRI;
1228        cfg->sync_req = true;
1229        cfg->deq_prefetch_option = FMAN_PORT_DEQ_FULL_PREFETCH;
1230        cfg->tx_fifo_deq_pipeline_depth =
1231                BMI_DEQUEUE_PIPELINE_DEPTH(port->port_type, port->port_speed);
1232        cfg->deq_byte_cnt = QMI_BYTE_COUNT_LEVEL_CONTROL(port->port_type);
1233
1234        cfg->rx_pri_elevation =
1235                DFLT_PORT_RX_FIFO_PRI_ELEVATION_LEV(port->max_port_fifo_size);
1236        port->cfg->rx_fifo_thr =
1237                DFLT_PORT_RX_FIFO_THRESHOLD(port->rev_info.major,
1238                                            port->max_port_fifo_size);
1239
1240        if ((port->rev_info.major == 6) &&
1241            ((port->rev_info.minor == 0) || (port->rev_info.minor == 3)))
1242                cfg->errata_A006320 = true;
1243
1244        /* Excessive Threshold register - exists for pre-FMv3 chips only */
1245        if (port->rev_info.major < 6) {
1246                cfg->excessive_threshold_register = true;
1247        } else {
1248                cfg->fmbm_rebm_has_sgd = true;
1249                cfg->fmbm_tfne_has_features = true;
1250        }
1251
1252        cfg->qmi_deq_options_support = true;
1253
1254        cfg->buffer_prefix_content.data_align =
1255                DFLT_PORT_BUFFER_PREFIX_CONTEXT_DATA_ALIGN;
1256}
1257
1258static void set_rx_dflt_cfg(struct fman_port *port,
1259                            struct fman_port_params *port_params)
1260{
1261        port->cfg->discard_mask = DFLT_PORT_ERRORS_TO_DISCARD;
1262
1263        memcpy(&port->cfg->ext_buf_pools,
1264               &port_params->specific_params.rx_params.ext_buf_pools,
1265               sizeof(struct fman_ext_pools));
1266        port->cfg->err_fqid =
1267                port_params->specific_params.rx_params.err_fqid;
1268        port->cfg->dflt_fqid =
1269                port_params->specific_params.rx_params.dflt_fqid;
1270
1271        /* Set BCB workaround on Rx ports, only for B4860 rev1 */
1272        if (port->rev_info.major >= 6) {
1273                unsigned int svr;
1274
1275                svr = mfspr(SPRN_SVR);
1276                if ((SVR_SOC_VER(svr) == SVR_B4860) && (SVR_MAJ(svr) == 1))
1277                        port->cfg->bcb_workaround = true;
1278        }
1279}
1280
1281static void set_tx_dflt_cfg(struct fman_port *port,
1282                            struct fman_port_params *port_params,
1283                            struct fman_port_dts_params *dts_params)
1284{
1285        port->cfg->tx_fifo_deq_pipeline_depth =
1286                get_dflt_fifo_deq_pipeline_depth(port->rev_info.major,
1287                                                 port->port_type,
1288                                                 port->port_speed);
1289        port->cfg->err_fqid =
1290                port_params->specific_params.non_rx_params.err_fqid;
1291        port->cfg->deq_sp =
1292                (u8)(dts_params->qman_channel_id & QMI_DEQ_CFG_SUBPORTAL_MASK);
1293        port->cfg->dflt_fqid =
1294                port_params->specific_params.non_rx_params.dflt_fqid;
1295        port->cfg->deq_high_priority = true;
1296}
1297
1298int fman_port_config(struct fman_port *port, struct fman_port_params *params)
1299{
1300        void __iomem *base_addr = port->dts_params.base_addr;
1301        int err;
1302
1303        /* Allocate the FM driver's parameters structure */
1304        port->cfg = kzalloc(sizeof(*port->cfg), GFP_KERNEL);
1305        if (!port->cfg)
1306                goto err_params;
1307
1308        /* Initialize FM port parameters which will be kept by the driver */
1309        port->port_type = port->dts_params.type;
1310        port->port_speed = port->dts_params.speed;
1311        port->port_id = port->dts_params.id;
1312        port->fm = port->dts_params.fman;
1313        port->ext_pools_num = (u8)8;
1314
1315        /* get FM revision */
1316        fman_get_revision(port->fm, &port->rev_info);
1317
1318        err = fill_soc_specific_params(port);
1319        if (err)
1320                goto err_port_cfg;
1321
1322        switch (port->port_type) {
1323        case FMAN_PORT_TYPE_RX:
1324                set_rx_dflt_cfg(port, params);
1325        case FMAN_PORT_TYPE_TX:
1326                set_tx_dflt_cfg(port, params, &port->dts_params);
1327        default:
1328                set_dflt_cfg(port, params);
1329        }
1330
1331        /* Continue with other parameters */
1332        /* set memory map pointers */
1333        port->bmi_regs = (union fman_port_bmi_regs __iomem *)
1334                         (base_addr + BMI_PORT_REGS_OFFSET);
1335        port->qmi_regs = (struct fman_port_qmi_regs __iomem *)
1336                         (base_addr + QMI_PORT_REGS_OFFSET);
1337
1338        port->max_frame_length = DFLT_PORT_MAX_FRAME_LENGTH;
1339        /* resource distribution. */
1340
1341        port->fifo_bufs.num =
1342        get_dflt_num_of_fifo_bufs(port->rev_info.major, port->port_type,
1343                                  port->port_speed) * FMAN_BMI_FIFO_UNITS;
1344        port->fifo_bufs.extra =
1345        DFLT_PORT_EXTRA_NUM_OF_FIFO_BUFS * FMAN_BMI_FIFO_UNITS;
1346
1347        port->open_dmas.num =
1348        get_dflt_num_of_open_dmas(port->rev_info.major,
1349                                  port->port_type, port->port_speed);
1350        port->open_dmas.extra =
1351        get_dflt_extra_num_of_open_dmas(port->rev_info.major,
1352                                        port->port_type, port->port_speed);
1353        port->tasks.num =
1354        get_dflt_num_of_tasks(port->rev_info.major,
1355                              port->port_type, port->port_speed);
1356        port->tasks.extra =
1357        get_dflt_extra_num_of_tasks(port->rev_info.major,
1358                                    port->port_type, port->port_speed);
1359
1360        /* FM_HEAVY_TRAFFIC_SEQUENCER_HANG_ERRATA_FMAN_A006981 errata
1361         * workaround
1362         */
1363        if ((port->rev_info.major == 6) && (port->rev_info.minor == 0) &&
1364            (((port->port_type == FMAN_PORT_TYPE_TX) &&
1365            (port->port_speed == 1000)))) {
1366                port->open_dmas.num = 16;
1367                port->open_dmas.extra = 0;
1368        }
1369
1370        if (port->rev_info.major >= 6 &&
1371            port->port_type == FMAN_PORT_TYPE_TX &&
1372            port->port_speed == 1000) {
1373                /* FM_WRONG_RESET_VALUES_ERRATA_FMAN_A005127 Errata
1374                 * workaround
1375                 */
1376                if (port->rev_info.major >= 6) {
1377                        u32 reg;
1378
1379                        reg = 0x00001013;
1380                        out_be32(&port->bmi_regs->tx.fmbm_tfp, reg);
1381                }
1382        }
1383
1384        return 0;
1385
1386err_port_cfg:
1387        kfree(port->cfg);
1388err_params:
1389        kfree(port);
1390        return -EINVAL;
1391}
1392EXPORT_SYMBOL(fman_port_config);
1393
1394int fman_port_init(struct fman_port *port)
1395{
1396        struct fman_port_cfg *cfg;
1397        int err;
1398        struct fman_port_init_params params;
1399
1400        if (is_init_done(port->cfg))
1401                return -EINVAL;
1402
1403        err = fman_sp_build_buffer_struct(&port->cfg->int_context,
1404                                          &port->cfg->buffer_prefix_content,
1405                                          &port->cfg->buf_margins,
1406                                          &port->buffer_offsets,
1407                                          &port->internal_buf_offset);
1408        if (err)
1409                return err;
1410
1411        /* FM_HEAVY_TRAFFIC_HANG_ERRATA_FMAN_A005669 Errata workaround */
1412        if (port->rev_info.major >= 6 && (port->cfg->bcb_workaround) &&
1413            ((port->port_type == FMAN_PORT_TYPE_RX) &&
1414            (port->port_speed == 1000))) {
1415                port->cfg->discard_mask |= FM_PORT_FRM_ERR_PHYSICAL;
1416                port->fifo_bufs.num += 4 * 1024;
1417        }
1418
1419        cfg = port->cfg;
1420
1421        if (port->port_type == FMAN_PORT_TYPE_RX) {
1422                /* Call the external Buffer routine which also checks fifo
1423                 * size and updates it if necessary
1424                 */
1425                /* define external buffer pools and pool depletion */
1426                err = set_ext_buffer_pools(port);
1427                if (err)
1428                        return err;
1429                /* check if the largest external buffer pool is large enough */
1430                if (cfg->buf_margins.start_margins + MIN_EXT_BUF_SIZE +
1431                    cfg->buf_margins.end_margins >
1432                    port->rx_pools_params.largest_buf_size) {
1433                        pr_err("buf_margins.start_margins (%d) + minimum buf size (64) + buf_margins.end_margins (%d) is larger than maximum external buffer size (%d)\n",
1434                               cfg->buf_margins.start_margins,
1435                               cfg->buf_margins.end_margins,
1436                               port->rx_pools_params.largest_buf_size);
1437                        return -EINVAL;
1438                }
1439        }
1440
1441        /* Call FM module routine for communicating parameters */
1442        memset(&params, 0, sizeof(params));
1443        params.port_id = port->port_id;
1444        params.port_type = port->port_type;
1445        params.port_speed = port->port_speed;
1446        params.num_of_tasks = (u8)port->tasks.num;
1447        params.num_of_extra_tasks = (u8)port->tasks.extra;
1448        params.num_of_open_dmas = (u8)port->open_dmas.num;
1449        params.num_of_extra_open_dmas = (u8)port->open_dmas.extra;
1450
1451        if (port->fifo_bufs.num) {
1452                err = verify_size_of_fifo(port);
1453                if (err)
1454                        return err;
1455        }
1456        params.size_of_fifo = port->fifo_bufs.num;
1457        params.extra_size_of_fifo = port->fifo_bufs.extra;
1458        params.deq_pipeline_depth = port->cfg->tx_fifo_deq_pipeline_depth;
1459        params.max_frame_length = port->max_frame_length;
1460
1461        err = fman_set_port_params(port->fm, &params);
1462        if (err)
1463                return err;
1464
1465        err = init_low_level_driver(port);
1466        if (err)
1467                return err;
1468
1469        kfree(port->cfg);
1470        port->cfg = NULL;
1471
1472        return 0;
1473}
1474EXPORT_SYMBOL(fman_port_init);
1475
1476int fman_port_cfg_buf_prefix_content(struct fman_port *port,
1477                                     struct fman_buffer_prefix_content *
1478                                     buffer_prefix_content)
1479{
1480        if (is_init_done(port->cfg))
1481                return -EINVAL;
1482
1483        memcpy(&port->cfg->buffer_prefix_content,
1484               buffer_prefix_content,
1485               sizeof(struct fman_buffer_prefix_content));
1486        /* if data_align was not initialized by user,
1487         * we return to driver's default
1488         */
1489        if (!port->cfg->buffer_prefix_content.data_align)
1490                port->cfg->buffer_prefix_content.data_align =
1491                DFLT_PORT_BUFFER_PREFIX_CONTEXT_DATA_ALIGN;
1492
1493        return 0;
1494}
1495EXPORT_SYMBOL(fman_port_cfg_buf_prefix_content);
1496
1497int fman_port_disable(struct fman_port *port)
1498{
1499        u32 __iomem *bmi_cfg_reg, *bmi_status_reg, tmp;
1500        bool rx_port, failure = false;
1501        int count;
1502
1503        if (!is_init_done(port->cfg))
1504                return -EINVAL;
1505
1506        switch (port->port_type) {
1507        case FMAN_PORT_TYPE_RX:
1508                bmi_cfg_reg = &port->bmi_regs->rx.fmbm_rcfg;
1509                bmi_status_reg = &port->bmi_regs->rx.fmbm_rst;
1510                rx_port = true;
1511                break;
1512        case FMAN_PORT_TYPE_TX:
1513                bmi_cfg_reg = &port->bmi_regs->tx.fmbm_tcfg;
1514                bmi_status_reg = &port->bmi_regs->tx.fmbm_tst;
1515                rx_port = false;
1516                break;
1517        default:
1518                return -EINVAL;
1519        }
1520
1521        /* Disable QMI */
1522        if (!rx_port) {
1523                tmp = ioread32be(&port->qmi_regs->fmqm_pnc) & ~QMI_PORT_CFG_EN;
1524                iowrite32be(tmp, &port->qmi_regs->fmqm_pnc);
1525
1526                /* Wait for QMI to finish FD handling */
1527                count = 100;
1528                do {
1529                        udelay(10);
1530                        tmp = ioread32be(&port->qmi_regs->fmqm_pns);
1531                } while ((tmp & QMI_PORT_STATUS_DEQ_FD_BSY) && --count);
1532
1533                if (count == 0) {
1534                        /* Timeout */
1535                        failure = true;
1536                }
1537        }
1538
1539        /* Disable BMI */
1540        tmp = ioread32be(bmi_cfg_reg) & ~BMI_PORT_CFG_EN;
1541        iowrite32be(tmp, bmi_cfg_reg);
1542
1543        /* Wait for graceful stop end */
1544        count = 500;
1545        do {
1546                udelay(10);
1547                tmp = ioread32be(bmi_status_reg);
1548        } while ((tmp & BMI_PORT_STATUS_BSY) && --count);
1549
1550        if (count == 0) {
1551                /* Timeout */
1552                failure = true;
1553        }
1554
1555        if (failure)
1556                pr_debug("FMan Port[%d]: BMI or QMI is Busy. Port forced down\n",
1557                         port->port_id);
1558
1559        return 0;
1560}
1561EXPORT_SYMBOL(fman_port_disable);
1562
1563int fman_port_enable(struct fman_port *port)
1564{
1565        u32 __iomem *bmi_cfg_reg, tmp;
1566        bool rx_port;
1567
1568        if (!is_init_done(port->cfg))
1569                return -EINVAL;
1570
1571        switch (port->port_type) {
1572        case FMAN_PORT_TYPE_RX:
1573                bmi_cfg_reg = &port->bmi_regs->rx.fmbm_rcfg;
1574                rx_port = true;
1575                break;
1576        case FMAN_PORT_TYPE_TX:
1577                bmi_cfg_reg = &port->bmi_regs->tx.fmbm_tcfg;
1578                rx_port = false;
1579                break;
1580        default:
1581                return -EINVAL;
1582        }
1583
1584        /* Enable QMI */
1585        if (!rx_port) {
1586                tmp = ioread32be(&port->qmi_regs->fmqm_pnc) | QMI_PORT_CFG_EN;
1587                iowrite32be(tmp, &port->qmi_regs->fmqm_pnc);
1588        }
1589
1590        /* Enable BMI */
1591        tmp = ioread32be(bmi_cfg_reg) | BMI_PORT_CFG_EN;
1592        iowrite32be(tmp, bmi_cfg_reg);
1593
1594        return 0;
1595}
1596EXPORT_SYMBOL(fman_port_enable);
1597
1598struct fman_port *fman_port_bind(struct device *dev)
1599{
1600        return (struct fman_port *)(dev_get_drvdata(get_device(dev)));
1601}
1602EXPORT_SYMBOL(fman_port_bind);
1603
1604u32 fman_port_get_qman_channel_id(struct fman_port *port)
1605{
1606        return port->dts_params.qman_channel_id;
1607}
1608EXPORT_SYMBOL(fman_port_get_qman_channel_id);
1609
1610#ifndef __rtems__
1611static int fman_port_probe(struct platform_device *of_dev)
1612#else /* __rtems__ */
1613static int fman_port_probe(struct platform_device *of_dev, struct fman *fman)
1614#endif /* __rtems__ */
1615{
1616        struct fman_port *port;
1617#ifndef __rtems__
1618        struct fman *fman;
1619        struct device_node *fm_node, *port_node;
1620#else /* __rtems__ */
1621        struct device_node *port_node;
1622#endif /* __rtems__ */
1623        struct resource res;
1624#ifndef __rtems__
1625        struct resource *dev_res;
1626#endif /* __rtems__ */
1627        const u32 *u32_prop;
1628        int err = 0, lenp;
1629        enum fman_port_type port_type;
1630        u16 port_speed;
1631        u8 port_id;
1632
1633        port = kzalloc(sizeof(*port), GFP_KERNEL);
1634        if (!port)
1635                return -ENOMEM;
1636
1637        port_node = of_node_get(of_dev->dev.of_node);
1638
1639        /* Get the FM node */
1640#ifndef __rtems__
1641        fm_node = of_get_parent(port_node);
1642        if (!fm_node) {
1643                pr_err("of_get_parent() failed\n");
1644                err = -ENODEV;
1645                goto return_err;
1646        }
1647
1648        fman = dev_get_drvdata(&of_find_device_by_node(fm_node)->dev);
1649        of_node_put(fm_node);
1650        if (!fman) {
1651                err = -EINVAL;
1652                goto return_err;
1653        }
1654#endif /* __rtems__ */
1655
1656        u32_prop = (const u32 *)of_get_property(port_node, "cell-index", &lenp);
1657        if (!u32_prop) {
1658                pr_err("of_get_property(%s, cell-index) failed\n",
1659                       port_node->full_name);
1660                err = -EINVAL;
1661                goto return_err;
1662        }
1663        if (WARN_ON(lenp != sizeof(u32))) {
1664                err = -EINVAL;
1665                goto return_err;
1666        }
1667        port_id = (u8)*u32_prop;
1668
1669        port->dts_params.id = port_id;
1670
1671        if (of_device_is_compatible(port_node, "fsl,fman-v3-port-tx")) {
1672                port_type = FMAN_PORT_TYPE_TX;
1673                port_speed = 1000;
1674                u32_prop = (const u32 *)of_get_property(port_node,
1675                                                        "fsl,fman-10g-port",
1676                                                        &lenp);
1677                if (u32_prop)
1678                        port_speed = 10000;
1679
1680        } else if (of_device_is_compatible(port_node, "fsl,fman-v2-port-tx")) {
1681                if (port_id >= TX_10G_PORT_BASE)
1682                        port_speed = 10000;
1683                else
1684                        port_speed = 1000;
1685                port_type = FMAN_PORT_TYPE_TX;
1686
1687        } else if (of_device_is_compatible(port_node, "fsl,fman-v3-port-rx")) {
1688                port_type = FMAN_PORT_TYPE_RX;
1689                port_speed = 1000;
1690                u32_prop = (const u32 *)of_get_property(port_node,
1691                                                  "fsl,fman-10g-port", &lenp);
1692                if (u32_prop)
1693                        port_speed = 10000;
1694
1695        } else if (of_device_is_compatible(port_node, "fsl,fman-v2-port-rx")) {
1696                if (port_id >= RX_10G_PORT_BASE)
1697                        port_speed = 10000;
1698                else
1699                        port_speed = 1000;
1700                port_type = FMAN_PORT_TYPE_RX;
1701
1702        }  else {
1703                pr_err("Illegal port type\n");
1704                err = -EINVAL;
1705                goto return_err;
1706        }
1707
1708        port->dts_params.type = port_type;
1709        port->dts_params.speed = port_speed;
1710
1711        if (port_type == FMAN_PORT_TYPE_TX) {
1712                u32 qman_channel_id;
1713
1714                qman_channel_id = fman_get_qman_channel_id(fman, port_id);
1715                if (qman_channel_id == 0) {
1716                        pr_err("incorrect qman-channel-id\n");
1717                        err = -EINVAL;
1718                        goto return_err;
1719                }
1720                port->dts_params.qman_channel_id = qman_channel_id;
1721        }
1722
1723        err = of_address_to_resource(port_node, 0, &res);
1724        if (err < 0) {
1725                pr_err("of_address_to_resource() failed\n");
1726                err = -ENOMEM;
1727                goto return_err;
1728        }
1729
1730        port->dts_params.fman = fman;
1731
1732        of_node_put(port_node);
1733
1734#ifndef __rtems__
1735        dev_res = __devm_request_region(fman_get_device(fman), &res,
1736                                        res.start, (res.end + 1 - res.start),
1737                                        "fman-port");
1738        if (!dev_res) {
1739                pr_err("__devm_request_region() failed\n");
1740                err = -EINVAL;
1741                goto free_port;
1742        }
1743#endif /* __rtems__ */
1744
1745        port->dts_params.base_addr = devm_ioremap(fman_get_device(fman),
1746                                                  res.start,
1747                                                  (res.end + 1 - res.start));
1748        if (port->dts_params.base_addr == 0)
1749                pr_err("devm_ioremap() failed\n");
1750
1751        dev_set_drvdata(&of_dev->dev, port);
1752
1753        return 0;
1754
1755return_err:
1756        of_node_put(port_node);
1757#ifndef __rtems__
1758free_port:
1759#endif /* __rtems__ */
1760        kfree(port);
1761        return err;
1762}
1763
1764#ifndef __rtems__
1765static const struct of_device_id fman_port_match[] = {
1766        {.compatible = "fsl,fman-v3-port-rx"},
1767        {.compatible = "fsl,fman-v2-port-rx"},
1768        {.compatible = "fsl,fman-v3-port-tx"},
1769        {.compatible = "fsl,fman-v2-port-tx"},
1770        {}
1771};
1772
1773MODULE_DEVICE_TABLE(of, fman_port_match);
1774
1775static struct platform_driver fman_port_driver = {
1776        .driver = {
1777                   .name = "fsl-fman-port",
1778                   .of_match_table = fman_port_match,
1779                   },
1780        .probe = fman_port_probe,
1781};
1782
1783builtin_platform_driver(fman_port_driver);
1784
1785#else /* __rtems__ */
1786#include <sys/cdefs.h>
1787#include <sys/param.h>
1788#include <sys/systm.h>
1789#include <sys/bus.h>
1790#include <sys/kernel.h>
1791
1792static int
1793fman_port_dev_probe(device_t dev)
1794{
1795        struct fman_ivars *ivars = device_get_ivars(dev);
1796        int err;
1797
1798        err = fman_port_probe(&ivars->of_dev, ivars->fman);
1799        if (err == 0) {
1800                device_set_desc(dev, "FMan Port");
1801                return (BUS_PROBE_DEFAULT);
1802        } else {
1803                return (ENXIO);
1804        }
1805}
1806
1807static device_method_t fman_port_methods[] = {
1808        /* Device interface */
1809        DEVMETHOD(device_probe, fman_port_dev_probe),
1810        DEVMETHOD(device_attach, bus_generic_attach),
1811        DEVMETHOD(device_detach, bus_generic_detach),
1812        DEVMETHOD(device_suspend, bus_generic_suspend),
1813        DEVMETHOD(device_resume, bus_generic_resume),
1814        DEVMETHOD(device_shutdown, bus_generic_shutdown),
1815
1816        DEVMETHOD_END
1817};
1818
1819driver_t fman_port_driver = {
1820        .name = "fman_port",
1821        .methods = fman_port_methods
1822};
1823
1824static devclass_t fman_port_devclass;
1825
1826DRIVER_MODULE(fman_port, fman_mac, fman_port_driver, fman_port_devclass, 0, 0);
1827#endif /* __rtems__ */
Note: See TracBrowser for help on using the repository browser.