1922 lines · c
1// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0-or-later2/*3 * Copyright 2008 - 2015 Freescale Semiconductor Inc.4 */5 6#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt7 8#include <linux/io.h>9#include <linux/platform_device.h>10#include <linux/slab.h>11#include <linux/module.h>12#include <linux/interrupt.h>13#include <linux/of_platform.h>14#include <linux/of_address.h>15#include <linux/delay.h>16#include <linux/libfdt_env.h>17 18#include "fman.h"19#include "fman_port.h"20#include "fman_sp.h"21#include "fman_keygen.h"22 23/* Queue ID */24#define DFLT_FQ_ID 0x00FFFFFF25 26/* General defines */27#define PORT_BMI_FIFO_UNITS 0x10028 29#define MAX_PORT_FIFO_SIZE(bmi_max_fifo_size) \30 min((u32)bmi_max_fifo_size, (u32)1024 * FMAN_BMI_FIFO_UNITS)31 32#define PORT_CG_MAP_NUM 833#define PORT_PRS_RESULT_WORDS_NUM 834#define PORT_IC_OFFSET_UNITS 0x1035 36#define MIN_EXT_BUF_SIZE 6437 38#define BMI_PORT_REGS_OFFSET 039#define QMI_PORT_REGS_OFFSET 0x40040#define HWP_PORT_REGS_OFFSET 0x80041 42/* Default values */43#define DFLT_PORT_BUFFER_PREFIX_CONTEXT_DATA_ALIGN \44 DFLT_FM_SP_BUFFER_PREFIX_CONTEXT_DATA_ALIGN45 46#define DFLT_PORT_CUT_BYTES_FROM_END 447 48#define DFLT_PORT_ERRORS_TO_DISCARD FM_PORT_FRM_ERR_CLS_DISCARD49#define DFLT_PORT_MAX_FRAME_LENGTH 960050 51#define DFLT_PORT_RX_FIFO_PRI_ELEVATION_LEV(bmi_max_fifo_size) \52 MAX_PORT_FIFO_SIZE(bmi_max_fifo_size)53 54#define DFLT_PORT_RX_FIFO_THRESHOLD(major, bmi_max_fifo_size) \55 (major == 6 ? \56 MAX_PORT_FIFO_SIZE(bmi_max_fifo_size) : \57 (MAX_PORT_FIFO_SIZE(bmi_max_fifo_size) * 3 / 4)) \58 59#define DFLT_PORT_EXTRA_NUM_OF_FIFO_BUFS 060 61/* QMI defines */62#define QMI_DEQ_CFG_SUBPORTAL_MASK 0x1f63 64#define QMI_PORT_CFG_EN 0x8000000065#define QMI_PORT_STATUS_DEQ_FD_BSY 0x2000000066 67#define QMI_DEQ_CFG_PRI 0x8000000068#define QMI_DEQ_CFG_TYPE1 0x1000000069#define QMI_DEQ_CFG_TYPE2 0x2000000070#define QMI_DEQ_CFG_TYPE3 0x3000000071#define QMI_DEQ_CFG_PREFETCH_PARTIAL 0x0100000072#define QMI_DEQ_CFG_PREFETCH_FULL 0x0300000073#define QMI_DEQ_CFG_SP_MASK 0xf74#define QMI_DEQ_CFG_SP_SHIFT 2075 76#define QMI_BYTE_COUNT_LEVEL_CONTROL(_type) \77 (_type == FMAN_PORT_TYPE_TX ? 0x1400 : 0x400)78 79/* BMI defins */80#define BMI_EBD_EN 0x8000000081 82#define BMI_PORT_CFG_EN 0x8000000083 84#define BMI_PORT_STATUS_BSY 0x8000000085 86#define BMI_DMA_ATTR_SWP_SHIFT FMAN_SP_DMA_ATTR_SWP_SHIFT87#define BMI_DMA_ATTR_WRITE_OPTIMIZE FMAN_SP_DMA_ATTR_WRITE_OPTIMIZE88 89#define BMI_RX_FIFO_PRI_ELEVATION_SHIFT 1690#define BMI_RX_FIFO_THRESHOLD_ETHE 0x8000000091 92#define BMI_FRAME_END_CS_IGNORE_SHIFT 2493#define BMI_FRAME_END_CS_IGNORE_MASK 0x0000001f94 95#define BMI_RX_FRAME_END_CUT_SHIFT 1696#define BMI_RX_FRAME_END_CUT_MASK 0x0000001f97 98#define BMI_IC_TO_EXT_SHIFT FMAN_SP_IC_TO_EXT_SHIFT99#define BMI_IC_TO_EXT_MASK 0x0000001f100#define BMI_IC_FROM_INT_SHIFT FMAN_SP_IC_FROM_INT_SHIFT101#define BMI_IC_FROM_INT_MASK 0x0000000f102#define BMI_IC_SIZE_MASK 0x0000001f103 104#define BMI_INT_BUF_MARG_SHIFT 28105#define BMI_INT_BUF_MARG_MASK 0x0000000f106#define BMI_EXT_BUF_MARG_START_SHIFT FMAN_SP_EXT_BUF_MARG_START_SHIFT107#define BMI_EXT_BUF_MARG_START_MASK 0x000001ff108#define BMI_EXT_BUF_MARG_END_MASK 0x000001ff109 110#define BMI_CMD_MR_LEAC 0x00200000111#define BMI_CMD_MR_SLEAC 0x00100000112#define BMI_CMD_MR_MA 0x00080000113#define BMI_CMD_MR_DEAS 0x00040000114#define BMI_CMD_RX_MR_DEF (BMI_CMD_MR_LEAC | \115 BMI_CMD_MR_SLEAC | \116 BMI_CMD_MR_MA | \117 BMI_CMD_MR_DEAS)118#define BMI_CMD_TX_MR_DEF 0119 120#define BMI_CMD_ATTR_ORDER 0x80000000121#define BMI_CMD_ATTR_SYNC 0x02000000122#define BMI_CMD_ATTR_COLOR_SHIFT 26123 124#define BMI_FIFO_PIPELINE_DEPTH_SHIFT 12125#define BMI_FIFO_PIPELINE_DEPTH_MASK 0x0000000f126#define BMI_NEXT_ENG_FD_BITS_SHIFT 24127 128#define BMI_EXT_BUF_POOL_VALID FMAN_SP_EXT_BUF_POOL_VALID129#define BMI_EXT_BUF_POOL_EN_COUNTER FMAN_SP_EXT_BUF_POOL_EN_COUNTER130#define BMI_EXT_BUF_POOL_BACKUP FMAN_SP_EXT_BUF_POOL_BACKUP131#define BMI_EXT_BUF_POOL_ID_SHIFT 16132#define BMI_EXT_BUF_POOL_ID_MASK 0x003F0000133#define BMI_POOL_DEP_NUM_OF_POOLS_SHIFT 16134 135#define BMI_TX_FIFO_MIN_FILL_SHIFT 16136 137#define BMI_PRIORITY_ELEVATION_LEVEL ((0x3FF + 1) * PORT_BMI_FIFO_UNITS)138#define BMI_FIFO_THRESHOLD ((0x3FF + 1) * PORT_BMI_FIFO_UNITS)139 140#define BMI_DEQUEUE_PIPELINE_DEPTH(_type, _speed) \141 ((_type == FMAN_PORT_TYPE_TX && _speed == 10000) ? 4 : 1)142 143#define RX_ERRS_TO_ENQ \144 (FM_PORT_FRM_ERR_DMA | \145 FM_PORT_FRM_ERR_PHYSICAL | \146 FM_PORT_FRM_ERR_SIZE | \147 FM_PORT_FRM_ERR_EXTRACTION | \148 FM_PORT_FRM_ERR_NO_SCHEME | \149 FM_PORT_FRM_ERR_PRS_TIMEOUT | \150 FM_PORT_FRM_ERR_PRS_ILL_INSTRUCT | \151 FM_PORT_FRM_ERR_BLOCK_LIMIT_EXCEEDED | \152 FM_PORT_FRM_ERR_PRS_HDR_ERR | \153 FM_PORT_FRM_ERR_KEYSIZE_OVERFLOW | \154 FM_PORT_FRM_ERR_IPRE)155 156/* NIA defines */157#define NIA_ORDER_RESTOR 0x00800000158#define NIA_ENG_BMI 0x00500000159#define NIA_ENG_QMI_ENQ 0x00540000160#define NIA_ENG_QMI_DEQ 0x00580000161#define NIA_ENG_HWP 0x00440000162#define NIA_ENG_HWK 0x00480000163#define NIA_BMI_AC_ENQ_FRAME 0x00000002164#define NIA_BMI_AC_TX_RELEASE 0x000002C0165#define NIA_BMI_AC_RELEASE 0x000000C0166#define NIA_BMI_AC_TX 0x00000274167#define NIA_BMI_AC_FETCH_ALL_FRAME 0x0000020c168 169/* Port IDs */170#define TX_10G_PORT_BASE 0x30171#define RX_10G_PORT_BASE 0x10172 173/* BMI Rx port register map */174struct fman_port_rx_bmi_regs {175 u32 fmbm_rcfg; /* Rx Configuration */176 u32 fmbm_rst; /* Rx Status */177 u32 fmbm_rda; /* Rx DMA attributes */178 u32 fmbm_rfp; /* Rx FIFO Parameters */179 u32 fmbm_rfed; /* Rx Frame End Data */180 u32 fmbm_ricp; /* Rx Internal Context Parameters */181 u32 fmbm_rim; /* Rx Internal Buffer Margins */182 u32 fmbm_rebm; /* Rx External Buffer Margins */183 u32 fmbm_rfne; /* Rx Frame Next Engine */184 u32 fmbm_rfca; /* Rx Frame Command Attributes. */185 u32 fmbm_rfpne; /* Rx Frame Parser Next Engine */186 u32 fmbm_rpso; /* Rx Parse Start Offset */187 u32 fmbm_rpp; /* Rx Policer Profile */188 u32 fmbm_rccb; /* Rx Coarse Classification Base */189 u32 fmbm_reth; /* Rx Excessive Threshold */190 u32 reserved003c[1]; /* (0x03C 0x03F) */191 u32 fmbm_rprai[PORT_PRS_RESULT_WORDS_NUM];192 /* Rx Parse Results Array Init */193 u32 fmbm_rfqid; /* Rx Frame Queue ID */194 u32 fmbm_refqid; /* Rx Error Frame Queue ID */195 u32 fmbm_rfsdm; /* Rx Frame Status Discard Mask */196 u32 fmbm_rfsem; /* Rx Frame Status Error Mask */197 u32 fmbm_rfene; /* Rx Frame Enqueue Next Engine */198 u32 reserved0074[0x2]; /* (0x074-0x07C) */199 u32 fmbm_rcmne; /* Rx Frame Continuous Mode Next Engine */200 u32 reserved0080[0x20]; /* (0x080 0x0FF) */201 u32 fmbm_ebmpi[FMAN_PORT_MAX_EXT_POOLS_NUM];202 /* Buffer Manager pool Information- */203 u32 fmbm_acnt[FMAN_PORT_MAX_EXT_POOLS_NUM]; /* Allocate Counter- */204 u32 reserved0130[8]; /* 0x130/0x140 - 0x15F reserved - */205 u32 fmbm_rcgm[PORT_CG_MAP_NUM]; /* Congestion Group Map */206 u32 fmbm_mpd; /* BM Pool Depletion */207 u32 reserved0184[0x1F]; /* (0x184 0x1FF) */208 u32 fmbm_rstc; /* Rx Statistics Counters */209 u32 fmbm_rfrc; /* Rx Frame Counter */210 u32 fmbm_rfbc; /* Rx Bad Frames Counter */211 u32 fmbm_rlfc; /* Rx Large Frames Counter */212 u32 fmbm_rffc; /* Rx Filter Frames Counter */213 u32 fmbm_rfdc; /* Rx Frame Discard Counter */214 u32 fmbm_rfldec; /* Rx Frames List DMA Error Counter */215 u32 fmbm_rodc; /* Rx Out of Buffers Discard nntr */216 u32 fmbm_rbdc; /* Rx Buffers Deallocate Counter */217 u32 fmbm_rpec; /* RX Prepare to enqueue Counte */218 u32 reserved0224[0x16]; /* (0x224 0x27F) */219 u32 fmbm_rpc; /* Rx Performance Counters */220 u32 fmbm_rpcp; /* Rx Performance Count Parameters */221 u32 fmbm_rccn; /* Rx Cycle Counter */222 u32 fmbm_rtuc; /* Rx Tasks Utilization Counter */223 u32 fmbm_rrquc; /* Rx Receive Queue Utilization cntr */224 u32 fmbm_rduc; /* Rx DMA Utilization Counter */225 u32 fmbm_rfuc; /* Rx FIFO Utilization Counter */226 u32 fmbm_rpac; /* Rx Pause Activation Counter */227 u32 reserved02a0[0x18]; /* (0x2A0 0x2FF) */228 u32 fmbm_rdcfg[0x3]; /* Rx Debug Configuration */229 u32 fmbm_rgpr; /* Rx General Purpose Register */230 u32 reserved0310[0x3a];231};232 233/* BMI Tx port register map */234struct fman_port_tx_bmi_regs {235 u32 fmbm_tcfg; /* Tx Configuration */236 u32 fmbm_tst; /* Tx Status */237 u32 fmbm_tda; /* Tx DMA attributes */238 u32 fmbm_tfp; /* Tx FIFO Parameters */239 u32 fmbm_tfed; /* Tx Frame End Data */240 u32 fmbm_ticp; /* Tx Internal Context Parameters */241 u32 fmbm_tfdne; /* Tx Frame Dequeue Next Engine. */242 u32 fmbm_tfca; /* Tx Frame Command attribute. */243 u32 fmbm_tcfqid; /* Tx Confirmation Frame Queue ID. */244 u32 fmbm_tefqid; /* Tx Frame Error Queue ID */245 u32 fmbm_tfene; /* Tx Frame Enqueue Next Engine */246 u32 fmbm_trlmts; /* Tx Rate Limiter Scale */247 u32 fmbm_trlmt; /* Tx Rate Limiter */248 u32 reserved0034[0x0e]; /* (0x034-0x6c) */249 u32 fmbm_tccb; /* Tx Coarse Classification base */250 u32 fmbm_tfne; /* Tx Frame Next Engine */251 u32 fmbm_tpfcm[0x02];252 /* Tx Priority based Flow Control (PFC) Mapping */253 u32 fmbm_tcmne; /* Tx Frame Continuous Mode Next Engine */254 u32 reserved0080[0x60]; /* (0x080-0x200) */255 u32 fmbm_tstc; /* Tx Statistics Counters */256 u32 fmbm_tfrc; /* Tx Frame Counter */257 u32 fmbm_tfdc; /* Tx Frames Discard Counter */258 u32 fmbm_tfledc; /* Tx Frame len error discard cntr */259 u32 fmbm_tfufdc; /* Tx Frame unsprt frmt discard cntr */260 u32 fmbm_tbdc; /* Tx Buffers Deallocate Counter */261 u32 reserved0218[0x1A]; /* (0x218-0x280) */262 u32 fmbm_tpc; /* Tx Performance Counters */263 u32 fmbm_tpcp; /* Tx Performance Count Parameters */264 u32 fmbm_tccn; /* Tx Cycle Counter */265 u32 fmbm_ttuc; /* Tx Tasks Utilization Counter */266 u32 fmbm_ttcquc; /* Tx Transmit conf Q util Counter */267 u32 fmbm_tduc; /* Tx DMA Utilization Counter */268 u32 fmbm_tfuc; /* Tx FIFO Utilization Counter */269 u32 reserved029c[16]; /* (0x29C-0x2FF) */270 u32 fmbm_tdcfg[0x3]; /* Tx Debug Configuration */271 u32 fmbm_tgpr; /* Tx General Purpose Register */272 u32 reserved0310[0x3a]; /* (0x310-0x3FF) */273};274 275/* BMI port register map */276union fman_port_bmi_regs {277 struct fman_port_rx_bmi_regs rx;278 struct fman_port_tx_bmi_regs tx;279};280 281/* QMI port register map */282struct fman_port_qmi_regs {283 u32 fmqm_pnc; /* PortID n Configuration Register */284 u32 fmqm_pns; /* PortID n Status Register */285 u32 fmqm_pnts; /* PortID n Task Status Register */286 u32 reserved00c[4]; /* 0xn00C - 0xn01B */287 u32 fmqm_pnen; /* PortID n Enqueue NIA Register */288 u32 fmqm_pnetfc; /* PortID n Enq Total Frame Counter */289 u32 reserved024[2]; /* 0xn024 - 0x02B */290 u32 fmqm_pndn; /* PortID n Dequeue NIA Register */291 u32 fmqm_pndc; /* PortID n Dequeue Config Register */292 u32 fmqm_pndtfc; /* PortID n Dequeue tot Frame cntr */293 u32 fmqm_pndfdc; /* PortID n Dequeue FQID Dflt Cntr */294 u32 fmqm_pndcc; /* PortID n Dequeue Confirm Counter */295};296 297#define HWP_HXS_COUNT 16298#define HWP_HXS_PHE_REPORT 0x00000800299#define HWP_HXS_PCAC_PSTAT 0x00000100300#define HWP_HXS_PCAC_PSTOP 0x00000001301#define HWP_HXS_TCP_OFFSET 0xA302#define HWP_HXS_UDP_OFFSET 0xB303#define HWP_HXS_SH_PAD_REM 0x80000000304 305struct fman_port_hwp_regs {306 struct {307 u32 ssa; /* Soft Sequence Attachment */308 u32 lcv; /* Line-up Enable Confirmation Mask */309 } pmda[HWP_HXS_COUNT]; /* Parse Memory Direct Access Registers */310 u32 reserved080[(0x3f8 - 0x080) / 4]; /* (0x080-0x3f7) */311 u32 fmpr_pcac; /* Configuration Access Control */312};313 314/* QMI dequeue prefetch modes */315enum fman_port_deq_prefetch {316 FMAN_PORT_DEQ_NO_PREFETCH, /* No prefetch mode */317 FMAN_PORT_DEQ_PART_PREFETCH, /* Partial prefetch mode */318 FMAN_PORT_DEQ_FULL_PREFETCH /* Full prefetch mode */319};320 321/* A structure for defining FM port resources */322struct fman_port_rsrc {323 u32 num; /* Committed required resource */324 u32 extra; /* Extra (not committed) required resource */325};326 327enum fman_port_dma_swap {328 FMAN_PORT_DMA_NO_SWAP, /* No swap, transfer data as is */329 FMAN_PORT_DMA_SWAP_LE,330 /* The transferred data should be swapped in PPC Little Endian mode */331 FMAN_PORT_DMA_SWAP_BE332 /* The transferred data should be swapped in Big Endian mode */333};334 335/* Default port color */336enum fman_port_color {337 FMAN_PORT_COLOR_GREEN, /* Default port color is green */338 FMAN_PORT_COLOR_YELLOW, /* Default port color is yellow */339 FMAN_PORT_COLOR_RED, /* Default port color is red */340 FMAN_PORT_COLOR_OVERRIDE /* Ignore color */341};342 343/* QMI dequeue from the SP channel - types */344enum fman_port_deq_type {345 FMAN_PORT_DEQ_BY_PRI,346 /* Priority precedence and Intra-Class scheduling */347 FMAN_PORT_DEQ_ACTIVE_FQ,348 /* Active FQ precedence and Intra-Class scheduling */349 FMAN_PORT_DEQ_ACTIVE_FQ_NO_ICS350 /* Active FQ precedence and override Intra-Class scheduling */351};352 353/* External buffer pools configuration */354struct fman_port_bpools {355 u8 count; /* Num of pools to set up */356 bool counters_enable; /* Enable allocate counters */357 u8 grp_bp_depleted_num;358 /* Number of depleted pools - if reached the BMI indicates359 * the MAC to send a pause frame360 */361 struct {362 u8 bpid; /* BM pool ID */363 u16 size;364 /* Pool's size - must be in ascending order */365 bool is_backup;366 /* If this is a backup pool */367 bool grp_bp_depleted;368 /* Consider this buffer in multiple pools depletion criteria */369 bool single_bp_depleted;370 /* Consider this buffer in single pool depletion criteria */371 } bpool[FMAN_PORT_MAX_EXT_POOLS_NUM];372};373 374struct fman_port_cfg {375 u32 dflt_fqid;376 u32 err_fqid;377 u32 pcd_base_fqid;378 u32 pcd_fqs_count;379 u8 deq_sp;380 bool deq_high_priority;381 enum fman_port_deq_type deq_type;382 enum fman_port_deq_prefetch deq_prefetch_option;383 u16 deq_byte_cnt;384 u8 cheksum_last_bytes_ignore;385 u8 rx_cut_end_bytes;386 struct fman_buf_pool_depletion buf_pool_depletion;387 struct fman_ext_pools ext_buf_pools;388 u32 tx_fifo_min_level;389 u32 tx_fifo_low_comf_level;390 u32 rx_pri_elevation;391 u32 rx_fifo_thr;392 struct fman_sp_buf_margins buf_margins;393 u32 int_buf_start_margin;394 struct fman_sp_int_context_data_copy int_context;395 u32 discard_mask;396 u32 err_mask;397 struct fman_buffer_prefix_content buffer_prefix_content;398 bool dont_release_buf;399 400 u8 rx_fd_bits;401 u32 tx_fifo_deq_pipeline_depth;402 bool errata_A006320;403 bool excessive_threshold_register;404 bool fmbm_tfne_has_features;405 406 enum fman_port_dma_swap dma_swap_data;407 enum fman_port_color color;408};409 410struct fman_port_rx_pools_params {411 u8 num_of_pools;412 u16 largest_buf_size;413};414 415struct fman_port_dts_params {416 void __iomem *base_addr; /* FMan port virtual memory */417 enum fman_port_type type; /* Port type */418 u16 speed; /* Port speed */419 u8 id; /* HW Port Id */420 u32 qman_channel_id; /* QMan channel id (non RX only) */421 struct fman *fman; /* FMan Handle */422};423 424struct fman_port {425 void *fm;426 struct device *dev;427 struct fman_rev_info rev_info;428 u8 port_id;429 enum fman_port_type port_type;430 u16 port_speed;431 432 union fman_port_bmi_regs __iomem *bmi_regs;433 struct fman_port_qmi_regs __iomem *qmi_regs;434 struct fman_port_hwp_regs __iomem *hwp_regs;435 436 struct fman_sp_buffer_offsets buffer_offsets;437 438 u8 internal_buf_offset;439 struct fman_ext_pools ext_buf_pools;440 441 u16 max_frame_length;442 struct fman_port_rsrc open_dmas;443 struct fman_port_rsrc tasks;444 struct fman_port_rsrc fifo_bufs;445 struct fman_port_rx_pools_params rx_pools_params;446 447 struct fman_port_cfg *cfg;448 struct fman_port_dts_params dts_params;449 450 u8 ext_pools_num;451 u32 max_port_fifo_size;452 u32 max_num_of_ext_pools;453 u32 max_num_of_sub_portals;454 u32 bm_max_num_of_pools;455};456 457static int init_bmi_rx(struct fman_port *port)458{459 struct fman_port_rx_bmi_regs __iomem *regs = &port->bmi_regs->rx;460 struct fman_port_cfg *cfg = port->cfg;461 u32 tmp;462 463 /* DMA attributes */464 tmp = (u32)cfg->dma_swap_data << BMI_DMA_ATTR_SWP_SHIFT;465 /* Enable write optimization */466 tmp |= BMI_DMA_ATTR_WRITE_OPTIMIZE;467 iowrite32be(tmp, ®s->fmbm_rda);468 469 /* Rx FIFO parameters */470 tmp = (cfg->rx_pri_elevation / PORT_BMI_FIFO_UNITS - 1) <<471 BMI_RX_FIFO_PRI_ELEVATION_SHIFT;472 tmp |= cfg->rx_fifo_thr / PORT_BMI_FIFO_UNITS - 1;473 iowrite32be(tmp, ®s->fmbm_rfp);474 475 if (cfg->excessive_threshold_register)476 /* always allow access to the extra resources */477 iowrite32be(BMI_RX_FIFO_THRESHOLD_ETHE, ®s->fmbm_reth);478 479 /* Frame end data */480 tmp = (cfg->cheksum_last_bytes_ignore & BMI_FRAME_END_CS_IGNORE_MASK) <<481 BMI_FRAME_END_CS_IGNORE_SHIFT;482 tmp |= (cfg->rx_cut_end_bytes & BMI_RX_FRAME_END_CUT_MASK) <<483 BMI_RX_FRAME_END_CUT_SHIFT;484 if (cfg->errata_A006320)485 tmp &= 0xffe0ffff;486 iowrite32be(tmp, ®s->fmbm_rfed);487 488 /* Internal context parameters */489 tmp = ((cfg->int_context.ext_buf_offset / PORT_IC_OFFSET_UNITS) &490 BMI_IC_TO_EXT_MASK) << BMI_IC_TO_EXT_SHIFT;491 tmp |= ((cfg->int_context.int_context_offset / PORT_IC_OFFSET_UNITS) &492 BMI_IC_FROM_INT_MASK) << BMI_IC_FROM_INT_SHIFT;493 tmp |= (cfg->int_context.size / PORT_IC_OFFSET_UNITS) &494 BMI_IC_SIZE_MASK;495 iowrite32be(tmp, ®s->fmbm_ricp);496 497 /* Internal buffer offset */498 tmp = ((cfg->int_buf_start_margin / PORT_IC_OFFSET_UNITS) &499 BMI_INT_BUF_MARG_MASK) << BMI_INT_BUF_MARG_SHIFT;500 iowrite32be(tmp, ®s->fmbm_rim);501 502 /* External buffer margins */503 tmp = (cfg->buf_margins.start_margins & BMI_EXT_BUF_MARG_START_MASK) <<504 BMI_EXT_BUF_MARG_START_SHIFT;505 tmp |= cfg->buf_margins.end_margins & BMI_EXT_BUF_MARG_END_MASK;506 iowrite32be(tmp, ®s->fmbm_rebm);507 508 /* Frame attributes */509 tmp = BMI_CMD_RX_MR_DEF;510 tmp |= BMI_CMD_ATTR_ORDER;511 tmp |= (u32)cfg->color << BMI_CMD_ATTR_COLOR_SHIFT;512 /* Synchronization request */513 tmp |= BMI_CMD_ATTR_SYNC;514 515 iowrite32be(tmp, ®s->fmbm_rfca);516 517 /* NIA */518 tmp = (u32)cfg->rx_fd_bits << BMI_NEXT_ENG_FD_BITS_SHIFT;519 520 tmp |= NIA_ENG_HWP;521 iowrite32be(tmp, ®s->fmbm_rfne);522 523 /* Parser Next Engine NIA */524 iowrite32be(NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME, ®s->fmbm_rfpne);525 526 /* Enqueue NIA */527 iowrite32be(NIA_ENG_QMI_ENQ | NIA_ORDER_RESTOR, ®s->fmbm_rfene);528 529 /* Default/error queues */530 iowrite32be((cfg->dflt_fqid & DFLT_FQ_ID), ®s->fmbm_rfqid);531 iowrite32be((cfg->err_fqid & DFLT_FQ_ID), ®s->fmbm_refqid);532 533 /* Discard/error masks */534 iowrite32be(cfg->discard_mask, ®s->fmbm_rfsdm);535 iowrite32be(cfg->err_mask, ®s->fmbm_rfsem);536 537 return 0;538}539 540static int init_bmi_tx(struct fman_port *port)541{542 struct fman_port_tx_bmi_regs __iomem *regs = &port->bmi_regs->tx;543 struct fman_port_cfg *cfg = port->cfg;544 u32 tmp;545 546 /* Tx Configuration register */547 tmp = 0;548 iowrite32be(tmp, ®s->fmbm_tcfg);549 550 /* DMA attributes */551 tmp = (u32)cfg->dma_swap_data << BMI_DMA_ATTR_SWP_SHIFT;552 iowrite32be(tmp, ®s->fmbm_tda);553 554 /* Tx FIFO parameters */555 tmp = (cfg->tx_fifo_min_level / PORT_BMI_FIFO_UNITS) <<556 BMI_TX_FIFO_MIN_FILL_SHIFT;557 tmp |= ((cfg->tx_fifo_deq_pipeline_depth - 1) &558 BMI_FIFO_PIPELINE_DEPTH_MASK) << BMI_FIFO_PIPELINE_DEPTH_SHIFT;559 tmp |= (cfg->tx_fifo_low_comf_level / PORT_BMI_FIFO_UNITS) - 1;560 iowrite32be(tmp, ®s->fmbm_tfp);561 562 /* Frame end data */563 tmp = (cfg->cheksum_last_bytes_ignore & BMI_FRAME_END_CS_IGNORE_MASK) <<564 BMI_FRAME_END_CS_IGNORE_SHIFT;565 iowrite32be(tmp, ®s->fmbm_tfed);566 567 /* Internal context parameters */568 tmp = ((cfg->int_context.ext_buf_offset / PORT_IC_OFFSET_UNITS) &569 BMI_IC_TO_EXT_MASK) << BMI_IC_TO_EXT_SHIFT;570 tmp |= ((cfg->int_context.int_context_offset / PORT_IC_OFFSET_UNITS) &571 BMI_IC_FROM_INT_MASK) << BMI_IC_FROM_INT_SHIFT;572 tmp |= (cfg->int_context.size / PORT_IC_OFFSET_UNITS) &573 BMI_IC_SIZE_MASK;574 iowrite32be(tmp, ®s->fmbm_ticp);575 576 /* Frame attributes */577 tmp = BMI_CMD_TX_MR_DEF;578 tmp |= BMI_CMD_ATTR_ORDER;579 tmp |= (u32)cfg->color << BMI_CMD_ATTR_COLOR_SHIFT;580 iowrite32be(tmp, ®s->fmbm_tfca);581 582 /* Dequeue NIA + enqueue NIA */583 iowrite32be(NIA_ENG_QMI_DEQ, ®s->fmbm_tfdne);584 iowrite32be(NIA_ENG_QMI_ENQ | NIA_ORDER_RESTOR, ®s->fmbm_tfene);585 if (cfg->fmbm_tfne_has_features)586 iowrite32be(!cfg->dflt_fqid ?587 BMI_EBD_EN | NIA_BMI_AC_FETCH_ALL_FRAME :588 NIA_BMI_AC_FETCH_ALL_FRAME, ®s->fmbm_tfne);589 if (!cfg->dflt_fqid && cfg->dont_release_buf) {590 iowrite32be(DFLT_FQ_ID, ®s->fmbm_tcfqid);591 iowrite32be(NIA_ENG_BMI | NIA_BMI_AC_TX_RELEASE,592 ®s->fmbm_tfene);593 if (cfg->fmbm_tfne_has_features)594 iowrite32be(ioread32be(®s->fmbm_tfne) & ~BMI_EBD_EN,595 ®s->fmbm_tfne);596 }597 598 /* Confirmation/error queues */599 if (cfg->dflt_fqid || !cfg->dont_release_buf)600 iowrite32be(cfg->dflt_fqid & DFLT_FQ_ID, ®s->fmbm_tcfqid);601 iowrite32be((cfg->err_fqid & DFLT_FQ_ID), ®s->fmbm_tefqid);602 603 return 0;604}605 606static int init_qmi(struct fman_port *port)607{608 struct fman_port_qmi_regs __iomem *regs = port->qmi_regs;609 struct fman_port_cfg *cfg = port->cfg;610 u32 tmp;611 612 /* Rx port configuration */613 if (port->port_type == FMAN_PORT_TYPE_RX) {614 /* Enqueue NIA */615 iowrite32be(NIA_ENG_BMI | NIA_BMI_AC_RELEASE, ®s->fmqm_pnen);616 return 0;617 }618 619 /* Continue with Tx port configuration */620 if (port->port_type == FMAN_PORT_TYPE_TX) {621 /* Enqueue NIA */622 iowrite32be(NIA_ENG_BMI | NIA_BMI_AC_TX_RELEASE,623 ®s->fmqm_pnen);624 /* Dequeue NIA */625 iowrite32be(NIA_ENG_BMI | NIA_BMI_AC_TX, ®s->fmqm_pndn);626 }627 628 /* Dequeue Configuration register */629 tmp = 0;630 if (cfg->deq_high_priority)631 tmp |= QMI_DEQ_CFG_PRI;632 633 switch (cfg->deq_type) {634 case FMAN_PORT_DEQ_BY_PRI:635 tmp |= QMI_DEQ_CFG_TYPE1;636 break;637 case FMAN_PORT_DEQ_ACTIVE_FQ:638 tmp |= QMI_DEQ_CFG_TYPE2;639 break;640 case FMAN_PORT_DEQ_ACTIVE_FQ_NO_ICS:641 tmp |= QMI_DEQ_CFG_TYPE3;642 break;643 default:644 return -EINVAL;645 }646 647 switch (cfg->deq_prefetch_option) {648 case FMAN_PORT_DEQ_NO_PREFETCH:649 break;650 case FMAN_PORT_DEQ_PART_PREFETCH:651 tmp |= QMI_DEQ_CFG_PREFETCH_PARTIAL;652 break;653 case FMAN_PORT_DEQ_FULL_PREFETCH:654 tmp |= QMI_DEQ_CFG_PREFETCH_FULL;655 break;656 default:657 return -EINVAL;658 }659 660 tmp |= (cfg->deq_sp & QMI_DEQ_CFG_SP_MASK) << QMI_DEQ_CFG_SP_SHIFT;661 tmp |= cfg->deq_byte_cnt;662 iowrite32be(tmp, ®s->fmqm_pndc);663 664 return 0;665}666 667static void stop_port_hwp(struct fman_port *port)668{669 struct fman_port_hwp_regs __iomem *regs = port->hwp_regs;670 int cnt = 100;671 672 iowrite32be(HWP_HXS_PCAC_PSTOP, ®s->fmpr_pcac);673 674 while (cnt-- > 0 &&675 (ioread32be(®s->fmpr_pcac) & HWP_HXS_PCAC_PSTAT))676 udelay(10);677 if (!cnt)678 pr_err("Timeout stopping HW Parser\n");679}680 681static void start_port_hwp(struct fman_port *port)682{683 struct fman_port_hwp_regs __iomem *regs = port->hwp_regs;684 int cnt = 100;685 686 iowrite32be(0, ®s->fmpr_pcac);687 688 while (cnt-- > 0 &&689 !(ioread32be(®s->fmpr_pcac) & HWP_HXS_PCAC_PSTAT))690 udelay(10);691 if (!cnt)692 pr_err("Timeout starting HW Parser\n");693}694 695static void init_hwp(struct fman_port *port)696{697 struct fman_port_hwp_regs __iomem *regs = port->hwp_regs;698 int i;699 700 stop_port_hwp(port);701 702 for (i = 0; i < HWP_HXS_COUNT; i++) {703 /* enable HXS error reporting into FD[STATUS] PHE */704 iowrite32be(0x00000000, ®s->pmda[i].ssa);705 iowrite32be(0xffffffff, ®s->pmda[i].lcv);706 }707 708 /* Short packet padding removal from checksum calculation */709 iowrite32be(HWP_HXS_SH_PAD_REM, ®s->pmda[HWP_HXS_TCP_OFFSET].ssa);710 iowrite32be(HWP_HXS_SH_PAD_REM, ®s->pmda[HWP_HXS_UDP_OFFSET].ssa);711 712 start_port_hwp(port);713}714 715static int init(struct fman_port *port)716{717 int err;718 719 /* Init BMI registers */720 switch (port->port_type) {721 case FMAN_PORT_TYPE_RX:722 err = init_bmi_rx(port);723 if (!err)724 init_hwp(port);725 break;726 case FMAN_PORT_TYPE_TX:727 err = init_bmi_tx(port);728 break;729 default:730 return -EINVAL;731 }732 733 if (err)734 return err;735 736 /* Init QMI registers */737 err = init_qmi(port);738 if (err)739 return err;740 741 return 0;742}743 744static int set_bpools(const struct fman_port *port,745 const struct fman_port_bpools *bp)746{747 u32 __iomem *bp_reg, *bp_depl_reg;748 u32 tmp;749 u8 i, max_bp_num;750 bool grp_depl_used = false, rx_port;751 752 switch (port->port_type) {753 case FMAN_PORT_TYPE_RX:754 max_bp_num = port->ext_pools_num;755 rx_port = true;756 bp_reg = port->bmi_regs->rx.fmbm_ebmpi;757 bp_depl_reg = &port->bmi_regs->rx.fmbm_mpd;758 break;759 default:760 return -EINVAL;761 }762 763 if (rx_port) {764 /* Check buffers are provided in ascending order */765 for (i = 0; (i < (bp->count - 1) &&766 (i < FMAN_PORT_MAX_EXT_POOLS_NUM - 1)); i++) {767 if (bp->bpool[i].size > bp->bpool[i + 1].size)768 return -EINVAL;769 }770 }771 772 /* Set up external buffers pools */773 for (i = 0; i < bp->count; i++) {774 tmp = BMI_EXT_BUF_POOL_VALID;775 tmp |= ((u32)bp->bpool[i].bpid <<776 BMI_EXT_BUF_POOL_ID_SHIFT) & BMI_EXT_BUF_POOL_ID_MASK;777 778 if (rx_port) {779 if (bp->counters_enable)780 tmp |= BMI_EXT_BUF_POOL_EN_COUNTER;781 782 if (bp->bpool[i].is_backup)783 tmp |= BMI_EXT_BUF_POOL_BACKUP;784 785 tmp |= (u32)bp->bpool[i].size;786 }787 788 iowrite32be(tmp, &bp_reg[i]);789 }790 791 /* Clear unused pools */792 for (i = bp->count; i < max_bp_num; i++)793 iowrite32be(0, &bp_reg[i]);794 795 /* Pools depletion */796 tmp = 0;797 for (i = 0; i < FMAN_PORT_MAX_EXT_POOLS_NUM; i++) {798 if (bp->bpool[i].grp_bp_depleted) {799 grp_depl_used = true;800 tmp |= 0x80000000 >> i;801 }802 803 if (bp->bpool[i].single_bp_depleted)804 tmp |= 0x80 >> i;805 }806 807 if (grp_depl_used)808 tmp |= ((u32)bp->grp_bp_depleted_num - 1) <<809 BMI_POOL_DEP_NUM_OF_POOLS_SHIFT;810 811 iowrite32be(tmp, bp_depl_reg);812 return 0;813}814 815static bool is_init_done(struct fman_port_cfg *cfg)816{817 /* Checks if FMan port driver parameters were initialized */818 if (!cfg)819 return true;820 821 return false;822}823 824static int verify_size_of_fifo(struct fman_port *port)825{826 u32 min_fifo_size_required = 0, opt_fifo_size_for_b2b = 0;827 828 /* TX Ports */829 if (port->port_type == FMAN_PORT_TYPE_TX) {830 min_fifo_size_required = (u32)831 (roundup(port->max_frame_length,832 FMAN_BMI_FIFO_UNITS) + (3 * FMAN_BMI_FIFO_UNITS));833 834 min_fifo_size_required +=835 port->cfg->tx_fifo_deq_pipeline_depth *836 FMAN_BMI_FIFO_UNITS;837 838 opt_fifo_size_for_b2b = min_fifo_size_required;839 840 /* Add some margin for back-to-back capability to improve841 * performance, allows the hardware to pipeline new frame dma842 * while the previous frame not yet transmitted.843 */844 if (port->port_speed == 10000)845 opt_fifo_size_for_b2b += 3 * FMAN_BMI_FIFO_UNITS;846 else847 opt_fifo_size_for_b2b += 2 * FMAN_BMI_FIFO_UNITS;848 }849 850 /* RX Ports */851 else if (port->port_type == FMAN_PORT_TYPE_RX) {852 if (port->rev_info.major >= 6)853 min_fifo_size_required = (u32)854 (roundup(port->max_frame_length,855 FMAN_BMI_FIFO_UNITS) +856 (5 * FMAN_BMI_FIFO_UNITS));857 /* 4 according to spec + 1 for FOF>0 */858 else859 min_fifo_size_required = (u32)860 (roundup(min(port->max_frame_length,861 port->rx_pools_params.largest_buf_size),862 FMAN_BMI_FIFO_UNITS) +863 (7 * FMAN_BMI_FIFO_UNITS));864 865 opt_fifo_size_for_b2b = min_fifo_size_required;866 867 /* Add some margin for back-to-back capability to improve868 * performance,allows the hardware to pipeline new frame dma869 * while the previous frame not yet transmitted.870 */871 if (port->port_speed == 10000)872 opt_fifo_size_for_b2b += 8 * FMAN_BMI_FIFO_UNITS;873 else874 opt_fifo_size_for_b2b += 3 * FMAN_BMI_FIFO_UNITS;875 }876 877 WARN_ON(min_fifo_size_required <= 0);878 WARN_ON(opt_fifo_size_for_b2b < min_fifo_size_required);879 880 /* Verify the size */881 if (port->fifo_bufs.num < min_fifo_size_required)882 dev_dbg(port->dev, "%s: FIFO size should be enlarged to %d bytes\n",883 __func__, min_fifo_size_required);884 else if (port->fifo_bufs.num < opt_fifo_size_for_b2b)885 dev_dbg(port->dev, "%s: For b2b processing,FIFO may be enlarged to %d bytes\n",886 __func__, opt_fifo_size_for_b2b);887 888 return 0;889}890 891static int set_ext_buffer_pools(struct fman_port *port)892{893 struct fman_ext_pools *ext_buf_pools = &port->cfg->ext_buf_pools;894 struct fman_buf_pool_depletion *buf_pool_depletion =895 &port->cfg->buf_pool_depletion;896 u8 ordered_array[FMAN_PORT_MAX_EXT_POOLS_NUM];897 u16 sizes_array[BM_MAX_NUM_OF_POOLS];898 int i = 0, j = 0, err;899 struct fman_port_bpools bpools;900 901 memset(&ordered_array, 0, sizeof(u8) * FMAN_PORT_MAX_EXT_POOLS_NUM);902 memset(&sizes_array, 0, sizeof(u16) * BM_MAX_NUM_OF_POOLS);903 memcpy(&port->ext_buf_pools, ext_buf_pools,904 sizeof(struct fman_ext_pools));905 906 fman_sp_set_buf_pools_in_asc_order_of_buf_sizes(ext_buf_pools,907 ordered_array,908 sizes_array);909 910 memset(&bpools, 0, sizeof(struct fman_port_bpools));911 bpools.count = ext_buf_pools->num_of_pools_used;912 bpools.counters_enable = true;913 for (i = 0; i < ext_buf_pools->num_of_pools_used; i++) {914 bpools.bpool[i].bpid = ordered_array[i];915 bpools.bpool[i].size = sizes_array[ordered_array[i]];916 }917 918 /* save pools parameters for later use */919 port->rx_pools_params.num_of_pools = ext_buf_pools->num_of_pools_used;920 port->rx_pools_params.largest_buf_size =921 sizes_array[ordered_array[ext_buf_pools->num_of_pools_used - 1]];922 923 /* FMBM_RMPD reg. - pool depletion */924 if (buf_pool_depletion->pools_grp_mode_enable) {925 bpools.grp_bp_depleted_num = buf_pool_depletion->num_of_pools;926 for (i = 0; i < port->bm_max_num_of_pools; i++) {927 if (buf_pool_depletion->pools_to_consider[i]) {928 for (j = 0; j < ext_buf_pools->929 num_of_pools_used; j++) {930 if (i == ordered_array[j]) {931 bpools.bpool[j].932 grp_bp_depleted = true;933 break;934 }935 }936 }937 }938 }939 940 if (buf_pool_depletion->single_pool_mode_enable) {941 for (i = 0; i < port->bm_max_num_of_pools; i++) {942 if (buf_pool_depletion->943 pools_to_consider_for_single_mode[i]) {944 for (j = 0; j < ext_buf_pools->945 num_of_pools_used; j++) {946 if (i == ordered_array[j]) {947 bpools.bpool[j].948 single_bp_depleted = true;949 break;950 }951 }952 }953 }954 }955 956 err = set_bpools(port, &bpools);957 if (err != 0) {958 dev_err(port->dev, "%s: set_bpools() failed\n", __func__);959 return -EINVAL;960 }961 962 return 0;963}964 965static int init_low_level_driver(struct fman_port *port)966{967 struct fman_port_cfg *cfg = port->cfg;968 u32 tmp_val;969 970 switch (port->port_type) {971 case FMAN_PORT_TYPE_RX:972 cfg->err_mask = (RX_ERRS_TO_ENQ & ~cfg->discard_mask);973 break;974 default:975 break;976 }977 978 tmp_val = (u32)((port->internal_buf_offset % OFFSET_UNITS) ?979 (port->internal_buf_offset / OFFSET_UNITS + 1) :980 (port->internal_buf_offset / OFFSET_UNITS));981 port->internal_buf_offset = (u8)(tmp_val * OFFSET_UNITS);982 port->cfg->int_buf_start_margin = port->internal_buf_offset;983 984 if (init(port) != 0) {985 dev_err(port->dev, "%s: fman port initialization failed\n",986 __func__);987 return -ENODEV;988 }989 990 /* The code bellow is a trick so the FM will not release the buffer991 * to BM nor will try to enqueue the frame to QM992 */993 if (port->port_type == FMAN_PORT_TYPE_TX) {994 if (!cfg->dflt_fqid && cfg->dont_release_buf) {995 /* override fmbm_tcfqid 0 with a false non-0 value.996 * This will force FM to act according to tfene.997 * Otherwise, if fmbm_tcfqid is 0 the FM will release998 * buffers to BM regardless of fmbm_tfene999 */1000 iowrite32be(0xFFFFFF, &port->bmi_regs->tx.fmbm_tcfqid);1001 iowrite32be(NIA_ENG_BMI | NIA_BMI_AC_TX_RELEASE,1002 &port->bmi_regs->tx.fmbm_tfene);1003 }1004 }1005 1006 return 0;1007}1008 1009static int fill_soc_specific_params(struct fman_port *port)1010{1011 u32 bmi_max_fifo_size;1012 1013 bmi_max_fifo_size = fman_get_bmi_max_fifo_size(port->fm);1014 port->max_port_fifo_size = MAX_PORT_FIFO_SIZE(bmi_max_fifo_size);1015 port->bm_max_num_of_pools = 64;1016 1017 /* P4080 - Major 21018 * P2041/P3041/P5020/P5040 - Major 31019 * Tx/Bx - Major 61020 */1021 switch (port->rev_info.major) {1022 case 2:1023 case 3:1024 port->max_num_of_ext_pools = 4;1025 port->max_num_of_sub_portals = 12;1026 break;1027 1028 case 6:1029 port->max_num_of_ext_pools = 8;1030 port->max_num_of_sub_portals = 16;1031 break;1032 1033 default:1034 dev_err(port->dev, "%s: Unsupported FMan version\n", __func__);1035 return -EINVAL;1036 }1037 1038 return 0;1039}1040 1041static int get_dflt_fifo_deq_pipeline_depth(u8 major, enum fman_port_type type,1042 u16 speed)1043{1044 switch (type) {1045 case FMAN_PORT_TYPE_RX:1046 case FMAN_PORT_TYPE_TX:1047 switch (speed) {1048 case 10000:1049 return 4;1050 case 1000:1051 if (major >= 6)1052 return 2;1053 else1054 return 1;1055 default:1056 return 0;1057 }1058 default:1059 return 0;1060 }1061}1062 1063static int get_dflt_num_of_tasks(u8 major, enum fman_port_type type,1064 u16 speed)1065{1066 switch (type) {1067 case FMAN_PORT_TYPE_RX:1068 case FMAN_PORT_TYPE_TX:1069 switch (speed) {1070 case 10000:1071 return 16;1072 case 1000:1073 if (major >= 6)1074 return 4;1075 else1076 return 3;1077 default:1078 return 0;1079 }1080 default:1081 return 0;1082 }1083}1084 1085static int get_dflt_extra_num_of_tasks(u8 major, enum fman_port_type type,1086 u16 speed)1087{1088 switch (type) {1089 case FMAN_PORT_TYPE_RX:1090 /* FMan V3 */1091 if (major >= 6)1092 return 0;1093 1094 /* FMan V2 */1095 if (speed == 10000)1096 return 8;1097 else1098 return 2;1099 case FMAN_PORT_TYPE_TX:1100 default:1101 return 0;1102 }1103}1104 1105static int get_dflt_num_of_open_dmas(u8 major, enum fman_port_type type,1106 u16 speed)1107{1108 int val;1109 1110 if (major >= 6) {1111 switch (type) {1112 case FMAN_PORT_TYPE_TX:1113 if (speed == 10000)1114 val = 12;1115 else1116 val = 3;1117 break;1118 case FMAN_PORT_TYPE_RX:1119 if (speed == 10000)1120 val = 8;1121 else1122 val = 2;1123 break;1124 default:1125 return 0;1126 }1127 } else {1128 switch (type) {1129 case FMAN_PORT_TYPE_TX:1130 case FMAN_PORT_TYPE_RX:1131 if (speed == 10000)1132 val = 8;1133 else1134 val = 1;1135 break;1136 default:1137 val = 0;1138 }1139 }1140 1141 return val;1142}1143 1144static int get_dflt_extra_num_of_open_dmas(u8 major, enum fman_port_type type,1145 u16 speed)1146{1147 /* FMan V3 */1148 if (major >= 6)1149 return 0;1150 1151 /* FMan V2 */1152 switch (type) {1153 case FMAN_PORT_TYPE_RX:1154 case FMAN_PORT_TYPE_TX:1155 if (speed == 10000)1156 return 8;1157 else1158 return 1;1159 default:1160 return 0;1161 }1162}1163 1164static int get_dflt_num_of_fifo_bufs(u8 major, enum fman_port_type type,1165 u16 speed)1166{1167 int val;1168 1169 if (major >= 6) {1170 switch (type) {1171 case FMAN_PORT_TYPE_TX:1172 if (speed == 10000)1173 val = 64;1174 else1175 val = 50;1176 break;1177 case FMAN_PORT_TYPE_RX:1178 if (speed == 10000)1179 val = 96;1180 else1181 val = 50;1182 break;1183 default:1184 val = 0;1185 }1186 } else {1187 switch (type) {1188 case FMAN_PORT_TYPE_TX:1189 if (speed == 10000)1190 val = 48;1191 else1192 val = 44;1193 break;1194 case FMAN_PORT_TYPE_RX:1195 if (speed == 10000)1196 val = 48;1197 else1198 val = 45;1199 break;1200 default:1201 val = 0;1202 }1203 }1204 1205 return val;1206}1207 1208static void set_dflt_cfg(struct fman_port *port,1209 struct fman_port_params *port_params)1210{1211 struct fman_port_cfg *cfg = port->cfg;1212 1213 cfg->dma_swap_data = FMAN_PORT_DMA_NO_SWAP;1214 cfg->color = FMAN_PORT_COLOR_GREEN;1215 cfg->rx_cut_end_bytes = DFLT_PORT_CUT_BYTES_FROM_END;1216 cfg->rx_pri_elevation = BMI_PRIORITY_ELEVATION_LEVEL;1217 cfg->rx_fifo_thr = BMI_FIFO_THRESHOLD;1218 cfg->tx_fifo_low_comf_level = (5 * 1024);1219 cfg->deq_type = FMAN_PORT_DEQ_BY_PRI;1220 cfg->deq_prefetch_option = FMAN_PORT_DEQ_FULL_PREFETCH;1221 cfg->tx_fifo_deq_pipeline_depth =1222 BMI_DEQUEUE_PIPELINE_DEPTH(port->port_type, port->port_speed);1223 cfg->deq_byte_cnt = QMI_BYTE_COUNT_LEVEL_CONTROL(port->port_type);1224 1225 cfg->rx_pri_elevation =1226 DFLT_PORT_RX_FIFO_PRI_ELEVATION_LEV(port->max_port_fifo_size);1227 port->cfg->rx_fifo_thr =1228 DFLT_PORT_RX_FIFO_THRESHOLD(port->rev_info.major,1229 port->max_port_fifo_size);1230 1231 if ((port->rev_info.major == 6) &&1232 ((port->rev_info.minor == 0) || (port->rev_info.minor == 3)))1233 cfg->errata_A006320 = true;1234 1235 /* Excessive Threshold register - exists for pre-FMv3 chips only */1236 if (port->rev_info.major < 6)1237 cfg->excessive_threshold_register = true;1238 else1239 cfg->fmbm_tfne_has_features = true;1240 1241 cfg->buffer_prefix_content.data_align =1242 DFLT_PORT_BUFFER_PREFIX_CONTEXT_DATA_ALIGN;1243}1244 1245static void set_rx_dflt_cfg(struct fman_port *port,1246 struct fman_port_params *port_params)1247{1248 port->cfg->discard_mask = DFLT_PORT_ERRORS_TO_DISCARD;1249 1250 memcpy(&port->cfg->ext_buf_pools,1251 &port_params->specific_params.rx_params.ext_buf_pools,1252 sizeof(struct fman_ext_pools));1253 port->cfg->err_fqid =1254 port_params->specific_params.rx_params.err_fqid;1255 port->cfg->dflt_fqid =1256 port_params->specific_params.rx_params.dflt_fqid;1257 port->cfg->pcd_base_fqid =1258 port_params->specific_params.rx_params.pcd_base_fqid;1259 port->cfg->pcd_fqs_count =1260 port_params->specific_params.rx_params.pcd_fqs_count;1261}1262 1263static void set_tx_dflt_cfg(struct fman_port *port,1264 struct fman_port_params *port_params,1265 struct fman_port_dts_params *dts_params)1266{1267 port->cfg->tx_fifo_deq_pipeline_depth =1268 get_dflt_fifo_deq_pipeline_depth(port->rev_info.major,1269 port->port_type,1270 port->port_speed);1271 port->cfg->err_fqid =1272 port_params->specific_params.non_rx_params.err_fqid;1273 port->cfg->deq_sp =1274 (u8)(dts_params->qman_channel_id & QMI_DEQ_CFG_SUBPORTAL_MASK);1275 port->cfg->dflt_fqid =1276 port_params->specific_params.non_rx_params.dflt_fqid;1277 port->cfg->deq_high_priority = true;1278}1279 1280/**1281 * fman_port_config1282 * @port: Pointer to the port structure1283 * @params: Pointer to data structure of parameters1284 *1285 * Creates a descriptor for the FM PORT module.1286 * The routine returns a pointer to the FM PORT object.1287 * This descriptor must be passed as first parameter to all other FM PORT1288 * function calls.1289 * No actual initialization or configuration of FM hardware is done by this1290 * routine.1291 *1292 * Return: 0 on success; Error code otherwise.1293 */1294int fman_port_config(struct fman_port *port, struct fman_port_params *params)1295{1296 void __iomem *base_addr = port->dts_params.base_addr;1297 int err;1298 1299 /* Allocate the FM driver's parameters structure */1300 port->cfg = kzalloc(sizeof(*port->cfg), GFP_KERNEL);1301 if (!port->cfg)1302 return -EINVAL;1303 1304 /* Initialize FM port parameters which will be kept by the driver */1305 port->port_type = port->dts_params.type;1306 port->port_speed = port->dts_params.speed;1307 port->port_id = port->dts_params.id;1308 port->fm = port->dts_params.fman;1309 port->ext_pools_num = (u8)8;1310 1311 /* get FM revision */1312 fman_get_revision(port->fm, &port->rev_info);1313 1314 err = fill_soc_specific_params(port);1315 if (err)1316 goto err_port_cfg;1317 1318 switch (port->port_type) {1319 case FMAN_PORT_TYPE_RX:1320 set_rx_dflt_cfg(port, params);1321 fallthrough;1322 case FMAN_PORT_TYPE_TX:1323 set_tx_dflt_cfg(port, params, &port->dts_params);1324 fallthrough;1325 default:1326 set_dflt_cfg(port, params);1327 }1328 1329 /* Continue with other parameters */1330 /* set memory map pointers */1331 port->bmi_regs = base_addr + BMI_PORT_REGS_OFFSET;1332 port->qmi_regs = base_addr + QMI_PORT_REGS_OFFSET;1333 port->hwp_regs = base_addr + HWP_PORT_REGS_OFFSET;1334 1335 port->max_frame_length = DFLT_PORT_MAX_FRAME_LENGTH;1336 /* resource distribution. */1337 1338 port->fifo_bufs.num =1339 get_dflt_num_of_fifo_bufs(port->rev_info.major, port->port_type,1340 port->port_speed) * FMAN_BMI_FIFO_UNITS;1341 port->fifo_bufs.extra =1342 DFLT_PORT_EXTRA_NUM_OF_FIFO_BUFS * FMAN_BMI_FIFO_UNITS;1343 1344 port->open_dmas.num =1345 get_dflt_num_of_open_dmas(port->rev_info.major,1346 port->port_type, port->port_speed);1347 port->open_dmas.extra =1348 get_dflt_extra_num_of_open_dmas(port->rev_info.major,1349 port->port_type, port->port_speed);1350 port->tasks.num =1351 get_dflt_num_of_tasks(port->rev_info.major,1352 port->port_type, port->port_speed);1353 port->tasks.extra =1354 get_dflt_extra_num_of_tasks(port->rev_info.major,1355 port->port_type, port->port_speed);1356 1357 /* FM_HEAVY_TRAFFIC_SEQUENCER_HANG_ERRATA_FMAN_A006981 errata1358 * workaround1359 */1360 if ((port->rev_info.major == 6) && (port->rev_info.minor == 0) &&1361 (((port->port_type == FMAN_PORT_TYPE_TX) &&1362 (port->port_speed == 1000)))) {1363 port->open_dmas.num = 16;1364 port->open_dmas.extra = 0;1365 }1366 1367 if (port->rev_info.major >= 6 &&1368 port->port_type == FMAN_PORT_TYPE_TX &&1369 port->port_speed == 1000) {1370 /* FM_WRONG_RESET_VALUES_ERRATA_FMAN_A005127 Errata1371 * workaround1372 */1373 u32 reg;1374 1375 reg = 0x00001013;1376 iowrite32be(reg, &port->bmi_regs->tx.fmbm_tfp);1377 }1378 1379 return 0;1380 1381err_port_cfg:1382 kfree(port->cfg);1383 return -EINVAL;1384}1385EXPORT_SYMBOL(fman_port_config);1386 1387/*1388 * fman_port_use_kg_hash1389 * @port: A pointer to a FM Port module.1390 * @enable: enable or disable1391 *1392 * Sets the HW KeyGen or the BMI as HW Parser next engine, enabling1393 * or bypassing the KeyGen hashing of Rx traffic1394 */1395void fman_port_use_kg_hash(struct fman_port *port, bool enable)1396{1397 if (enable)1398 /* After the Parser frames go to KeyGen */1399 iowrite32be(NIA_ENG_HWK, &port->bmi_regs->rx.fmbm_rfpne);1400 else1401 /* After the Parser frames go to BMI */1402 iowrite32be(NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME,1403 &port->bmi_regs->rx.fmbm_rfpne);1404}1405EXPORT_SYMBOL(fman_port_use_kg_hash);1406 1407/**1408 * fman_port_init1409 * @port: A pointer to a FM Port module.1410 *1411 * Initializes the FM PORT module by defining the software structure and1412 * configuring the hardware registers.1413 *1414 * Return: 0 on success; Error code otherwise.1415 */1416int fman_port_init(struct fman_port *port)1417{1418 struct fman_port_init_params params;1419 struct fman_keygen *keygen;1420 struct fman_port_cfg *cfg;1421 int err;1422 1423 if (is_init_done(port->cfg))1424 return -EINVAL;1425 1426 err = fman_sp_build_buffer_struct(&port->cfg->int_context,1427 &port->cfg->buffer_prefix_content,1428 &port->cfg->buf_margins,1429 &port->buffer_offsets,1430 &port->internal_buf_offset);1431 if (err)1432 return err;1433 1434 cfg = port->cfg;1435 1436 if (port->port_type == FMAN_PORT_TYPE_RX) {1437 /* Call the external Buffer routine which also checks fifo1438 * size and updates it if necessary1439 */1440 /* define external buffer pools and pool depletion */1441 err = set_ext_buffer_pools(port);1442 if (err)1443 return err;1444 /* check if the largest external buffer pool is large enough */1445 if (cfg->buf_margins.start_margins + MIN_EXT_BUF_SIZE +1446 cfg->buf_margins.end_margins >1447 port->rx_pools_params.largest_buf_size) {1448 dev_err(port->dev, "%s: buf_margins.start_margins (%d) + minimum buf size (64) + buf_margins.end_margins (%d) is larger than maximum external buffer size (%d)\n",1449 __func__, cfg->buf_margins.start_margins,1450 cfg->buf_margins.end_margins,1451 port->rx_pools_params.largest_buf_size);1452 return -EINVAL;1453 }1454 }1455 1456 /* Call FM module routine for communicating parameters */1457 memset(¶ms, 0, sizeof(params));1458 params.port_id = port->port_id;1459 params.port_type = port->port_type;1460 params.port_speed = port->port_speed;1461 params.num_of_tasks = (u8)port->tasks.num;1462 params.num_of_extra_tasks = (u8)port->tasks.extra;1463 params.num_of_open_dmas = (u8)port->open_dmas.num;1464 params.num_of_extra_open_dmas = (u8)port->open_dmas.extra;1465 1466 if (port->fifo_bufs.num) {1467 err = verify_size_of_fifo(port);1468 if (err)1469 return err;1470 }1471 params.size_of_fifo = port->fifo_bufs.num;1472 params.extra_size_of_fifo = port->fifo_bufs.extra;1473 params.deq_pipeline_depth = port->cfg->tx_fifo_deq_pipeline_depth;1474 params.max_frame_length = port->max_frame_length;1475 1476 err = fman_set_port_params(port->fm, ¶ms);1477 if (err)1478 return err;1479 1480 err = init_low_level_driver(port);1481 if (err)1482 return err;1483 1484 if (port->cfg->pcd_fqs_count) {1485 keygen = port->dts_params.fman->keygen;1486 err = keygen_port_hashing_init(keygen, port->port_id,1487 port->cfg->pcd_base_fqid,1488 port->cfg->pcd_fqs_count);1489 if (err)1490 return err;1491 1492 fman_port_use_kg_hash(port, true);1493 }1494 1495 kfree(port->cfg);1496 port->cfg = NULL;1497 1498 return 0;1499}1500EXPORT_SYMBOL(fman_port_init);1501 1502/**1503 * fman_port_cfg_buf_prefix_content1504 * @port: A pointer to a FM Port module.1505 * @buffer_prefix_content: A structure of parameters describing1506 * the structure of the buffer.1507 * Out parameter:1508 * Start margin - offset of data from1509 * start of external buffer.1510 * Defines the structure, size and content of the application buffer.1511 * The prefix, in Tx ports, if 'pass_prs_result', the application should set1512 * a value to their offsets in the prefix of the FM will save the first1513 * 'priv_data_size', than, depending on 'pass_prs_result' and1514 * 'pass_time_stamp', copy parse result and timeStamp, and the packet itself1515 * (in this order), to the application buffer, and to offset.1516 * Calling this routine changes the buffer margins definitions in the internal1517 * driver data base from its default configuration:1518 * Data size: [DEFAULT_PORT_BUFFER_PREFIX_CONTENT_PRIV_DATA_SIZE]1519 * Pass Parser result: [DEFAULT_PORT_BUFFER_PREFIX_CONTENT_PASS_PRS_RESULT].1520 * Pass timestamp: [DEFAULT_PORT_BUFFER_PREFIX_CONTENT_PASS_TIME_STAMP].1521 * May be used for all ports1522 *1523 * Allowed only following fman_port_config() and before fman_port_init().1524 *1525 * Return: 0 on success; Error code otherwise.1526 */1527int fman_port_cfg_buf_prefix_content(struct fman_port *port,1528 struct fman_buffer_prefix_content *1529 buffer_prefix_content)1530{1531 if (is_init_done(port->cfg))1532 return -EINVAL;1533 1534 memcpy(&port->cfg->buffer_prefix_content,1535 buffer_prefix_content,1536 sizeof(struct fman_buffer_prefix_content));1537 /* if data_align was not initialized by user,1538 * we return to driver's default1539 */1540 if (!port->cfg->buffer_prefix_content.data_align)1541 port->cfg->buffer_prefix_content.data_align =1542 DFLT_PORT_BUFFER_PREFIX_CONTEXT_DATA_ALIGN;1543 1544 return 0;1545}1546EXPORT_SYMBOL(fman_port_cfg_buf_prefix_content);1547 1548/**1549 * fman_port_disable1550 * @port: A pointer to a FM Port module.1551 *1552 * Gracefully disable an FM port. The port will not start new tasks after all1553 * tasks associated with the port are terminated.1554 *1555 * This is a blocking routine, it returns after port is gracefully stopped,1556 * i.e. the port will not except new frames, but it will finish all frames1557 * or tasks which were already began.1558 * Allowed only following fman_port_init().1559 *1560 * Return: 0 on success; Error code otherwise.1561 */1562int fman_port_disable(struct fman_port *port)1563{1564 u32 __iomem *bmi_cfg_reg, *bmi_status_reg;1565 u32 tmp;1566 bool rx_port, failure = false;1567 int count;1568 1569 if (!is_init_done(port->cfg))1570 return -EINVAL;1571 1572 switch (port->port_type) {1573 case FMAN_PORT_TYPE_RX:1574 bmi_cfg_reg = &port->bmi_regs->rx.fmbm_rcfg;1575 bmi_status_reg = &port->bmi_regs->rx.fmbm_rst;1576 rx_port = true;1577 break;1578 case FMAN_PORT_TYPE_TX:1579 bmi_cfg_reg = &port->bmi_regs->tx.fmbm_tcfg;1580 bmi_status_reg = &port->bmi_regs->tx.fmbm_tst;1581 rx_port = false;1582 break;1583 default:1584 return -EINVAL;1585 }1586 1587 /* Disable QMI */1588 if (!rx_port) {1589 tmp = ioread32be(&port->qmi_regs->fmqm_pnc) & ~QMI_PORT_CFG_EN;1590 iowrite32be(tmp, &port->qmi_regs->fmqm_pnc);1591 1592 /* Wait for QMI to finish FD handling */1593 count = 100;1594 do {1595 udelay(10);1596 tmp = ioread32be(&port->qmi_regs->fmqm_pns);1597 } while ((tmp & QMI_PORT_STATUS_DEQ_FD_BSY) && --count);1598 1599 if (count == 0) {1600 /* Timeout */1601 failure = true;1602 }1603 }1604 1605 /* Disable BMI */1606 tmp = ioread32be(bmi_cfg_reg) & ~BMI_PORT_CFG_EN;1607 iowrite32be(tmp, bmi_cfg_reg);1608 1609 /* Wait for graceful stop end */1610 count = 500;1611 do {1612 udelay(10);1613 tmp = ioread32be(bmi_status_reg);1614 } while ((tmp & BMI_PORT_STATUS_BSY) && --count);1615 1616 if (count == 0) {1617 /* Timeout */1618 failure = true;1619 }1620 1621 if (failure)1622 dev_dbg(port->dev, "%s: FMan Port[%d]: BMI or QMI is Busy. Port forced down\n",1623 __func__, port->port_id);1624 1625 return 0;1626}1627EXPORT_SYMBOL(fman_port_disable);1628 1629/**1630 * fman_port_enable1631 * @port: A pointer to a FM Port module.1632 *1633 * A runtime routine provided to allow disable/enable of port.1634 *1635 * Allowed only following fman_port_init().1636 *1637 * Return: 0 on success; Error code otherwise.1638 */1639int fman_port_enable(struct fman_port *port)1640{1641 u32 __iomem *bmi_cfg_reg;1642 u32 tmp;1643 bool rx_port;1644 1645 if (!is_init_done(port->cfg))1646 return -EINVAL;1647 1648 switch (port->port_type) {1649 case FMAN_PORT_TYPE_RX:1650 bmi_cfg_reg = &port->bmi_regs->rx.fmbm_rcfg;1651 rx_port = true;1652 break;1653 case FMAN_PORT_TYPE_TX:1654 bmi_cfg_reg = &port->bmi_regs->tx.fmbm_tcfg;1655 rx_port = false;1656 break;1657 default:1658 return -EINVAL;1659 }1660 1661 /* Enable QMI */1662 if (!rx_port) {1663 tmp = ioread32be(&port->qmi_regs->fmqm_pnc) | QMI_PORT_CFG_EN;1664 iowrite32be(tmp, &port->qmi_regs->fmqm_pnc);1665 }1666 1667 /* Enable BMI */1668 tmp = ioread32be(bmi_cfg_reg) | BMI_PORT_CFG_EN;1669 iowrite32be(tmp, bmi_cfg_reg);1670 1671 return 0;1672}1673EXPORT_SYMBOL(fman_port_enable);1674 1675/**1676 * fman_port_bind1677 * @dev: FMan Port OF device pointer1678 *1679 * Bind to a specific FMan Port.1680 *1681 * Allowed only after the port was created.1682 *1683 * Return: A pointer to the FMan port device.1684 */1685struct fman_port *fman_port_bind(struct device *dev)1686{1687 return (struct fman_port *)(dev_get_drvdata(get_device(dev)));1688}1689EXPORT_SYMBOL(fman_port_bind);1690 1691/**1692 * fman_port_get_qman_channel_id1693 * @port: Pointer to the FMan port devuce1694 *1695 * Get the QMan channel ID for the specific port1696 *1697 * Return: QMan channel ID1698 */1699u32 fman_port_get_qman_channel_id(struct fman_port *port)1700{1701 return port->dts_params.qman_channel_id;1702}1703EXPORT_SYMBOL(fman_port_get_qman_channel_id);1704 1705/**1706 * fman_port_get_device1707 * @port: Pointer to the FMan port device1708 *1709 * Get the 'struct device' associated to the specified FMan port device1710 *1711 * Return: pointer to associated 'struct device'1712 */1713struct device *fman_port_get_device(struct fman_port *port)1714{1715 return port->dev;1716}1717EXPORT_SYMBOL(fman_port_get_device);1718 1719int fman_port_get_hash_result_offset(struct fman_port *port, u32 *offset)1720{1721 if (port->buffer_offsets.hash_result_offset == ILLEGAL_BASE)1722 return -EINVAL;1723 1724 *offset = port->buffer_offsets.hash_result_offset;1725 1726 return 0;1727}1728EXPORT_SYMBOL(fman_port_get_hash_result_offset);1729 1730int fman_port_get_tstamp(struct fman_port *port, const void *data, u64 *tstamp)1731{1732 if (port->buffer_offsets.time_stamp_offset == ILLEGAL_BASE)1733 return -EINVAL;1734 1735 *tstamp = be64_to_cpu(*(__be64 *)(data +1736 port->buffer_offsets.time_stamp_offset));1737 1738 return 0;1739}1740EXPORT_SYMBOL(fman_port_get_tstamp);1741 1742static int fman_port_probe(struct platform_device *of_dev)1743{1744 struct fman_port *port;1745 struct fman *fman;1746 struct device_node *fm_node, *port_node;1747 struct platform_device *fm_pdev;1748 struct resource res;1749 struct resource *dev_res;1750 u32 val;1751 int err = 0;1752 enum fman_port_type port_type;1753 u16 port_speed;1754 u8 port_id;1755 1756 port = kzalloc(sizeof(*port), GFP_KERNEL);1757 if (!port)1758 return -ENOMEM;1759 1760 port->dev = &of_dev->dev;1761 1762 port_node = of_node_get(of_dev->dev.of_node);1763 1764 /* Get the FM node */1765 fm_node = of_get_parent(port_node);1766 if (!fm_node) {1767 dev_err(port->dev, "%s: of_get_parent() failed\n", __func__);1768 err = -ENODEV;1769 goto return_err;1770 }1771 1772 fm_pdev = of_find_device_by_node(fm_node);1773 of_node_put(fm_node);1774 if (!fm_pdev) {1775 err = -EINVAL;1776 goto return_err;1777 }1778 1779 fman = dev_get_drvdata(&fm_pdev->dev);1780 if (!fman) {1781 err = -EINVAL;1782 goto put_device;1783 }1784 1785 err = of_property_read_u32(port_node, "cell-index", &val);1786 if (err) {1787 dev_err(port->dev, "%s: reading cell-index for %pOF failed\n",1788 __func__, port_node);1789 err = -EINVAL;1790 goto put_device;1791 }1792 port_id = (u8)val;1793 port->dts_params.id = port_id;1794 1795 if (of_device_is_compatible(port_node, "fsl,fman-v3-port-tx")) {1796 port_type = FMAN_PORT_TYPE_TX;1797 port_speed = 1000;1798 if (of_property_read_bool(port_node, "fsl,fman-10g-port"))1799 port_speed = 10000;1800 1801 } else if (of_device_is_compatible(port_node, "fsl,fman-v2-port-tx")) {1802 if (port_id >= TX_10G_PORT_BASE)1803 port_speed = 10000;1804 else1805 port_speed = 1000;1806 port_type = FMAN_PORT_TYPE_TX;1807 1808 } else if (of_device_is_compatible(port_node, "fsl,fman-v3-port-rx")) {1809 port_type = FMAN_PORT_TYPE_RX;1810 port_speed = 1000;1811 if (of_property_read_bool(port_node, "fsl,fman-10g-port"))1812 port_speed = 10000;1813 1814 } else if (of_device_is_compatible(port_node, "fsl,fman-v2-port-rx")) {1815 if (port_id >= RX_10G_PORT_BASE)1816 port_speed = 10000;1817 else1818 port_speed = 1000;1819 port_type = FMAN_PORT_TYPE_RX;1820 1821 } else {1822 dev_err(port->dev, "%s: Illegal port type\n", __func__);1823 err = -EINVAL;1824 goto put_device;1825 }1826 1827 port->dts_params.type = port_type;1828 port->dts_params.speed = port_speed;1829 1830 if (port_type == FMAN_PORT_TYPE_TX) {1831 u32 qman_channel_id;1832 1833 qman_channel_id = fman_get_qman_channel_id(fman, port_id);1834 if (qman_channel_id == 0) {1835 dev_err(port->dev, "%s: incorrect qman-channel-id\n",1836 __func__);1837 err = -EINVAL;1838 goto put_device;1839 }1840 port->dts_params.qman_channel_id = qman_channel_id;1841 }1842 1843 err = of_address_to_resource(port_node, 0, &res);1844 if (err < 0) {1845 dev_err(port->dev, "%s: of_address_to_resource() failed\n",1846 __func__);1847 err = -ENOMEM;1848 goto put_device;1849 }1850 1851 port->dts_params.fman = fman;1852 1853 of_node_put(port_node);1854 1855 dev_res = __devm_request_region(port->dev, &res, res.start,1856 resource_size(&res), "fman-port");1857 if (!dev_res) {1858 dev_err(port->dev, "%s: __devm_request_region() failed\n",1859 __func__);1860 err = -EINVAL;1861 goto free_port;1862 }1863 1864 port->dts_params.base_addr = devm_ioremap(port->dev, res.start,1865 resource_size(&res));1866 if (!port->dts_params.base_addr)1867 dev_err(port->dev, "%s: devm_ioremap() failed\n", __func__);1868 1869 dev_set_drvdata(&of_dev->dev, port);1870 1871 return 0;1872 1873put_device:1874 put_device(&fm_pdev->dev);1875return_err:1876 of_node_put(port_node);1877free_port:1878 kfree(port);1879 return err;1880}1881 1882static const struct of_device_id fman_port_match[] = {1883 {.compatible = "fsl,fman-v3-port-rx"},1884 {.compatible = "fsl,fman-v2-port-rx"},1885 {.compatible = "fsl,fman-v3-port-tx"},1886 {.compatible = "fsl,fman-v2-port-tx"},1887 {}1888};1889 1890MODULE_DEVICE_TABLE(of, fman_port_match);1891 1892static struct platform_driver fman_port_driver = {1893 .driver = {1894 .name = "fsl-fman-port",1895 .of_match_table = fman_port_match,1896 },1897 .probe = fman_port_probe,1898};1899 1900static int __init fman_port_load(void)1901{1902 int err;1903 1904 pr_debug("FSL DPAA FMan driver\n");1905 1906 err = platform_driver_register(&fman_port_driver);1907 if (err < 0)1908 pr_err("Error, platform_driver_register() = %d\n", err);1909 1910 return err;1911}1912module_init(fman_port_load);1913 1914static void __exit fman_port_unload(void)1915{1916 platform_driver_unregister(&fman_port_driver);1917}1918module_exit(fman_port_unload);1919 1920MODULE_LICENSE("Dual BSD/GPL");1921MODULE_DESCRIPTION("Freescale DPAA Frame Manager Port driver");1922