brintos

brintos / linux-shallow public Read only

0
0
Text · 51.6 KiB · f17a4e5 Raw
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, &regs->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, &regs->fmbm_rfp);474 475	if (cfg->excessive_threshold_register)476		/* always allow access to the extra resources */477		iowrite32be(BMI_RX_FIFO_THRESHOLD_ETHE, &regs->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, &regs->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, &regs->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, &regs->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, &regs->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, &regs->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, &regs->fmbm_rfne);522 523	/* Parser Next Engine NIA */524	iowrite32be(NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME, &regs->fmbm_rfpne);525 526	/* Enqueue NIA */527	iowrite32be(NIA_ENG_QMI_ENQ | NIA_ORDER_RESTOR, &regs->fmbm_rfene);528 529	/* Default/error queues */530	iowrite32be((cfg->dflt_fqid & DFLT_FQ_ID), &regs->fmbm_rfqid);531	iowrite32be((cfg->err_fqid & DFLT_FQ_ID), &regs->fmbm_refqid);532 533	/* Discard/error masks */534	iowrite32be(cfg->discard_mask, &regs->fmbm_rfsdm);535	iowrite32be(cfg->err_mask, &regs->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, &regs->fmbm_tcfg);549 550	/* DMA attributes */551	tmp = (u32)cfg->dma_swap_data << BMI_DMA_ATTR_SWP_SHIFT;552	iowrite32be(tmp, &regs->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, &regs->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, &regs->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, &regs->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, &regs->fmbm_tfca);581 582	/* Dequeue NIA + enqueue NIA */583	iowrite32be(NIA_ENG_QMI_DEQ, &regs->fmbm_tfdne);584	iowrite32be(NIA_ENG_QMI_ENQ | NIA_ORDER_RESTOR, &regs->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, &regs->fmbm_tfne);589	if (!cfg->dflt_fqid && cfg->dont_release_buf) {590		iowrite32be(DFLT_FQ_ID, &regs->fmbm_tcfqid);591		iowrite32be(NIA_ENG_BMI | NIA_BMI_AC_TX_RELEASE,592			    &regs->fmbm_tfene);593		if (cfg->fmbm_tfne_has_features)594			iowrite32be(ioread32be(&regs->fmbm_tfne) & ~BMI_EBD_EN,595				    &regs->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, &regs->fmbm_tcfqid);601	iowrite32be((cfg->err_fqid & DFLT_FQ_ID), &regs->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, &regs->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			    &regs->fmqm_pnen);624		/* Dequeue NIA */625		iowrite32be(NIA_ENG_BMI | NIA_BMI_AC_TX, &regs->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, &regs->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, &regs->fmpr_pcac);673 674	while (cnt-- > 0 &&675	       (ioread32be(&regs->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, &regs->fmpr_pcac);687 688	while (cnt-- > 0 &&689	       !(ioread32be(&regs->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, &regs->pmda[i].ssa);705		iowrite32be(0xffffffff, &regs->pmda[i].lcv);706	}707 708	/* Short packet padding removal from checksum calculation */709	iowrite32be(HWP_HXS_SH_PAD_REM, &regs->pmda[HWP_HXS_TCP_OFFSET].ssa);710	iowrite32be(HWP_HXS_SH_PAD_REM, &regs->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(&params, 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, &params);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